source: src/config.cpp@ 8927ae

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 8927ae was 235bed, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Moved saveConfig method from oldmenu to a method inside config class

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