source: src/config.cpp@ a7b761b

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 a7b761b was a7b761b, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Merge branch 'MoleculeStartEndSwitch' into StructureRefactoring

Conflicts:

molecuilder/src/Helpers/Assert.cpp
molecuilder/src/Helpers/Assert.hpp
molecuilder/src/Legacy/oldmenu.cpp
molecuilder/src/Makefile.am
molecuilder/src/Patterns/Cacheable.hpp
molecuilder/src/Patterns/Observer.cpp
molecuilder/src/Patterns/Observer.hpp
molecuilder/src/analysis_correlation.cpp
molecuilder/src/boundary.cpp
molecuilder/src/builder.cpp
molecuilder/src/config.cpp
molecuilder/src/helpers.hpp
molecuilder/src/molecule.cpp
molecuilder/src/molecule.hpp
molecuilder/src/molecule_dynamics.cpp
molecuilder/src/molecule_fragmentation.cpp
molecuilder/src/molecule_geometry.cpp
molecuilder/src/molecule_graph.cpp
molecuilder/src/moleculelist.cpp
molecuilder/src/tesselation.cpp
molecuilder/src/unittests/AnalysisCorrelationToSurfaceUnitTest.cpp
molecuilder/src/unittests/ObserverTest.cpp
molecuilder/src/unittests/ObserverTest.hpp

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