source: src/config.cpp@ 42af9e

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 Candidate_v1.7.0 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 42af9e was 42af9e, checked in by Frederik Heber <heber@…>, 15 years ago

MEMFIXES: no more default saving/loading of element's db, config::SaveTREMOLO(), molecule::CreateMappingLabelsToConfigSequence()

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