source: src/config.cpp@ fc1b24

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 fc1b24 was 04b6f9, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Merge commit 'heber/Analysis_PairCorrelation' into MenuRefactoring

Conflicts:

molecuilder/src/unittests/Makefile.am

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