source: src/config.cpp@ 23b830

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 23b830 was fcd7b6, checked in by Frederik Heber <heber@…>, 16 years ago

In molecule::OutputTrajectories() ActOnAllAtoms() with new function atom::OutputTrajectory() is used.

For this to work, I had to change the Trajectory struct that was so far included in molecule.hpp to be incorporated directly into the class atom.
NOTE: This incorporation is incomplete and a ticket (#34) has been filed to remind of this issue.
However, the trajectory is better suited to reside in atom anyway and was probably just put in molecule due to memory prejudices against STL vector<>.
Functions in molecule.cpp, config.cpp, molecule_geometry.cpp and molecule_dynamics.cpp were adapted (changed from Trajectories[atom *] to atom *->Trajectory).
And the atom pointer in the Trajectory structure was removed.

  • Property mode set to 100755
File size: 89.5 KB
Line 
1/** \file config.cpp
2 *
3 * Function implementations for the class config.
4 *
5 */
6
7#include "config.hpp"
8#include "memoryallocator.hpp"
9
10/******************************** Functions for class ConfigFileBuffer **********************/
11
12/** Structure containing compare function for Ion_Type sorting.
13 */
14struct IonTypeCompare {
15 bool operator()(const char* s1, const char *s2) const {
16 char number1[8];
17 char number2[8];
18 char *dummy1, *dummy2;
19 //cout << s1 << " " << s2 << endl;
20 dummy1 = strchr(s1, '_')+sizeof(char)*5; // go just after "Ion_Type"
21 dummy2 = strchr(dummy1, '_');
22 strncpy(number1, dummy1, dummy2-dummy1); // copy the number
23 number1[dummy2-dummy1]='\0';
24 dummy1 = strchr(s2, '_')+sizeof(char)*5; // go just after "Ion_Type"
25 dummy2 = strchr(dummy1, '_');
26 strncpy(number2, dummy1, dummy2-dummy1); // copy the number
27 number2[dummy2-dummy1]='\0';
28 if (atoi(number1) != atoi(number2))
29 return (atoi(number1) < atoi(number2));
30 else {
31 dummy1 = strchr(s1, '_')+sizeof(char);
32 dummy1 = strchr(dummy1, '_')+sizeof(char);
33 dummy2 = strchr(dummy1, ' ') < strchr(dummy1, '\t') ? strchr(dummy1, ' ') : strchr(dummy1, '\t');
34 strncpy(number1, dummy1, dummy2-dummy1); // copy the number
35 number1[dummy2-dummy1]='\0';
36 dummy1 = strchr(s2, '_')+sizeof(char);
37 dummy1 = strchr(dummy1, '_')+sizeof(char);
38 dummy2 = strchr(dummy1, ' ') < strchr(dummy1, '\t') ? strchr(dummy1, ' ') : strchr(dummy1, '\t');
39 strncpy(number2, dummy1, dummy2-dummy1); // copy the number
40 number2[dummy2-dummy1]='\0';
41 return (atoi(number1) < atoi(number2));
42 }
43 }
44};
45
46/** Constructor for ConfigFileBuffer class.
47 */
48ConfigFileBuffer::ConfigFileBuffer()
49{
50 NoLines = 0;
51 CurrentLine = 0;
52 buffer = NULL;
53 LineMapping = NULL;
54}
55
56/** Constructor for ConfigFileBuffer class with filename to be parsed.
57 * \param *filename file name
58 */
59ConfigFileBuffer::ConfigFileBuffer(char *filename)
60{
61 NoLines = 0;
62 CurrentLine = 0;
63 buffer = NULL;
64 LineMapping = NULL;
65 ifstream *file = NULL;
66 char line[MAXSTRINGSIZE];
67
68 // prescan number of lines
69 file= new ifstream(filename);
70 if (file == NULL) {
71 cerr << "ERROR: config file " << filename << " missing!" << endl;
72 return;
73 }
74 NoLines = 0; // we're overcounting by one
75 long file_position = file->tellg(); // mark current position
76 do {
77 file->getline(line, 256);
78 NoLines++;
79 } while (!file->eof());
80 file->clear();
81 file->seekg(file_position, ios::beg);
82 cout << Verbose(1) << NoLines-1 << " lines were recognized." << endl;
83
84 // allocate buffer's 1st dimension
85 if (buffer != NULL) {
86 cerr << "ERROR: FileBuffer->buffer is not NULL!" << endl;
87 return;
88 } else
89 buffer = Malloc<char*>(NoLines, "ConfigFileBuffer::ConfigFileBuffer: **buffer");
90
91 // scan each line and put into buffer
92 int lines=0;
93 int i;
94 do {
95 buffer[lines] = Malloc<char>(MAXSTRINGSIZE, "ConfigFileBuffer::ConfigFileBuffer: *buffer[]");
96 file->getline(buffer[lines], MAXSTRINGSIZE-1);
97 i = strlen(buffer[lines]);
98 buffer[lines][i] = '\n';
99 buffer[lines][i+1] = '\0';
100 lines++;
101 } while((!file->eof()) && (lines < NoLines));
102 cout << Verbose(1) << lines-1 << " lines were read into the buffer." << endl;
103
104 // close and exit
105 file->close();
106 file->clear();
107 delete(file);
108}
109
110/** Destructor for ConfigFileBuffer class.
111 */
112ConfigFileBuffer::~ConfigFileBuffer()
113{
114 for(int i=0;i<NoLines;++i)
115 Free(&buffer[i]);
116 Free(&buffer);
117 Free(&LineMapping);
118}
119
120
121/** Create trivial mapping.
122 */
123void ConfigFileBuffer::InitMapping()
124{
125 LineMapping = Malloc<int>(NoLines, "ConfigFileBuffer::InitMapping: *LineMapping");
126 for (int i=0;i<NoLines;i++)
127 LineMapping[i] = i;
128}
129
130/** Creates a mapping for the \a *FileBuffer's lines containing the Ion_Type keyword such that they are sorted.
131 * \a *map on return contains a list of NoAtom entries such that going through the list, yields indices to the
132 * lines in \a *FileBuffer in a sorted manner of the Ion_Type?_? keywords. We assume that ConfigFileBuffer::CurrentLine
133 * points to first Ion_Type entry.
134 * \param *FileBuffer pointer to buffer structure
135 * \param NoAtoms of subsequent lines to look at
136 */
137void ConfigFileBuffer::MapIonTypesInBuffer(int NoAtoms)
138{
139 map<const char *, int, IonTypeCompare> LineList;
140 if (LineMapping == NULL) {
141 cerr << "map pointer is NULL: " << LineMapping << endl;
142 return;
143 }
144
145 // put all into hashed map
146 for (int i=0; i<NoAtoms; ++i) {
147 LineList.insert(pair<const char *, int> (buffer[CurrentLine+i], CurrentLine+i));
148 }
149
150 // fill map
151 int nr=0;
152 for (map<const char *, int, IonTypeCompare>::iterator runner = LineList.begin(); runner != LineList.end(); ++runner) {
153 if (CurrentLine+nr < NoLines)
154 LineMapping[CurrentLine+(nr++)] = runner->second;
155 else
156 cerr << "config::MapIonTypesInBuffer - NoAtoms is wrong: We are past the end of the file!" << endl;
157 }
158}
159
160/************************************* Functions for class config ***************************/
161
162/** Constructor for config file class.
163 */
164config::config()
165{
166 mainname = Malloc<char>(MAXSTRINGSIZE,"config constructor: mainname");
167 defaultpath = Malloc<char>(MAXSTRINGSIZE,"config constructor: defaultpath");
168 pseudopotpath = Malloc<char>(MAXSTRINGSIZE,"config constructor: pseudopotpath");
169 databasepath = Malloc<char>(MAXSTRINGSIZE,"config constructor: databasepath");
170 configpath = Malloc<char>(MAXSTRINGSIZE,"config constructor: configpath");
171 configname = Malloc<char>(MAXSTRINGSIZE,"config constructor: configname");
172 ThermostatImplemented = Malloc<int>(MaxThermostats, "config constructor: *ThermostatImplemented");
173 ThermostatNames = Malloc<char*>(MaxThermostats, "config constructor: *ThermostatNames");
174 for (int j=0;j<MaxThermostats;j++)
175 ThermostatNames[j] = Malloc<char>(12, "config constructor: ThermostatNames[]");
176 Thermostat = 4;
177 alpha = 0.;
178 ScaleTempStep = 25;
179 TempFrequency = 2.5;
180 strcpy(mainname,"pcp");
181 strcpy(defaultpath,"not specified");
182 strcpy(pseudopotpath,"not specified");
183 configpath[0]='\0';
184 configname[0]='\0';
185 basis = "3-21G";
186
187 strcpy(ThermostatNames[0],"None");
188 ThermostatImplemented[0] = 1;
189 strcpy(ThermostatNames[1],"Woodcock");
190 ThermostatImplemented[1] = 1;
191 strcpy(ThermostatNames[2],"Gaussian");
192 ThermostatImplemented[2] = 1;
193 strcpy(ThermostatNames[3],"Langevin");
194 ThermostatImplemented[3] = 1;
195 strcpy(ThermostatNames[4],"Berendsen");
196 ThermostatImplemented[4] = 1;
197 strcpy(ThermostatNames[5],"NoseHoover");
198 ThermostatImplemented[5] = 1;
199
200 FastParsing = false;
201 ProcPEGamma=8;
202 ProcPEPsi=1;
203 DoOutVis=0;
204 DoOutMes=1;
205 DoOutNICS=0;
206 DoOutOrbitals=0;
207 DoOutCurrent=0;
208 DoPerturbation=0;
209 DoFullCurrent=0;
210 DoWannier=0;
211 DoConstrainedMD=0;
212 CommonWannier=0;
213 SawtoothStart=0.01;
214 VectorPlane=0;
215 VectorCut=0;
216 UseAddGramSch=1;
217 Seed=1;
218
219 MaxOuterStep=0;
220 Deltat=0.01;
221 OutVisStep=10;
222 OutSrcStep=5;
223 TargetTemp=0.00095004455;
224 ScaleTempStep=25;
225 MaxPsiStep=0;
226 EpsWannier=1e-7;
227
228 MaxMinStep=100;
229 RelEpsTotalEnergy=1e-7;
230 RelEpsKineticEnergy=1e-5;
231 MaxMinStopStep=1;
232 MaxMinGapStopStep=0;
233 MaxInitMinStep=100;
234 InitRelEpsTotalEnergy=1e-5;
235 InitRelEpsKineticEnergy=1e-4;
236 InitMaxMinStopStep=1;
237 InitMaxMinGapStopStep=0;
238
239 //BoxLength[NDIM*NDIM];
240
241 ECut=128.;
242 MaxLevel=5;
243 RiemannTensor=0;
244 LevRFactor=0;
245 RiemannLevel=0;
246 Lev0Factor=2;
247 RTActualUse=0;
248 PsiType=0;
249 MaxPsiDouble=0;
250 PsiMaxNoUp=0;
251 PsiMaxNoDown=0;
252 AddPsis=0;
253
254 RCut=20.;
255 StructOpt=0;
256 IsAngstroem=1;
257 RelativeCoord=0;
258 MaxTypes=0;
259};
260
261
262/** Destructor for config file class.
263 */
264config::~config()
265{
266 Free(&mainname);
267 Free(&defaultpath);
268 Free(&pseudopotpath);
269 Free(&databasepath);
270 Free(&configpath);
271 Free(&configname);
272 Free(&ThermostatImplemented);
273 for (int j=0;j<MaxThermostats;j++)
274 Free(&ThermostatNames[j]);
275 Free(&ThermostatNames);
276};
277
278/** Readin of Thermostat related values from parameter file.
279 * \param *fb file buffer containing the config file
280 */
281void config::InitThermostats(class ConfigFileBuffer *fb)
282{
283 char *thermo = Malloc<char>(12, "IonsInitRead: thermo");
284 int verbose = 0;
285
286 // read desired Thermostat from file along with needed additional parameters
287 if (ParseForParameter(verbose,fb,"Thermostat", 0, 1, 1, string_type, thermo, 1, optional)) {
288 if (strcmp(thermo, ThermostatNames[0]) == 0) { // None
289 if (ThermostatImplemented[0] == 1) {
290 Thermostat = None;
291 } else {
292 cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
293 Thermostat = None;
294 }
295 } else if (strcmp(thermo, ThermostatNames[1]) == 0) { // Woodcock
296 if (ThermostatImplemented[1] == 1) {
297 Thermostat = Woodcock;
298 ParseForParameter(verbose,fb,"Thermostat", 0, 2, 1, int_type, &ScaleTempStep, 1, critical); // read scaling frequency
299 } else {
300 cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
301 Thermostat = None;
302 }
303 } else if (strcmp(thermo, ThermostatNames[2]) == 0) { // Gaussian
304 if (ThermostatImplemented[2] == 1) {
305 Thermostat = Gaussian;
306 ParseForParameter(verbose,fb,"Thermostat", 0, 2, 1, int_type, &ScaleTempStep, 1, critical); // read collision rate
307 } else {
308 cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
309 Thermostat = None;
310 }
311 } else if (strcmp(thermo, ThermostatNames[3]) == 0) { // Langevin
312 if (ThermostatImplemented[3] == 1) {
313 Thermostat = Langevin;
314 ParseForParameter(verbose,fb,"Thermostat", 0, 2, 1, double_type, &TempFrequency, 1, critical); // read gamma
315 if (ParseForParameter(verbose,fb,"Thermostat", 0, 3, 1, double_type, &alpha, 1, optional)) {
316 cout << Verbose(2) << "Extended Stochastic Thermostat detected with interpolation coefficient " << alpha << "." << endl;
317 } else {
318 alpha = 1.;
319 }
320 } else {
321 cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
322 Thermostat = None;
323 }
324 } else if (strcmp(thermo, ThermostatNames[4]) == 0) { // Berendsen
325 if (ThermostatImplemented[4] == 1) {
326 Thermostat = Berendsen;
327 ParseForParameter(verbose,fb,"Thermostat", 0, 2, 1, double_type, &TempFrequency, 1, critical); // read \tau_T
328 } else {
329 cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
330 Thermostat = None;
331 }
332 } else if (strcmp(thermo, ThermostatNames[5]) == 0) { // Nose-Hoover
333 if (ThermostatImplemented[5] == 1) {
334 Thermostat = NoseHoover;
335 ParseForParameter(verbose,fb,"Thermostat", 0, 2, 1, double_type, &HooverMass, 1, critical); // read Hoovermass
336 alpha = 0.;
337 } else {
338 cout << Verbose(1) << "Warning: " << ThermostatNames[0] << " thermostat not implemented, falling back to None." << endl;
339 Thermostat = None;
340 }
341 } else {
342 cout << Verbose(1) << " Warning: thermostat name was not understood!" << endl;
343 Thermostat = None;
344 }
345 } else {
346 if ((MaxOuterStep > 0) && (TargetTemp != 0))
347 cout << Verbose(2) << "No thermostat chosen despite finite temperature MD, falling back to None." << endl;
348 Thermostat = None;
349 }
350 Free(&thermo);
351};
352
353
354/** Displays menu for editing each entry of the config file.
355 * Nothing fancy here, just lots of cout << Verbose(0)s for the menu and a switch/case
356 * for each entry of the config file structure.
357 */
358void config::Edit()
359{
360 char choice;
361
362 do {
363 cout << Verbose(0) << "===========EDIT CONFIGURATION============================" << endl;
364 cout << Verbose(0) << " A - mainname (prefix for all runtime files)" << endl;
365 cout << Verbose(0) << " B - Default path (for runtime files)" << endl;
366 cout << Verbose(0) << " C - Path of pseudopotential files" << endl;
367 cout << Verbose(0) << " D - Number of coefficient sharing processes" << endl;
368 cout << Verbose(0) << " E - Number of wave function sharing processes" << endl;
369 cout << Verbose(0) << " F - 0: Don't output density for OpenDX, 1: do" << endl;
370 cout << Verbose(0) << " G - 0: Don't output physical data, 1: do" << endl;
371 cout << Verbose(0) << " H - 0: Don't output densities of each unperturbed orbital for OpenDX, 1: do" << endl;
372 cout << Verbose(0) << " I - 0: Don't output current density for OpenDX, 1: do" << endl;
373 cout << Verbose(0) << " J - 0: Don't do the full current calculation, 1: do" << endl;
374 cout << Verbose(0) << " K - 0: Don't do perturbation calculation to obtain susceptibility and shielding, 1: do" << endl;
375 cout << Verbose(0) << " L - 0: Wannier centres as calculated, 1: common centre for all, 2: unite centres according to spread, 3: cell centre, 4: shifted to nearest grid point" << endl;
376 cout << Verbose(0) << " M - Absolute begin of unphysical sawtooth transfer for position operator within cell" << endl;
377 cout << Verbose(0) << " N - (0,1,2) x,y,z-plane to do two-dimensional current vector cut" << endl;
378 cout << Verbose(0) << " O - Absolute position along vector cut axis for cut plane" << endl;
379 cout << Verbose(0) << " P - Additional Gram-Schmidt-Orthonormalization to stabilize numerics" << endl;
380 cout << Verbose(0) << " Q - Initial integer value of random number generator" << endl;
381 cout << Verbose(0) << " R - for perturbation 0, for structure optimization defines upper limit of iterations" << endl;
382 cout << Verbose(0) << " T - Output visual after ...th step" << endl;
383 cout << Verbose(0) << " U - Output source densities of wave functions after ...th step" << endl;
384 cout << Verbose(0) << " X - minimization iterations per wave function, if unsure leave at default value 0" << endl;
385 cout << Verbose(0) << " Y - tolerance value for total spread in iterative Jacobi diagonalization" << endl;
386 cout << Verbose(0) << " Z - Maximum number of minimization iterations" << endl;
387 cout << Verbose(0) << " a - Relative change in total energy to stop min. iteration" << endl;
388 cout << Verbose(0) << " b - Relative change in kinetic energy to stop min. iteration" << endl;
389 cout << Verbose(0) << " c - Check stop conditions every ..th step during min. iteration" << endl;
390 cout << Verbose(0) << " e - Maximum number of minimization iterations during initial level" << endl;
391 cout << Verbose(0) << " f - Relative change in total energy to stop min. iteration during initial level" << endl;
392 cout << Verbose(0) << " g - Relative change in kinetic energy to stop min. iteration during initial level" << endl;
393 cout << Verbose(0) << " h - Check stop conditions every ..th step during min. iteration during initial level" << endl;
394// cout << Verbose(0) << " j - six lower diagonal entries of matrix, defining the unit cell" << endl;
395 cout << Verbose(0) << " k - Energy cutoff of plane wave basis in Hartree" << endl;
396 cout << Verbose(0) << " l - Maximum number of levels in multi-level-ansatz" << endl;
397 cout << Verbose(0) << " m - Factor by which grid nodes increase between standard and upper level" << endl;
398 cout << Verbose(0) << " n - 0: Don't use RiemannTensor, 1: Do" << endl;
399 cout << Verbose(0) << " o - Factor by which grid nodes increase between Riemann and standard(?) level" << endl;
400 cout << Verbose(0) << " p - Number of Riemann levels" << endl;
401 cout << Verbose(0) << " r - 0: Don't Use RiemannTensor, 1: Do" << endl;
402 cout << Verbose(0) << " s - 0: Doubly occupied orbitals, 1: Up-/Down-Orbitals" << endl;
403 cout << Verbose(0) << " t - Number of orbitals (depends pn SpinType)" << endl;
404 cout << Verbose(0) << " u - Number of SpinUp orbitals (depends on SpinType)" << endl;
405 cout << Verbose(0) << " v - Number of SpinDown orbitals (depends on SpinType)" << endl;
406 cout << Verbose(0) << " w - Number of additional, unoccupied orbitals" << endl;
407 cout << Verbose(0) << " x - radial cutoff for ewald summation in Bohrradii" << endl;
408 cout << Verbose(0) << " y - 0: Don't do structure optimization beforehand, 1: Do" << endl;
409 cout << Verbose(0) << " z - 0: Units are in Bohr radii, 1: units are in Aengstrom" << endl;
410 cout << Verbose(0) << " i - 0: Coordinates given in file are absolute, 1: ... are relative to unit cell" << endl;
411 cout << Verbose(0) << "=========================================================" << endl;
412 cout << Verbose(0) << "INPUT: ";
413 cin >> choice;
414
415 switch (choice) {
416 case 'A': // mainname
417 cout << Verbose(0) << "Old: " << config::mainname << "\t new: ";
418 cin >> config::mainname;
419 break;
420 case 'B': // defaultpath
421 cout << Verbose(0) << "Old: " << config::defaultpath << "\t new: ";
422 cin >> config::defaultpath;
423 break;
424 case 'C': // pseudopotpath
425 cout << Verbose(0) << "Old: " << config::pseudopotpath << "\t new: ";
426 cin >> config::pseudopotpath;
427 break;
428
429 case 'D': // ProcPEGamma
430 cout << Verbose(0) << "Old: " << config::ProcPEGamma << "\t new: ";
431 cin >> config::ProcPEGamma;
432 break;
433 case 'E': // ProcPEPsi
434 cout << Verbose(0) << "Old: " << config::ProcPEPsi << "\t new: ";
435 cin >> config::ProcPEPsi;
436 break;
437 case 'F': // DoOutVis
438 cout << Verbose(0) << "Old: " << config::DoOutVis << "\t new: ";
439 cin >> config::DoOutVis;
440 break;
441 case 'G': // DoOutMes
442 cout << Verbose(0) << "Old: " << config::DoOutMes << "\t new: ";
443 cin >> config::DoOutMes;
444 break;
445 case 'H': // DoOutOrbitals
446 cout << Verbose(0) << "Old: " << config::DoOutOrbitals << "\t new: ";
447 cin >> config::DoOutOrbitals;
448 break;
449 case 'I': // DoOutCurrent
450 cout << Verbose(0) << "Old: " << config::DoOutCurrent << "\t new: ";
451 cin >> config::DoOutCurrent;
452 break;
453 case 'J': // DoFullCurrent
454 cout << Verbose(0) << "Old: " << config::DoFullCurrent << "\t new: ";
455 cin >> config::DoFullCurrent;
456 break;
457 case 'K': // DoPerturbation
458 cout << Verbose(0) << "Old: " << config::DoPerturbation << "\t new: ";
459 cin >> config::DoPerturbation;
460 break;
461 case 'L': // CommonWannier
462 cout << Verbose(0) << "Old: " << config::CommonWannier << "\t new: ";
463 cin >> config::CommonWannier;
464 break;
465 case 'M': // SawtoothStart
466 cout << Verbose(0) << "Old: " << config::SawtoothStart << "\t new: ";
467 cin >> config::SawtoothStart;
468 break;
469 case 'N': // VectorPlane
470 cout << Verbose(0) << "Old: " << config::VectorPlane << "\t new: ";
471 cin >> config::VectorPlane;
472 break;
473 case 'O': // VectorCut
474 cout << Verbose(0) << "Old: " << config::VectorCut << "\t new: ";
475 cin >> config::VectorCut;
476 break;
477 case 'P': // UseAddGramSch
478 cout << Verbose(0) << "Old: " << config::UseAddGramSch << "\t new: ";
479 cin >> config::UseAddGramSch;
480 break;
481 case 'Q': // Seed
482 cout << Verbose(0) << "Old: " << config::Seed << "\t new: ";
483 cin >> config::Seed;
484 break;
485
486 case 'R': // MaxOuterStep
487 cout << Verbose(0) << "Old: " << config::MaxOuterStep << "\t new: ";
488 cin >> config::MaxOuterStep;
489 break;
490 case 'T': // OutVisStep
491 cout << Verbose(0) << "Old: " << config::OutVisStep << "\t new: ";
492 cin >> config::OutVisStep;
493 break;
494 case 'U': // OutSrcStep
495 cout << Verbose(0) << "Old: " << config::OutSrcStep << "\t new: ";
496 cin >> config::OutSrcStep;
497 break;
498 case 'X': // MaxPsiStep
499 cout << Verbose(0) << "Old: " << config::MaxPsiStep << "\t new: ";
500 cin >> config::MaxPsiStep;
501 break;
502 case 'Y': // EpsWannier
503 cout << Verbose(0) << "Old: " << config::EpsWannier << "\t new: ";
504 cin >> config::EpsWannier;
505 break;
506
507 case 'Z': // MaxMinStep
508 cout << Verbose(0) << "Old: " << config::MaxMinStep << "\t new: ";
509 cin >> config::MaxMinStep;
510 break;
511 case 'a': // RelEpsTotalEnergy
512 cout << Verbose(0) << "Old: " << config::RelEpsTotalEnergy << "\t new: ";
513 cin >> config::RelEpsTotalEnergy;
514 break;
515 case 'b': // RelEpsKineticEnergy
516 cout << Verbose(0) << "Old: " << config::RelEpsKineticEnergy << "\t new: ";
517 cin >> config::RelEpsKineticEnergy;
518 break;
519 case 'c': // MaxMinStopStep
520 cout << Verbose(0) << "Old: " << config::MaxMinStopStep << "\t new: ";
521 cin >> config::MaxMinStopStep;
522 break;
523 case 'e': // MaxInitMinStep
524 cout << Verbose(0) << "Old: " << config::MaxInitMinStep << "\t new: ";
525 cin >> config::MaxInitMinStep;
526 break;
527 case 'f': // InitRelEpsTotalEnergy
528 cout << Verbose(0) << "Old: " << config::InitRelEpsTotalEnergy << "\t new: ";
529 cin >> config::InitRelEpsTotalEnergy;
530 break;
531 case 'g': // InitRelEpsKineticEnergy
532 cout << Verbose(0) << "Old: " << config::InitRelEpsKineticEnergy << "\t new: ";
533 cin >> config::InitRelEpsKineticEnergy;
534 break;
535 case 'h': // InitMaxMinStopStep
536 cout << Verbose(0) << "Old: " << config::InitMaxMinStopStep << "\t new: ";
537 cin >> config::InitMaxMinStopStep;
538 break;
539
540// case 'j': // BoxLength
541// cout << Verbose(0) << "enter lower triadiagonalo form of basis matrix" << endl << endl;
542// for (int i=0;i<6;i++) {
543// cout << Verbose(0) << "Cell size" << i << ": ";
544// cin >> mol->cell_size[i];
545// }
546// break;
547
548 case 'k': // ECut
549 cout << Verbose(0) << "Old: " << config::ECut << "\t new: ";
550 cin >> config::ECut;
551 break;
552 case 'l': // MaxLevel
553 cout << Verbose(0) << "Old: " << config::MaxLevel << "\t new: ";
554 cin >> config::MaxLevel;
555 break;
556 case 'm': // RiemannTensor
557 cout << Verbose(0) << "Old: " << config::RiemannTensor << "\t new: ";
558 cin >> config::RiemannTensor;
559 break;
560 case 'n': // LevRFactor
561 cout << Verbose(0) << "Old: " << config::LevRFactor << "\t new: ";
562 cin >> config::LevRFactor;
563 break;
564 case 'o': // RiemannLevel
565 cout << Verbose(0) << "Old: " << config::RiemannLevel << "\t new: ";
566 cin >> config::RiemannLevel;
567 break;
568 case 'p': // Lev0Factor
569 cout << Verbose(0) << "Old: " << config::Lev0Factor << "\t new: ";
570 cin >> config::Lev0Factor;
571 break;
572 case 'r': // RTActualUse
573 cout << Verbose(0) << "Old: " << config::RTActualUse << "\t new: ";
574 cin >> config::RTActualUse;
575 break;
576 case 's': // PsiType
577 cout << Verbose(0) << "Old: " << config::PsiType << "\t new: ";
578 cin >> config::PsiType;
579 break;
580 case 't': // MaxPsiDouble
581 cout << Verbose(0) << "Old: " << config::MaxPsiDouble << "\t new: ";
582 cin >> config::MaxPsiDouble;
583 break;
584 case 'u': // PsiMaxNoUp
585 cout << Verbose(0) << "Old: " << config::PsiMaxNoUp << "\t new: ";
586 cin >> config::PsiMaxNoUp;
587 break;
588 case 'v': // PsiMaxNoDown
589 cout << Verbose(0) << "Old: " << config::PsiMaxNoDown << "\t new: ";
590 cin >> config::PsiMaxNoDown;
591 break;
592 case 'w': // AddPsis
593 cout << Verbose(0) << "Old: " << config::AddPsis << "\t new: ";
594 cin >> config::AddPsis;
595 break;
596
597 case 'x': // RCut
598 cout << Verbose(0) << "Old: " << config::RCut << "\t new: ";
599 cin >> config::RCut;
600 break;
601 case 'y': // StructOpt
602 cout << Verbose(0) << "Old: " << config::StructOpt << "\t new: ";
603 cin >> config::StructOpt;
604 break;
605 case 'z': // IsAngstroem
606 cout << Verbose(0) << "Old: " << config::IsAngstroem << "\t new: ";
607 cin >> config::IsAngstroem;
608 break;
609 case 'i': // RelativeCoord
610 cout << Verbose(0) << "Old: " << config::RelativeCoord << "\t new: ";
611 cin >> config::RelativeCoord;
612 break;
613 };
614 } while (choice != 'q');
615};
616
617/** Tests whether a given configuration file adhears to old or new syntax.
618 * \param *filename filename of config file to be tested
619 * \param *periode pointer to a periodentafel class with all elements
620 * \param *mol pointer to molecule containing all atoms of the molecule
621 * \return 0 - old syntax, 1 - new syntax, -1 - unknown syntax
622 */
623int config::TestSyntax(char *filename, periodentafel *periode, molecule *mol)
624{
625 int test;
626 ifstream file(filename);
627
628 // search file for keyword: ProcPEGamma (new syntax)
629 if (ParseForParameter(1,&file,"ProcPEGamma", 0, 1, 1, int_type, &test, 1, optional)) {
630 file.close();
631 return 1;
632 }
633 // search file for keyword: ProcsGammaPsi (old syntax)
634 if (ParseForParameter(1,&file,"ProcsGammaPsi", 0, 1, 1, int_type, &test, 1, optional)) {
635 file.close();
636 return 0;
637 }
638 file.close();
639 return -1;
640}
641
642/** Returns private config::IsAngstroem.
643 * \return IsAngstroem
644 */
645bool config::GetIsAngstroem() const
646{
647 return (IsAngstroem == 1);
648};
649
650/** Returns private config::*defaultpath.
651 * \return *defaultpath
652 */
653char * config::GetDefaultPath() const
654{
655 return defaultpath;
656};
657
658
659/** Returns private config::*defaultpath.
660 * \return *defaultpath
661 */
662void config::SetDefaultPath(const char *path)
663{
664 strcpy(defaultpath, path);
665};
666
667/** Retrieves the path in the given config file name.
668 * \param filename config file string
669 */
670void config::RetrieveConfigPathAndName(string filename)
671{
672 char *ptr = NULL;
673 char *buffer = new char[MAXSTRINGSIZE];
674 strncpy(buffer, filename.c_str(), MAXSTRINGSIZE);
675 int last = -1;
676 for(last=MAXSTRINGSIZE;last--;) {
677 if (buffer[last] == '/')
678 break;
679 }
680 if (last == -1) { // no path in front, set to local directory.
681 strcpy(configpath, "./");
682 ptr = buffer;
683 } else {
684 strncpy(configpath, buffer, last+1);
685 ptr = &buffer[last+1];
686 if (last < 254)
687 configpath[last+1]='\0';
688 }
689 strcpy(configname, ptr);
690 cout << "Found configpath: " << configpath << ", dir slash was found at " << last << ", config name is " << configname << "." << endl;
691 delete[](buffer);
692};
693
694
695/** Initializes config file structure by loading elements from a give file.
696 * \param *file input file stream being the opened config file
697 * \param *periode pointer to a periodentafel class with all elements
698 * \param *mol pointer to molecule containing all atoms of the molecule
699 */
700void config::Load(char *filename, periodentafel *periode, molecule *mol)
701{
702 ifstream *file = new ifstream(filename);
703 if (file == NULL) {
704 cerr << "ERROR: config file " << filename << " missing!" << endl;
705 return;
706 }
707 file->close();
708 delete(file);
709 RetrieveConfigPathAndName(filename);
710
711 // ParseParameterFile
712 struct ConfigFileBuffer *FileBuffer = new ConfigFileBuffer(filename);
713 FileBuffer->InitMapping();
714
715 /* Oeffne Hauptparameterdatei */
716 int di;
717 double BoxLength[9];
718 string zeile;
719 string dummy;
720 element *elementhash[MAX_ELEMENTS];
721 char name[MAX_ELEMENTS];
722 char keyword[MAX_ELEMENTS];
723 int Z, No[MAX_ELEMENTS];
724 int verbose = 0;
725 double value[3];
726
727 InitThermostats(FileBuffer);
728
729 /* Namen einlesen */
730
731 ParseForParameter(verbose,FileBuffer, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical);
732 ParseForParameter(verbose,FileBuffer, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical);
733 ParseForParameter(verbose,FileBuffer, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical);
734 ParseForParameter(verbose,FileBuffer,"ProcPEGamma", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical);
735 ParseForParameter(verbose,FileBuffer,"ProcPEPsi", 0, 1, 1, int_type, &(config::ProcPEPsi), 1, critical);
736
737 if (!ParseForParameter(verbose,FileBuffer,"Seed", 0, 1, 1, int_type, &(config::Seed), 1, optional))
738 config::Seed = 1;
739
740 if(!ParseForParameter(verbose,FileBuffer,"DoOutOrbitals", 0, 1, 1, int_type, &(config::DoOutOrbitals), 1, optional)) {
741 config::DoOutOrbitals = 0;
742 } else {
743 if (config::DoOutOrbitals < 0) config::DoOutOrbitals = 0;
744 if (config::DoOutOrbitals > 1) config::DoOutOrbitals = 1;
745 }
746 ParseForParameter(verbose,FileBuffer,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical);
747 if (config::DoOutVis < 0) config::DoOutVis = 0;
748 if (config::DoOutVis > 1) config::DoOutVis = 1;
749 if (!ParseForParameter(verbose,FileBuffer,"VectorPlane", 0, 1, 1, int_type, &(config::VectorPlane), 1, optional))
750 config::VectorPlane = -1;
751 if (!ParseForParameter(verbose,FileBuffer,"VectorCut", 0, 1, 1, double_type, &(config::VectorCut), 1, optional))
752 config::VectorCut = 0.;
753 ParseForParameter(verbose,FileBuffer,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical);
754 if (config::DoOutMes < 0) config::DoOutMes = 0;
755 if (config::DoOutMes > 1) config::DoOutMes = 1;
756 if (!ParseForParameter(verbose,FileBuffer,"DoOutCurr", 0, 1, 1, int_type, &(config::DoOutCurrent), 1, optional))
757 config::DoOutCurrent = 0;
758 if (config::DoOutCurrent < 0) config::DoOutCurrent = 0;
759 if (config::DoOutCurrent > 1) config::DoOutCurrent = 1;
760 ParseForParameter(verbose,FileBuffer,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical);
761 if (config::UseAddGramSch < 0) config::UseAddGramSch = 0;
762 if (config::UseAddGramSch > 2) config::UseAddGramSch = 2;
763 if(!ParseForParameter(verbose,FileBuffer,"DoWannier", 0, 1, 1, int_type, &(config::DoWannier), 1, optional)) {
764 config::DoWannier = 0;
765 } else {
766 if (config::DoWannier < 0) config::DoWannier = 0;
767 if (config::DoWannier > 1) config::DoWannier = 1;
768 }
769 if(!ParseForParameter(verbose,FileBuffer,"CommonWannier", 0, 1, 1, int_type, &(config::CommonWannier), 1, optional)) {
770 config::CommonWannier = 0;
771 } else {
772 if (config::CommonWannier < 0) config::CommonWannier = 0;
773 if (config::CommonWannier > 4) config::CommonWannier = 4;
774 }
775 if(!ParseForParameter(verbose,FileBuffer,"SawtoothStart", 0, 1, 1, double_type, &(config::SawtoothStart), 1, optional)) {
776 config::SawtoothStart = 0.01;
777 } else {
778 if (config::SawtoothStart < 0.) config::SawtoothStart = 0.;
779 if (config::SawtoothStart > 1.) config::SawtoothStart = 1.;
780 }
781
782 if (ParseForParameter(verbose,FileBuffer,"DoConstrainedMD", 0, 1, 1, int_type, &(config::DoConstrainedMD), 1, optional))
783 if (config::DoConstrainedMD < 0)
784 config::DoConstrainedMD = 0;
785 ParseForParameter(verbose,FileBuffer,"MaxOuterStep", 0, 1, 1, int_type, &(config::MaxOuterStep), 1, critical);
786 if (!ParseForParameter(verbose,FileBuffer,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional))
787 config::Deltat = 1;
788 ParseForParameter(verbose,FileBuffer,"OutVisStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional);
789 ParseForParameter(verbose,FileBuffer,"OutSrcStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional);
790 ParseForParameter(verbose,FileBuffer,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional);
791 //ParseForParameter(verbose,FileBuffer,"Thermostat", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional);
792 if (!ParseForParameter(verbose,FileBuffer,"EpsWannier", 0, 1, 1, double_type, &(config::EpsWannier), 1, optional))
793 config::EpsWannier = 1e-8;
794
795 // stop conditions
796 //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1;
797 ParseForParameter(verbose,FileBuffer,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical);
798 if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3;
799
800 ParseForParameter(verbose,FileBuffer,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical);
801 ParseForParameter(verbose,FileBuffer,"RelEpsTotalE", 0, 1, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical);
802 ParseForParameter(verbose,FileBuffer,"RelEpsKineticE", 0, 1, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical);
803 ParseForParameter(verbose,FileBuffer,"MaxMinStopStep", 0, 1, 1, int_type, &(config::MaxMinStopStep), 1, critical);
804 ParseForParameter(verbose,FileBuffer,"MaxMinGapStopStep", 0, 1, 1, int_type, &(config::MaxMinGapStopStep), 1, critical);
805 if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep;
806 if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1;
807 if (config::MaxMinGapStopStep < 1) config::MaxMinGapStopStep = 1;
808
809 ParseForParameter(verbose,FileBuffer,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical);
810 ParseForParameter(verbose,FileBuffer,"InitRelEpsTotalE", 0, 1, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical);
811 ParseForParameter(verbose,FileBuffer,"InitRelEpsKineticE", 0, 1, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical);
812 ParseForParameter(verbose,FileBuffer,"InitMaxMinStopStep", 0, 1, 1, int_type, &(config::InitMaxMinStopStep), 1, critical);
813 ParseForParameter(verbose,FileBuffer,"InitMaxMinGapStopStep", 0, 1, 1, int_type, &(config::InitMaxMinGapStopStep), 1, critical);
814 if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep;
815 if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1;
816 if (config::InitMaxMinGapStopStep < 1) config::InitMaxMinGapStopStep = 1;
817
818 // Unit cell and magnetic field
819 ParseForParameter(verbose,FileBuffer, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */
820 mol->cell_size[0] = BoxLength[0];
821 mol->cell_size[1] = BoxLength[3];
822 mol->cell_size[2] = BoxLength[4];
823 mol->cell_size[3] = BoxLength[6];
824 mol->cell_size[4] = BoxLength[7];
825 mol->cell_size[5] = BoxLength[8];
826 //if (1) fprintf(stderr,"\n");
827
828 ParseForParameter(verbose,FileBuffer,"DoPerturbation", 0, 1, 1, int_type, &(config::DoPerturbation), 1, optional);
829 ParseForParameter(verbose,FileBuffer,"DoOutNICS", 0, 1, 1, int_type, &(config::DoOutNICS), 1, optional);
830 if (!ParseForParameter(verbose,FileBuffer,"DoFullCurrent", 0, 1, 1, int_type, &(config::DoFullCurrent), 1, optional))
831 config::DoFullCurrent = 0;
832 if (config::DoFullCurrent < 0) config::DoFullCurrent = 0;
833 if (config::DoFullCurrent > 2) config::DoFullCurrent = 2;
834 if (config::DoOutNICS < 0) config::DoOutNICS = 0;
835 if (config::DoOutNICS > 2) config::DoOutNICS = 2;
836 if (config::DoPerturbation == 0) {
837 config::DoFullCurrent = 0;
838 config::DoOutNICS = 0;
839 }
840
841 ParseForParameter(verbose,FileBuffer,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical);
842 ParseForParameter(verbose,FileBuffer,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical);
843 ParseForParameter(verbose,FileBuffer,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical);
844 if (config::Lev0Factor < 2) {
845 config::Lev0Factor = 2;
846 }
847 ParseForParameter(verbose,FileBuffer,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical);
848 if (di >= 0 && di < 2) {
849 config::RiemannTensor = di;
850 } else {
851 fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT");
852 exit(1);
853 }
854 switch (config::RiemannTensor) {
855 case 0: //UseNoRT
856 if (config::MaxLevel < 2) {
857 config::MaxLevel = 2;
858 }
859 config::LevRFactor = 2;
860 config::RTActualUse = 0;
861 break;
862 case 1: // UseRT
863 if (config::MaxLevel < 3) {
864 config::MaxLevel = 3;
865 }
866 ParseForParameter(verbose,FileBuffer,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical);
867 if (config::RiemannLevel < 2) {
868 config::RiemannLevel = 2;
869 }
870 if (config::RiemannLevel > config::MaxLevel-1) {
871 config::RiemannLevel = config::MaxLevel-1;
872 }
873 ParseForParameter(verbose,FileBuffer,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical);
874 if (config::LevRFactor < 2) {
875 config::LevRFactor = 2;
876 }
877 config::Lev0Factor = 2;
878 config::RTActualUse = 2;
879 break;
880 }
881 ParseForParameter(verbose,FileBuffer,"PsiType", 0, 1, 1, int_type, &di, 1, critical);
882 if (di >= 0 && di < 2) {
883 config::PsiType = di;
884 } else {
885 fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown");
886 exit(1);
887 }
888 switch (config::PsiType) {
889 case 0: // SpinDouble
890 ParseForParameter(verbose,FileBuffer,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical);
891 ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional);
892 break;
893 case 1: // SpinUpDown
894 if (config::ProcPEGamma % 2) config::ProcPEGamma*=2;
895 ParseForParameter(verbose,FileBuffer,"PsiMaxNoUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical);
896 ParseForParameter(verbose,FileBuffer,"PsiMaxNoDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical);
897 ParseForParameter(verbose,FileBuffer,"AddPsis", 0, 1, 1, int_type, &(config::AddPsis), 1, optional);
898 break;
899 }
900
901 // IonsInitRead
902
903 ParseForParameter(verbose,FileBuffer,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical);
904 ParseForParameter(verbose,FileBuffer,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical);
905 ParseForParameter(verbose,FileBuffer,"MaxTypes", 0, 1, 1, int_type, &(config::MaxTypes), 1, critical);
906 if (!ParseForParameter(verbose,FileBuffer,"RelativeCoord", 0, 1, 1, int_type, &(config::RelativeCoord) , 1, optional))
907 config::RelativeCoord = 0;
908 if (!ParseForParameter(verbose,FileBuffer,"StructOpt", 0, 1, 1, int_type, &(config::StructOpt), 1, optional))
909 config::StructOpt = 0;
910 if (MaxTypes == 0) {
911 cerr << "There are no atoms according to MaxTypes in this config file." << endl;
912 } else {
913 // prescan number of ions per type
914 cout << Verbose(0) << "Prescanning ions per type: " << endl;
915 int NoAtoms = 0;
916 for (int i=0; i < config::MaxTypes; i++) {
917 sprintf(name,"Ion_Type%i",i+1);
918 ParseForParameter(verbose,FileBuffer, (const char*)name, 0, 1, 1, int_type, &No[i], 1, critical);
919 ParseForParameter(verbose,FileBuffer, name, 0, 2, 1, int_type, &Z, 1, critical);
920 elementhash[i] = periode->FindElement(Z);
921 cout << Verbose(1) << i << ". Z = " << elementhash[i]->Z << " with " << No[i] << " ions." << endl;
922 NoAtoms += No[i];
923 }
924 int repetition = 0; // which repeated keyword shall be read
925
926 // sort the lines via the LineMapping
927 sprintf(name,"Ion_Type%i",config::MaxTypes);
928 if (!ParseForParameter(verbose,FileBuffer, (const char*)name, 1, 1, 1, int_type, &value[0], 1, critical)) {
929 cerr << "There are no atoms in the config file!" << endl;
930 return;
931 }
932 FileBuffer->CurrentLine++;
933 //cout << FileBuffer->buffer[ FileBuffer->LineMapping[FileBuffer->CurrentLine]];
934 FileBuffer->MapIonTypesInBuffer(NoAtoms);
935 //for (int i=0; i<(NoAtoms < 100 ? NoAtoms : 100 < 100 ? NoAtoms : 100);++i) {
936 // cout << FileBuffer->buffer[ FileBuffer->LineMapping[FileBuffer->CurrentLine+i]];
937 //}
938
939 map<int, atom *> AtomList[config::MaxTypes];
940 map<int, atom *> LinearList;
941 atom *neues = NULL;
942 if (!FastParsing) {
943 // parse in trajectories
944 bool status = true;
945 while (status) {
946 cout << "Currently parsing MD step " << repetition << "." << endl;
947 for (int i=0; i < config::MaxTypes; i++) {
948 sprintf(name,"Ion_Type%i",i+1);
949 for(int j=0;j<No[i];j++) {
950 sprintf(keyword,"%s_%i",name, j+1);
951 if (repetition == 0) {
952 neues = new atom();
953 AtomList[i][j] = neues;
954 LinearList[ FileBuffer->LineMapping[FileBuffer->CurrentLine] ] = neues;
955 neues->type = elementhash[i]; // find element type
956 } else
957 neues = AtomList[i][j];
958 status = (status &&
959 ParseForParameter(verbose,FileBuffer, keyword, 0, 1, 1, double_type, &neues->x.x[0], 1, (repetition == 0) ? critical : optional) &&
960 ParseForParameter(verbose,FileBuffer, keyword, 0, 2, 1, double_type, &neues->x.x[1], 1, (repetition == 0) ? critical : optional) &&
961 ParseForParameter(verbose,FileBuffer, keyword, 0, 3, 1, double_type, &neues->x.x[2], 1, (repetition == 0) ? critical : optional) &&
962 ParseForParameter(verbose,FileBuffer, keyword, 0, 4, 1, int_type, &neues->FixedIon, 1, (repetition == 0) ? critical : optional));
963 if (!status) break;
964
965 // check size of vectors
966 if (neues->Trajectory.R.size() <= (unsigned int)(repetition)) {
967 //cout << "Increasing size for trajectory array of " << keyword << " to " << (repetition+10) << "." << endl;
968 neues->Trajectory.R.resize(repetition+10);
969 neues->Trajectory.U.resize(repetition+10);
970 neues->Trajectory.F.resize(repetition+10);
971 }
972
973 // put into trajectories list
974 for (int d=0;d<NDIM;d++)
975 neues->Trajectory.R.at(repetition).x[d] = neues->x.x[d];
976
977 // parse velocities if present
978 if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 5, 1, double_type, &neues->v.x[0], 1,optional))
979 neues->v.x[0] = 0.;
980 if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 6, 1, double_type, &neues->v.x[1], 1,optional))
981 neues->v.x[1] = 0.;
982 if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 7, 1, double_type, &neues->v.x[2], 1,optional))
983 neues->v.x[2] = 0.;
984 for (int d=0;d<NDIM;d++)
985 neues->Trajectory.U.at(repetition).x[d] = neues->v.x[d];
986
987 // parse forces if present
988 if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 8, 1, double_type, &value[0], 1,optional))
989 value[0] = 0.;
990 if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 9, 1, double_type, &value[1], 1,optional))
991 value[1] = 0.;
992 if(!ParseForParameter(verbose,FileBuffer, keyword, 1, 10, 1, double_type, &value[2], 1,optional))
993 value[2] = 0.;
994 for (int d=0;d<NDIM;d++)
995 neues->Trajectory.F.at(repetition).x[d] = value[d];
996
997 // cout << "Parsed position of step " << (repetition) << ": (";
998 // for (int d=0;d<NDIM;d++)
999 // cout << neues->Trajectory.R.at(repetition).x[d] << " "; // next step
1000 // cout << ")\t(";
1001 // for (int d=0;d<NDIM;d++)
1002 // cout << neues->Trajectory.U.at(repetition).x[d] << " "; // next step
1003 // cout << ")\t(";
1004 // for (int d=0;d<NDIM;d++)
1005 // cout << neues->Trajectory.F.at(repetition).x[d] << " "; // next step
1006 // cout << ")" << endl;
1007 }
1008 }
1009 repetition++;
1010 }
1011 repetition--;
1012 cout << "Found " << repetition << " trajectory steps." << endl;
1013 if (repetition <= 1) // if onyl one step, desactivate use of trajectories
1014 mol->MDSteps = 0;
1015 else
1016 mol->MDSteps = repetition;
1017 } else {
1018 // find the maximum number of MD steps so that we may parse last one (Ion_Type1_1 must always be present, because is the first atom)
1019 repetition = 0;
1020 while ( ParseForParameter(verbose,FileBuffer, "Ion_Type1_1", 0, 1, 1, double_type, &value[0], repetition, (repetition == 0) ? critical : optional) &&
1021 ParseForParameter(verbose,FileBuffer, "Ion_Type1_1", 0, 2, 1, double_type, &value[1], repetition, (repetition == 0) ? critical : optional) &&
1022 ParseForParameter(verbose,FileBuffer, "Ion_Type1_1", 0, 3, 1, double_type, &value[2], repetition, (repetition == 0) ? critical : optional))
1023 repetition++;
1024 cout << "I found " << repetition << " times the keyword Ion_Type1_1." << endl;
1025 // parse in molecule coordinates
1026 for (int i=0; i < config::MaxTypes; i++) {
1027 sprintf(name,"Ion_Type%i",i+1);
1028 for(int j=0;j<No[i];j++) {
1029 sprintf(keyword,"%s_%i",name, j+1);
1030 if (repetition == 0) {
1031 neues = new atom();
1032 AtomList[i][j] = neues;
1033 LinearList[ FileBuffer->LineMapping[FileBuffer->CurrentLine] ] = neues;
1034 neues->type = elementhash[i]; // find element type
1035 } else
1036 neues = AtomList[i][j];
1037 // then parse for each atom the coordinates as often as present
1038 ParseForParameter(verbose,FileBuffer, keyword, 0, 1, 1, double_type, &neues->x.x[0], repetition,critical);
1039 ParseForParameter(verbose,FileBuffer, keyword, 0, 2, 1, double_type, &neues->x.x[1], repetition,critical);
1040 ParseForParameter(verbose,FileBuffer, keyword, 0, 3, 1, double_type, &neues->x.x[2], repetition,critical);
1041 ParseForParameter(verbose,FileBuffer, keyword, 0, 4, 1, int_type, &neues->FixedIon, repetition,critical);
1042 if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 5, 1, double_type, &neues->v.x[0], repetition,optional))
1043 neues->v.x[0] = 0.;
1044 if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 6, 1, double_type, &neues->v.x[1], repetition,optional))
1045 neues->v.x[1] = 0.;
1046 if(!ParseForParameter(verbose,FileBuffer, keyword, 0, 7, 1, double_type, &neues->v.x[2], repetition,optional))
1047 neues->v.x[2] = 0.;
1048 // here we don't care if forces are present (last in trajectories is always equal to current position)
1049 neues->type = elementhash[i]; // find element type
1050 mol->AddAtom(neues);
1051 }
1052 }
1053 }
1054 // put atoms into the molecule in their original order
1055 for(map<int, atom*>::iterator runner = LinearList.begin(); runner != LinearList.end(); ++runner) {
1056 mol->AddAtom(runner->second);
1057 }
1058 }
1059 delete(FileBuffer);
1060};
1061
1062/** Initializes config file structure by loading elements from a give file with old pcp syntax.
1063 * \param *file input file stream being the opened config file with old pcp syntax
1064 * \param *periode pointer to a periodentafel class with all elements
1065 * \param *mol pointer to molecule containing all atoms of the molecule
1066 */
1067void config::LoadOld(char *filename, periodentafel *periode, molecule *mol)
1068{
1069 ifstream *file = new ifstream(filename);
1070 if (file == NULL) {
1071 cerr << "ERROR: config file " << filename << " missing!" << endl;
1072 return;
1073 }
1074 RetrieveConfigPathAndName(filename);
1075 // ParseParameters
1076
1077 /* Oeffne Hauptparameterdatei */
1078 int l, i, di;
1079 double a,b;
1080 double BoxLength[9];
1081 string zeile;
1082 string dummy;
1083 element *elementhash[128];
1084 int Z, No, AtomNo, found;
1085 int verbose = 0;
1086
1087 /* Namen einlesen */
1088
1089 ParseForParameter(verbose,file, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical);
1090 ParseForParameter(verbose,file, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical);
1091 ParseForParameter(verbose,file, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical);
1092 ParseForParameter(verbose,file, "ProcsGammaPsi", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical);
1093 ParseForParameter(verbose,file, "ProcsGammaPsi", 0, 2, 1, int_type, &(config::ProcPEPsi), 1, critical);
1094 config::Seed = 1;
1095 config::DoOutOrbitals = 0;
1096 ParseForParameter(verbose,file,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical);
1097 if (config::DoOutVis < 0) config::DoOutVis = 0;
1098 if (config::DoOutVis > 1) config::DoOutVis = 1;
1099 config::VectorPlane = -1;
1100 config::VectorCut = 0.;
1101 ParseForParameter(verbose,file,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical);
1102 if (config::DoOutMes < 0) config::DoOutMes = 0;
1103 if (config::DoOutMes > 1) config::DoOutMes = 1;
1104 config::DoOutCurrent = 0;
1105 ParseForParameter(verbose,file,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical);
1106 if (config::UseAddGramSch < 0) config::UseAddGramSch = 0;
1107 if (config::UseAddGramSch > 2) config::UseAddGramSch = 2;
1108 config::CommonWannier = 0;
1109 config::SawtoothStart = 0.01;
1110
1111 ParseForParameter(verbose,file,"MaxOuterStep", 0, 1, 1, double_type, &(config::MaxOuterStep), 1, critical);
1112 ParseForParameter(verbose,file,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional);
1113 ParseForParameter(verbose,file,"VisOuterStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional);
1114 ParseForParameter(verbose,file,"VisSrcOuterStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional);
1115 ParseForParameter(verbose,file,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional);
1116 ParseForParameter(verbose,file,"ScaleTempStep", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional);
1117 config::EpsWannier = 1e-8;
1118
1119 // stop conditions
1120 //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1;
1121 ParseForParameter(verbose,file,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical);
1122 if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3;
1123
1124 ParseForParameter(verbose,file,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical);
1125 ParseForParameter(verbose,file,"MaxMinStep", 0, 2, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical);
1126 ParseForParameter(verbose,file,"MaxMinStep", 0, 3, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical);
1127 ParseForParameter(verbose,file,"MaxMinStep", 0, 4, 1, int_type, &(config::MaxMinStopStep), 1, critical);
1128 if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep;
1129 if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1;
1130 config::MaxMinGapStopStep = 1;
1131
1132 ParseForParameter(verbose,file,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical);
1133 ParseForParameter(verbose,file,"MaxInitMinStep", 0, 2, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical);
1134 ParseForParameter(verbose,file,"MaxInitMinStep", 0, 3, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical);
1135 ParseForParameter(verbose,file,"MaxInitMinStep", 0, 4, 1, int_type, &(config::InitMaxMinStopStep), 1, critical);
1136 if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep;
1137 if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1;
1138 config::InitMaxMinGapStopStep = 1;
1139
1140 ParseForParameter(verbose,file, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */
1141 mol->cell_size[0] = BoxLength[0];
1142 mol->cell_size[1] = BoxLength[3];
1143 mol->cell_size[2] = BoxLength[4];
1144 mol->cell_size[3] = BoxLength[6];
1145 mol->cell_size[4] = BoxLength[7];
1146 mol->cell_size[5] = BoxLength[8];
1147 if (1) fprintf(stderr,"\n");
1148 config::DoPerturbation = 0;
1149 config::DoFullCurrent = 0;
1150
1151 ParseForParameter(verbose,file,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical);
1152 ParseForParameter(verbose,file,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical);
1153 ParseForParameter(verbose,file,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical);
1154 if (config::Lev0Factor < 2) {
1155 config::Lev0Factor = 2;
1156 }
1157 ParseForParameter(verbose,file,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical);
1158 if (di >= 0 && di < 2) {
1159 config::RiemannTensor = di;
1160 } else {
1161 fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT");
1162 exit(1);
1163 }
1164 switch (config::RiemannTensor) {
1165 case 0: //UseNoRT
1166 if (config::MaxLevel < 2) {
1167 config::MaxLevel = 2;
1168 }
1169 config::LevRFactor = 2;
1170 config::RTActualUse = 0;
1171 break;
1172 case 1: // UseRT
1173 if (config::MaxLevel < 3) {
1174 config::MaxLevel = 3;
1175 }
1176 ParseForParameter(verbose,file,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical);
1177 if (config::RiemannLevel < 2) {
1178 config::RiemannLevel = 2;
1179 }
1180 if (config::RiemannLevel > config::MaxLevel-1) {
1181 config::RiemannLevel = config::MaxLevel-1;
1182 }
1183 ParseForParameter(verbose,file,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical);
1184 if (config::LevRFactor < 2) {
1185 config::LevRFactor = 2;
1186 }
1187 config::Lev0Factor = 2;
1188 config::RTActualUse = 2;
1189 break;
1190 }
1191 ParseForParameter(verbose,file,"PsiType", 0, 1, 1, int_type, &di, 1, critical);
1192 if (di >= 0 && di < 2) {
1193 config::PsiType = di;
1194 } else {
1195 fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown");
1196 exit(1);
1197 }
1198 switch (config::PsiType) {
1199 case 0: // SpinDouble
1200 ParseForParameter(verbose,file,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical);
1201 config::AddPsis = 0;
1202 break;
1203 case 1: // SpinUpDown
1204 if (config::ProcPEGamma % 2) config::ProcPEGamma*=2;
1205 ParseForParameter(verbose,file,"MaxPsiUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical);
1206 ParseForParameter(verbose,file,"MaxPsiDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical);
1207 config::AddPsis = 0;
1208 break;
1209 }
1210
1211 // IonsInitRead
1212
1213 ParseForParameter(verbose,file,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical);
1214 ParseForParameter(verbose,file,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical);
1215 config::RelativeCoord = 0;
1216 config::StructOpt = 0;
1217
1218 // Routine from builder.cpp
1219
1220
1221 for (i=MAX_ELEMENTS;i--;)
1222 elementhash[i] = NULL;
1223 cout << Verbose(0) << "Parsing Ions ..." << endl;
1224 No=0;
1225 found = 0;
1226 while (getline(*file,zeile,'\n')) {
1227 if (zeile.find("Ions_Data") == 0) {
1228 cout << Verbose(1) << "found Ions_Data...begin parsing" << endl;
1229 found ++;
1230 }
1231 if (found > 0) {
1232 if (zeile.find("Ions_Data") == 0)
1233 getline(*file,zeile,'\n'); // read next line and parse this one
1234 istringstream input(zeile);
1235 input >> AtomNo; // number of atoms
1236 input >> Z; // atomic number
1237 input >> a;
1238 input >> l;
1239 input >> l;
1240 input >> b; // element mass
1241 elementhash[No] = periode->FindElement(Z);
1242 cout << Verbose(1) << "AtomNo: " << AtomNo << "\tZ: " << Z << "\ta:" << a << "\tl:" << l << "\b:" << b << "\tElement:" << elementhash[No] << "\t:" << endl;
1243 for(i=0;i<AtomNo;i++) {
1244 if (!getline(*file,zeile,'\n')) {// parse on and on
1245 cout << Verbose(2) << "Error: Too few items in ionic list of element" << elementhash[No] << "." << endl << "Exiting." << endl;
1246 // return 1;
1247 } else {
1248 //cout << Verbose(2) << "Reading line: " << zeile << endl;
1249 }
1250 istringstream input2(zeile);
1251 atom *neues = new atom();
1252 input2 >> neues->x.x[0]; // x
1253 input2 >> neues->x.x[1]; // y
1254 input2 >> neues->x.x[2]; // z
1255 input2 >> l;
1256 neues->type = elementhash[No]; // find element type
1257 mol->AddAtom(neues);
1258 }
1259 No++;
1260 }
1261 }
1262 file->close();
1263 delete(file);
1264};
1265
1266/** Stores all elements of config structure from which they can be re-read.
1267 * \param *filename name of file
1268 * \param *periode pointer to a periodentafel class with all elements
1269 * \param *mol pointer to molecule containing all atoms of the molecule
1270 */
1271bool config::Save(const char *filename, periodentafel *periode, molecule *mol) const
1272{
1273 bool result = true;
1274 // bring MaxTypes up to date
1275 mol->CountElements();
1276 ofstream *output = NULL;
1277 output = new ofstream(filename, ios::out);
1278 if (output != NULL) {
1279 *output << "# ParallelCarParinello - main configuration file - created with molecuilder" << endl;
1280 *output << endl;
1281 *output << "mainname\t" << config::mainname << "\t# programm name (for runtime files)" << endl;
1282 *output << "defaultpath\t" << config::defaultpath << "\t# where to put files during runtime" << endl;
1283 *output << "pseudopotpath\t" << config::pseudopotpath << "\t# where to find pseudopotentials" << endl;
1284 *output << endl;
1285 *output << "ProcPEGamma\t" << config::ProcPEGamma << "\t# for parallel computing: share constants" << endl;
1286 *output << "ProcPEPsi\t" << config::ProcPEPsi << "\t# for parallel computing: share wave functions" << endl;
1287 *output << "DoOutVis\t" << config::DoOutVis << "\t# Output data for OpenDX" << endl;
1288 *output << "DoOutMes\t" << config::DoOutMes << "\t# Output data for measurements" << endl;
1289 *output << "DoOutOrbitals\t" << config::DoOutOrbitals << "\t# Output all Orbitals" << endl;
1290 *output << "DoOutCurr\t" << config::DoOutCurrent << "\t# Ouput current density for OpenDx" << endl;
1291 *output << "DoOutNICS\t" << config::DoOutNICS << "\t# Output Nucleus independent current shieldings" << endl;
1292 *output << "DoPerturbation\t" << config::DoPerturbation << "\t# Do perturbation calculate and determine susceptibility and shielding" << endl;
1293 *output << "DoFullCurrent\t" << config::DoFullCurrent << "\t# Do full perturbation" << endl;
1294 *output << "DoConstrainedMD\t" << config::DoConstrainedMD << "\t# Do perform a constrained (>0, relating to current MD step) instead of unconstrained (0) MD" << endl;
1295 *output << "Thermostat\t" << ThermostatNames[Thermostat] << "\t";
1296 switch(Thermostat) {
1297 default:
1298 case None:
1299 break;
1300 case Woodcock:
1301 *output << ScaleTempStep;
1302 break;
1303 case Gaussian:
1304 *output << ScaleTempStep;
1305 break;
1306 case Langevin:
1307 *output << TempFrequency << "\t" << alpha;
1308 break;
1309 case Berendsen:
1310 *output << TempFrequency;
1311 break;
1312 case NoseHoover:
1313 *output << HooverMass;
1314 break;
1315 };
1316 *output << "\t# Which Thermostat and its parameters to use in MD case." << endl;
1317 *output << "CommonWannier\t" << config::CommonWannier << "\t# Put virtual centers at indivual orbits, all common, merged by variance, to grid point, to cell center" << endl;
1318 *output << "SawtoothStart\t" << config::SawtoothStart << "\t# Absolute value for smooth transition at cell border " << endl;
1319 *output << "VectorPlane\t" << config::VectorPlane << "\t# Cut plane axis (x, y or z: 0,1,2) for two-dim current vector plot" << endl;
1320 *output << "VectorCut\t" << config::VectorCut << "\t# Cut plane axis value" << endl;
1321 *output << "AddGramSch\t" << config::UseAddGramSch << "\t# Additional GramSchmidtOrtogonalization to be safe" << endl;
1322 *output << "Seed\t\t" << config::Seed << "\t# initial value for random seed for Psi coefficients" << endl;
1323 *output << endl;
1324 *output << "MaxOuterStep\t" << config::MaxOuterStep << "\t# number of MolecularDynamics/Structure optimization steps" << endl;
1325 *output << "Deltat\t" << config::Deltat << "\t# time per MD step" << endl;
1326 *output << "OutVisStep\t" << config::OutVisStep << "\t# Output visual data every ...th step" << endl;
1327 *output << "OutSrcStep\t" << config::OutSrcStep << "\t# Output \"restart\" data every ..th step" << endl;
1328 *output << "TargetTemp\t" << config::TargetTemp << "\t# Target temperature" << endl;
1329 *output << "MaxPsiStep\t" << config::MaxPsiStep << "\t# number of Minimisation steps per state (0 - default)" << endl;
1330 *output << "EpsWannier\t" << config::EpsWannier << "\t# tolerance value for spread minimisation of orbitals" << endl;
1331 *output << endl;
1332 *output << "# Values specifying when to stop" << endl;
1333 *output << "MaxMinStep\t" << config::MaxMinStep << "\t# Maximum number of steps" << endl;
1334 *output << "RelEpsTotalE\t" << config::RelEpsTotalEnergy << "\t# relative change in total energy" << endl;
1335 *output << "RelEpsKineticE\t" << config::RelEpsKineticEnergy << "\t# relative change in kinetic energy" << endl;
1336 *output << "MaxMinStopStep\t" << config::MaxMinStopStep << "\t# check every ..th steps" << endl;
1337 *output << "MaxMinGapStopStep\t" << config::MaxMinGapStopStep << "\t# check every ..th steps" << endl;
1338 *output << endl;
1339 *output << "# Values specifying when to stop for INIT, otherwise same as above" << endl;
1340 *output << "MaxInitMinStep\t" << config::MaxInitMinStep << "\t# Maximum number of steps" << endl;
1341 *output << "InitRelEpsTotalE\t" << config::InitRelEpsTotalEnergy << "\t# relative change in total energy" << endl;
1342 *output << "InitRelEpsKineticE\t" << config::InitRelEpsKineticEnergy << "\t# relative change in kinetic energy" << endl;
1343 *output << "InitMaxMinStopStep\t" << config::InitMaxMinStopStep << "\t# check every ..th steps" << endl;
1344 *output << "InitMaxMinGapStopStep\t" << config::InitMaxMinGapStopStep << "\t# check every ..th steps" << endl;
1345 *output << endl;
1346 *output << "BoxLength\t\t\t# (Length of a unit cell)" << endl;
1347 *output << mol->cell_size[0] << "\t" << endl;
1348 *output << mol->cell_size[1] << "\t" << mol->cell_size[2] << "\t" << endl;
1349 *output << mol->cell_size[3] << "\t" << mol->cell_size[4] << "\t" << mol->cell_size[5] << "\t" << endl;
1350 // FIXME
1351 *output << endl;
1352 *output << "ECut\t\t" << config::ECut << "\t# energy cutoff for discretization in Hartrees" << endl;
1353 *output << "MaxLevel\t" << config::MaxLevel << "\t# number of different levels in the code, >=2" << endl;
1354 *output << "Level0Factor\t" << config::Lev0Factor << "\t# factor by which node number increases from S to 0 level" << endl;
1355 *output << "RiemannTensor\t" << config::RiemannTensor << "\t# (Use metric)" << endl;
1356 switch (config::RiemannTensor) {
1357 case 0: //UseNoRT
1358 break;
1359 case 1: // UseRT
1360 *output << "RiemannLevel\t" << config::RiemannLevel << "\t# Number of Riemann Levels" << endl;
1361 *output << "LevRFactor\t" << config::LevRFactor << "\t# factor by which node number increases from 0 to R level from" << endl;
1362 break;
1363 }
1364 *output << "PsiType\t\t" << config::PsiType << "\t# 0 - doubly occupied, 1 - SpinUp,SpinDown" << endl;
1365 // write out both types for easier changing afterwards
1366 // switch (PsiType) {
1367 // case 0:
1368 *output << "MaxPsiDouble\t" << config::MaxPsiDouble << "\t# here: specifying both maximum number of SpinUp- and -Down-states" << endl;
1369 // break;
1370 // case 1:
1371 *output << "PsiMaxNoUp\t" << config::PsiMaxNoUp << "\t# here: specifying maximum number of SpinUp-states" << endl;
1372 *output << "PsiMaxNoDown\t" << config::PsiMaxNoDown << "\t# here: specifying maximum number of SpinDown-states" << endl;
1373 // break;
1374 // }
1375 *output << "AddPsis\t\t" << config::AddPsis << "\t# Additional unoccupied Psis for bandgap determination" << endl;
1376 *output << endl;
1377 *output << "RCut\t\t" << config::RCut << "\t# R-cut for the ewald summation" << endl;
1378 *output << "StructOpt\t" << config::StructOpt << "\t# Do structure optimization beforehand" << endl;
1379 *output << "IsAngstroem\t" << config::IsAngstroem << "\t# 0 - Bohr, 1 - Angstroem" << endl;
1380 *output << "RelativeCoord\t" << config::RelativeCoord << "\t# whether ion coordinates are relative (1) or absolute (0)" << endl;
1381 *output << "MaxTypes\t" << mol->ElementCount << "\t# maximum number of different ion types" << endl;
1382 *output << endl;
1383 result = result && mol->Checkout(output);
1384 if (mol->MDSteps <=1 )
1385 result = result && mol->Output(output);
1386 else
1387 result = result && mol->OutputTrajectories(output);
1388 output->close();
1389 output->clear();
1390 delete(output);
1391 return result;
1392 } else
1393 return false;
1394};
1395
1396/** Stores all elements in a MPQC input file.
1397 * Note that this format cannot be parsed again.
1398 * \param *filename name of file (without ".in" suffix!)
1399 * \param *mol pointer to molecule containing all atoms of the molecule
1400 */
1401bool config::SaveMPQC(const char *filename, molecule *mol) const
1402{
1403 int ElementNo = 0;
1404 int AtomNo;
1405 atom *Walker = NULL;
1406 element *runner = NULL;
1407 Vector *center = NULL;
1408 ofstream *output = NULL;
1409 stringstream *fname = NULL;
1410
1411 // first without hessian
1412 fname = new stringstream;
1413 *fname << filename << ".in";
1414 output = new ofstream(fname->str().c_str(), ios::out);
1415 *output << "% Created by MoleCuilder" << endl;
1416 *output << "mpqc: (" << endl;
1417 *output << "\tsavestate = no" << endl;
1418 *output << "\tdo_gradient = yes" << endl;
1419 *output << "\tmole<MBPT2>: (" << endl;
1420 *output << "\t\tmaxiter = 200" << endl;
1421 *output << "\t\tbasis = $:basis" << endl;
1422 *output << "\t\tmolecule = $:molecule" << endl;
1423 *output << "\t\treference<CLHF>: (" << endl;
1424 *output << "\t\t\tbasis = $:basis" << endl;
1425 *output << "\t\t\tmolecule = $:molecule" << endl;
1426 *output << "\t\t)" << endl;
1427 *output << "\t)" << endl;
1428 *output << ")" << endl;
1429 *output << "molecule<Molecule>: (" << endl;
1430 *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
1431 *output << "\t{ atoms geometry } = {" << endl;
1432 center = mol->DetermineCenterOfAll(output);
1433 // output of atoms
1434 runner = mol->elemente->start;
1435 while (runner->next != mol->elemente->end) { // go through every element
1436 runner = runner->next;
1437 if (mol->ElementsInMolecule[runner->Z]) { // if this element got atoms
1438 ElementNo++;
1439 AtomNo = 0;
1440 Walker = mol->start;
1441 while (Walker->next != mol->end) { // go through every atom of this element
1442 Walker = Walker->next;
1443 if (Walker->type == runner) { // if this atom fits to element
1444 AtomNo++;
1445 *output << "\t\t" << Walker->type->symbol << " [ " << Walker->x.x[0]-center->x[0] << "\t" << Walker->x.x[1]-center->x[1] << "\t" << Walker->x.x[2]-center->x[2] << " ]" << endl;
1446 }
1447 }
1448 }
1449 }
1450 delete(center);
1451 *output << "\t}" << endl;
1452 *output << ")" << endl;
1453 *output << "basis<GaussianBasisSet>: (" << endl;
1454 *output << "\tname = \"" << basis << "\"" << endl;
1455 *output << "\tmolecule = $:molecule" << endl;
1456 *output << ")" << endl;
1457 output->close();
1458 delete(output);
1459 delete(fname);
1460
1461 // second with hessian
1462 fname = new stringstream;
1463 *fname << filename << ".hess.in";
1464 output = new ofstream(fname->str().c_str(), ios::out);
1465 *output << "% Created by MoleCuilder" << endl;
1466 *output << "mpqc: (" << endl;
1467 *output << "\tsavestate = no" << endl;
1468 *output << "\tdo_gradient = yes" << endl;
1469 *output << "\tmole<CLHF>: (" << endl;
1470 *output << "\t\tmaxiter = 200" << endl;
1471 *output << "\t\tbasis = $:basis" << endl;
1472 *output << "\t\tmolecule = $:molecule" << endl;
1473 *output << "\t)" << endl;
1474 *output << "\tfreq<MolecularFrequencies>: (" << endl;
1475 *output << "\t\tmolecule=$:molecule" << endl;
1476 *output << "\t)" << endl;
1477 *output << ")" << endl;
1478 *output << "molecule<Molecule>: (" << endl;
1479 *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
1480 *output << "\t{ atoms geometry } = {" << endl;
1481 center = mol->DetermineCenterOfAll(output);
1482 // output of atoms
1483 runner = mol->elemente->start;
1484 while (runner->next != mol->elemente->end) { // go through every element
1485 runner = runner->next;
1486 if (mol->ElementsInMolecule[runner->Z]) { // if this element got atoms
1487 ElementNo++;
1488 AtomNo = 0;
1489 Walker = mol->start;
1490 while (Walker->next != mol->end) { // go through every atom of this element
1491 Walker = Walker->next;
1492 if (Walker->type == runner) { // if this atom fits to element
1493 AtomNo++;
1494 *output << "\t\t" << Walker->type->symbol << " [ " << Walker->x.x[0]-center->x[0] << "\t" << Walker->x.x[1]-center->x[1] << "\t" << Walker->x.x[2]-center->x[2] << " ]" << endl;
1495 }
1496 }
1497 }
1498 }
1499 delete(center);
1500 *output << "\t}" << endl;
1501 *output << ")" << endl;
1502 *output << "basis<GaussianBasisSet>: (" << endl;
1503 *output << "\tname = \"3-21G\"" << endl;
1504 *output << "\tmolecule = $:molecule" << endl;
1505 *output << ")" << endl;
1506 output->close();
1507 delete(output);
1508 delete(fname);
1509
1510 return true;
1511};
1512
1513/** Reads parameter from a parsed file.
1514 * The file is either parsed for a certain keyword or if null is given for
1515 * the value in row yth and column xth. If the keyword was necessity#critical,
1516 * then an error is thrown and the programme aborted.
1517 * \warning value is modified (both in contents and position)!
1518 * \param verbose 1 - print found value to stderr, 0 - don't
1519 * \param *file file to be parsed
1520 * \param name Name of value in file (at least 3 chars!)
1521 * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning
1522 * (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read -
1523 * best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now
1524 * counted from this unresetted position!)
1525 * \param xth Which among a number of parameters it is (in grid case it's row number as grid is read as a whole!)
1526 * \param yth In grid case specifying column number, otherwise the yth \a name matching line
1527 * \param type Type of the Parameter to be read
1528 * \param value address of the value to be read (must have been allocated)
1529 * \param repetition determines, if the keyword appears multiply in the config file, which repetition shall be parsed, i.e. 1 if not multiply
1530 * \param critical necessity of this keyword being specified (optional, critical)
1531 * \return 1 - found, 0 - not found
1532 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++
1533 */
1534int config::ParseForParameter(int verbose, ifstream *file, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical) {
1535 int i,j; // loop variables
1536 int length = 0, maxlength = -1;
1537 long file_position = file->tellg(); // mark current position
1538 char *dummy1, *dummy, *free_dummy; // pointers in the line that is read in per step
1539 dummy1 = free_dummy = Malloc<char>(256, "config::ParseForParameter: *free_dummy");
1540
1541 //fprintf(stderr,"Parsing for %s\n",name);
1542 if (repetition == 0)
1543 //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!");
1544 return 0;
1545
1546 int line = 0; // marks line where parameter was found
1547 int found = (type >= grid) ? 0 : (-yth + 1); // marks if yth parameter name was found
1548 while((found != repetition)) {
1549 dummy1 = dummy = free_dummy;
1550 do {
1551 file->getline(dummy1, 256); // Read the whole line
1552 if (file->eof()) {
1553 if ((critical) && (found == 0)) {
1554 Free(&free_dummy);
1555 //Error(InitReading, name);
1556 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
1557 exit(255);
1558 } else {
1559 //if (!sequential)
1560 file->clear();
1561 file->seekg(file_position, ios::beg); // rewind to start position
1562 Free(&free_dummy);
1563 return 0;
1564 }
1565 }
1566 line++;
1567 } while (dummy != NULL && dummy1 != NULL && ((dummy1[0] == '#') || (dummy1[0] == '\0'))); // skip commentary and empty lines
1568
1569 // C++ getline removes newline at end, thus re-add
1570 if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
1571 i = strlen(dummy1);
1572 dummy1[i] = '\n';
1573 dummy1[i+1] = '\0';
1574 }
1575 //fprintf(stderr,"line %i ends at %i, newline at %i\n", line, strlen(dummy1), strchr(dummy1,'\n')-free_dummy);
1576
1577 if (dummy1 == NULL) {
1578 if (verbose) fprintf(stderr,"Error reading line %i\n",line);
1579 } else {
1580 //fprintf(stderr,"Now parsing the line %i: %s\n", line, dummy1);
1581 }
1582 // Seek for possible end of keyword on line if given ...
1583 if (name != NULL) {
1584 dummy = strchr(dummy1,'\t'); // set dummy on first tab or space which ever's nearer
1585 if (dummy == NULL) {
1586 dummy = strchr(dummy1, ' '); // if not found seek for space
1587 while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' '))) // skip some more tabs and spaces if necessary
1588 dummy++;
1589 }
1590 if (dummy == NULL) {
1591 dummy = strchr(dummy1, '\n'); // set on line end then (whole line = keyword)
1592 //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name);
1593 //Free((void **)&free_dummy);
1594 //Error(FileOpenParams, NULL);
1595 } else {
1596 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)dummy1);
1597 }
1598 } else dummy = dummy1;
1599 // ... and check if it is the keyword!
1600 //fprintf(stderr,"name %p, dummy %i/%c, dummy1 %i/%c, strlen(name) %i\n", &name, dummy, *dummy, dummy1, *dummy1, strlen(name));
1601 if ((name == NULL) || (((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name)))) {
1602 found++; // found the parameter!
1603 //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy);
1604
1605 if (found == repetition) {
1606 for (i=0;i<xth;i++) { // i = rows
1607 if (type >= grid) {
1608 // grid structure means that grid starts on the next line, not right after keyword
1609 dummy1 = dummy = free_dummy;
1610 do {
1611 file->getline(dummy1, 256); // Read the whole line, skip commentary and empty ones
1612 if (file->eof()) {
1613 if ((critical) && (found == 0)) {
1614 Free(&free_dummy);
1615 //Error(InitReading, name);
1616 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
1617 exit(255);
1618 } else {
1619 //if (!sequential)
1620 file->clear();
1621 file->seekg(file_position, ios::beg); // rewind to start position
1622 Free(&free_dummy);
1623 return 0;
1624 }
1625 }
1626 line++;
1627 } while ((dummy1[0] == '#') || (dummy1[0] == '\n'));
1628 if (dummy1 == NULL){
1629 if (verbose) fprintf(stderr,"Error reading line %i\n", line);
1630 } else {
1631 //fprintf(stderr,"Reading next line %i: %s\n", line, dummy1);
1632 }
1633 } else { // simple int, strings or doubles start in the same line
1634 while ((*dummy == '\t') || (*dummy == ' ')) // skip interjacent tabs and spaces
1635 dummy++;
1636 }
1637 // C++ getline removes newline at end, thus re-add
1638 if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
1639 j = strlen(dummy1);
1640 dummy1[j] = '\n';
1641 dummy1[j+1] = '\0';
1642 }
1643
1644 int start = (type >= grid) ? 0 : yth-1 ;
1645 for (j=start;j<yth;j++) { // j = columns
1646 // check for lower triangular area and upper triangular area
1647 if ( ((i > j) && (type == upper_trigrid)) || ((j > i) && (type == lower_trigrid))) {
1648 *((double *)value) = 0.0;
1649 fprintf(stderr,"%f\t",*((double *)value));
1650 value = (void *)((long)value + sizeof(double));
1651 //value += sizeof(double);
1652 } else {
1653 // otherwise we must skip all interjacent tabs and spaces and find next value
1654 dummy1 = dummy;
1655 dummy = strchr(dummy1, '\t'); // seek for tab or space
1656 if (dummy == NULL)
1657 dummy = strchr(dummy1, ' '); // if not found seek for space
1658 if (dummy == NULL) { // if still zero returned ...
1659 dummy = strchr(dummy1, '\n'); // ... at line end then
1660 if ((j < yth-1) && (type < 4)) { // check if xth value or not yet
1661 if (critical) {
1662 if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
1663 Free(&free_dummy);
1664 //return 0;
1665 exit(255);
1666 //Error(FileOpenParams, NULL);
1667 } else {
1668 //if (!sequential)
1669 file->clear();
1670 file->seekg(file_position, ios::beg); // rewind to start position
1671 Free(&free_dummy);
1672 return 0;
1673 }
1674 }
1675 } else {
1676 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)free_dummy);
1677 }
1678 if (*dummy1 == '#') {
1679 // found comment, skipping rest of line
1680 //if (verbose) fprintf(stderr,"Error: '#' at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
1681 if (!sequential) { // here we need it!
1682 file->seekg(file_position, ios::beg); // rewind to start position
1683 }
1684 Free(&free_dummy);
1685 return 0;
1686 }
1687 //fprintf(stderr,"value from %i to %i\n",(char *)dummy1-(char *)free_dummy,(char *)dummy-(char *)free_dummy);
1688 switch(type) {
1689 case (row_int):
1690 *((int *)value) = atoi(dummy1);
1691 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
1692 if (verbose) fprintf(stderr,"%i\t",*((int *)value));
1693 value = (void *)((long)value + sizeof(int));
1694 //value += sizeof(int);
1695 break;
1696 case(row_double):
1697 case(grid):
1698 case(lower_trigrid):
1699 case(upper_trigrid):
1700 *((double *)value) = atof(dummy1);
1701 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
1702 if (verbose) fprintf(stderr,"%lg\t",*((double *)value));
1703 value = (void *)((long)value + sizeof(double));
1704 //value += sizeof(double);
1705 break;
1706 case(double_type):
1707 *((double *)value) = atof(dummy1);
1708 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %lg\n", name, *((double *) value));
1709 //value += sizeof(double);
1710 break;
1711 case(int_type):
1712 *((int *)value) = atoi(dummy1);
1713 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %i\n", name, *((int *) value));
1714 //value += sizeof(int);
1715 break;
1716 default:
1717 case(string_type):
1718 if (value != NULL) {
1719 //if (maxlength == -1) maxlength = strlen((char *)value); // get maximum size of string array
1720 maxlength = MAXSTRINGSIZE;
1721 length = maxlength > (dummy-dummy1) ? (dummy-dummy1) : maxlength; // cap at maximum
1722 strncpy((char *)value, dummy1, length); // copy as much
1723 ((char *)value)[length] = '\0'; // and set end marker
1724 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s is '%s' (%i chars)\n",name,((char *) value), length);
1725 //value += sizeof(char);
1726 } else {
1727 }
1728 break;
1729 }
1730 }
1731 while (*dummy == '\t')
1732 dummy++;
1733 }
1734 }
1735 }
1736 }
1737 }
1738 if ((type >= row_int) && (verbose))
1739 fprintf(stderr,"\n");
1740 Free(&free_dummy);
1741 if (!sequential) {
1742 file->clear();
1743 file->seekg(file_position, ios::beg); // rewind to start position
1744 }
1745 //fprintf(stderr, "End of Parsing\n\n");
1746
1747 return (found); // true if found, false if not
1748}
1749
1750
1751/** Reads parameter from a parsed file.
1752 * The file is either parsed for a certain keyword or if null is given for
1753 * the value in row yth and column xth. If the keyword was necessity#critical,
1754 * then an error is thrown and the programme aborted.
1755 * \warning value is modified (both in contents and position)!
1756 * \param verbose 1 - print found value to stderr, 0 - don't
1757 * \param *FileBuffer pointer to buffer structure
1758 * \param name Name of value in file (at least 3 chars!)
1759 * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning
1760 * (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read -
1761 * best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now
1762 * counted from this unresetted position!)
1763 * \param xth Which among a number of parameters it is (in grid case it's row number as grid is read as a whole!)
1764 * \param yth In grid case specifying column number, otherwise the yth \a name matching line
1765 * \param type Type of the Parameter to be read
1766 * \param value address of the value to be read (must have been allocated)
1767 * \param repetition determines, if the keyword appears multiply in the config file, which repetition shall be parsed, i.e. 1 if not multiply
1768 * \param critical necessity of this keyword being specified (optional, critical)
1769 * \return 1 - found, 0 - not found
1770 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++
1771 */
1772int config::ParseForParameter(int verbose, struct ConfigFileBuffer *FileBuffer, const char *name, int sequential, int const xth, int const yth, int type, void *value, int repetition, int critical) {
1773 int i,j; // loop variables
1774 int length = 0, maxlength = -1;
1775 int OldCurrentLine = FileBuffer->CurrentLine;
1776 char *dummy1, *dummy; // pointers in the line that is read in per step
1777
1778 //fprintf(stderr,"Parsing for %s\n",name);
1779 if (repetition == 0)
1780 //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!");
1781 return 0;
1782
1783 int line = 0; // marks line where parameter was found
1784 int found = (type >= grid) ? 0 : (-yth + 1); // marks if yth parameter name was found
1785 while((found != repetition)) {
1786 dummy1 = dummy = NULL;
1787 do {
1788 dummy1 = FileBuffer->buffer[ FileBuffer->LineMapping[FileBuffer->CurrentLine++] ];
1789 if (FileBuffer->CurrentLine >= FileBuffer->NoLines) {
1790 if ((critical) && (found == 0)) {
1791 //Error(InitReading, name);
1792 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
1793 exit(255);
1794 } else {
1795 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
1796 return 0;
1797 }
1798 }
1799 if (dummy1 == NULL) {
1800 if (verbose) fprintf(stderr,"Error reading line %i\n",line);
1801 } else {
1802 //fprintf(stderr,"Now parsing the line %i: %s\n", line, dummy1);
1803 }
1804 line++;
1805 } while (dummy1 != NULL && ((dummy1[0] == '#') || (dummy1[0] == '\0'))); // skip commentary and empty lines
1806
1807 // Seek for possible end of keyword on line if given ...
1808 if (name != NULL) {
1809 dummy = strchr(dummy1,'\t'); // set dummy on first tab or space which ever's nearer
1810 if (dummy == NULL) {
1811 dummy = strchr(dummy1, ' '); // if not found seek for space
1812 while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' '))) // skip some more tabs and spaces if necessary
1813 dummy++;
1814 }
1815 if (dummy == NULL) {
1816 dummy = strchr(dummy1, '\n'); // set on line end then (whole line = keyword)
1817 //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name);
1818 //Free(&free_dummy);
1819 //Error(FileOpenParams, NULL);
1820 } else {
1821 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)dummy1);
1822 }
1823 } else dummy = dummy1;
1824 // ... and check if it is the keyword!
1825 //fprintf(stderr,"name %p, dummy %i/%c, dummy1 %i/%c, strlen(name) %i\n", &name, dummy, *dummy, dummy1, *dummy1, strlen(name));
1826 if ((name == NULL) || (((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name)))) {
1827 found++; // found the parameter!
1828 //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy);
1829
1830 if (found == repetition) {
1831 for (i=0;i<xth;i++) { // i = rows
1832 if (type >= grid) {
1833 // grid structure means that grid starts on the next line, not right after keyword
1834 dummy1 = dummy = NULL;
1835 do {
1836 dummy1 = FileBuffer->buffer[ FileBuffer->LineMapping[ FileBuffer->CurrentLine++] ];
1837 if (FileBuffer->CurrentLine >= FileBuffer->NoLines) {
1838 if ((critical) && (found == 0)) {
1839 //Error(InitReading, name);
1840 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
1841 exit(255);
1842 } else {
1843 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
1844 return 0;
1845 }
1846 }
1847 if (dummy1 == NULL) {
1848 if (verbose) fprintf(stderr,"Error reading line %i\n", line);
1849 } else {
1850 //fprintf(stderr,"Reading next line %i: %s\n", line, dummy1);
1851 }
1852 line++;
1853 } while (dummy1 != NULL && (dummy1[0] == '#') || (dummy1[0] == '\n'));
1854 dummy = dummy1;
1855 } else { // simple int, strings or doubles start in the same line
1856 while ((*dummy == '\t') || (*dummy == ' ')) // skip interjacent tabs and spaces
1857 dummy++;
1858 }
1859
1860 for (j=((type >= grid) ? 0 : yth-1);j<yth;j++) { // j = columns
1861 // check for lower triangular area and upper triangular area
1862 if ( ((i > j) && (type == upper_trigrid)) || ((j > i) && (type == lower_trigrid))) {
1863 *((double *)value) = 0.0;
1864 fprintf(stderr,"%f\t",*((double *)value));
1865 value = (void *)((long)value + sizeof(double));
1866 //value += sizeof(double);
1867 } else {
1868 // otherwise we must skip all interjacent tabs and spaces and find next value
1869 dummy1 = dummy;
1870 dummy = strchr(dummy1, '\t'); // seek for tab or space
1871 if (dummy == NULL)
1872 dummy = strchr(dummy1, ' '); // if not found seek for space
1873 if (dummy == NULL) { // if still zero returned ...
1874 dummy = strchr(dummy1, '\n'); // ... at line end then
1875 if ((j < yth-1) && (type < 4)) { // check if xth value or not yet
1876 if (critical) {
1877 if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
1878 //return 0;
1879 exit(255);
1880 //Error(FileOpenParams, NULL);
1881 } else {
1882 if (!sequential) { // here we need it!
1883 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
1884 }
1885 return 0;
1886 }
1887 }
1888 } else {
1889 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)free_dummy);
1890 }
1891 if (*dummy1 == '#') {
1892 // found comment, skipping rest of line
1893 //if (verbose) fprintf(stderr,"Error: '#' at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
1894 if (!sequential) { // here we need it!
1895 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
1896 }
1897 return 0;
1898 }
1899 //fprintf(stderr,"value from %i to %i\n",(char *)dummy1-(char *)free_dummy,(char *)dummy-(char *)free_dummy);
1900 switch(type) {
1901 case (row_int):
1902 *((int *)value) = atoi(dummy1);
1903 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
1904 if (verbose) fprintf(stderr,"%i\t",*((int *)value));
1905 value = (void *)((long)value + sizeof(int));
1906 //value += sizeof(int);
1907 break;
1908 case(row_double):
1909 case(grid):
1910 case(lower_trigrid):
1911 case(upper_trigrid):
1912 *((double *)value) = atof(dummy1);
1913 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
1914 if (verbose) fprintf(stderr,"%lg\t",*((double *)value));
1915 value = (void *)((long)value + sizeof(double));
1916 //value += sizeof(double);
1917 break;
1918 case(double_type):
1919 *((double *)value) = atof(dummy1);
1920 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %lg\n", name, *((double *) value));
1921 //value += sizeof(double);
1922 break;
1923 case(int_type):
1924 *((int *)value) = atoi(dummy1);
1925 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %i\n", name, *((int *) value));
1926 //value += sizeof(int);
1927 break;
1928 default:
1929 case(string_type):
1930 if (value != NULL) {
1931 //if (maxlength == -1) maxlength = strlen((char *)value); // get maximum size of string array
1932 maxlength = MAXSTRINGSIZE;
1933 length = maxlength > (dummy-dummy1) ? (dummy-dummy1) : maxlength; // cap at maximum
1934 strncpy((char *)value, dummy1, length); // copy as much
1935 ((char *)value)[length] = '\0'; // and set end marker
1936 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s is '%s' (%i chars)\n",name,((char *) value), length);
1937 //value += sizeof(char);
1938 } else {
1939 }
1940 break;
1941 }
1942 }
1943 while (*dummy == '\t')
1944 dummy++;
1945 }
1946 }
1947 }
1948 }
1949 }
1950 if ((type >= row_int) && (verbose)) fprintf(stderr,"\n");
1951 if (!sequential) {
1952 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
1953 }
1954 //fprintf(stderr, "End of Parsing\n\n");
1955
1956 return (found); // true if found, false if not
1957}
Note: See TracBrowser for help on using the repository browser.