source: src/config.cpp@ 8725ed

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 8725ed was 6a7f78c, checked in by Frederik Heber <heber@…>, 15 years ago

Fixes and naming of final Tecplot output file is now molecule name.

  • FIXES to builder.cpp:
    • case 'p' would not dissect the molecule into connected subgraphs
    • if done so, the BondGraph was not yet initialised
    • if done so, we need to check whether BondGraphFileName has been set
    • BondGraphFileName.empty() could not be used as a check, as was set to "" instead of "\n"
    • if (finally) done so, we have to remove the empty molecule that we parsed in
    • ... and then pick the newly added molecule for mol to point at
    • SaveConfig() did not set the merged molecule name correctly.
    • if empty config is given, the empty molecule now receives the ConfigFileName as name
  • FIXES to config.cpp
    • Load() did not set the name of the molecule
  • changes to tesselationhelper.cpp and tesselation.cpp
  • changes to PointCloud and molecule
    • new virtual function PointCloud::GetName() returns "unknown"
    • new function molecule::GetName() returns pointer to name of molecule
    • IsEmpty() and IsEnd() now return true by default
  • all .dat files in the "Tesselations" tests were changed accordingly (i.e. have now the name in the second line)
  • benzene was added as a new test for an absolutely flat molecule. So far, it fails horribly.
  • 13 of 17 tests run fine

Signed-off-by: Frederik Heber <heber@…>

  • Property mode set to 100644
File size: 99.8 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 if (BG == NULL) {
1059 BG = new BondGraph(IsAngstroem);
1060 if (BG->LoadBondLengthTable(BondGraphFileName)) {
1061 Log() << Verbose(0) << "Bond length table loaded successfully." << endl;
1062 } else {
1063 eLog() << Verbose(1) << "Bond length table loading failed." << endl;
1064 }
1065 }
1066
1067 // 3. parse the molecule in
1068 LoadMolecule(mol, FileBuffer, periode, FastParsing);
1069 mol->SetNameFromFilename(filename);
1070 mol->ActiveFlag = true;
1071
1072 // 4. dissect the molecule into connected subgraphs
1073 MolList->DissectMoleculeIntoConnectedSubgraphs(mol,this);
1074
1075 delete(mol);
1076 delete(FileBuffer);
1077};
1078
1079/** Initializes config file structure by loading elements from a give file with old pcp syntax.
1080 * \param *file input file stream being the opened config file with old pcp syntax
1081 * \param BondGraphFileName file name of the bond length table file, if string is left blank, no table is parsed.
1082 * \param *periode pointer to a periodentafel class with all elements
1083 * \param *&MolList pointer to MoleculeListClass, on return containing all parsed molecules in system
1084 */
1085void config::LoadOld(const char * const filename, const string &BondGraphFileName, const periodentafel * const periode, MoleculeListClass * const &MolList)
1086{
1087 molecule *mol = new molecule(periode);
1088 ifstream *file = new ifstream(filename);
1089 if (file == NULL) {
1090 eLog() << Verbose(1) << "config file " << filename << " missing!" << endl;
1091 return;
1092 }
1093 RetrieveConfigPathAndName(filename);
1094 // ParseParameters
1095
1096 /* Oeffne Hauptparameterdatei */
1097 int l = 0;
1098 int i = 0;
1099 int di = 0;
1100 double a = 0.;
1101 double b = 0.;
1102 double BoxLength[9];
1103 string zeile;
1104 string dummy;
1105 element *elementhash[128];
1106 int Z = -1;
1107 int No = -1;
1108 int AtomNo = -1;
1109 int found = 0;
1110 int verbose = 0;
1111
1112 mol->ActiveFlag = true;
1113 MolList->insert(mol);
1114 /* Namen einlesen */
1115
1116 ParseForParameter(verbose,file, "mainname", 0, 1, 1, string_type, (config::mainname), 1, critical);
1117 ParseForParameter(verbose,file, "defaultpath", 0, 1, 1, string_type, (config::defaultpath), 1, critical);
1118 ParseForParameter(verbose,file, "pseudopotpath", 0, 1, 1, string_type, (config::pseudopotpath), 1, critical);
1119 ParseForParameter(verbose,file, "ProcsGammaPsi", 0, 1, 1, int_type, &(config::ProcPEGamma), 1, critical);
1120 ParseForParameter(verbose,file, "ProcsGammaPsi", 0, 2, 1, int_type, &(config::ProcPEPsi), 1, critical);
1121 config::Seed = 1;
1122 config::DoOutOrbitals = 0;
1123 ParseForParameter(verbose,file,"DoOutVis", 0, 1, 1, int_type, &(config::DoOutVis), 1, critical);
1124 if (config::DoOutVis < 0) config::DoOutVis = 0;
1125 if (config::DoOutVis > 1) config::DoOutVis = 1;
1126 config::VectorPlane = -1;
1127 config::VectorCut = 0.;
1128 ParseForParameter(verbose,file,"DoOutMes", 0, 1, 1, int_type, &(config::DoOutMes), 1, critical);
1129 if (config::DoOutMes < 0) config::DoOutMes = 0;
1130 if (config::DoOutMes > 1) config::DoOutMes = 1;
1131 config::DoOutCurrent = 0;
1132 ParseForParameter(verbose,file,"AddGramSch", 0, 1, 1, int_type, &(config::UseAddGramSch), 1, critical);
1133 if (config::UseAddGramSch < 0) config::UseAddGramSch = 0;
1134 if (config::UseAddGramSch > 2) config::UseAddGramSch = 2;
1135 config::CommonWannier = 0;
1136 config::SawtoothStart = 0.01;
1137
1138 ParseForParameter(verbose,file,"MaxOuterStep", 0, 1, 1, double_type, &(config::MaxOuterStep), 1, critical);
1139 ParseForParameter(verbose,file,"Deltat", 0, 1, 1, double_type, &(config::Deltat), 1, optional);
1140 ParseForParameter(verbose,file,"VisOuterStep", 0, 1, 1, int_type, &(config::OutVisStep), 1, optional);
1141 ParseForParameter(verbose,file,"VisSrcOuterStep", 0, 1, 1, int_type, &(config::OutSrcStep), 1, optional);
1142 ParseForParameter(verbose,file,"TargetTemp", 0, 1, 1, double_type, &(config::TargetTemp), 1, optional);
1143 ParseForParameter(verbose,file,"ScaleTempStep", 0, 1, 1, int_type, &(config::ScaleTempStep), 1, optional);
1144 config::EpsWannier = 1e-8;
1145
1146 // stop conditions
1147 //if (config::MaxOuterStep <= 0) config::MaxOuterStep = 1;
1148 ParseForParameter(verbose,file,"MaxPsiStep", 0, 1, 1, int_type, &(config::MaxPsiStep), 1, critical);
1149 if (config::MaxPsiStep <= 0) config::MaxPsiStep = 3;
1150
1151 ParseForParameter(verbose,file,"MaxMinStep", 0, 1, 1, int_type, &(config::MaxMinStep), 1, critical);
1152 ParseForParameter(verbose,file,"MaxMinStep", 0, 2, 1, double_type, &(config::RelEpsTotalEnergy), 1, critical);
1153 ParseForParameter(verbose,file,"MaxMinStep", 0, 3, 1, double_type, &(config::RelEpsKineticEnergy), 1, critical);
1154 ParseForParameter(verbose,file,"MaxMinStep", 0, 4, 1, int_type, &(config::MaxMinStopStep), 1, critical);
1155 if (config::MaxMinStep <= 0) config::MaxMinStep = config::MaxPsiStep;
1156 if (config::MaxMinStopStep < 1) config::MaxMinStopStep = 1;
1157 config::MaxMinGapStopStep = 1;
1158
1159 ParseForParameter(verbose,file,"MaxInitMinStep", 0, 1, 1, int_type, &(config::MaxInitMinStep), 1, critical);
1160 ParseForParameter(verbose,file,"MaxInitMinStep", 0, 2, 1, double_type, &(config::InitRelEpsTotalEnergy), 1, critical);
1161 ParseForParameter(verbose,file,"MaxInitMinStep", 0, 3, 1, double_type, &(config::InitRelEpsKineticEnergy), 1, critical);
1162 ParseForParameter(verbose,file,"MaxInitMinStep", 0, 4, 1, int_type, &(config::InitMaxMinStopStep), 1, critical);
1163 if (config::MaxInitMinStep <= 0) config::MaxInitMinStep = config::MaxPsiStep;
1164 if (config::InitMaxMinStopStep < 1) config::InitMaxMinStopStep = 1;
1165 config::InitMaxMinGapStopStep = 1;
1166
1167 ParseForParameter(verbose,file, "BoxLength", 0, 3, 3, lower_trigrid, BoxLength, 1, critical); /* Lattice->RealBasis */
1168 mol->cell_size[0] = BoxLength[0];
1169 mol->cell_size[1] = BoxLength[3];
1170 mol->cell_size[2] = BoxLength[4];
1171 mol->cell_size[3] = BoxLength[6];
1172 mol->cell_size[4] = BoxLength[7];
1173 mol->cell_size[5] = BoxLength[8];
1174 if (1) fprintf(stderr,"\n");
1175 config::DoPerturbation = 0;
1176 config::DoFullCurrent = 0;
1177
1178 ParseForParameter(verbose,file,"ECut", 0, 1, 1, double_type, &(config::ECut), 1, critical);
1179 ParseForParameter(verbose,file,"MaxLevel", 0, 1, 1, int_type, &(config::MaxLevel), 1, critical);
1180 ParseForParameter(verbose,file,"Level0Factor", 0, 1, 1, int_type, &(config::Lev0Factor), 1, critical);
1181 if (config::Lev0Factor < 2) {
1182 config::Lev0Factor = 2;
1183 }
1184 ParseForParameter(verbose,file,"RiemannTensor", 0, 1, 1, int_type, &di, 1, critical);
1185 if (di >= 0 && di < 2) {
1186 config::RiemannTensor = di;
1187 } else {
1188 fprintf(stderr, "0 <= RiemanTensor < 2: 0 UseNotRT, 1 UseRT");
1189 exit(1);
1190 }
1191 switch (config::RiemannTensor) {
1192 case 0: //UseNoRT
1193 if (config::MaxLevel < 2) {
1194 config::MaxLevel = 2;
1195 }
1196 config::LevRFactor = 2;
1197 config::RTActualUse = 0;
1198 break;
1199 case 1: // UseRT
1200 if (config::MaxLevel < 3) {
1201 config::MaxLevel = 3;
1202 }
1203 ParseForParameter(verbose,file,"RiemannLevel", 0, 1, 1, int_type, &(config::RiemannLevel), 1, critical);
1204 if (config::RiemannLevel < 2) {
1205 config::RiemannLevel = 2;
1206 }
1207 if (config::RiemannLevel > config::MaxLevel-1) {
1208 config::RiemannLevel = config::MaxLevel-1;
1209 }
1210 ParseForParameter(verbose,file,"LevRFactor", 0, 1, 1, int_type, &(config::LevRFactor), 1, critical);
1211 if (config::LevRFactor < 2) {
1212 config::LevRFactor = 2;
1213 }
1214 config::Lev0Factor = 2;
1215 config::RTActualUse = 2;
1216 break;
1217 }
1218 ParseForParameter(verbose,file,"PsiType", 0, 1, 1, int_type, &di, 1, critical);
1219 if (di >= 0 && di < 2) {
1220 config::PsiType = di;
1221 } else {
1222 fprintf(stderr, "0 <= PsiType < 2: 0 UseSpinDouble, 1 UseSpinUpDown");
1223 exit(1);
1224 }
1225 switch (config::PsiType) {
1226 case 0: // SpinDouble
1227 ParseForParameter(verbose,file,"MaxPsiDouble", 0, 1, 1, int_type, &(config::MaxPsiDouble), 1, critical);
1228 config::AddPsis = 0;
1229 break;
1230 case 1: // SpinUpDown
1231 if (config::ProcPEGamma % 2) config::ProcPEGamma*=2;
1232 ParseForParameter(verbose,file,"MaxPsiUp", 0, 1, 1, int_type, &(config::PsiMaxNoUp), 1, critical);
1233 ParseForParameter(verbose,file,"MaxPsiDown", 0, 1, 1, int_type, &(config::PsiMaxNoDown), 1, critical);
1234 config::AddPsis = 0;
1235 break;
1236 }
1237
1238 // IonsInitRead
1239
1240 ParseForParameter(verbose,file,"RCut", 0, 1, 1, double_type, &(config::RCut), 1, critical);
1241 ParseForParameter(verbose,file,"IsAngstroem", 0, 1, 1, int_type, &(config::IsAngstroem), 1, critical);
1242 config::RelativeCoord = 0;
1243 config::StructOpt = 0;
1244
1245
1246 // 2. parse the bond graph file if given
1247 BG = new BondGraph(IsAngstroem);
1248 if (BG->LoadBondLengthTable(BondGraphFileName)) {
1249 Log() << Verbose(0) << "Bond length table loaded successfully." << endl;
1250 } else {
1251 Log() << Verbose(0) << "Bond length table loading failed." << endl;
1252 }
1253
1254 // Routine from builder.cpp
1255
1256 for (i=MAX_ELEMENTS;i--;)
1257 elementhash[i] = NULL;
1258 Log() << Verbose(0) << "Parsing Ions ..." << endl;
1259 No=0;
1260 found = 0;
1261 while (getline(*file,zeile,'\n')) {
1262 if (zeile.find("Ions_Data") == 0) {
1263 Log() << Verbose(1) << "found Ions_Data...begin parsing" << endl;
1264 found ++;
1265 }
1266 if (found > 0) {
1267 if (zeile.find("Ions_Data") == 0)
1268 getline(*file,zeile,'\n'); // read next line and parse this one
1269 istringstream input(zeile);
1270 input >> AtomNo; // number of atoms
1271 input >> Z; // atomic number
1272 input >> a;
1273 input >> l;
1274 input >> l;
1275 input >> b; // element mass
1276 elementhash[No] = periode->FindElement(Z);
1277 Log() << Verbose(1) << "AtomNo: " << AtomNo << "\tZ: " << Z << "\ta:" << a << "\tl:" << l << "\b:" << b << "\tElement:" << elementhash[No] << "\t:" << endl;
1278 for(i=0;i<AtomNo;i++) {
1279 if (!getline(*file,zeile,'\n')) {// parse on and on
1280 Log() << Verbose(2) << "Error: Too few items in ionic list of element" << elementhash[No] << "." << endl << "Exiting." << endl;
1281 // return 1;
1282 } else {
1283 //Log() << Verbose(2) << "Reading line: " << zeile << endl;
1284 }
1285 istringstream input2(zeile);
1286 atom *neues = new atom();
1287 input2 >> neues->x.x[0]; // x
1288 input2 >> neues->x.x[1]; // y
1289 input2 >> neues->x.x[2]; // z
1290 input2 >> l;
1291 neues->type = elementhash[No]; // find element type
1292 mol->AddAtom(neues);
1293 }
1294 No++;
1295 }
1296 }
1297 file->close();
1298 delete(file);
1299};
1300
1301/** Stores all elements of config structure from which they can be re-read.
1302 * \param *filename name of file
1303 * \param *periode pointer to a periodentafel class with all elements
1304 * \param *mol pointer to molecule containing all atoms of the molecule
1305 */
1306bool config::Save(const char * const filename, const periodentafel * const periode, molecule * const mol) const
1307{
1308 bool result = true;
1309 // bring MaxTypes up to date
1310 mol->CountElements();
1311 ofstream * const output = new ofstream(filename, ios::out);
1312 if (output != NULL) {
1313 *output << "# ParallelCarParinello - main configuration file - created with molecuilder" << endl;
1314 *output << endl;
1315 *output << "mainname\t" << config::mainname << "\t# programm name (for runtime files)" << endl;
1316 *output << "defaultpath\t" << config::defaultpath << "\t# where to put files during runtime" << endl;
1317 *output << "pseudopotpath\t" << config::pseudopotpath << "\t# where to find pseudopotentials" << endl;
1318 *output << endl;
1319 *output << "ProcPEGamma\t" << config::ProcPEGamma << "\t# for parallel computing: share constants" << endl;
1320 *output << "ProcPEPsi\t" << config::ProcPEPsi << "\t# for parallel computing: share wave functions" << endl;
1321 *output << "DoOutVis\t" << config::DoOutVis << "\t# Output data for OpenDX" << endl;
1322 *output << "DoOutMes\t" << config::DoOutMes << "\t# Output data for measurements" << endl;
1323 *output << "DoOutOrbitals\t" << config::DoOutOrbitals << "\t# Output all Orbitals" << endl;
1324 *output << "DoOutCurr\t" << config::DoOutCurrent << "\t# Ouput current density for OpenDx" << endl;
1325 *output << "DoOutNICS\t" << config::DoOutNICS << "\t# Output Nucleus independent current shieldings" << endl;
1326 *output << "DoPerturbation\t" << config::DoPerturbation << "\t# Do perturbation calculate and determine susceptibility and shielding" << endl;
1327 *output << "DoFullCurrent\t" << config::DoFullCurrent << "\t# Do full perturbation" << endl;
1328 *output << "DoConstrainedMD\t" << config::DoConstrainedMD << "\t# Do perform a constrained (>0, relating to current MD step) instead of unconstrained (0) MD" << endl;
1329 *output << "Thermostat\t" << ThermostatNames[Thermostat] << "\t";
1330 switch(Thermostat) {
1331 default:
1332 case None:
1333 break;
1334 case Woodcock:
1335 *output << ScaleTempStep;
1336 break;
1337 case Gaussian:
1338 *output << ScaleTempStep;
1339 break;
1340 case Langevin:
1341 *output << TempFrequency << "\t" << alpha;
1342 break;
1343 case Berendsen:
1344 *output << TempFrequency;
1345 break;
1346 case NoseHoover:
1347 *output << HooverMass;
1348 break;
1349 };
1350 *output << "\t# Which Thermostat and its parameters to use in MD case." << endl;
1351 *output << "CommonWannier\t" << config::CommonWannier << "\t# Put virtual centers at indivual orbits, all common, merged by variance, to grid point, to cell center" << endl;
1352 *output << "SawtoothStart\t" << config::SawtoothStart << "\t# Absolute value for smooth transition at cell border " << endl;
1353 *output << "VectorPlane\t" << config::VectorPlane << "\t# Cut plane axis (x, y or z: 0,1,2) for two-dim current vector plot" << endl;
1354 *output << "VectorCut\t" << config::VectorCut << "\t# Cut plane axis value" << endl;
1355 *output << "AddGramSch\t" << config::UseAddGramSch << "\t# Additional GramSchmidtOrtogonalization to be safe" << endl;
1356 *output << "Seed\t\t" << config::Seed << "\t# initial value for random seed for Psi coefficients" << endl;
1357 *output << endl;
1358 *output << "MaxOuterStep\t" << config::MaxOuterStep << "\t# number of MolecularDynamics/Structure optimization steps" << endl;
1359 *output << "Deltat\t" << config::Deltat << "\t# time per MD step" << endl;
1360 *output << "OutVisStep\t" << config::OutVisStep << "\t# Output visual data every ...th step" << endl;
1361 *output << "OutSrcStep\t" << config::OutSrcStep << "\t# Output \"restart\" data every ..th step" << endl;
1362 *output << "TargetTemp\t" << config::TargetTemp << "\t# Target temperature" << endl;
1363 *output << "MaxPsiStep\t" << config::MaxPsiStep << "\t# number of Minimisation steps per state (0 - default)" << endl;
1364 *output << "EpsWannier\t" << config::EpsWannier << "\t# tolerance value for spread minimisation of orbitals" << endl;
1365 *output << endl;
1366 *output << "# Values specifying when to stop" << endl;
1367 *output << "MaxMinStep\t" << config::MaxMinStep << "\t# Maximum number of steps" << endl;
1368 *output << "RelEpsTotalE\t" << config::RelEpsTotalEnergy << "\t# relative change in total energy" << endl;
1369 *output << "RelEpsKineticE\t" << config::RelEpsKineticEnergy << "\t# relative change in kinetic energy" << endl;
1370 *output << "MaxMinStopStep\t" << config::MaxMinStopStep << "\t# check every ..th steps" << endl;
1371 *output << "MaxMinGapStopStep\t" << config::MaxMinGapStopStep << "\t# check every ..th steps" << endl;
1372 *output << endl;
1373 *output << "# Values specifying when to stop for INIT, otherwise same as above" << endl;
1374 *output << "MaxInitMinStep\t" << config::MaxInitMinStep << "\t# Maximum number of steps" << endl;
1375 *output << "InitRelEpsTotalE\t" << config::InitRelEpsTotalEnergy << "\t# relative change in total energy" << endl;
1376 *output << "InitRelEpsKineticE\t" << config::InitRelEpsKineticEnergy << "\t# relative change in kinetic energy" << endl;
1377 *output << "InitMaxMinStopStep\t" << config::InitMaxMinStopStep << "\t# check every ..th steps" << endl;
1378 *output << "InitMaxMinGapStopStep\t" << config::InitMaxMinGapStopStep << "\t# check every ..th steps" << endl;
1379 *output << endl;
1380 *output << "BoxLength\t\t\t# (Length of a unit cell)" << endl;
1381 *output << mol->cell_size[0] << "\t" << endl;
1382 *output << mol->cell_size[1] << "\t" << mol->cell_size[2] << "\t" << endl;
1383 *output << mol->cell_size[3] << "\t" << mol->cell_size[4] << "\t" << mol->cell_size[5] << "\t" << endl;
1384 // FIXME
1385 *output << endl;
1386 *output << "ECut\t\t" << config::ECut << "\t# energy cutoff for discretization in Hartrees" << endl;
1387 *output << "MaxLevel\t" << config::MaxLevel << "\t# number of different levels in the code, >=2" << endl;
1388 *output << "Level0Factor\t" << config::Lev0Factor << "\t# factor by which node number increases from S to 0 level" << endl;
1389 *output << "RiemannTensor\t" << config::RiemannTensor << "\t# (Use metric)" << endl;
1390 switch (config::RiemannTensor) {
1391 case 0: //UseNoRT
1392 break;
1393 case 1: // UseRT
1394 *output << "RiemannLevel\t" << config::RiemannLevel << "\t# Number of Riemann Levels" << endl;
1395 *output << "LevRFactor\t" << config::LevRFactor << "\t# factor by which node number increases from 0 to R level from" << endl;
1396 break;
1397 }
1398 *output << "PsiType\t\t" << config::PsiType << "\t# 0 - doubly occupied, 1 - SpinUp,SpinDown" << endl;
1399 // write out both types for easier changing afterwards
1400 // switch (PsiType) {
1401 // case 0:
1402 *output << "MaxPsiDouble\t" << config::MaxPsiDouble << "\t# here: specifying both maximum number of SpinUp- and -Down-states" << endl;
1403 // break;
1404 // case 1:
1405 *output << "PsiMaxNoUp\t" << config::PsiMaxNoUp << "\t# here: specifying maximum number of SpinUp-states" << endl;
1406 *output << "PsiMaxNoDown\t" << config::PsiMaxNoDown << "\t# here: specifying maximum number of SpinDown-states" << endl;
1407 // break;
1408 // }
1409 *output << "AddPsis\t\t" << config::AddPsis << "\t# Additional unoccupied Psis for bandgap determination" << endl;
1410 *output << endl;
1411 *output << "RCut\t\t" << config::RCut << "\t# R-cut for the ewald summation" << endl;
1412 *output << "StructOpt\t" << config::StructOpt << "\t# Do structure optimization beforehand" << endl;
1413 *output << "IsAngstroem\t" << config::IsAngstroem << "\t# 0 - Bohr, 1 - Angstroem" << endl;
1414 *output << "RelativeCoord\t" << config::RelativeCoord << "\t# whether ion coordinates are relative (1) or absolute (0)" << endl;
1415 *output << "MaxTypes\t" << mol->ElementCount << "\t# maximum number of different ion types" << endl;
1416 *output << endl;
1417 result = result && mol->Checkout(output);
1418 if (mol->MDSteps <=1 )
1419 result = result && mol->Output(output);
1420 else
1421 result = result && mol->OutputTrajectories(output);
1422 output->close();
1423 output->clear();
1424 delete(output);
1425 return result;
1426 } else {
1427 eLog() << Verbose(1) << "Cannot open output file:" << filename << endl;
1428 return false;
1429 }
1430};
1431
1432/** Stores all elements in a MPQC input file.
1433 * Note that this format cannot be parsed again.
1434 * \param *filename name of file (without ".in" suffix!)
1435 * \param *mol pointer to molecule containing all atoms of the molecule
1436 */
1437bool config::SaveMPQC(const char * const filename, const molecule * const mol) const
1438{
1439 int AtomNo = -1;
1440 Vector *center = NULL;
1441 ofstream *output = NULL;
1442
1443 // first without hessian
1444 {
1445 stringstream * const fname = new stringstream;;
1446 *fname << filename << ".in";
1447 output = new ofstream(fname->str().c_str(), ios::out);
1448 if (output == NULL) {
1449 eLog() << Verbose(1) << "Cannot open mpqc output file:" << fname << endl;
1450 delete(fname);
1451 return false;
1452 }
1453 *output << "% Created by MoleCuilder" << endl;
1454 *output << "mpqc: (" << endl;
1455 *output << "\tsavestate = no" << endl;
1456 *output << "\tdo_gradient = yes" << endl;
1457 *output << "\tmole<MBPT2>: (" << endl;
1458 *output << "\t\tmaxiter = 200" << endl;
1459 *output << "\t\tbasis = $:basis" << endl;
1460 *output << "\t\tmolecule = $:molecule" << endl;
1461 *output << "\t\treference<CLHF>: (" << endl;
1462 *output << "\t\t\tbasis = $:basis" << endl;
1463 *output << "\t\t\tmolecule = $:molecule" << endl;
1464 *output << "\t\t)" << endl;
1465 *output << "\t)" << endl;
1466 *output << ")" << endl;
1467 *output << "molecule<Molecule>: (" << endl;
1468 *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
1469 *output << "\t{ atoms geometry } = {" << endl;
1470 center = mol->DetermineCenterOfAll();
1471 // output of atoms
1472 AtomNo = 0;
1473 mol->ActOnAllAtoms( &atom::OutputMPQCLine, output, (const Vector *)center, &AtomNo );
1474 delete(center);
1475 *output << "\t}" << endl;
1476 *output << ")" << endl;
1477 *output << "basis<GaussianBasisSet>: (" << endl;
1478 *output << "\tname = \"" << basis << "\"" << endl;
1479 *output << "\tmolecule = $:molecule" << endl;
1480 *output << ")" << endl;
1481 output->close();
1482 delete(output);
1483 delete(fname);
1484 }
1485
1486 // second with hessian
1487 {
1488 stringstream * const fname = new stringstream;
1489 *fname << filename << ".hess.in";
1490 output = new ofstream(fname->str().c_str(), ios::out);
1491 if (output == NULL) {
1492 eLog() << Verbose(1) << "Cannot open mpqc hessian output file:" << fname << endl;
1493 delete(fname);
1494 return false;
1495 }
1496 *output << "% Created by MoleCuilder" << endl;
1497 *output << "mpqc: (" << endl;
1498 *output << "\tsavestate = no" << endl;
1499 *output << "\tdo_gradient = yes" << endl;
1500 *output << "\tmole<CLHF>: (" << endl;
1501 *output << "\t\tmaxiter = 200" << endl;
1502 *output << "\t\tbasis = $:basis" << endl;
1503 *output << "\t\tmolecule = $:molecule" << endl;
1504 *output << "\t)" << endl;
1505 *output << "\tfreq<MolecularFrequencies>: (" << endl;
1506 *output << "\t\tmolecule=$:molecule" << endl;
1507 *output << "\t)" << endl;
1508 *output << ")" << endl;
1509 *output << "molecule<Molecule>: (" << endl;
1510 *output << "\tunit = " << (IsAngstroem ? "angstrom" : "bohr" ) << endl;
1511 *output << "\t{ atoms geometry } = {" << endl;
1512 center = mol->DetermineCenterOfAll();
1513 // output of atoms
1514 AtomNo = 0;
1515 mol->ActOnAllAtoms( &atom::OutputMPQCLine, output, (const Vector *)center, &AtomNo );
1516 delete(center);
1517 *output << "\t}" << endl;
1518 *output << ")" << endl;
1519 *output << "basis<GaussianBasisSet>: (" << endl;
1520 *output << "\tname = \"3-21G\"" << endl;
1521 *output << "\tmolecule = $:molecule" << endl;
1522 *output << ")" << endl;
1523 output->close();
1524 delete(output);
1525 delete(fname);
1526 }
1527
1528 return true;
1529};
1530
1531/** Stores all atoms from all molecules in a PDB input file.
1532 * Note that this format cannot be parsed again.
1533 * \param *filename name of file (without ".in" suffix!)
1534 * \param *MolList pointer to MoleculeListClass containing all atoms
1535 */
1536bool config::SavePDB(const char * const filename, const MoleculeListClass * const MolList) const
1537{
1538 int AtomNo = -1;
1539 int MolNo = 0;
1540 atom *Walker = NULL;
1541 FILE *f = NULL;
1542
1543 char name[MAXSTRINGSIZE];
1544 strncpy(name, filename, MAXSTRINGSIZE-1);
1545 strncat(name, ".pdb", MAXSTRINGSIZE-(strlen(name)+1));
1546 f = fopen(name, "w" );
1547 if (f == NULL) {
1548 eLog() << Verbose(1) << "Cannot open pdb output file:" << name << endl;
1549 return false;
1550 }
1551 fprintf(f, "# Created by MoleCuilder\n");
1552
1553 for (MoleculeList::const_iterator Runner = MolList->ListOfMolecules.begin(); Runner != MolList->ListOfMolecules.end(); Runner++) {
1554 Walker = (*Runner)->start;
1555 int *elementNo = Calloc<int>(MAX_ELEMENTS, "config::SavePDB - elementNo");
1556 AtomNo = 0;
1557 while (Walker->next != (*Runner)->end) {
1558 Walker = Walker->next;
1559 sprintf(name, "%2s%2d",Walker->type->symbol, elementNo[Walker->type->Z]);
1560 elementNo[Walker->type->Z] = (elementNo[Walker->type->Z]+1) % 100; // confine to two digits
1561 fprintf(f,
1562 "ATOM %6u %-4s %4s%c%4u %8.3f%8.3f%8.3f%6.2f%6.2f %4s%2s%2s\n",
1563 Walker->nr, /* atom serial number */
1564 name, /* atom name */
1565 (*Runner)->name, /* residue name */
1566 'a'+(unsigned char)(AtomNo % 26), /* letter for chain */
1567 MolNo, /* residue sequence number */
1568 Walker->node->x[0], /* position X in Angstroem */
1569 Walker->node->x[1], /* position Y in Angstroem */
1570 Walker->node->x[2], /* position Z in Angstroem */
1571 (double)Walker->type->Valence, /* occupancy */
1572 (double)Walker->type->NoValenceOrbitals, /* temperature factor */
1573 "0", /* segment identifier */
1574 Walker->type->symbol, /* element symbol */
1575 "0"); /* charge */
1576 AtomNo++;
1577 }
1578 Free(&elementNo);
1579 MolNo++;
1580 }
1581 fclose(f);
1582
1583 return true;
1584};
1585
1586/** Stores all atoms in a PDB input file.
1587 * Note that this format cannot be parsed again.
1588 * \param *filename name of file (without ".in" suffix!)
1589 * \param *mol pointer to molecule
1590 */
1591bool config::SavePDB(const char * const filename, const molecule * const mol) const
1592{
1593 int AtomNo = -1;
1594 atom *Walker = NULL;
1595 FILE *f = NULL;
1596
1597 int *elementNo = Calloc<int>(MAX_ELEMENTS, "config::SavePDB - elementNo");
1598 char name[MAXSTRINGSIZE];
1599 strncpy(name, filename, MAXSTRINGSIZE-1);
1600 strncat(name, ".pdb", MAXSTRINGSIZE-(strlen(name)+1));
1601 f = fopen(name, "w" );
1602 if (f == NULL) {
1603 eLog() << Verbose(1) << "Cannot open pdb output file:" << name << endl;
1604 Free(&elementNo);
1605 return false;
1606 }
1607 fprintf(f, "# Created by MoleCuilder\n");
1608
1609 Walker = mol->start;
1610 AtomNo = 0;
1611 while (Walker->next != mol->end) {
1612 Walker = Walker->next;
1613 sprintf(name, "%2s%2d",Walker->type->symbol, elementNo[Walker->type->Z]);
1614 elementNo[Walker->type->Z] = (elementNo[Walker->type->Z]+1) % 100; // confine to two digits
1615 fprintf(f,
1616 "ATOM %6u %-4s %4s%c%4u %8.3f%8.3f%8.3f%6.2f%6.2f %4s%2s%2s\n",
1617 Walker->nr, /* atom serial number */
1618 name, /* atom name */
1619 mol->name, /* residue name */
1620 'a'+(unsigned char)(AtomNo % 26), /* letter for chain */
1621 0, /* residue sequence number */
1622 Walker->node->x[0], /* position X in Angstroem */
1623 Walker->node->x[1], /* position Y in Angstroem */
1624 Walker->node->x[2], /* position Z in Angstroem */
1625 (double)Walker->type->Valence, /* occupancy */
1626 (double)Walker->type->NoValenceOrbitals, /* temperature factor */
1627 "0", /* segment identifier */
1628 Walker->type->symbol, /* element symbol */
1629 "0"); /* charge */
1630 AtomNo++;
1631 }
1632 fclose(f);
1633 Free(&elementNo);
1634
1635 return true;
1636};
1637
1638/** Stores all atoms in a TREMOLO data input file.
1639 * Note that this format cannot be parsed again.
1640 * \param *filename name of file (without ".in" suffix!)
1641 * \param *mol pointer to molecule
1642 */
1643bool config::SaveTREMOLO(const char * const filename, const molecule * const mol) const
1644{
1645 atom *Walker = NULL;
1646 ofstream *output = NULL;
1647 stringstream * const fname = new stringstream;
1648
1649 *fname << filename << ".data";
1650 output = new ofstream(fname->str().c_str(), ios::out);
1651 if (output == NULL) {
1652 eLog() << Verbose(1) << "Cannot open tremolo output file:" << fname << endl;
1653 delete(fname);
1654 return false;
1655 }
1656
1657 // scan maximum number of neighbours
1658 Walker = mol->start;
1659 int MaxNeighbours = 0;
1660 while (Walker->next != mol->end) {
1661 Walker = Walker->next;
1662 const int count = Walker->ListOfBonds.size();
1663 if (MaxNeighbours < count)
1664 MaxNeighbours = count;
1665 }
1666 *output << "# ATOMDATA Id name resName resSeq x=3 charge type neighbors=" << MaxNeighbours << endl;
1667
1668 Walker = mol->start;
1669 while (Walker->next != mol->end) {
1670 Walker = Walker->next;
1671 *output << Walker->nr << "\t";
1672 *output << Walker->Name << "\t";
1673 *output << mol->name << "\t";
1674 *output << 0 << "\t";
1675 *output << Walker->node->x[0] << "\t" << Walker->node->x[1] << "\t" << Walker->node->x[2] << "\t";
1676 *output << (double)Walker->type->Valence << "\t";
1677 *output << Walker->type->symbol << "\t";
1678 for (BondList::iterator runner = Walker->ListOfBonds.begin(); runner != Walker->ListOfBonds.end(); runner++)
1679 *output << (*runner)->GetOtherAtom(Walker)->nr << "\t";
1680 for(int i=Walker->ListOfBonds.size(); i < MaxNeighbours; i++)
1681 *output << "-\t";
1682 *output << endl;
1683 }
1684 output->flush();
1685 output->close();
1686 delete(output);
1687 delete(fname);
1688
1689 return true;
1690};
1691
1692/** Stores all atoms from all molecules in a TREMOLO data input file.
1693 * Note that this format cannot be parsed again.
1694 * \param *filename name of file (without ".in" suffix!)
1695 * \param *MolList pointer to MoleculeListClass containing all atoms
1696 */
1697bool config::SaveTREMOLO(const char * const filename, const MoleculeListClass * const MolList) const
1698{
1699 atom *Walker = NULL;
1700 ofstream *output = NULL;
1701 stringstream * const fname = new stringstream;
1702
1703 *fname << filename << ".data";
1704 output = new ofstream(fname->str().c_str(), ios::out);
1705 if (output == NULL) {
1706 eLog() << Verbose(1) << "Cannot open tremolo output file:" << fname << endl;
1707 delete(fname);
1708 return false;
1709 }
1710
1711 // scan maximum number of neighbours
1712 int MaxNeighbours = 0;
1713 for (MoleculeList::const_iterator MolWalker = MolList->ListOfMolecules.begin(); MolWalker != MolList->ListOfMolecules.end(); MolWalker++) {
1714 Walker = (*MolWalker)->start;
1715 while (Walker->next != (*MolWalker)->end) {
1716 Walker = Walker->next;
1717 const int count = Walker->ListOfBonds.size();
1718 if (MaxNeighbours < count)
1719 MaxNeighbours = count;
1720 }
1721 }
1722 *output << "# ATOMDATA Id name resName resSeq x=3 charge type neighbors=" << MaxNeighbours << endl;
1723
1724 // create global to local id map
1725 int **LocalNotoGlobalNoMap = Calloc<int *>(MolList->ListOfMolecules.size(), "config::SaveTREMOLO - **LocalNotoGlobalNoMap");
1726 {
1727 int MolCounter = 0;
1728 int AtomNo = 0;
1729 for (MoleculeList::const_iterator MolWalker = MolList->ListOfMolecules.begin(); MolWalker != MolList->ListOfMolecules.end(); MolWalker++) {
1730 LocalNotoGlobalNoMap[MolCounter] = Calloc<int>(MolList->CountAllAtoms(), "config::SaveTREMOLO - *LocalNotoGlobalNoMap[]");
1731
1732 (*MolWalker)->SetIndexedArrayForEachAtomTo( LocalNotoGlobalNoMap[MolCounter], &atom::nr, IncrementalAbsoluteValue, &AtomNo);
1733
1734 MolCounter++;
1735 }
1736 }
1737
1738 // write the file
1739 {
1740 int MolCounter = 0;
1741 int AtomNo = 0;
1742 for (MoleculeList::const_iterator MolWalker = MolList->ListOfMolecules.begin(); MolWalker != MolList->ListOfMolecules.end(); MolWalker++) {
1743 Walker = (*MolWalker)->start;
1744 while (Walker->next != (*MolWalker)->end) {
1745 Walker = Walker->next;
1746 *output << AtomNo << "\t";
1747 *output << Walker->Name << "\t";
1748 *output << (*MolWalker)->name << "\t";
1749 *output << MolCounter << "\t";
1750 *output << Walker->node->x[0] << "\t" << Walker->node->x[1] << "\t" << Walker->node->x[2] << "\t";
1751 *output << (double)Walker->type->Valence << "\t";
1752 *output << Walker->type->symbol << "\t";
1753 for (BondList::iterator runner = Walker->ListOfBonds.begin(); runner != Walker->ListOfBonds.end(); runner++)
1754 *output << LocalNotoGlobalNoMap[MolCounter][ (*runner)->GetOtherAtom(Walker)->nr ] << "\t";
1755 for(int i=Walker->ListOfBonds.size(); i < MaxNeighbours; i++)
1756 *output << "-\t";
1757 *output << endl;
1758 AtomNo++;
1759 }
1760 MolCounter++;
1761 }
1762 }
1763
1764 // store & free
1765 output->flush();
1766 output->close();
1767 delete(output);
1768 delete(fname);
1769 for(size_t i=0;i<MolList->ListOfMolecules.size(); i++)
1770 Free(&LocalNotoGlobalNoMap[i]);
1771 Free(&LocalNotoGlobalNoMap);
1772
1773 return true;
1774};
1775
1776/** Reads parameter from a parsed file.
1777 * The file is either parsed for a certain keyword or if null is given for
1778 * the value in row yth and column xth. If the keyword was necessity#critical,
1779 * then an error is thrown and the programme aborted.
1780 * \warning value is modified (both in contents and position)!
1781 * \param verbose 1 - print found value to stderr, 0 - don't
1782 * \param *file file to be parsed
1783 * \param name Name of value in file (at least 3 chars!)
1784 * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning
1785 * (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read -
1786 * best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now
1787 * counted from this unresetted position!)
1788 * \param xth Which among a number of parameters it is (in grid case it's row number as grid is read as a whole!)
1789 * \param yth In grid case specifying column number, otherwise the yth \a name matching line
1790 * \param type Type of the Parameter to be read
1791 * \param value address of the value to be read (must have been allocated)
1792 * \param repetition determines, if the keyword appears multiply in the config file, which repetition shall be parsed, i.e. 1 if not multiply
1793 * \param critical necessity of this keyword being specified (optional, critical)
1794 * \return 1 - found, 0 - not found
1795 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++
1796 */
1797int 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) {
1798 int i = 0;
1799 int j = 0; // loop variables
1800 int length = 0;
1801 int maxlength = -1;
1802 long file_position = file->tellg(); // mark current position
1803 char *dummy1 = NULL;
1804 char *dummy = NULL;
1805 char * const free_dummy = Malloc<char>(256, "config::ParseForParameter: *free_dummy"); // pointers in the line that is read in per step
1806 dummy1 = free_dummy;
1807
1808 //fprintf(stderr,"Parsing for %s\n",name);
1809 if (repetition == 0)
1810 //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!");
1811 return 0;
1812
1813 int line = 0; // marks line where parameter was found
1814 int found = (type >= grid) ? 0 : (-yth + 1); // marks if yth parameter name was found
1815 while((found != repetition)) {
1816 dummy1 = dummy = free_dummy;
1817 do {
1818 file->getline(dummy1, 256); // Read the whole line
1819 if (file->eof()) {
1820 if ((critical) && (found == 0)) {
1821 Free(free_dummy);
1822 //Error(InitReading, name);
1823 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
1824 exit(255);
1825 } else {
1826 //if (!sequential)
1827 file->clear();
1828 file->seekg(file_position, ios::beg); // rewind to start position
1829 Free(free_dummy);
1830 return 0;
1831 }
1832 }
1833 line++;
1834 } while (dummy != NULL && dummy1 != NULL && ((dummy1[0] == '#') || (dummy1[0] == '\0'))); // skip commentary and empty lines
1835
1836 // C++ getline removes newline at end, thus re-add
1837 if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
1838 i = strlen(dummy1);
1839 dummy1[i] = '\n';
1840 dummy1[i+1] = '\0';
1841 }
1842 //fprintf(stderr,"line %i ends at %i, newline at %i\n", line, strlen(dummy1), strchr(dummy1,'\n')-free_dummy);
1843
1844 if (dummy1 == NULL) {
1845 if (verbose) fprintf(stderr,"Error reading line %i\n",line);
1846 } else {
1847 //fprintf(stderr,"Now parsing the line %i: %s\n", line, dummy1);
1848 }
1849 // Seek for possible end of keyword on line if given ...
1850 if (name != NULL) {
1851 dummy = strchr(dummy1,'\t'); // set dummy on first tab or space which ever's nearer
1852 if (dummy == NULL) {
1853 dummy = strchr(dummy1, ' '); // if not found seek for space
1854 while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' '))) // skip some more tabs and spaces if necessary
1855 dummy++;
1856 }
1857 if (dummy == NULL) {
1858 dummy = strchr(dummy1, '\n'); // set on line end then (whole line = keyword)
1859 //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name);
1860 //Free((void **)&free_dummy);
1861 //Error(FileOpenParams, NULL);
1862 } else {
1863 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)dummy1);
1864 }
1865 } else dummy = dummy1;
1866 // ... and check if it is the keyword!
1867 //fprintf(stderr,"name %p, dummy %i/%c, dummy1 %i/%c, strlen(name) %i\n", &name, dummy, *dummy, dummy1, *dummy1, strlen(name));
1868 if ((name == NULL) || (((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name)))) {
1869 found++; // found the parameter!
1870 //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy);
1871
1872 if (found == repetition) {
1873 for (i=0;i<xth;i++) { // i = rows
1874 if (type >= grid) {
1875 // grid structure means that grid starts on the next line, not right after keyword
1876 dummy1 = dummy = free_dummy;
1877 do {
1878 file->getline(dummy1, 256); // Read the whole line, skip commentary and empty ones
1879 if (file->eof()) {
1880 if ((critical) && (found == 0)) {
1881 Free(free_dummy);
1882 //Error(InitReading, name);
1883 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
1884 exit(255);
1885 } else {
1886 //if (!sequential)
1887 file->clear();
1888 file->seekg(file_position, ios::beg); // rewind to start position
1889 Free(free_dummy);
1890 return 0;
1891 }
1892 }
1893 line++;
1894 } while ((dummy1[0] == '#') || (dummy1[0] == '\n'));
1895 if (dummy1 == NULL){
1896 if (verbose) fprintf(stderr,"Error reading line %i\n", line);
1897 } else {
1898 //fprintf(stderr,"Reading next line %i: %s\n", line, dummy1);
1899 }
1900 } else { // simple int, strings or doubles start in the same line
1901 while ((*dummy == '\t') || (*dummy == ' ')) // skip interjacent tabs and spaces
1902 dummy++;
1903 }
1904 // C++ getline removes newline at end, thus re-add
1905 if ((dummy1 != NULL) && (strchr(dummy1,'\n') == NULL)) {
1906 j = strlen(dummy1);
1907 dummy1[j] = '\n';
1908 dummy1[j+1] = '\0';
1909 }
1910
1911 int start = (type >= grid) ? 0 : yth-1 ;
1912 for (j=start;j<yth;j++) { // j = columns
1913 // check for lower triangular area and upper triangular area
1914 if ( ((i > j) && (type == upper_trigrid)) || ((j > i) && (type == lower_trigrid))) {
1915 *((double *)value) = 0.0;
1916 fprintf(stderr,"%f\t",*((double *)value));
1917 value = (void *)((long)value + sizeof(double));
1918 //value += sizeof(double);
1919 } else {
1920 // otherwise we must skip all interjacent tabs and spaces and find next value
1921 dummy1 = dummy;
1922 dummy = strchr(dummy1, '\t'); // seek for tab or space
1923 if (dummy == NULL)
1924 dummy = strchr(dummy1, ' '); // if not found seek for space
1925 if (dummy == NULL) { // if still zero returned ...
1926 dummy = strchr(dummy1, '\n'); // ... at line end then
1927 if ((j < yth-1) && (type < 4)) { // check if xth value or not yet
1928 if (critical) {
1929 if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
1930 Free(free_dummy);
1931 //return 0;
1932 exit(255);
1933 //Error(FileOpenParams, NULL);
1934 } else {
1935 //if (!sequential)
1936 file->clear();
1937 file->seekg(file_position, ios::beg); // rewind to start position
1938 Free(free_dummy);
1939 return 0;
1940 }
1941 }
1942 } else {
1943 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)free_dummy);
1944 }
1945 if (*dummy1 == '#') {
1946 // found comment, skipping rest of line
1947 //if (verbose) fprintf(stderr,"Error: '#' at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
1948 if (!sequential) { // here we need it!
1949 file->seekg(file_position, ios::beg); // rewind to start position
1950 }
1951 Free(free_dummy);
1952 return 0;
1953 }
1954 //fprintf(stderr,"value from %i to %i\n",(char *)dummy1-(char *)free_dummy,(char *)dummy-(char *)free_dummy);
1955 switch(type) {
1956 case (row_int):
1957 *((int *)value) = atoi(dummy1);
1958 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
1959 if (verbose) fprintf(stderr,"%i\t",*((int *)value));
1960 value = (void *)((long)value + sizeof(int));
1961 //value += sizeof(int);
1962 break;
1963 case(row_double):
1964 case(grid):
1965 case(lower_trigrid):
1966 case(upper_trigrid):
1967 *((double *)value) = atof(dummy1);
1968 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
1969 if (verbose) fprintf(stderr,"%lg\t",*((double *)value));
1970 value = (void *)((long)value + sizeof(double));
1971 //value += sizeof(double);
1972 break;
1973 case(double_type):
1974 *((double *)value) = atof(dummy1);
1975 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %lg\n", name, *((double *) value));
1976 //value += sizeof(double);
1977 break;
1978 case(int_type):
1979 *((int *)value) = atoi(dummy1);
1980 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %i\n", name, *((int *) value));
1981 //value += sizeof(int);
1982 break;
1983 default:
1984 case(string_type):
1985 if (value != NULL) {
1986 //if (maxlength == -1) maxlength = strlen((char *)value); // get maximum size of string array
1987 maxlength = MAXSTRINGSIZE;
1988 length = maxlength > (dummy-dummy1) ? (dummy-dummy1) : maxlength; // cap at maximum
1989 strncpy((char *)value, dummy1, length); // copy as much
1990 ((char *)value)[length] = '\0'; // and set end marker
1991 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s is '%s' (%i chars)\n",name,((char *) value), length);
1992 //value += sizeof(char);
1993 } else {
1994 }
1995 break;
1996 }
1997 }
1998 while (*dummy == '\t')
1999 dummy++;
2000 }
2001 }
2002 }
2003 }
2004 }
2005 if ((type >= row_int) && (verbose))
2006 fprintf(stderr,"\n");
2007 Free(free_dummy);
2008 if (!sequential) {
2009 file->clear();
2010 file->seekg(file_position, ios::beg); // rewind to start position
2011 }
2012 //fprintf(stderr, "End of Parsing\n\n");
2013
2014 return (found); // true if found, false if not
2015}
2016
2017
2018/** Reads parameter from a parsed file.
2019 * The file is either parsed for a certain keyword or if null is given for
2020 * the value in row yth and column xth. If the keyword was necessity#critical,
2021 * then an error is thrown and the programme aborted.
2022 * \warning value is modified (both in contents and position)!
2023 * \param verbose 1 - print found value to stderr, 0 - don't
2024 * \param *FileBuffer pointer to buffer structure
2025 * \param name Name of value in file (at least 3 chars!)
2026 * \param sequential 1 - do not reset file pointer to begin of file, 0 - set to beginning
2027 * (if file is sequentially parsed this can be way faster! However, beware of multiple values per line, as whole line is read -
2028 * best approach: 0 0 0 1 (not resetted only on last value of line) - and of yth, which is now
2029 * counted from this unresetted position!)
2030 * \param xth Which among a number of parameters it is (in grid case it's row number as grid is read as a whole!)
2031 * \param yth In grid case specifying column number, otherwise the yth \a name matching line
2032 * \param type Type of the Parameter to be read
2033 * \param value address of the value to be read (must have been allocated)
2034 * \param repetition determines, if the keyword appears multiply in the config file, which repetition shall be parsed, i.e. 1 if not multiply
2035 * \param critical necessity of this keyword being specified (optional, critical)
2036 * \return 1 - found, 0 - not found
2037 * \note Routine is taken from the pcp project and hack-a-slack adapted to C++
2038 */
2039int 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) {
2040 int i = 0;
2041 int j = 0; // loop variables
2042 int length = 0;
2043 int maxlength = -1;
2044 int OldCurrentLine = FileBuffer->CurrentLine;
2045 char *dummy1 = NULL;
2046 char *dummy = NULL; // pointers in the line that is read in per step
2047
2048 //fprintf(stderr,"Parsing for %s\n",name);
2049 if (repetition == 0)
2050 //Error(SomeError, "ParseForParameter(): argument repetition must not be 0!");
2051 return 0;
2052
2053 int line = 0; // marks line where parameter was found
2054 int found = (type >= grid) ? 0 : (-yth + 1); // marks if yth parameter name was found
2055 while((found != repetition)) {
2056 dummy1 = dummy = NULL;
2057 do {
2058 dummy1 = FileBuffer->buffer[ FileBuffer->LineMapping[FileBuffer->CurrentLine++] ];
2059 if (FileBuffer->CurrentLine >= FileBuffer->NoLines) {
2060 if ((critical) && (found == 0)) {
2061 //Error(InitReading, name);
2062 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
2063 exit(255);
2064 } else {
2065 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
2066 return 0;
2067 }
2068 }
2069 if (dummy1 == NULL) {
2070 if (verbose) fprintf(stderr,"Error reading line %i\n",line);
2071 } else {
2072 //fprintf(stderr,"Now parsing the line %i: %s\n", line, dummy1);
2073 }
2074 line++;
2075 } while (dummy1 != NULL && ((dummy1[0] == '#') || (dummy1[0] == '\0'))); // skip commentary and empty lines
2076
2077 // Seek for possible end of keyword on line if given ...
2078 if (name != NULL) {
2079 dummy = strchr(dummy1,'\t'); // set dummy on first tab or space which ever's nearer
2080 if (dummy == NULL) {
2081 dummy = strchr(dummy1, ' '); // if not found seek for space
2082 while ((dummy != NULL) && ((*dummy == '\t') || (*dummy == ' '))) // skip some more tabs and spaces if necessary
2083 dummy++;
2084 }
2085 if (dummy == NULL) {
2086 dummy = strchr(dummy1, '\n'); // set on line end then (whole line = keyword)
2087 //fprintf(stderr,"Error: Cannot find tabs or spaces on line %i in search for %s\n", line, name);
2088 //Free(&free_dummy);
2089 //Error(FileOpenParams, NULL);
2090 } else {
2091 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)dummy1);
2092 }
2093 } else dummy = dummy1;
2094 // ... and check if it is the keyword!
2095 //fprintf(stderr,"name %p, dummy %i/%c, dummy1 %i/%c, strlen(name) %i\n", &name, dummy, *dummy, dummy1, *dummy1, strlen(name));
2096 if ((name == NULL) || (((dummy-dummy1 >= 3) && (strncmp(dummy1, name, strlen(name)) == 0)) && ((unsigned int)(dummy-dummy1) == strlen(name)))) {
2097 found++; // found the parameter!
2098 //fprintf(stderr,"found %s at line %i between %i and %i\n", name, line, dummy1, dummy);
2099
2100 if (found == repetition) {
2101 for (i=0;i<xth;i++) { // i = rows
2102 if (type >= grid) {
2103 // grid structure means that grid starts on the next line, not right after keyword
2104 dummy1 = dummy = NULL;
2105 do {
2106 dummy1 = FileBuffer->buffer[ FileBuffer->LineMapping[ FileBuffer->CurrentLine++] ];
2107 if (FileBuffer->CurrentLine >= FileBuffer->NoLines) {
2108 if ((critical) && (found == 0)) {
2109 //Error(InitReading, name);
2110 fprintf(stderr,"Error:InitReading, critical %s not found\n", name);
2111 exit(255);
2112 } else {
2113 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
2114 return 0;
2115 }
2116 }
2117 if (dummy1 == NULL) {
2118 if (verbose) fprintf(stderr,"Error reading line %i\n", line);
2119 } else {
2120 //fprintf(stderr,"Reading next line %i: %s\n", line, dummy1);
2121 }
2122 line++;
2123 } while (dummy1 != NULL && (dummy1[0] == '#') || (dummy1[0] == '\n'));
2124 dummy = dummy1;
2125 } else { // simple int, strings or doubles start in the same line
2126 while ((*dummy == '\t') || (*dummy == ' ')) // skip interjacent tabs and spaces
2127 dummy++;
2128 }
2129
2130 for (j=((type >= grid) ? 0 : yth-1);j<yth;j++) { // j = columns
2131 // check for lower triangular area and upper triangular area
2132 if ( ((i > j) && (type == upper_trigrid)) || ((j > i) && (type == lower_trigrid))) {
2133 *((double *)value) = 0.0;
2134 fprintf(stderr,"%f\t",*((double *)value));
2135 value = (void *)((long)value + sizeof(double));
2136 //value += sizeof(double);
2137 } else {
2138 // otherwise we must skip all interjacent tabs and spaces and find next value
2139 dummy1 = dummy;
2140 dummy = strchr(dummy1, '\t'); // seek for tab or space
2141 if (dummy == NULL)
2142 dummy = strchr(dummy1, ' '); // if not found seek for space
2143 if (dummy == NULL) { // if still zero returned ...
2144 dummy = strchr(dummy1, '\n'); // ... at line end then
2145 if ((j < yth-1) && (type < 4)) { // check if xth value or not yet
2146 if (critical) {
2147 if (verbose) fprintf(stderr,"Error: EoL at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
2148 //return 0;
2149 exit(255);
2150 //Error(FileOpenParams, NULL);
2151 } else {
2152 if (!sequential) { // here we need it!
2153 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
2154 }
2155 return 0;
2156 }
2157 }
2158 } else {
2159 //fprintf(stderr,"found tab at %i\n",(char *)dummy-(char *)free_dummy);
2160 }
2161 if (*dummy1 == '#') {
2162 // found comment, skipping rest of line
2163 //if (verbose) fprintf(stderr,"Error: '#' at %i and still missing %i value(s) for parameter %s\n", line, yth-j, name);
2164 if (!sequential) { // here we need it!
2165 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
2166 }
2167 return 0;
2168 }
2169 //fprintf(stderr,"value from %i to %i\n",(char *)dummy1-(char *)free_dummy,(char *)dummy-(char *)free_dummy);
2170 switch(type) {
2171 case (row_int):
2172 *((int *)value) = atoi(dummy1);
2173 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
2174 if (verbose) fprintf(stderr,"%i\t",*((int *)value));
2175 value = (void *)((long)value + sizeof(int));
2176 //value += sizeof(int);
2177 break;
2178 case(row_double):
2179 case(grid):
2180 case(lower_trigrid):
2181 case(upper_trigrid):
2182 *((double *)value) = atof(dummy1);
2183 if ((verbose) && (i==0) && (j==0)) fprintf(stderr,"%s = ", name);
2184 if (verbose) fprintf(stderr,"%lg\t",*((double *)value));
2185 value = (void *)((long)value + sizeof(double));
2186 //value += sizeof(double);
2187 break;
2188 case(double_type):
2189 *((double *)value) = atof(dummy1);
2190 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %lg\n", name, *((double *) value));
2191 //value += sizeof(double);
2192 break;
2193 case(int_type):
2194 *((int *)value) = atoi(dummy1);
2195 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s = %i\n", name, *((int *) value));
2196 //value += sizeof(int);
2197 break;
2198 default:
2199 case(string_type):
2200 if (value != NULL) {
2201 //if (maxlength == -1) maxlength = strlen((char *)value); // get maximum size of string array
2202 maxlength = MAXSTRINGSIZE;
2203 length = maxlength > (dummy-dummy1) ? (dummy-dummy1) : maxlength; // cap at maximum
2204 strncpy((char *)value, dummy1, length); // copy as much
2205 ((char *)value)[length] = '\0'; // and set end marker
2206 if ((verbose) && (i == xth-1)) fprintf(stderr,"%s is '%s' (%i chars)\n",name,((char *) value), length);
2207 //value += sizeof(char);
2208 } else {
2209 }
2210 break;
2211 }
2212 }
2213 while (*dummy == '\t')
2214 dummy++;
2215 }
2216 }
2217 }
2218 }
2219 }
2220 if ((type >= row_int) && (verbose)) fprintf(stderr,"\n");
2221 if (!sequential) {
2222 FileBuffer->CurrentLine = OldCurrentLine; // rewind to start position
2223 }
2224 //fprintf(stderr, "End of Parsing\n\n");
2225
2226 return (found); // true if found, false if not
2227}
Note: See TracBrowser for help on using the repository browser.