source: src/config.cpp@ f2bb0f

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 f2bb0f was 9879f6, checked in by Frederik Heber <heber@…>, 15 years ago

Huge Refactoring due to class molecule now being an STL container.

  • molecule::start and molecule::end were dropped. Hence, the usual construct Walker = start while (Walker->next != end) {

Walker = walker->next
...

}
was changed to
for (molecule::iterator iter = begin(); iter != end(); ++iter) {

...

}
and (*iter) used instead of Walker.

  • Two build errors remain (beside some more in folder Actions, Patterns and unittest) in molecule_pointcloud.cpp and molecule.cpp
  • lists.cpp was deleted as specialization of atom* was not needed anymore
  • link, unlink, add, remove, removewithoutcheck all are not needed for atoms anymore, just for bonds (where first, last entries remain in molecule)
  • CreateFatherLookupTable() was put back into class molecule.
  • molecule::InternalPointer is now an iterator
  • class PointCloud: GoToPrevious() and GetTerminalPoint() were dropped as not needed.
  • some new STL functions in class molecule: size(), empty(), erase(), find() and insert()
  • Property mode set to 100644
File size: 104.0 KB
Line 
1/** \file config.cpp
2 *
3 * Function implementations for the class config.
4 *
5 */
6
7#include <stdio.h>
8#include <cstring>
9
10#include "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 = World::get()->createMolecule();
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 = World::get()->createMolecule();
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 FILE *f = NULL;
1545
1546 char name[MAXSTRINGSIZE];
1547 strncpy(name, filename, MAXSTRINGSIZE-1);
1548 strncat(name, ".pdb", MAXSTRINGSIZE-(strlen(name)+1));
1549 f = fopen(name, "w" );
1550 if (f == NULL) {
1551 eLog() << Verbose(1) << "Cannot open pdb output file:" << name << endl;
1552 return false;
1553 }
1554 fprintf(f, "# Created by MoleCuilder\n");
1555
1556 for (MoleculeList::const_iterator MolRunner = MolList->ListOfMolecules.begin(); MolRunner != MolList->ListOfMolecules.end(); MolRunner++) {
1557 int *elementNo = Calloc<int>(MAX_ELEMENTS, "config::SavePDB - elementNo");
1558 AtomNo = 0;
1559 for (molecule::const_iterator iter = (*MolRunner)->begin(); iter != (*MolRunner)->end(); ++iter) {
1560 sprintf(name, "%2s%2d",(*iter)->type->symbol, elementNo[(*iter)->type->Z]);
1561 elementNo[(*iter)->type->Z] = (elementNo[(*iter)->type->Z]+1) % 100; // confine to two digits
1562 fprintf(f,
1563 "ATOM %6u %-4s %4s%c%4u %8.3f%8.3f%8.3f%6.2f%6.2f %4s%2s%2s\n",
1564 (*iter)->nr, /* atom serial number */
1565 name, /* atom name */
1566 (*MolRunner)->name, /* residue name */
1567 'a'+(unsigned char)(AtomNo % 26), /* letter for chain */
1568 MolNo, /* residue sequence number */
1569 (*iter)->node->x[0], /* position X in Angstroem */
1570 (*iter)->node->x[1], /* position Y in Angstroem */
1571 (*iter)->node->x[2], /* position Z in Angstroem */
1572 (double)(*iter)->type->Valence, /* occupancy */
1573 (double)(*iter)->type->NoValenceOrbitals, /* temperature factor */
1574 "0", /* segment identifier */
1575 (*iter)->type->symbol, /* element symbol */
1576 "0"); /* charge */
1577 AtomNo++;
1578 }
1579 Free(&elementNo);
1580 MolNo++;
1581 }
1582 fclose(f);
1583
1584 return true;
1585};
1586
1587/** Stores all atoms in a PDB input file.
1588 * Note that this format cannot be parsed again.
1589 * \param *filename name of file (without ".in" suffix!)
1590 * \param *mol pointer to molecule
1591 */
1592bool config::SavePDB(const char * const filename, const molecule * const mol) const
1593{
1594 int AtomNo = -1;
1595 FILE *f = NULL;
1596
1597 int *elementNo = Calloc<int>(MAX_ELEMENTS, "config::SavePDB - elementNo");
1598 char name[MAXSTRINGSIZE];
1599 strncpy(name, filename, MAXSTRINGSIZE-1);
1600 strncat(name, ".pdb", MAXSTRINGSIZE-(strlen(name)+1));
1601 f = fopen(name, "w" );
1602 if (f == NULL) {
1603 eLog() << Verbose(1) << "Cannot open pdb output file:" << name << endl;
1604 Free(&elementNo);
1605 return false;
1606 }
1607 fprintf(f, "# Created by MoleCuilder\n");
1608
1609 AtomNo = 0;
1610 for (molecule::const_iterator iter = mol->begin(); iter != mol->end(); ++iter) {
1611 sprintf(name, "%2s%2d",(*iter)->type->symbol, elementNo[(*iter)->type->Z]);
1612 elementNo[(*iter)->type->Z] = (elementNo[(*iter)->type->Z]+1) % 100; // confine to two digits
1613 fprintf(f,
1614 "ATOM %6u %-4s %4s%c%4u %8.3f%8.3f%8.3f%6.2f%6.2f %4s%2s%2s\n",
1615 (*iter)->nr, /* atom serial number */
1616 name, /* atom name */
1617 mol->name, /* residue name */
1618 'a'+(unsigned char)(AtomNo % 26), /* letter for chain */
1619 0, /* residue sequence number */
1620 (*iter)->node->x[0], /* position X in Angstroem */
1621 (*iter)->node->x[1], /* position Y in Angstroem */
1622 (*iter)->node->x[2], /* position Z in Angstroem */
1623 (double)(*iter)->type->Valence, /* occupancy */
1624 (double)(*iter)->type->NoValenceOrbitals, /* temperature factor */
1625 "0", /* segment identifier */
1626 (*iter)->type->symbol, /* element symbol */
1627 "0"); /* charge */
1628 AtomNo++;
1629 }
1630 fclose(f);
1631 Free(&elementNo);
1632
1633 return true;
1634};
1635
1636/** Stores all atoms in a TREMOLO data input file.
1637 * Note that this format cannot be parsed again.
1638 * \param *filename name of file (without ".in" suffix!)
1639 * \param *mol pointer to molecule
1640 */
1641bool config::SaveTREMOLO(const char * const filename, const molecule * const mol) const
1642{
1643 ofstream *output = NULL;
1644 stringstream * const fname = new stringstream;
1645
1646 *fname << filename << ".data";
1647 output = new ofstream(fname->str().c_str(), ios::out);
1648 if (output == NULL) {
1649 eLog() << Verbose(1) << "Cannot open tremolo output file:" << fname << endl;
1650 delete(fname);
1651 return false;
1652 }
1653
1654 // scan maximum number of neighbours
1655 int MaxNeighbours = 0;
1656 for (molecule::const_iterator iter = mol->begin(); iter != mol->end(); ++iter) {
1657 const int count = (*iter)->ListOfBonds.size();
1658 if (MaxNeighbours < count)
1659 MaxNeighbours = count;
1660 }
1661 *output << "# ATOMDATA Id name resName resSeq x=3 Charge type neighbors=" << MaxNeighbours << endl;
1662
1663 for (molecule::const_iterator iter = mol->begin(); iter != mol->end(); ++iter) {
1664 *output << (*iter)->nr << "\t";
1665 *output << (*iter)->Name << "\t";
1666 *output << mol->name << "\t";
1667 *output << 0 << "\t";
1668 for (int i=0;i<NDIM;i++)
1669 *output << (*iter)->node->x[i] << "\t";
1670 *output << (double)(*iter)->type->Valence << "\t";
1671 *output << (*iter)->type->symbol << "\t";
1672 for (BondList::iterator runner = (*iter)->ListOfBonds.begin(); runner != (*iter)->ListOfBonds.end(); runner++)
1673 *output << (*runner)->GetOtherAtom((*iter))->nr << "\t";
1674 for(int i=(*iter)->ListOfBonds.size(); i < MaxNeighbours; i++)
1675 *output << "-\t";
1676 *output << endl;
1677 }
1678 output->flush();
1679 output->close();
1680 delete(output);
1681 delete(fname);
1682
1683 return true;
1684};
1685
1686/** Stores all atoms from all molecules in a TREMOLO data input file.
1687 * Note that this format cannot be parsed again.
1688 * \param *filename name of file (without ".in" suffix!)
1689 * \param *MolList pointer to MoleculeListClass containing all atoms
1690 */
1691bool config::SaveTREMOLO(const char * const filename, const MoleculeListClass * const MolList) const
1692{
1693 ofstream *output = NULL;
1694 stringstream * const fname = new stringstream;
1695
1696 *fname << filename << ".data";
1697 output = new ofstream(fname->str().c_str(), ios::out);
1698 if (output == NULL) {
1699 eLog() << Verbose(1) << "Cannot open tremolo output file:" << fname << endl;
1700 delete(fname);
1701 return false;
1702 }
1703
1704 // scan maximum number of neighbours
1705 int MaxNeighbours = 0;
1706 for (MoleculeList::const_iterator MolWalker = MolList->ListOfMolecules.begin(); MolWalker != MolList->ListOfMolecules.end(); MolWalker++) {
1707 for (molecule::const_iterator iter = (*MolWalker)->begin(); iter != (*MolWalker)->end(); ++iter) {
1708 const int count = (*iter)->ListOfBonds.size();
1709 if (MaxNeighbours < count)
1710 MaxNeighbours = count;
1711 }
1712 }
1713 *output << "# ATOMDATA Id name resName resSeq x=3 Charge type neighbors=" << MaxNeighbours << endl;
1714
1715 // create global to local id map
1716 int **LocalNotoGlobalNoMap = Calloc<int *>(MolList->ListOfMolecules.size(), "config::SaveTREMOLO - **LocalNotoGlobalNoMap");
1717 {
1718 int MolCounter = 0;
1719 int AtomNo = 0;
1720 for (MoleculeList::const_iterator MolWalker = MolList->ListOfMolecules.begin(); MolWalker != MolList->ListOfMolecules.end(); MolWalker++) {
1721 LocalNotoGlobalNoMap[MolCounter] = Calloc<int>(MolList->CountAllAtoms(), "config::SaveTREMOLO - *LocalNotoGlobalNoMap[]");
1722
1723 (*MolWalker)->SetIndexedArrayForEachAtomTo( LocalNotoGlobalNoMap[MolCounter], &atom::nr, IncrementalAbsoluteValue, &AtomNo);
1724
1725 MolCounter++;
1726 }
1727 }
1728
1729 // write the file
1730 {
1731 int MolCounter = 0;
1732 int AtomNo = 0;
1733 for (MoleculeList::const_iterator MolWalker = MolList->ListOfMolecules.begin(); MolWalker != MolList->ListOfMolecules.end(); MolWalker++) {
1734 for (molecule::const_iterator iter = (*MolWalker)->begin(); iter != (*MolWalker)->end(); ++iter) {
1735 *output << AtomNo << "\t";
1736 *output << (*iter)->Name << "\t";
1737 *output << (*MolWalker)->name << "\t";
1738 *output << MolCounter << "\t";
1739 for (int i=0;i<NDIM;i++)
1740 *output << (*iter)->node->x[i] << "\t";
1741 *output << (double)(*iter)->type->Valence << "\t";
1742 *output << (*iter)->type->symbol << "\t";
1743 for (BondList::iterator runner = (*iter)->ListOfBonds.begin(); runner != (*iter)->ListOfBonds.end(); runner++)
1744 *output << LocalNotoGlobalNoMap[MolCounter][ (*runner)->GetOtherAtom((*iter))->nr ] << "\t";
1745 for(int i=(*iter)->ListOfBonds.size(); i < MaxNeighbours; i++)
1746 *output << "-\t";
1747 *output << endl;
1748 AtomNo++;
1749 }
1750 MolCounter++;
1751 }
1752 }
1753
1754 // store & free
1755 output->flush();
1756 output->close();
1757 delete(output);
1758 delete(fname);
1759 for(size_t i=0;i<MolList->ListOfMolecules.size(); i++)
1760 Free(&LocalNotoGlobalNoMap[i]);
1761 Free(&LocalNotoGlobalNoMap);
1762
1763 return true;
1764};
1765
1766
1767/** Tries given filename or standard on saving the config file.
1768 * \param *ConfigFileName name of file
1769 * \param *periode pointer to periodentafel structure with all the elements
1770 * \param *molecules list of molecules structure with all the atoms and coordinates
1771 */
1772void config::SaveAll(char *ConfigFileName, periodentafel *periode, MoleculeListClass *molecules)
1773{
1774 char filename[MAXSTRINGSIZE];
1775 ofstream output;
1776 molecule *mol = World::get()->createMolecule();
1777 mol->SetNameFromFilename(ConfigFileName);
1778
1779 if (!strcmp(configpath, GetDefaultPath())) {
1780 eLog() << Verbose(2) << "config is found under different path then stated in config file::defaultpath!" << endl;
1781 }
1782
1783
1784 // first save as PDB data
1785 if (ConfigFileName != NULL)
1786 strcpy(filename, ConfigFileName);
1787 if (output == NULL)
1788 strcpy(filename,"main_pcp_linux");
1789 Log() << Verbose(0) << "Saving as pdb input ";
1790 if (SavePDB(filename, molecules))
1791 Log() << Verbose(0) << "done." << endl;
1792 else
1793 Log() << Verbose(0) << "failed." << endl;
1794
1795 // then save as tremolo data file
1796 if (ConfigFileName != NULL)
1797 strcpy(filename, ConfigFileName);
1798 if (output == NULL)
1799 strcpy(filename,"main_pcp_linux");
1800 Log() << Verbose(0) << "Saving as tremolo data input ";
1801 if (SaveTREMOLO(filename, molecules))
1802 Log() << Verbose(0) << "done." << endl;
1803 else
1804 Log() << Verbose(0) << "failed." << endl;
1805
1806 // translate each to its center and merge all molecules in MoleculeListClass into this molecule
1807 int N = molecules->ListOfMolecules.size();
1808 int *src = new int[N];
1809 N=0;
1810 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
1811 src[N++] = (*ListRunner)->IndexNr;
1812 (*ListRunner)->Translate(&(*ListRunner)->Center);
1813 }
1814 molecules->SimpleMultiAdd(mol, src, N);
1815 delete[](src);
1816
1817 // ... and translate back
1818 for (MoleculeList::iterator ListRunner = molecules->ListOfMolecules.begin(); ListRunner != molecules->ListOfMolecules.end(); ListRunner++) {
1819 (*ListRunner)->Center.Scale(-1.);
1820 (*ListRunner)->Translate(&(*ListRunner)->Center);
1821 (*ListRunner)->Center.Scale(-1.);
1822 }
1823
1824 Log() << Verbose(0) << "Storing configuration ... " << endl;
1825 // get correct valence orbitals
1826 mol->CalculateOrbitals(*this);
1827 InitMaxMinStopStep = MaxMinStopStep = MaxPsiDouble;
1828 if (ConfigFileName != NULL) { // test the file name
1829 strcpy(filename, ConfigFileName);
1830 output.open(filename, ios::trunc);
1831 } else if (strlen(configname) != 0) {
1832 strcpy(filename, configname);
1833 output.open(configname, ios::trunc);
1834 } else {
1835 strcpy(filename, DEFAULTCONFIG);
1836 output.open(DEFAULTCONFIG, ios::trunc);
1837 }
1838 output.close();
1839 output.clear();
1840 Log() << Verbose(0) << "Saving of config file ";
1841 if (Save(filename, periode, mol))
1842 Log() << Verbose(0) << "successful." << endl;
1843 else
1844 Log() << Verbose(0) << "failed." << endl;
1845
1846 // and save to xyz file
1847 if (ConfigFileName != NULL) {
1848 strcpy(filename, ConfigFileName);
1849 strcat(filename, ".xyz");
1850 output.open(filename, ios::trunc);
1851 }
1852 if (output == NULL) {
1853 strcpy(filename,"main_pcp_linux");
1854 strcat(filename, ".xyz");
1855 output.open(filename, ios::trunc);
1856 }
1857 Log() << Verbose(0) << "Saving of XYZ file ";
1858 if (mol->MDSteps <= 1) {
1859 if (mol->OutputXYZ(&output))
1860 Log() << Verbose(0) << "successful." << endl;
1861 else
1862 Log() << Verbose(0) << "failed." << endl;
1863 } else {
1864 if (mol->OutputTrajectoriesXYZ(&output))
1865 Log() << Verbose(0) << "successful." << endl;
1866 else
1867 Log() << Verbose(0) << "failed." << endl;
1868 }
1869 output.close();
1870 output.clear();
1871
1872 // and save as MPQC configuration
1873 if (ConfigFileName != NULL)
1874 strcpy(filename, ConfigFileName);
1875 if (output == NULL)
1876 strcpy(filename,"main_pcp_linux");
1877 Log() << Verbose(0) << "Saving as mpqc input ";
1878 if (SaveMPQC(filename, mol))
1879 Log() << Verbose(0) << "done." << endl;
1880 else
1881 Log() << Verbose(0) << "failed." << endl;
1882
1883 if (!strcmp(configpath, GetDefaultPath())) {
1884 eLog() << Verbose(2) << "config is found under different path then stated in config file::defaultpath!" << endl;
1885 }
1886
1887 World::get()->destroyMolecule(mol);
1888};
1889
1890/** Reads parameter from a parsed file.
1891 * The file is either parsed for a certain keyword or if null is given for
1892 * the value in row yth and column xth. If the keyword was necessity#critical,
1893 * then an error is thrown and the programme aborted.
1894 * \warning value is modified (both in contents and position)!
1895 * \param verbose 1 - print found value to stderr, 0 - don't
1896 * \param *file file to be parsed
1897 * \param name Name of value in file (at least 3 chars!)
1898 * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning
1899 * (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read -
1900 * best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now
1901 * counted from this unresetted position!)
1902 * \param xth Which among a number of parameters it is (in grid case it's row number as grid is read as a whole!)
1903 * \param yth In grid case specifying column number, otherwise the yth \a name matching line
1904 * \param type Type of the Parameter to be read
1905 * \param value address of the value to be read (must have been allocated)
1906 * \param repetition determines, if the keyword appears multiply in the config file, which repetition shall be parsed, i.e. 1 if not multiply
1907 * \param critical necessity of this keyword being specified (optional, critical)
1908 * \return 1 - found, 0 - not found
1909 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++
1910 */
1911int 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) {
1912 int i = 0;
1913 int j = 0; // loop variables
1914 int length = 0;
1915 int maxlength = -1;
1916 long file_position = file->tellg(); // mark current position
1917 char *dummy1 = NULL;
1918 char *dummy = NULL;
1919 char * const free_dummy = Malloc<char>(256, "config::ParseForParameter: *free_dummy"); // pointers in the line that is read in per step
1920 dummy1 = free_dummy;
1921
1922 //fprintf(stderr,"Parsing for %s\n",name);
1923 if (repetition == 0)
1924 //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!");
1925 return 0;
1926
1927 int line = 0; // marks line where parameter was found
1928 int found = (type >= grid) ? 0 : (-yth + 1); // marks if yth parameter name was found
1929 while((found != repetition)) {
1930 dummy1 = dummy = free_dummy;
1931 do {
1932 file->getline(dummy1, 256); // Read the whole line
1933 if (file->eof()) {
1934 if ((critical) && (found == 0)) {
1935 Free(free_dummy);
1936 //Error(InitReading, name);
1937 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
1938 exit(255);
1939 } else {
1940 //if (!sequential)
1941 file->clear();
1942 file->seekg(file_position, ios::beg); // rewind to start position
1943 Free(free_dummy);
1944 return 0;
1945 }
1946 }
1947 line++;
1948 } while (dummy != NULL && dummy1 != NULL && ((dummy1[0] == '#') || (dummy1[0] == '\0'))); // skip commentary and empty lines
1949
1950 // C++ getline removes newline at end, thus re-add
1951 if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
1952 i = strlen(dummy1);
1953 dummy1[i] = '\n';
1954 dummy1[i+1] = '\0';
1955 }
1956 //fprintf(stderr,"line %i ends at %i, newline at %i\n", line, strlen(dummy1), strchr(dummy1,'\n')-free_dummy);
1957
1958 if (dummy1 == NULL) {
1959 if (verbose) fprintf(stderr,"Error reading line %i\n",line);
1960 } else {
1961 //fprintf(stderr,"Now parsing the line %i: %s\n", line, dummy1);
1962 }
1963 // Seek for possible end of keyword on line if given ...
1964 if (name != NULL) {
1965 dummy = strchr(dummy1,'\t'); // set dummy on first tab or space which ever's nearer
1966 if (dummy == NULL) {
1967 dummy = strchr(dummy1, ' '); // if not found seek for space
1968 while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' '))) // skip some more tabs and spaces if necessary
1969 dummy++;
1970 }
1971 if (dummy == NULL) {
1972 dummy = strchr(dummy1, '\n'); // set on line end then (whole line = keyword)
1973 //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name);
1974 //Free((void **)&free_dummy);
1975 //Error(FileOpenParams, NULL);
1976 } else {
1977 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)dummy1);
1978 }
1979 } else dummy = dummy1;
1980 // ... and check if it is the keyword!
1981 //fprintf(stderr,"name %p, dummy %i/%c, dummy1 %i/%c, strlen(name) %i\n", &name, dummy, *dummy, dummy1, *dummy1, strlen(name));
1982 if ((name == NULL) || (((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name)))) {
1983 found++; // found the parameter!
1984 //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy);
1985
1986 if (found == repetition) {
1987 for (i=0;i<xth;i++) { // i = rows
1988 if (type >= grid) {
1989 // grid structure means that grid starts on the next line, not right after keyword
1990 dummy1 = dummy = free_dummy;
1991 do {
1992 file->getline(dummy1, 256); // Read the whole line, skip commentary and empty ones
1993 if (file->eof()) {
1994 if ((critical) && (found == 0)) {
1995 Free(free_dummy);
1996 //Error(InitReading, name);
1997 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
1998 exit(255);
1999 } else {
2000 //if (!sequential)
2001 file->clear();
2002 file->seekg(file_position, ios::beg); // rewind to start position
2003 Free(free_dummy);
2004 return 0;
2005 }
2006 }
2007 line++;
2008 } while ((dummy1[0] == '#') || (dummy1[0] == '\n'));
2009 if (dummy1 == NULL){
2010 if (verbose) fprintf(stderr,"Error reading line %i\n", line);
2011 } else {
2012 //fprintf(stderr,"Reading next line %i: %s\n", line, dummy1);
2013 }
2014 } else { // simple int, strings or doubles start in the same line
2015 while ((*dummy == '\t') || (*dummy == ' ')) // skip interjacent tabs and spaces
2016 dummy++;
2017 }
2018 // C++ getline removes newline at end, thus re-add
2019 if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
2020 j = strlen(dummy1);
2021 dummy1[j] = '\n';
2022 dummy1[j+1] = '\0';
2023 }
2024
2025 int start = (type >= grid) ? 0 : yth-1 ;
2026 for (j=start;j<yth;j++) { // j = columns
2027 // check for lower triangular area and upper triangular area
2028 if ( ((i > j) && (type == upper_trigrid)) || ((j > i) && (type == lower_trigrid))) {
2029 *((double *)value) = 0.0;
2030 fprintf(stderr,"%f\t",*((double *)value));
2031 value = (void *)((long)value + sizeof(double));
2032 //value += sizeof(double);
2033 } else {
2034 // otherwise we must skip all interjacent tabs and spaces and find next value
2035 dummy1 = dummy;
2036 dummy = strchr(dummy1, '\t'); // seek for tab or space
2037 if (dummy == NULL)
2038 dummy = strchr(dummy1, ' '); // if not found seek for space
2039 if (dummy == NULL) { // if still zero returned ...
2040 dummy = strchr(dummy1, '\n'); // ... at line end then
2041 if ((j < yth-1) && (type < 4)) { // check if xth value or not yet
2042 if (critical) {
2043 if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
2044 Free(free_dummy);
2045 //return 0;
2046 exit(255);
2047 //Error(FileOpenParams, NULL);
2048 } else {
2049 //if (!sequential)
2050 file->clear();
2051 file->seekg(file_position, ios::beg); // rewind to start position
2052 Free(free_dummy);
2053 return 0;
2054 }
2055 }
2056 } else {
2057 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)free_dummy);
2058 }
2059 if (*dummy1 == '#') {
2060 // found comment, skipping rest of line
2061 //if (verbose) fprintf(stderr,"Error: '#' at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
2062 if (!sequential) { // here we need it!
2063 file->seekg(file_position, ios::beg); // rewind to start position
2064 }
2065 Free(free_dummy);
2066 return 0;
2067 }
2068 //fprintf(stderr,"value from %i to %i\n",(char *)dummy1-(char *)free_dummy,(char *)dummy-(char *)free_dummy);
2069 switch(type) {
2070 case (row_int):
2071 *((int *)value) = atoi(dummy1);
2072 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
2073 if (verbose) fprintf(stderr,"%i\t",*((int *)value));
2074 value = (void *)((long)value + sizeof(int));
2075 //value += sizeof(int);
2076 break;
2077 case(row_double):
2078 case(grid):
2079 case(lower_trigrid):
2080 case(upper_trigrid):
2081 *((double *)value) = atof(dummy1);
2082 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
2083 if (verbose) fprintf(stderr,"%lg\t",*((double *)value));
2084 value = (void *)((long)value + sizeof(double));
2085 //value += sizeof(double);
2086 break;
2087 case(double_type):
2088 *((double *)value) = atof(dummy1);
2089 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %lg\n", name, *((double *) value));
2090 //value += sizeof(double);
2091 break;
2092 case(int_type):
2093 *((int *)value) = atoi(dummy1);
2094 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %i\n", name, *((int *) value));
2095 //value += sizeof(int);
2096 break;
2097 default:
2098 case(string_type):
2099 if (value != NULL) {
2100 //if (maxlength == -1) maxlength = strlen((char *)value); // get maximum size of string array
2101 maxlength = MAXSTRINGSIZE;
2102 length = maxlength > (dummy-dummy1) ? (dummy-dummy1) : maxlength; // cap at maximum
2103 strncpy((char *)value, dummy1, length); // copy as much
2104 ((char *)value)[length] = '\0'; // and set end marker
2105 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s is '%s' (%i chars)\n",name,((char *) value), length);
2106 //value += sizeof(char);
2107 } else {
2108 }
2109 break;
2110 }
2111 }
2112 while (*dummy == '\t')
2113 dummy++;
2114 }
2115 }
2116 }
2117 }
2118 }
2119 if ((type >= row_int) && (verbose))
2120 fprintf(stderr,"\n");
2121 Free(free_dummy);
2122 if (!sequential) {
2123 file->clear();
2124 file->seekg(file_position, ios::beg); // rewind to start position
2125 }
2126 //fprintf(stderr, "End of Parsing\n\n");
2127
2128 return (found); // true if found, false if not
2129}
2130
2131
2132/** Reads parameter from a parsed file.
2133 * The file is either parsed for a certain keyword or if null is given for
2134 * the value in row yth and column xth. If the keyword was necessity#critical,
2135 * then an error is thrown and the programme aborted.
2136 * \warning value is modified (both in contents and position)!
2137 * \param verbose 1 - print found value to stderr, 0 - don't
2138 * \param *FileBuffer pointer to buffer structure
2139 * \param name Name of value in file (at least 3 chars!)
2140 * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning
2141 * (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read -
2142 * best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now
2143 * counted from this unresetted position!)
2144 * \param xth Which among a number of parameters it is (in grid case it's row number as grid is read as a whole!)
2145 * \param yth In grid case specifying column number, otherwise the yth \a name matching line
2146 * \param type Type of the Parameter to be read
2147 * \param value address of the value to be read (must have been allocated)
2148 * \param repetition determines, if the keyword appears multiply in the config file, which repetition shall be parsed, i.e. 1 if not multiply
2149 * \param critical necessity of this keyword being specified (optional, critical)
2150 * \return 1 - found, 0 - not found
2151 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++
2152 */
2153int 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) {
2154 int i = 0;
2155 int j = 0; // loop variables
2156 int length = 0;
2157 int maxlength = -1;
2158 int OldCurrentLine = FileBuffer->CurrentLine;
2159 char *dummy1 = NULL;
2160 char *dummy = NULL; // pointers in the line that is read in per step
2161
2162 //fprintf(stderr,"Parsing for %s\n",name);
2163 if (repetition == 0)
2164 //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!");
2165 return 0;
2166
2167 int line = 0; // marks line where parameter was found
2168 int found = (type >= grid) ? 0 : (-yth + 1); // marks if yth parameter name was found
2169 while((found != repetition)) {
2170 dummy1 = dummy = NULL;
2171 do {
2172 dummy1 = FileBuffer->buffer[ FileBuffer->LineMapping[FileBuffer->CurrentLine++] ];
2173 if (FileBuffer->CurrentLine >= FileBuffer->NoLines) {
2174 if ((critical) && (found == 0)) {
2175 //Error(InitReading, name);
2176 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
2177 exit(255);
2178 } else {
2179 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
2180 return 0;
2181 }
2182 }
2183 if (dummy1 == NULL) {
2184 if (verbose) fprintf(stderr,"Error reading line %i\n",line);
2185 } else {
2186 //fprintf(stderr,"Now parsing the line %i: %s\n", line, dummy1);
2187 }
2188 line++;
2189 } while (dummy1 != NULL && ((dummy1[0] == '#') || (dummy1[0] == '\0'))); // skip commentary and empty lines
2190
2191 // Seek for possible end of keyword on line if given ...
2192 if (name != NULL) {
2193 dummy = strchr(dummy1,'\t'); // set dummy on first tab or space which ever's nearer
2194 if (dummy == NULL) {
2195 dummy = strchr(dummy1, ' '); // if not found seek for space
2196 while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' '))) // skip some more tabs and spaces if necessary
2197 dummy++;
2198 }
2199 if (dummy == NULL) {
2200 dummy = strchr(dummy1, '\n'); // set on line end then (whole line = keyword)
2201 //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name);
2202 //Free(&free_dummy);
2203 //Error(FileOpenParams, NULL);
2204 } else {
2205 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)dummy1);
2206 }
2207 } else dummy = dummy1;
2208 // ... and check if it is the keyword!
2209 //fprintf(stderr,"name %p, dummy %i/%c, dummy1 %i/%c, strlen(name) %i\n", &name, dummy, *dummy, dummy1, *dummy1, strlen(name));
2210 if ((name == NULL) || (((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name)))) {
2211 found++; // found the parameter!
2212 //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy);
2213
2214 if (found == repetition) {
2215 for (i=0;i<xth;i++) { // i = rows
2216 if (type >= grid) {
2217 // grid structure means that grid starts on the next line, not right after keyword
2218 dummy1 = dummy = NULL;
2219 do {
2220 dummy1 = FileBuffer->buffer[ FileBuffer->LineMapping[ FileBuffer->CurrentLine++] ];
2221 if (FileBuffer->CurrentLine >= FileBuffer->NoLines) {
2222 if ((critical) && (found == 0)) {
2223 //Error(InitReading, name);
2224 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
2225 exit(255);
2226 } else {
2227 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
2228 return 0;
2229 }
2230 }
2231 if (dummy1 == NULL) {
2232 if (verbose) fprintf(stderr,"Error reading line %i\n", line);
2233 } else {
2234 //fprintf(stderr,"Reading next line %i: %s\n", line, dummy1);
2235 }
2236 line++;
2237 } while ((dummy1 != NULL) && ((dummy1[0] == '#') || (dummy1[0] == '\n')));
2238 dummy = dummy1;
2239 } else { // simple int, strings or doubles start in the same line
2240 while ((*dummy == '\t') || (*dummy == ' ')) // skip interjacent tabs and spaces
2241 dummy++;
2242 }
2243
2244 for (j=((type >= grid) ? 0 : yth-1);j<yth;j++) { // j = columns
2245 // check for lower triangular area and upper triangular area
2246 if ( ((i > j) && (type == upper_trigrid)) || ((j > i) && (type == lower_trigrid))) {
2247 *((double *)value) = 0.0;
2248 fprintf(stderr,"%f\t",*((double *)value));
2249 value = (void *)((long)value + sizeof(double));
2250 //value += sizeof(double);
2251 } else {
2252 // otherwise we must skip all interjacent tabs and spaces and find next value
2253 dummy1 = dummy;
2254 dummy = strchr(dummy1, '\t'); // seek for tab or space
2255 if (dummy == NULL)
2256 dummy = strchr(dummy1, ' '); // if not found seek for space
2257 if (dummy == NULL) { // if still zero returned ...
2258 dummy = strchr(dummy1, '\n'); // ... at line end then
2259 if ((j < yth-1) && (type < 4)) { // check if xth value or not yet
2260 if (critical) {
2261 if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
2262 //return 0;
2263 exit(255);
2264 //Error(FileOpenParams, NULL);
2265 } else {
2266 if (!sequential) { // here we need it!
2267 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
2268 }
2269 return 0;
2270 }
2271 }
2272 } else {
2273 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)free_dummy);
2274 }
2275 if (*dummy1 == '#') {
2276 // found comment, skipping rest of line
2277 //if (verbose) fprintf(stderr,"Error: '#' at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
2278 if (!sequential) { // here we need it!
2279 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
2280 }
2281 return 0;
2282 }
2283 //fprintf(stderr,"value from %i to %i\n",(char *)dummy1-(char *)free_dummy,(char *)dummy-(char *)free_dummy);
2284 switch(type) {
2285 case (row_int):
2286 *((int *)value) = atoi(dummy1);
2287 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
2288 if (verbose) fprintf(stderr,"%i\t",*((int *)value));
2289 value = (void *)((long)value + sizeof(int));
2290 //value += sizeof(int);
2291 break;
2292 case(row_double):
2293 case(grid):
2294 case(lower_trigrid):
2295 case(upper_trigrid):
2296 *((double *)value) = atof(dummy1);
2297 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
2298 if (verbose) fprintf(stderr,"%lg\t",*((double *)value));
2299 value = (void *)((long)value + sizeof(double));
2300 //value += sizeof(double);
2301 break;
2302 case(double_type):
2303 *((double *)value) = atof(dummy1);
2304 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %lg\n", name, *((double *) value));
2305 //value += sizeof(double);
2306 break;
2307 case(int_type):
2308 *((int *)value) = atoi(dummy1);
2309 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %i\n", name, *((int *) value));
2310 //value += sizeof(int);
2311 break;
2312 default:
2313 case(string_type):
2314 if (value != NULL) {
2315 //if (maxlength == -1) maxlength = strlen((char *)value); // get maximum size of string array
2316 maxlength = MAXSTRINGSIZE;
2317 length = maxlength > (dummy-dummy1) ? (dummy-dummy1) : maxlength; // cap at maximum
2318 strncpy((char *)value, dummy1, length); // copy as much
2319 ((char *)value)[length] = '\0'; // and set end marker
2320 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s is '%s' (%i chars)\n",name,((char *) value), length);
2321 //value += sizeof(char);
2322 } else {
2323 }
2324 break;
2325 }
2326 }
2327 while (*dummy == '\t')
2328 dummy++;
2329 }
2330 }
2331 }
2332 }
2333 }
2334 if ((type >= row_int) && (verbose)) fprintf(stderr,"\n");
2335 if (!sequential) {
2336 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
2337 }
2338 //fprintf(stderr, "End of Parsing\n\n");
2339
2340 return (found); // true if found, false if not
2341}
Note: See TracBrowser for help on using the repository browser.