source: src/config.cpp@ ae38fb

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

Fixing not created adjacency list, partially fixing subgraph dissection in config::Load()

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