source: src/config.cpp@ b8c9d8

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

Huge change: Log() << Verbose(.) --> DoLog(.) && (Log() << Verbose(.) << ...);

Most of the files are affected, but this is necessary as if DoLog() says verbosity is not enough, all the stream operators won"t get executed which saves substantial amount of computation time.

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

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