source: src/config.cpp@ fa649a

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

Small changes.

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