source: src/config.cpp@ 492279

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 492279 was 112b09, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Added #include "Helpers/MemDebug.hpp" to all .cpp files

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