source: src/config.cpp@ a5551b

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 Candidate_v1.7.0 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 a5551b was eecd33, checked in by Frederik Heber <heber@…>, 16 years ago

BUGFIX: Allocated one molecule too much in config::Load().

  • Count() was called from Subgraph not from Subgraph->next
  • Property mode set to 100644
File size: 92.2 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 //mol->ActiveFlag = true;
1058 //MolList->insert(mol);
1059
1060 // 4. dissect the molecule into connected subgraphs
1061 BG->ConstructBondGraph((ofstream *)&cout, mol);
1062
1063 // 5. scan for connected subgraphs
1064 MoleculeLeafClass *Subgraphs = NULL; // list of subgraphs from DFS analysis
1065 class StackClass<bond *> *BackEdgeStack = NULL;
1066 Subgraphs = mol->DepthFirstSearchAnalysis((ofstream *)&cout, BackEdgeStack);
1067 delete(BackEdgeStack);
1068
1069 // 6. dissect (the following construct is needed to have the atoms not in the order of the DFS, but in
1070 // the original one as parsed in)
1071 // TODO: Optimize this, when molecules just contain pointer list of global atoms!
1072
1073 // 6a. create array of molecules to fill
1074 const int MolCount = Subgraphs->next->Count();
1075 molecule **molecules = Malloc<molecule *>(MolCount, "config::Load() - **molecules");
1076 for (int i=0;i<MolCount;i++) {
1077 molecules[i] = (molecule*) new molecule(periode);
1078 molecules[i]->ActiveFlag = true;
1079 MolList->insert(molecules[i]);
1080 }
1081
1082 // 6b. create and fill map of which atom is associated to which connected molecule (note, counting starts at 1)
1083 int FragmentCounter = 0;
1084 int *MolMap = Calloc<int>(mol->AtomCount, "config::Load() - *MolMap");
1085 MoleculeLeafClass *MolecularWalker = Subgraphs;
1086 atom *Walker = NULL;
1087 while (MolecularWalker->next != NULL) {
1088 MolecularWalker = MolecularWalker->next;
1089 Walker = MolecularWalker->Leaf->start;
1090 while (Walker->next != MolecularWalker->Leaf->end) {
1091 Walker = Walker->next;
1092 MolMap[Walker->GetTrueFather()->nr] = FragmentCounter+1;
1093 }
1094 FragmentCounter++;
1095 }
1096
1097 // 6c. relocate atoms to new molecules and remove from Leafs
1098 Walker = mol->start;
1099 while (mol->start->next != mol->end) {
1100 Walker = mol->start->next;
1101 if ((Walker->nr <0) || (Walker->nr >= mol->AtomCount)) {
1102 cerr << "Index of atom " << *Walker << " is invalid!" << endl;
1103 performCriticalExit();
1104 }
1105 FragmentCounter = MolMap[Walker->nr];
1106 if (FragmentCounter != 0) {
1107 cout << Verbose(3) << "Re-linking " << *Walker << "..." << endl;
1108 unlink(Walker);
1109 molecules[FragmentCounter-1]->AddAtom(Walker); // counting starts at 1
1110 } else {
1111 cerr << "Atom " << *Walker << " not associated to molecule!" << endl;
1112 performCriticalExit();
1113 }
1114 }
1115 // 6d. we don't need to redo bonds, as they are connected subgraphs and still maintained their ListOfBonds
1116 // 6e. free Leafs
1117 MolecularWalker = Subgraphs;
1118 while (MolecularWalker->next != NULL) {
1119 MolecularWalker = MolecularWalker->next;
1120 delete(MolecularWalker->previous);
1121 }
1122 delete(MolecularWalker);
1123 delete(mol);
1124 Free(&MolMap);
1125 Free(&molecules);
1126 cout << Verbose(1) << "I scanned " << FragmentCounter << " molecules." << endl;
1127
1128 delete(FileBuffer);
1129};
1130
1131/** Initializes config file structure by loading elements from a give file with old pcp syntax.
1132 * \param *file input file stream being the opened config file with old pcp syntax
1133 * \param BondGraphFileName file name of the bond length table file, if string is left blank, no table is parsed.
1134 * \param *periode pointer to a periodentafel class with all elements
1135 * \param *&MolList pointer to MoleculeListClass, on return containing all parsed molecules in system
1136 */
1137void config::LoadOld(const char * const filename, const string &BondGraphFileName, const periodentafel * const periode, MoleculeListClass * const &MolList)
1138{
1139 molecule *mol = new molecule(periode);
1140 ifstream *file = new ifstream(filename);
1141 if (file == NULL) {
1142 cerr << "ERROR: config file " << filename << " missing!" << endl;
1143 return;
1144 }
1145 RetrieveConfigPathAndName(filename);
1146 // ParseParameters
1147
1148 /* Oeffne Hauptparameterdatei */
1149 int l = 0;
1150 int i = 0;
1151 int di = 0;
1152 double a = 0.;
1153 double b = 0.;
1154 double BoxLength[9];
1155 string zeile;
1156 string dummy;
1157 element *elementhash[128];
1158 int Z = -1;
1159 int No = -1;
1160 int AtomNo = -1;
1161 int found = 0;
1162 int verbose = 0;
1163
1164 mol->ActiveFlag = true;
1165 MolList->insert(mol);
1166 /* Namen einlesen */
1167
1168 ParseForParameter(verbose,file, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical);
1169 ParseForParameter(verbose,file, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical);
1170 ParseForParameter(verbose,file, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical);
1171 ParseForParameter(verbose,file, "ProcsGammaPsi", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical);
1172 ParseForParameter(verbose,file, "ProcsGammaPsi", 0, 2, 1, int_type, &(config::ProcPEPsi), 1, critical);
1173 config::Seed = 1;
1174 config::DoOutOrbitals = 0;
1175 ParseForParameter(verbose,file,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical);
1176 if (config::DoOutVis < 0) config::DoOutVis = 0;
1177 if (config::DoOutVis > 1) config::DoOutVis = 1;
1178 config::VectorPlane = -1;
1179 config::VectorCut = 0.;
1180 ParseForParameter(verbose,file,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical);
1181 if (config::DoOutMes < 0) config::DoOutMes = 0;
1182 if (config::DoOutMes > 1) config::DoOutMes = 1;
1183 config::DoOutCurrent = 0;
1184 ParseForParameter(verbose,file,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical);
1185 if (config::UseAddGramSch < 0) config::UseAddGramSch = 0;
1186 if (config::UseAddGramSch > 2) config::UseAddGramSch = 2;
1187 config::CommonWannier = 0;
1188 config::SawtoothStart = 0.01;
1189
1190 ParseForParameter(verbose,file,"MaxOuterStep", 0, 1, 1, double_type, &(config::MaxOuterStep), 1, critical);
1191 ParseForParameter(verbose,file,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional);
1192 ParseForParameter(verbose,file,"VisOuterStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional);
1193 ParseForParameter(verbose,file,"VisSrcOuterStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional);
1194 ParseForParameter(verbose,file,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional);
1195 ParseForParameter(verbose,file,"ScaleTempStep", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional);
1196 config::EpsWannier = 1e-8;
1197
1198 // stop conditions
1199 //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1;
1200 ParseForParameter(verbose,file,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical);
1201 if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3;
1202
1203 ParseForParameter(verbose,file,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical);
1204 ParseForParameter(verbose,file,"MaxMinStep", 0, 2, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical);
1205 ParseForParameter(verbose,file,"MaxMinStep", 0, 3, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical);
1206 ParseForParameter(verbose,file,"MaxMinStep", 0, 4, 1, int_type, &(config::MaxMinStopStep), 1, critical);
1207 if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep;
1208 if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1;
1209 config::MaxMinGapStopStep = 1;
1210
1211 ParseForParameter(verbose,file,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical);
1212 ParseForParameter(verbose,file,"MaxInitMinStep", 0, 2, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical);
1213 ParseForParameter(verbose,file,"MaxInitMinStep", 0, 3, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical);
1214 ParseForParameter(verbose,file,"MaxInitMinStep", 0, 4, 1, int_type, &(config::InitMaxMinStopStep), 1, critical);
1215 if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep;
1216 if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1;
1217 config::InitMaxMinGapStopStep = 1;
1218
1219 ParseForParameter(verbose,file, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */
1220 mol->cell_size[0] = BoxLength[0];
1221 mol->cell_size[1] = BoxLength[3];
1222 mol->cell_size[2] = BoxLength[4];
1223 mol->cell_size[3] = BoxLength[6];
1224 mol->cell_size[4] = BoxLength[7];
1225 mol->cell_size[5] = BoxLength[8];
1226 if (1) fprintf(stderr,"\n");
1227 config::DoPerturbation = 0;
1228 config::DoFullCurrent = 0;
1229
1230 ParseForParameter(verbose,file,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical);
1231 ParseForParameter(verbose,file,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical);
1232 ParseForParameter(verbose,file,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical);
1233 if (config::Lev0Factor < 2) {
1234 config::Lev0Factor = 2;
1235 }
1236 ParseForParameter(verbose,file,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical);
1237 if (di >= 0 && di < 2) {
1238 config::RiemannTensor = di;
1239 } else {
1240 fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT");
1241 exit(1);
1242 }
1243 switch (config::RiemannTensor) {
1244 case 0: //UseNoRT
1245 if (config::MaxLevel < 2) {
1246 config::MaxLevel = 2;
1247 }
1248 config::LevRFactor = 2;
1249 config::RTActualUse = 0;
1250 break;
1251 case 1: // UseRT
1252 if (config::MaxLevel < 3) {
1253 config::MaxLevel = 3;
1254 }
1255 ParseForParameter(verbose,file,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical);
1256 if (config::RiemannLevel < 2) {
1257 config::RiemannLevel = 2;
1258 }
1259 if (config::RiemannLevel > config::MaxLevel-1) {
1260 config::RiemannLevel = config::MaxLevel-1;
1261 }
1262 ParseForParameter(verbose,file,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical);
1263 if (config::LevRFactor < 2) {
1264 config::LevRFactor = 2;
1265 }
1266 config::Lev0Factor = 2;
1267 config::RTActualUse = 2;
1268 break;
1269 }
1270 ParseForParameter(verbose,file,"PsiType", 0, 1, 1, int_type, &di, 1, critical);
1271 if (di >= 0 && di < 2) {
1272 config::PsiType = di;
1273 } else {
1274 fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown");
1275 exit(1);
1276 }
1277 switch (config::PsiType) {
1278 case 0: // SpinDouble
1279 ParseForParameter(verbose,file,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical);
1280 config::AddPsis = 0;
1281 break;
1282 case 1: // SpinUpDown
1283 if (config::ProcPEGamma % 2) config::ProcPEGamma*=2;
1284 ParseForParameter(verbose,file,"MaxPsiUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical);
1285 ParseForParameter(verbose,file,"MaxPsiDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical);
1286 config::AddPsis = 0;
1287 break;
1288 }
1289
1290 // IonsInitRead
1291
1292 ParseForParameter(verbose,file,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical);
1293 ParseForParameter(verbose,file,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical);
1294 config::RelativeCoord = 0;
1295 config::StructOpt = 0;
1296
1297
1298 // 2. parse the bond graph file if given
1299 BG = new BondGraph(IsAngstroem);
1300 if (BG->LoadBondLengthTable((ofstream *)&cout, BondGraphFileName)) {
1301 cout << Verbose(0) << "Bond length table loaded successfully." << endl;
1302 } else {
1303 cout << Verbose(0) << "Bond length table loading failed." << endl;
1304 }
1305
1306 // Routine from builder.cpp
1307
1308 for (i=MAX_ELEMENTS;i--;)
1309 elementhash[i] = NULL;
1310 cout << Verbose(0) << "Parsing Ions ..." << endl;
1311 No=0;
1312 found = 0;
1313 while (getline(*file,zeile,'\n')) {
1314 if (zeile.find("Ions_Data") == 0) {
1315 cout << Verbose(1) << "found Ions_Data...begin parsing" << endl;
1316 found ++;
1317 }
1318 if (found > 0) {
1319 if (zeile.find("Ions_Data") == 0)
1320 getline(*file,zeile,'\n'); // read next line and parse this one
1321 istringstream input(zeile);
1322 input >> AtomNo; // number of atoms
1323 input >> Z; // atomic number
1324 input >> a;
1325 input >> l;
1326 input >> l;
1327 input >> b; // element mass
1328 elementhash[No] = periode->FindElement(Z);
1329 cout << Verbose(1) << "AtomNo: " << AtomNo << "\tZ: " << Z << "\ta:" << a << "\tl:" << l << "\b:" << b << "\tElement:" << elementhash[No] << "\t:" << endl;
1330 for(i=0;i<AtomNo;i++) {
1331 if (!getline(*file,zeile,'\n')) {// parse on and on
1332 cout << Verbose(2) << "Error: Too few items in ionic list of element" << elementhash[No] << "." << endl << "Exiting." << endl;
1333 // return 1;
1334 } else {
1335 //cout << Verbose(2) << "Reading line: " << zeile << endl;
1336 }
1337 istringstream input2(zeile);
1338 atom *neues = new atom();
1339 input2 >> neues->x.x[0]; // x
1340 input2 >> neues->x.x[1]; // y
1341 input2 >> neues->x.x[2]; // z
1342 input2 >> l;
1343 neues->type = elementhash[No]; // find element type
1344 mol->AddAtom(neues);
1345 }
1346 No++;
1347 }
1348 }
1349 file->close();
1350 delete(file);
1351};
1352
1353/** Stores all elements of config structure from which they can be re-read.
1354 * \param *filename name of file
1355 * \param *periode pointer to a periodentafel class with all elements
1356 * \param *mol pointer to molecule containing all atoms of the molecule
1357 */
1358bool config::Save(const char * const filename, const periodentafel * const periode, molecule * const mol) const
1359{
1360 bool result = true;
1361 // bring MaxTypes up to date
1362 mol->CountElements();
1363 ofstream * const output = new ofstream(filename, ios::out);
1364 if (output != NULL) {
1365 *output << "# ParallelCarParinello - main configuration file - created with molecuilder" << endl;
1366 *output << endl;
1367 *output << "mainname\t" << config::mainname << "\t# programm name (for runtime files)" << endl;
1368 *output << "defaultpath\t" << config::defaultpath << "\t# where to put files during runtime" << endl;
1369 *output << "pseudopotpath\t" << config::pseudopotpath << "\t# where to find pseudopotentials" << endl;
1370 *output << endl;
1371 *output << "ProcPEGamma\t" << config::ProcPEGamma << "\t# for parallel computing: share constants" << endl;
1372 *output << "ProcPEPsi\t" << config::ProcPEPsi << "\t# for parallel computing: share wave functions" << endl;
1373 *output << "DoOutVis\t" << config::DoOutVis << "\t# Output data for OpenDX" << endl;
1374 *output << "DoOutMes\t" << config::DoOutMes << "\t# Output data for measurements" << endl;
1375 *output << "DoOutOrbitals\t" << config::DoOutOrbitals << "\t# Output all Orbitals" << endl;
1376 *output << "DoOutCurr\t" << config::DoOutCurrent << "\t# Ouput current density for OpenDx" << endl;
1377 *output << "DoOutNICS\t" << config::DoOutNICS << "\t# Output Nucleus independent current shieldings" << endl;
1378 *output << "DoPerturbation\t" << config::DoPerturbation << "\t# Do perturbation calculate and determine susceptibility and shielding" << endl;
1379 *output << "DoFullCurrent\t" << config::DoFullCurrent << "\t# Do full perturbation" << endl;
1380 *output << "DoConstrainedMD\t" << config::DoConstrainedMD << "\t# Do perform a constrained (>0, relating to current MD step) instead of unconstrained (0) MD" << endl;
1381 *output << "Thermostat\t" << ThermostatNames[Thermostat] << "\t";
1382 switch(Thermostat) {
1383 default:
1384 case None:
1385 break;
1386 case Woodcock:
1387 *output << ScaleTempStep;
1388 break;
1389 case Gaussian:
1390 *output << ScaleTempStep;
1391 break;
1392 case Langevin:
1393 *output << TempFrequency << "\t" << alpha;
1394 break;
1395 case Berendsen:
1396 *output << TempFrequency;
1397 break;
1398 case NoseHoover:
1399 *output << HooverMass;
1400 break;
1401 };
1402 *output << "\t# Which Thermostat and its parameters to use in MD case." << endl;
1403 *output << "CommonWannier\t" << config::CommonWannier << "\t# Put virtual centers at indivual orbits, all common, merged by variance, to grid point, to cell center" << endl;
1404 *output << "SawtoothStart\t" << config::SawtoothStart << "\t# Absolute value for smooth transition at cell border " << endl;
1405 *output << "VectorPlane\t" << config::VectorPlane << "\t# Cut plane axis (x, y or z: 0,1,2) for two-dim current vector plot" << endl;
1406 *output << "VectorCut\t" << config::VectorCut << "\t# Cut plane axis value" << endl;
1407 *output << "AddGramSch\t" << config::UseAddGramSch << "\t# Additional GramSchmidtOrtogonalization to be safe" << endl;
1408 *output << "Seed\t\t" << config::Seed << "\t# initial value for random seed for Psi coefficients" << endl;
1409 *output << endl;
1410 *output << "MaxOuterStep\t" << config::MaxOuterStep << "\t# number of MolecularDynamics/Structure optimization steps" << endl;
1411 *output << "Deltat\t" << config::Deltat << "\t# time per MD step" << endl;
1412 *output << "OutVisStep\t" << config::OutVisStep << "\t# Output visual data every ...th step" << endl;
1413 *output << "OutSrcStep\t" << config::OutSrcStep << "\t# Output \"restart\" data every ..th step" << endl;
1414 *output << "TargetTemp\t" << config::TargetTemp << "\t# Target temperature" << endl;
1415 *output << "MaxPsiStep\t" << config::MaxPsiStep << "\t# number of Minimisation steps per state (0 - default)" << endl;
1416 *output << "EpsWannier\t" << config::EpsWannier << "\t# tolerance value for spread minimisation of orbitals" << endl;
1417 *output << endl;
1418 *output << "# Values specifying when to stop" << endl;
1419 *output << "MaxMinStep\t" << config::MaxMinStep << "\t# Maximum number of steps" << endl;
1420 *output << "RelEpsTotalE\t" << config::RelEpsTotalEnergy << "\t# relative change in total energy" << endl;
1421 *output << "RelEpsKineticE\t" << config::RelEpsKineticEnergy << "\t# relative change in kinetic energy" << endl;
1422 *output << "MaxMinStopStep\t" << config::MaxMinStopStep << "\t# check every ..th steps" << endl;
1423 *output << "MaxMinGapStopStep\t" << config::MaxMinGapStopStep << "\t# check every ..th steps" << endl;
1424 *output << endl;
1425 *output << "# Values specifying when to stop for INIT, otherwise same as above" << endl;
1426 *output << "MaxInitMinStep\t" << config::MaxInitMinStep << "\t# Maximum number of steps" << endl;
1427 *output << "InitRelEpsTotalE\t" << config::InitRelEpsTotalEnergy << "\t# relative change in total energy" << endl;
1428 *output << "InitRelEpsKineticE\t" << config::InitRelEpsKineticEnergy << "\t# relative change in kinetic energy" << endl;
1429 *output << "InitMaxMinStopStep\t" << config::InitMaxMinStopStep << "\t# check every ..th steps" << endl;
1430 *output << "InitMaxMinGapStopStep\t" << config::InitMaxMinGapStopStep << "\t# check every ..th steps" << endl;
1431 *output << endl;
1432 *output << "BoxLength\t\t\t# (Length of a unit cell)" << endl;
1433 *output << mol->cell_size[0] << "\t" << endl;
1434 *output << mol->cell_size[1] << "\t" << mol->cell_size[2] << "\t" << endl;
1435 *output << mol->cell_size[3] << "\t" << mol->cell_size[4] << "\t" << mol->cell_size[5] << "\t" << endl;
1436 // FIXME
1437 *output << endl;
1438 *output << "ECut\t\t" << config::ECut << "\t# energy cutoff for discretization in Hartrees" << endl;
1439 *output << "MaxLevel\t" << config::MaxLevel << "\t# number of different levels in the code, >=2" << endl;
1440 *output << "Level0Factor\t" << config::Lev0Factor << "\t# factor by which node number increases from S to 0 level" << endl;
1441 *output << "RiemannTensor\t" << config::RiemannTensor << "\t# (Use metric)" << endl;
1442 switch (config::RiemannTensor) {
1443 case 0: //UseNoRT
1444 break;
1445 case 1: // UseRT
1446 *output << "RiemannLevel\t" << config::RiemannLevel << "\t# Number of Riemann Levels" << endl;
1447 *output << "LevRFactor\t" << config::LevRFactor << "\t# factor by which node number increases from 0 to R level from" << endl;
1448 break;
1449 }
1450 *output << "PsiType\t\t" << config::PsiType << "\t# 0 - doubly occupied, 1 - SpinUp,SpinDown" << endl;
1451 // write out both types for easier changing afterwards
1452 // switch (PsiType) {
1453 // case 0:
1454 *output << "MaxPsiDouble\t" << config::MaxPsiDouble << "\t# here: specifying both maximum number of SpinUp- and -Down-states" << endl;
1455 // break;
1456 // case 1:
1457 *output << "PsiMaxNoUp\t" << config::PsiMaxNoUp << "\t# here: specifying maximum number of SpinUp-states" << endl;
1458 *output << "PsiMaxNoDown\t" << config::PsiMaxNoDown << "\t# here: specifying maximum number of SpinDown-states" << endl;
1459 // break;
1460 // }
1461 *output << "AddPsis\t\t" << config::AddPsis << "\t# Additional unoccupied Psis for bandgap determination" << endl;
1462 *output << endl;
1463 *output << "RCut\t\t" << config::RCut << "\t# R-cut for the ewald summation" << endl;
1464 *output << "StructOpt\t" << config::StructOpt << "\t# Do structure optimization beforehand" << endl;
1465 *output << "IsAngstroem\t" << config::IsAngstroem << "\t# 0 - Bohr, 1 - Angstroem" << endl;
1466 *output << "RelativeCoord\t" << config::RelativeCoord << "\t# whether ion coordinates are relative (1) or absolute (0)" << endl;
1467 *output << "MaxTypes\t" << mol->ElementCount << "\t# maximum number of different ion types" << endl;
1468 *output << endl;
1469 result = result && mol->Checkout(output);
1470 if (mol->MDSteps <=1 )
1471 result = result && mol->Output(output);
1472 else
1473 result = result && mol->OutputTrajectories(output);
1474 output->close();
1475 output->clear();
1476 delete(output);
1477 return result;
1478 } else
1479 return false;
1480};
1481
1482/** Stores all elements in a MPQC input file.
1483 * Note that this format cannot be parsed again.
1484 * \param *filename name of file (without ".in" suffix!)
1485 * \param *mol pointer to molecule containing all atoms of the molecule
1486 */
1487bool config::SaveMPQC(const char * const filename, const molecule * const mol) const
1488{
1489 int AtomNo = -1;
1490 Vector *center = NULL;
1491 ofstream *output = NULL;
1492
1493 // first without hessian
1494 {
1495 stringstream * const fname = new stringstream;;
1496 *fname << filename << ".in";
1497 output = new ofstream(fname->str().c_str(), ios::out);
1498 *output << "% Created by MoleCuilder" << endl;
1499 *output << "mpqc: (" << endl;
1500 *output << "\tsavestate = no" << endl;
1501 *output << "\tdo_gradient = yes" << endl;
1502 *output << "\tmole<MBPT2>: (" << endl;
1503 *output << "\t\tmaxiter = 200" << endl;
1504 *output << "\t\tbasis = $:basis" << endl;
1505 *output << "\t\tmolecule = $:molecule" << endl;
1506 *output << "\t\treference<CLHF>: (" << endl;
1507 *output << "\t\t\tbasis = $:basis" << endl;
1508 *output << "\t\t\tmolecule = $:molecule" << endl;
1509 *output << "\t\t)" << endl;
1510 *output << "\t)" << endl;
1511 *output << ")" << endl;
1512 *output << "molecule<Molecule>: (" << endl;
1513 *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
1514 *output << "\t{ atoms geometry } = {" << endl;
1515 center = mol->DetermineCenterOfAll(output);
1516 // output of atoms
1517 AtomNo = 0;
1518 mol->ActOnAllAtoms( &atom::OutputMPQCLine, output, (const Vector *)center, &AtomNo );
1519 delete(center);
1520 *output << "\t}" << endl;
1521 *output << ")" << endl;
1522 *output << "basis<GaussianBasisSet>: (" << endl;
1523 *output << "\tname = \"" << basis << "\"" << endl;
1524 *output << "\tmolecule = $:molecule" << endl;
1525 *output << ")" << endl;
1526 output->close();
1527 delete(output);
1528 delete(fname);
1529 }
1530
1531 // second with hessian
1532 {
1533 stringstream * const fname = new stringstream;
1534 *fname << filename << ".hess.in";
1535 output = new ofstream(fname->str().c_str(), ios::out);
1536 *output << "% Created by MoleCuilder" << endl;
1537 *output << "mpqc: (" << endl;
1538 *output << "\tsavestate = no" << endl;
1539 *output << "\tdo_gradient = yes" << endl;
1540 *output << "\tmole<CLHF>: (" << endl;
1541 *output << "\t\tmaxiter = 200" << endl;
1542 *output << "\t\tbasis = $:basis" << endl;
1543 *output << "\t\tmolecule = $:molecule" << endl;
1544 *output << "\t)" << endl;
1545 *output << "\tfreq<MolecularFrequencies>: (" << endl;
1546 *output << "\t\tmolecule=$:molecule" << endl;
1547 *output << "\t)" << endl;
1548 *output << ")" << endl;
1549 *output << "molecule<Molecule>: (" << endl;
1550 *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
1551 *output << "\t{ atoms geometry } = {" << endl;
1552 center = mol->DetermineCenterOfAll(output);
1553 // output of atoms
1554 AtomNo = 0;
1555 mol->ActOnAllAtoms( &atom::OutputMPQCLine, output, (const Vector *)center, &AtomNo );
1556 delete(center);
1557 *output << "\t}" << endl;
1558 *output << ")" << endl;
1559 *output << "basis<GaussianBasisSet>: (" << endl;
1560 *output << "\tname = \"3-21G\"" << endl;
1561 *output << "\tmolecule = $:molecule" << endl;
1562 *output << ")" << endl;
1563 output->close();
1564 delete(output);
1565 delete(fname);
1566 }
1567
1568 return true;
1569};
1570
1571/** Reads parameter from a parsed file.
1572 * The file is either parsed for a certain keyword or if null is given for
1573 * the value in row yth and column xth. If the keyword was necessity#critical,
1574 * then an error is thrown and the programme aborted.
1575 * \warning value is modified (both in contents and position)!
1576 * \param verbose 1 - print found value to stderr, 0 - don't
1577 * \param *file file to be parsed
1578 * \param name Name of value in file (at least 3 chars!)
1579 * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning
1580 * (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read -
1581 * best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now
1582 * counted from this unresetted position!)
1583 * \param xth Which among a number of parameters it is (in grid case it's row number as grid is read as a whole!)
1584 * \param yth In grid case specifying column number, otherwise the yth \a name matching line
1585 * \param type Type of the Parameter to be read
1586 * \param value address of the value to be read (must have been allocated)
1587 * \param repetition determines, if the keyword appears multiply in the config file, which repetition shall be parsed, i.e. 1 if not multiply
1588 * \param critical necessity of this keyword being specified (optional, critical)
1589 * \return 1 - found, 0 - not found
1590 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++
1591 */
1592int 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) {
1593 int i = 0;
1594 int j = 0; // loop variables
1595 int length = 0;
1596 int maxlength = -1;
1597 long file_position = file->tellg(); // mark current position
1598 char *dummy1 = NULL;
1599 char *dummy = NULL;
1600 char * const free_dummy = Malloc<char>(256, "config::ParseForParameter: *free_dummy"); // pointers in the line that is read in per step
1601 dummy1 = free_dummy;
1602
1603 //fprintf(stderr,"Parsing for %s\n",name);
1604 if (repetition == 0)
1605 //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!");
1606 return 0;
1607
1608 int line = 0; // marks line where parameter was found
1609 int found = (type >= grid) ? 0 : (-yth + 1); // marks if yth parameter name was found
1610 while((found != repetition)) {
1611 dummy1 = dummy = free_dummy;
1612 do {
1613 file->getline(dummy1, 256); // Read the whole line
1614 if (file->eof()) {
1615 if ((critical) && (found == 0)) {
1616 Free(free_dummy);
1617 //Error(InitReading, name);
1618 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
1619 exit(255);
1620 } else {
1621 //if (!sequential)
1622 file->clear();
1623 file->seekg(file_position, ios::beg); // rewind to start position
1624 Free(free_dummy);
1625 return 0;
1626 }
1627 }
1628 line++;
1629 } while (dummy != NULL && dummy1 != NULL && ((dummy1[0] == '#') || (dummy1[0] == '\0'))); // skip commentary and empty lines
1630
1631 // C++ getline removes newline at end, thus re-add
1632 if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
1633 i = strlen(dummy1);
1634 dummy1[i] = '\n';
1635 dummy1[i+1] = '\0';
1636 }
1637 //fprintf(stderr,"line %i ends at %i, newline at %i\n", line, strlen(dummy1), strchr(dummy1,'\n')-free_dummy);
1638
1639 if (dummy1 == NULL) {
1640 if (verbose) fprintf(stderr,"Error reading line %i\n",line);
1641 } else {
1642 //fprintf(stderr,"Now parsing the line %i: %s\n", line, dummy1);
1643 }
1644 // Seek for possible end of keyword on line if given ...
1645 if (name != NULL) {
1646 dummy = strchr(dummy1,'\t'); // set dummy on first tab or space which ever's nearer
1647 if (dummy == NULL) {
1648 dummy = strchr(dummy1, ' '); // if not found seek for space
1649 while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' '))) // skip some more tabs and spaces if necessary
1650 dummy++;
1651 }
1652 if (dummy == NULL) {
1653 dummy = strchr(dummy1, '\n'); // set on line end then (whole line = keyword)
1654 //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name);
1655 //Free((void **)&free_dummy);
1656 //Error(FileOpenParams, NULL);
1657 } else {
1658 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)dummy1);
1659 }
1660 } else dummy = dummy1;
1661 // ... and check if it is the keyword!
1662 //fprintf(stderr,"name %p, dummy %i/%c, dummy1 %i/%c, strlen(name) %i\n", &name, dummy, *dummy, dummy1, *dummy1, strlen(name));
1663 if ((name == NULL) || (((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name)))) {
1664 found++; // found the parameter!
1665 //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy);
1666
1667 if (found == repetition) {
1668 for (i=0;i<xth;i++) { // i = rows
1669 if (type >= grid) {
1670 // grid structure means that grid starts on the next line, not right after keyword
1671 dummy1 = dummy = free_dummy;
1672 do {
1673 file->getline(dummy1, 256); // Read the whole line, skip commentary and empty ones
1674 if (file->eof()) {
1675 if ((critical) && (found == 0)) {
1676 Free(free_dummy);
1677 //Error(InitReading, name);
1678 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
1679 exit(255);
1680 } else {
1681 //if (!sequential)
1682 file->clear();
1683 file->seekg(file_position, ios::beg); // rewind to start position
1684 Free(free_dummy);
1685 return 0;
1686 }
1687 }
1688 line++;
1689 } while ((dummy1[0] == '#') || (dummy1[0] == '\n'));
1690 if (dummy1 == NULL){
1691 if (verbose) fprintf(stderr,"Error reading line %i\n", line);
1692 } else {
1693 //fprintf(stderr,"Reading next line %i: %s\n", line, dummy1);
1694 }
1695 } else { // simple int, strings or doubles start in the same line
1696 while ((*dummy == '\t') || (*dummy == ' ')) // skip interjacent tabs and spaces
1697 dummy++;
1698 }
1699 // C++ getline removes newline at end, thus re-add
1700 if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
1701 j = strlen(dummy1);
1702 dummy1[j] = '\n';
1703 dummy1[j+1] = '\0';
1704 }
1705
1706 int start = (type >= grid) ? 0 : yth-1 ;
1707 for (j=start;j<yth;j++) { // j = columns
1708 // check for lower triangular area and upper triangular area
1709 if ( ((i > j) && (type == upper_trigrid)) || ((j > i) && (type == lower_trigrid))) {
1710 *((double *)value) = 0.0;
1711 fprintf(stderr,"%f\t",*((double *)value));
1712 value = (void *)((long)value + sizeof(double));
1713 //value += sizeof(double);
1714 } else {
1715 // otherwise we must skip all interjacent tabs and spaces and find next value
1716 dummy1 = dummy;
1717 dummy = strchr(dummy1, '\t'); // seek for tab or space
1718 if (dummy == NULL)
1719 dummy = strchr(dummy1, ' '); // if not found seek for space
1720 if (dummy == NULL) { // if still zero returned ...
1721 dummy = strchr(dummy1, '\n'); // ... at line end then
1722 if ((j < yth-1) && (type < 4)) { // check if xth value or not yet
1723 if (critical) {
1724 if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
1725 Free(free_dummy);
1726 //return 0;
1727 exit(255);
1728 //Error(FileOpenParams, NULL);
1729 } else {
1730 //if (!sequential)
1731 file->clear();
1732 file->seekg(file_position, ios::beg); // rewind to start position
1733 Free(free_dummy);
1734 return 0;
1735 }
1736 }
1737 } else {
1738 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)free_dummy);
1739 }
1740 if (*dummy1 == '#') {
1741 // found comment, skipping rest of line
1742 //if (verbose) fprintf(stderr,"Error: '#' at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
1743 if (!sequential) { // here we need it!
1744 file->seekg(file_position, ios::beg); // rewind to start position
1745 }
1746 Free(free_dummy);
1747 return 0;
1748 }
1749 //fprintf(stderr,"value from %i to %i\n",(char *)dummy1-(char *)free_dummy,(char *)dummy-(char *)free_dummy);
1750 switch(type) {
1751 case (row_int):
1752 *((int *)value) = atoi(dummy1);
1753 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
1754 if (verbose) fprintf(stderr,"%i\t",*((int *)value));
1755 value = (void *)((long)value + sizeof(int));
1756 //value += sizeof(int);
1757 break;
1758 case(row_double):
1759 case(grid):
1760 case(lower_trigrid):
1761 case(upper_trigrid):
1762 *((double *)value) = atof(dummy1);
1763 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
1764 if (verbose) fprintf(stderr,"%lg\t",*((double *)value));
1765 value = (void *)((long)value + sizeof(double));
1766 //value += sizeof(double);
1767 break;
1768 case(double_type):
1769 *((double *)value) = atof(dummy1);
1770 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %lg\n", name, *((double *) value));
1771 //value += sizeof(double);
1772 break;
1773 case(int_type):
1774 *((int *)value) = atoi(dummy1);
1775 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %i\n", name, *((int *) value));
1776 //value += sizeof(int);
1777 break;
1778 default:
1779 case(string_type):
1780 if (value != NULL) {
1781 //if (maxlength == -1) maxlength = strlen((char *)value); // get maximum size of string array
1782 maxlength = MAXSTRINGSIZE;
1783 length = maxlength > (dummy-dummy1) ? (dummy-dummy1) : maxlength; // cap at maximum
1784 strncpy((char *)value, dummy1, length); // copy as much
1785 ((char *)value)[length] = '\0'; // and set end marker
1786 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s is '%s' (%i chars)\n",name,((char *) value), length);
1787 //value += sizeof(char);
1788 } else {
1789 }
1790 break;
1791 }
1792 }
1793 while (*dummy == '\t')
1794 dummy++;
1795 }
1796 }
1797 }
1798 }
1799 }
1800 if ((type >= row_int) && (verbose))
1801 fprintf(stderr,"\n");
1802 Free(free_dummy);
1803 if (!sequential) {
1804 file->clear();
1805 file->seekg(file_position, ios::beg); // rewind to start position
1806 }
1807 //fprintf(stderr, "End of Parsing\n\n");
1808
1809 return (found); // true if found, false if not
1810}
1811
1812
1813/** Reads parameter from a parsed file.
1814 * The file is either parsed for a certain keyword or if null is given for
1815 * the value in row yth and column xth. If the keyword was necessity#critical,
1816 * then an error is thrown and the programme aborted.
1817 * \warning value is modified (both in contents and position)!
1818 * \param verbose 1 - print found value to stderr, 0 - don't
1819 * \param *FileBuffer pointer to buffer structure
1820 * \param name Name of value in file (at least 3 chars!)
1821 * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning
1822 * (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read -
1823 * best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now
1824 * counted from this unresetted position!)
1825 * \param xth Which among a number of parameters it is (in grid case it's row number as grid is read as a whole!)
1826 * \param yth In grid case specifying column number, otherwise the yth \a name matching line
1827 * \param type Type of the Parameter to be read
1828 * \param value address of the value to be read (must have been allocated)
1829 * \param repetition determines, if the keyword appears multiply in the config file, which repetition shall be parsed, i.e. 1 if not multiply
1830 * \param critical necessity of this keyword being specified (optional, critical)
1831 * \return 1 - found, 0 - not found
1832 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++
1833 */
1834int 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) {
1835 int i = 0;
1836 int j = 0; // loop variables
1837 int length = 0;
1838 int maxlength = -1;
1839 int OldCurrentLine = FileBuffer->CurrentLine;
1840 char *dummy1 = NULL;
1841 char *dummy = NULL; // pointers in the line that is read in per step
1842
1843 //fprintf(stderr,"Parsing for %s\n",name);
1844 if (repetition == 0)
1845 //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!");
1846 return 0;
1847
1848 int line = 0; // marks line where parameter was found
1849 int found = (type >= grid) ? 0 : (-yth + 1); // marks if yth parameter name was found
1850 while((found != repetition)) {
1851 dummy1 = dummy = NULL;
1852 do {
1853 dummy1 = FileBuffer->buffer[ FileBuffer->LineMapping[FileBuffer->CurrentLine++] ];
1854 if (FileBuffer->CurrentLine >= FileBuffer->NoLines) {
1855 if ((critical) && (found == 0)) {
1856 //Error(InitReading, name);
1857 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
1858 exit(255);
1859 } else {
1860 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
1861 return 0;
1862 }
1863 }
1864 if (dummy1 == NULL) {
1865 if (verbose) fprintf(stderr,"Error reading line %i\n",line);
1866 } else {
1867 //fprintf(stderr,"Now parsing the line %i: %s\n", line, dummy1);
1868 }
1869 line++;
1870 } while (dummy1 != NULL && ((dummy1[0] == '#') || (dummy1[0] == '\0'))); // skip commentary and empty lines
1871
1872 // Seek for possible end of keyword on line if given ...
1873 if (name != NULL) {
1874 dummy = strchr(dummy1,'\t'); // set dummy on first tab or space which ever's nearer
1875 if (dummy == NULL) {
1876 dummy = strchr(dummy1, ' '); // if not found seek for space
1877 while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' '))) // skip some more tabs and spaces if necessary
1878 dummy++;
1879 }
1880 if (dummy == NULL) {
1881 dummy = strchr(dummy1, '\n'); // set on line end then (whole line = keyword)
1882 //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name);
1883 //Free(&free_dummy);
1884 //Error(FileOpenParams, NULL);
1885 } else {
1886 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)dummy1);
1887 }
1888 } else dummy = dummy1;
1889 // ... and check if it is the keyword!
1890 //fprintf(stderr,"name %p, dummy %i/%c, dummy1 %i/%c, strlen(name) %i\n", &name, dummy, *dummy, dummy1, *dummy1, strlen(name));
1891 if ((name == NULL) || (((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name)))) {
1892 found++; // found the parameter!
1893 //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy);
1894
1895 if (found == repetition) {
1896 for (i=0;i<xth;i++) { // i = rows
1897 if (type >= grid) {
1898 // grid structure means that grid starts on the next line, not right after keyword
1899 dummy1 = dummy = NULL;
1900 do {
1901 dummy1 = FileBuffer->buffer[ FileBuffer->LineMapping[ FileBuffer->CurrentLine++] ];
1902 if (FileBuffer->CurrentLine >= FileBuffer->NoLines) {
1903 if ((critical) && (found == 0)) {
1904 //Error(InitReading, name);
1905 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
1906 exit(255);
1907 } else {
1908 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
1909 return 0;
1910 }
1911 }
1912 if (dummy1 == NULL) {
1913 if (verbose) fprintf(stderr,"Error reading line %i\n", line);
1914 } else {
1915 //fprintf(stderr,"Reading next line %i: %s\n", line, dummy1);
1916 }
1917 line++;
1918 } while (dummy1 != NULL && (dummy1[0] == '#') || (dummy1[0] == '\n'));
1919 dummy = dummy1;
1920 } else { // simple int, strings or doubles start in the same line
1921 while ((*dummy == '\t') || (*dummy == ' ')) // skip interjacent tabs and spaces
1922 dummy++;
1923 }
1924
1925 for (j=((type >= grid) ? 0 : yth-1);j<yth;j++) { // j = columns
1926 // check for lower triangular area and upper triangular area
1927 if ( ((i > j) && (type == upper_trigrid)) || ((j > i) && (type == lower_trigrid))) {
1928 *((double *)value) = 0.0;
1929 fprintf(stderr,"%f\t",*((double *)value));
1930 value = (void *)((long)value + sizeof(double));
1931 //value += sizeof(double);
1932 } else {
1933 // otherwise we must skip all interjacent tabs and spaces and find next value
1934 dummy1 = dummy;
1935 dummy = strchr(dummy1, '\t'); // seek for tab or space
1936 if (dummy == NULL)
1937 dummy = strchr(dummy1, ' '); // if not found seek for space
1938 if (dummy == NULL) { // if still zero returned ...
1939 dummy = strchr(dummy1, '\n'); // ... at line end then
1940 if ((j < yth-1) && (type < 4)) { // check if xth value or not yet
1941 if (critical) {
1942 if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
1943 //return 0;
1944 exit(255);
1945 //Error(FileOpenParams, NULL);
1946 } else {
1947 if (!sequential) { // here we need it!
1948 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
1949 }
1950 return 0;
1951 }
1952 }
1953 } else {
1954 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)free_dummy);
1955 }
1956 if (*dummy1 == '#') {
1957 // found comment, skipping rest of line
1958 //if (verbose) fprintf(stderr,"Error: '#' at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
1959 if (!sequential) { // here we need it!
1960 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
1961 }
1962 return 0;
1963 }
1964 //fprintf(stderr,"value from %i to %i\n",(char *)dummy1-(char *)free_dummy,(char *)dummy-(char *)free_dummy);
1965 switch(type) {
1966 case (row_int):
1967 *((int *)value) = atoi(dummy1);
1968 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
1969 if (verbose) fprintf(stderr,"%i\t",*((int *)value));
1970 value = (void *)((long)value + sizeof(int));
1971 //value += sizeof(int);
1972 break;
1973 case(row_double):
1974 case(grid):
1975 case(lower_trigrid):
1976 case(upper_trigrid):
1977 *((double *)value) = atof(dummy1);
1978 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
1979 if (verbose) fprintf(stderr,"%lg\t",*((double *)value));
1980 value = (void *)((long)value + sizeof(double));
1981 //value += sizeof(double);
1982 break;
1983 case(double_type):
1984 *((double *)value) = atof(dummy1);
1985 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %lg\n", name, *((double *) value));
1986 //value += sizeof(double);
1987 break;
1988 case(int_type):
1989 *((int *)value) = atoi(dummy1);
1990 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %i\n", name, *((int *) value));
1991 //value += sizeof(int);
1992 break;
1993 default:
1994 case(string_type):
1995 if (value != NULL) {
1996 //if (maxlength == -1) maxlength = strlen((char *)value); // get maximum size of string array
1997 maxlength = MAXSTRINGSIZE;
1998 length = maxlength > (dummy-dummy1) ? (dummy-dummy1) : maxlength; // cap at maximum
1999 strncpy((char *)value, dummy1, length); // copy as much
2000 ((char *)value)[length] = '\0'; // and set end marker
2001 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s is '%s' (%i chars)\n",name,((char *) value), length);
2002 //value += sizeof(char);
2003 } else {
2004 }
2005 break;
2006 }
2007 }
2008 while (*dummy == '\t')
2009 dummy++;
2010 }
2011 }
2012 }
2013 }
2014 }
2015 if ((type >= row_int) && (verbose)) fprintf(stderr,"\n");
2016 if (!sequential) {
2017 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
2018 }
2019 //fprintf(stderr, "End of Parsing\n\n");
2020
2021 return (found); // true if found, false if not
2022}
Note: See TracBrowser for help on using the repository browser.