source: src/config.cpp@ b9947d

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

Added config::SavePDB() and config::SaveMPQC().

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