source: src/config.cpp@ ce4487

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

FIX: Atoms were stored not in the sequence they were loaded.

  1. The main problem is molecule::atomSet which is a set<atom *>, i.e. atoms are sorted by their appearance in memory. As memory need not be allocated sequentially, this gives rise to extreme arbitririty which is not desired. Instead the atoms should be stored in the sequence they were loaded/created. The solution is as follows:
  • config::SaveAll()
  • molecule::atomSet is now a list<atom *>
  • molecule::atomIds is a new set<atomId_t> (atomIdSet) which controls that (global) ids remain unique in the no more Atomset's set (but list)
  • molecule::erase() erases also in atomIds
  • molecule::insert() checks whether id is present by atomIds
  • molecule::find() as std::list does not have a find, we just go through the list until the object is found (or not), this may be speeded up by another internal list.
  • molecule::InternalPointer made lots of confusion as virtual function GoToFirst() is const, hence begin() (needed therein) returns const_iterator, which then cannot be simply re-cast into an iterator: We make it a pointer, reinterpret_cast the pointer and reference it back. Although InternalPointer is mutable, the compiler cannot use the non-const function begin() (it cannot be made const, as overloading is not allowed). (this is noted in the code also extensively.)
  • molecule::containsAtom() does not use count but the new find, as it returns only boolean anyway.
  • rewrote MoleculeListClass::SimpleMerge() to get rid of the extra iterator, as we remove all atoms in the end anyway.
  • FIX: MoleculeListClass::SimpleMultiMerge() - the created mol was not inserted into the moleculelist in the end, although it is the only one to remain.
  1. All other databases had missing headers with respect to those stored in elements_db.cpp. Hence, valence of hydrogen was not parsed and this caused several failures in CalculateOrbitals() (Psi numbers and MaxMinSetp in pcp conf file).
  1. Subsequenytly, various test cases (12, 21, 30, 31, 36-38, 39) were broken. This had two reasons:
  • Seemingly, CalculateOrbitals() was broken before hence MaxMinStep (pcp config) and MaxPsiDouble/PsiMaxNn[Up|Down] were always 0. (10-21,30-31,39)
  • As the order is now correct, fixes from commits c9217161ec2a5d5db508557fe98a32068461f45b and 22a6da8380911571debebd69444d2615450bbbd8 were obselete and have been reverted (order of the Ion?_Type...): Molecules/6 (30), Molecules/7 (31), Filling/1 (39)
  • Due to different ordering, Tesselation/3 (38) had completely different .dat file (though same tesselation)
  • r3d had small differences, mostly order or epsilon (0 not being 0 but ..-e16), hence diffing was deactivated, as r3d is deprecated anyway (since vmd can render triangles as well and better).

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

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