source: src/config.cpp@ 99593f

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 99593f was c9bce3e, checked in by Frederik Heber <heber@…>, 16 years ago

config::Load() refactored: Dissection into connected subgraphs -> MoleculeListClass::DissectMoleculeIntoConnectedSubgraphs()

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