source: src/config.cpp@ 920c70

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

Removed all Malloc/Calloc/ReAlloc (&Free) and replaced by new and delete/delete[].

Due to the new MemDebug framework there is no need (or even unnecessary/unwanted competition between it and) for the MemoryAllocator and ..UsageObserver anymore.
They can however still be used with c codes such as pcp and alikes.

In Molecuilder lots of glibc corruptions arose and the C-like syntax make it generally harder to get allocation and deallocation straight.

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

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