source: src/config.cpp@ 5f612ee

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

Merge branch 'Analysis_PairCorrelation' into StructureRefactoring

Conflicts:

molecuilder/src/Makefile.am
molecuilder/src/World.cpp
molecuilder/src/World.hpp
molecuilder/src/boundary.cpp
molecuilder/src/builder.cpp
molecuilder/src/log.cpp
molecuilder/src/moleculelist.cpp
molecuilder/src/periodentafel.cpp
molecuilder/src/tesselation.cpp
molecuilder/src/unittests/AnalysisCorrelationToSurfaceUnitTest.cpp
molecuilder/src/unittests/Makefile.am
molecuilder/src/unittests/bondgraphunittest.cpp
molecuilder/src/unittests/gslvectorunittest.cpp
molecuilder/src/unittests/logunittest.cpp
molecuilder/src/unittests/tesselation_boundarytriangleunittest.hpp
molecuilder/src/vector.cpp
molecuilder/tests/Tesselations/defs.in

Conflicts have been many and too numerous to listen here, just the few general cases

  • new molecule() replaced by World::getInstance().createMolecule()
  • new atom() replaced by World::getInstance().createAtom() where appropriate.
  • Some DoLog()s added interfered with changes to the message produced by Log() << Verbose(.) << ...
  • DoLog() has been erroneously added to TestRunner.cpp as well, there cout is appropriate
  • ...

Additionally, there was a bug in atom::clone(), sort was set to atom::nr of the atom to clone not of the clone itself. This caused a failure of the fragmentation.

This merge has been fully checked from a clean build directory with subsequent configure,make all install and make check.
It configures, compiles and runs all test cases and the test suite without errors.

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

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