source: src/config.cpp@ 6056f1

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

Huge change from ofstream * (const) out --> Log().

  • first shift was done via regular expressions
  • then via error messages from the code
  • note that class atom, class element and class molecule kept in parts their output stream, was they print to file.
  • make check runs fine
  • MISSING: Verbosity is not fixed for everything (i.e. if no endl; is present and next has Verbose(0) ...)

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

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