source: src/config.cpp@ 436f04

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 436f04 was 35b698, checked in by Frederik Heber <heber@…>, 15 years ago

BIG CHANGE: config::load and config::save in ParseCommandLineOptions() and main() replaced with FormatParser replacements.

Fragmentation:

  • FIX: MoleculeFillWithMoleculeAction: filler atoms have to be removed before the system can be stored to file.
  • FIX: PcpParser::load() - has to put the molecule also into World's MoleculeListClass (otherwise the name cannot be set right after loading)
  • new Libparser.a
  • all sources from PARSER subdir are compiled into libparser such that only ParserUnitTest is recompiled.

Testfixes:

  • testsuite-fragmentation - changes to due to different -f calling syntax.
  • most of the xyz files had to be replaced due to a single whitespace at the end of each entry: Domain/6, Simple_configuration/2, Simple_configuration/3, Simple_configuration/4, Simple_configuration/5, Simple_configuration/8
  • in many cases were the number orbitals (and thus MaxMinStopStep) wrong: Filling/1, Simple_configuration/4, Simple_configuration/5

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

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