source: src/config.cpp@ 73b510

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 73b510 was cd7b0f, checked in by Frederik Heber <heber@…>, 15 years ago

BUGFIX: delete(mol) belongs to the commented-out DissectMoleculeIntoConnectedSubgraphs().

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