source: src/config.cpp@ cd5047

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

Merge commit 'jupiter/MoleculeStartEndSwitch' into CommandLineActionMapping

Conflicts:

molecuilder/src/Makefile.am
molecuilder/src/builder.cpp
molecuilder/src/config.cpp
molecuilder/src/helpers.hpp
molecuilder/src/molecule.cpp
molecuilder/src/molecule_dynamics.cpp
molecuilder/src/molecule_fragmentation.cpp
molecuilder/src/molecule_geometry.cpp
molecuilder/src/molecule_graph.cpp
molecuilder/src/moleculelist.cpp
molecuilder/src/unittests/AnalysisCorrelationToPointUnitTest.cpp
molecuilder/src/unittests/listofbondsunittest.cpp

Integration of MoleculeStartEndSwitch had the following consequences:

  • no more AtomCount -> getAtomCount()
  • no more start/end -> begin(), end() and iterator
  • no more decent ordering in atomic ids (hence, Simple_configuration/8 and Domain/5, Domain/6 now check by comparing sorted xyz, not confs)

There is still a huge problem with bonds. One test runs into an endless loop.

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

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