source: src/config.cpp@ d96277

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

class config, ConfigFileBuffer, periodentafel and Vector are refactored with respect to ticket #38, #4 and #39.

  • <type> * const ptr ... means the pointer itself is const (not its contents that he points at).
  • const <type> * ptr ... means the pointer's content is const.
  • "ofstream *out" ... can be changed to "ofstream * const out" (pointer is constant, not output).

Signed-off-by: Frederik Heber <heber@…>

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