source: src/config.cpp@ 147339

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

bugfix to errorLogger and some error verbosity changes.

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