source: src/config.cpp@ 34e0013

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

BondGraph is initialized within config::Load(), as it has to happen after parsing options and before loading molecule. And various fixes.

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