source: src/config.cpp@ f16a4b

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 f16a4b was 46d958, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Made the world solely responsible for creating and destroying atoms.

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