source: src/Parser/MpqcParser.cpp@ df5b8c

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 df5b8c was e3c4c5, checked in by Frederik Heber <heber@…>, 9 years ago

MpqcParser additionally allows to save optimization jobs.

  • this is enabled via a new flag "jobtype" that can be either Default or Optimization.
  • also storing "checkpoint = no" per default for all mpqc input files. This is a safety measures such that no old checkpoint files are used that reside in the same folder accidentally. This is especially important for fragment files.
  • TESTFIX: changed all regression tests comparing against .in files, added new checkpoint statement.
  • TESTFIX: changed unit test ParserMpqcUnitTest in the same manner.
  • Property mode set to 100644
File size: 18.2 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
6 *
7 *
8 * This file is part of MoleCuilder.
9 *
10 * MoleCuilder is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * MoleCuilder is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24/*
25 * MpqcParser.cpp
26 *
27 * Created on: 12.06.2010
28 * Author: heber
29 */
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include <iomanip>
37#include <iostream>
38#include <boost/foreach.hpp>
39#include <boost/tokenizer.hpp>
40#include <sstream>
41#include <string>
42
43#include "CodePatterns/MemDebug.hpp"
44
45#include "MpqcParser.hpp"
46#include "MpqcParser_Parameters.hpp"
47
48#include "Atom/atom.hpp"
49#include "CodePatterns/Log.hpp"
50#include "CodePatterns/toString.hpp"
51#include "config.hpp"
52#include "Element/element.hpp"
53#include "Element/periodentafel.hpp"
54#include "LinearAlgebra/Vector.hpp"
55#include "molecule.hpp"
56#include "MoleculeListClass.hpp"
57#include "Parser/Exceptions.hpp"
58#include "World.hpp"
59
60// declare specialized static variables
61const std::string FormatParserTrait<mpqc>::name = "mpqc";
62const std::string FormatParserTrait<mpqc>::suffix = "in";
63const ParserTypes FormatParserTrait<mpqc>::type = mpqc;
64
65// a converter we often need
66ConvertTo<bool> FormatParser<mpqc>::Converter;
67
68/** Constructor of MpqcParser.
69 *
70 */
71FormatParser< mpqc >::FormatParser() :
72 FormatParser_common(new MpqcParser_Parameters())
73{}
74
75/** Destructor of MpqcParser.
76 *
77 */
78FormatParser< mpqc >::~FormatParser()
79{}
80
81/** Load an MPQC config file into the World.
82 * \param *file input stream
83 */
84void FormatParser< mpqc >::load(istream *file)
85{
86 bool MpqcSection = false;
87 bool MoleculeSection = false;
88 bool GeometrySection = false;
89 bool GeometrySection_n = false;
90 bool BasisSection = false;
91 bool AuxBasisSection = false;
92 char line[MAXSTRINGSIZE];
93 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
94 boost::char_separator<char> sep("[]");
95 boost::char_separator<char> angularsep("<>");
96 boost::char_separator<char> equalitysep(" =");
97 boost::char_separator<char> whitesep(" \t");
98 ConvertTo<double> toDouble;
99 int old_n = -1; // note down the last parsed "n" to ascertain it's ascending
100
101 molecule *newmol = World::getInstance().createMolecule();
102 newmol->ActiveFlag = true;
103 // TODO: Remove the insertion into molecule when saving does not depend on them anymore. Also, remove molecule.hpp include
104 World::getInstance().getMolecules()->insert(newmol);
105 while (file->good()) {
106 file->getline(line, MAXSTRINGSIZE-1);
107 std::string linestring(line);
108 if (((linestring.find("atoms") == string::npos)
109 || (linestring.find("geometry") == string::npos))
110 && (linestring.find("}") != string::npos)) {
111 GeometrySection = false;
112 }
113 if ((linestring.find(")") != string::npos)) { // ends a section which do not overlap
114 MpqcSection = false;
115 MoleculeSection = false;
116 BasisSection = false;
117 AuxBasisSection = false;
118 }
119 if (MoleculeSection) {
120 if (GeometrySection) { // we have an atom
121// LOG(2, "DEBUG: Full line is '" << linestring << "'.");
122 // separate off [..] part
123 tokenizer tokens(linestring, sep);
124 // split part prior to [..] into tokens
125 std::string prior_part(*tokens.begin());
126 tokenizer prefixtokens(prior_part, whitesep);
127 tokenizer::iterator tok_iter = prefixtokens.begin();
128// LOG(2, "DEBUG: Current tok_iter is " << *tok_iter << ".");
129 if (GeometrySection_n) {
130 ASSERT(tok_iter != prefixtokens.end(),
131 "FormatParser< mpqc >::load() - missing n entry for MoleculeSection in line "
132 +linestring+"!");
133 // if additional n is given, parse and check but discard eventually
134 int n;
135 std::stringstream whitespacefilter(*tok_iter++);
136 whitespacefilter >> ws >> n;
137 if ((old_n != -1) && ((n-1) != old_n))
138 ELOG(2, "n index is not simply ascending by one but "
139 << n-old_n << ", specific ids are lost!");
140 if (old_n >= n) {
141 ELOG(1, "n index is not simply ascending, coordinates might get mixed!");
142 throw ParserException();
143 }
144 old_n = n;
145 }
146 ASSERT(tok_iter != prefixtokens.end(),
147 "FormatParser< mpqc >::load() - missing atoms entry for MoleculeSection in line "
148 +linestring+"!");
149// LOG(2, "DEBUG: Current tok_iter is " << *tok_iter << ".");
150 std::string element;
151 {
152 std::stringstream whitespacefilter(*tok_iter++);
153 whitespacefilter >> ws >> element;
154 }
155 // split [..] part and parse
156 tok_iter = (++tokens.begin());
157 ASSERT (tok_iter != tokens.end(),
158 "FormatParser< mpqc >::load() - missing geometry entry for MoleculeSection in line "
159 +linestring+"!");
160// LOG(2, "DEBUG: Current tok_iter is " << *tok_iter << ".");
161 std::string vector(*tok_iter);
162 tokenizer vectorcomponents(vector, whitesep);
163 Vector X;
164// if (vectorcomponents.size() != NDIM)
165// throw ParserException();
166 tok_iter = vectorcomponents.begin();
167 for (int i=0; i<NDIM; ++i) {
168// LOG(2, "DEBUG: Current tok_iter is " << *tok_iter << ".");
169 X[i] = toDouble(*tok_iter++);
170 }
171 // create atom
172 atom *newAtom = World::getInstance().createAtom();
173 newAtom->setType(World::getInstance().getPeriode()->FindElement(element));
174 newAtom->setPosition(X);
175 newmol->AddAtom(newAtom);
176 LOG(1, "Adding atom " << *newAtom);
177 }
178 }
179 if (MpqcSection) {
180 if (linestring.find("mole<") != string::npos) { // get theory
181 tokenizer tokens(linestring, angularsep);
182 tokenizer::iterator tok_iter = tokens.begin();
183 ++tok_iter;
184 ASSERT(tok_iter != tokens.end(),
185 "FormatParser< mpqc >::load() - missing token in brackets<> for mole< in line "+linestring+"!");
186 std::string value(*tok_iter);
187 std::stringstream linestream("theory = "+value);
188 linestream >> getParams();
189 } else if (linestring.find("integrals<") != string::npos) { // get theory
190 tokenizer tokens(linestring, angularsep);
191 tokenizer::iterator tok_iter = tokens.begin();
192 ++tok_iter;
193 ASSERT(tok_iter != tokens.end(),
194 "FormatParser< mpqc >::load() - missing token in brackets<> for integrals< in line "+linestring+"!");
195 std::string value(*tok_iter);
196 std::stringstream linestream("integration = "+value);
197 linestream >> getParams();
198 } else if ((linestring.find("molecule") == string::npos) && (linestring.find("basis") == string::npos)){
199 // molecule and basis must not be parsed in this section
200 tokenizer tokens(linestring, equalitysep);
201 tokenizer::iterator tok_iter = tokens.begin();
202 ASSERT(tok_iter != tokens.end(),
203 "FormatParser< mpqc >::load() - missing token before '=' for MpqcSection in line "+linestring+"!");
204 std::stringstream whitespacefilter(*tok_iter);
205 std::string key;
206 whitespacefilter >> ws >> key;
207 if (getParams().haveParameter(key)) {
208 std::stringstream linestream(linestring);
209 linestream >> getParams();
210 } else { // unknown keys are simply ignored as long as parser is incomplete
211 LOG(2, "INFO: '"+key+"' is unknown and ignored.");
212 }
213 }
214 }
215 if (BasisSection) {
216 tokenizer tokens(linestring, equalitysep);
217 tokenizer::iterator tok_iter = tokens.begin();
218 ASSERT(tok_iter != tokens.end(),
219 "FormatParser< mpqc >::load() - missing token for BasisSection in line "+linestring+"!");
220 std::string key(*tok_iter++);
221 ASSERT(tok_iter != tokens.end(),
222 "FormatParser< mpqc >::load() - missing value for BasisSection after key "+key+" in line "+linestring+"!");
223 std::string value(*tok_iter);
224 tok_iter++;
225 // TODO: use exception instead of ASSERT
226 ASSERT(tok_iter == tokens.end(),
227 "FormatParser< mpqc >::load() - more than (key = value) on line "+linestring+".");
228 if (key == "name") {
229 std::stringstream linestream("basis = "+value);
230 linestream >> getParams();
231 }
232 }
233 if (AuxBasisSection) {
234 tokenizer tokens(linestring, equalitysep);
235 tokenizer::iterator tok_iter = tokens.begin();
236 ASSERT(tok_iter != tokens.end(),
237 "FormatParser< mpqc >::load() - missing token for AuxBasisSection in line "+linestring+"!");
238 std::string key(*tok_iter++);
239 ASSERT(tok_iter != tokens.end(),
240 "FormatParser< mpqc >::load() - missing value for BasisSection after key "+key+" in line "+linestring+"!");
241 std::string value(*tok_iter);
242 tok_iter++;
243 // TODO: use exception instead of ASSERT
244 ASSERT(tok_iter == tokens.end(),
245 "FormatParser< mpqc >::load() - more than (key = value) on line "+linestring+".");
246 if (key == "name") {
247 std::stringstream linestream("aux_basis = "+value);
248 linestream >> getParams();
249 }
250 }
251 // set some scan flags
252 if (linestring.find("mpqc:") != string::npos) {
253 MpqcSection = true;
254 }
255 if (linestring.find("molecule<Molecule>:") != string::npos) {
256 MoleculeSection = true;
257 }
258 if ((linestring.find("atoms") != string::npos)
259 && (linestring.find("geometry") != string::npos)) {
260 GeometrySection = true;
261 if (linestring.find("n") != string::npos) // neither atoms nor geometry contains a letter n
262 GeometrySection_n = true;
263 }
264 if ((linestring.find("basis<GaussianBasisSet>:") != string::npos) && ((linestring.find("abasis<") == string::npos))) {
265 BasisSection = true;
266 }
267 if (linestring.find("abasis<") != string::npos) {
268 AuxBasisSection = true;
269 }
270 }
271 // refresh atom::nr and atom::name
272 newmol->getAtomCount();
273}
274
275void FormatParser< mpqc >::OutputMPQCLine(ostream * const out, const atom &_atom, const Vector *center) const
276{
277 Vector recentered(_atom.getPosition());
278 recentered -= *center;
279 *out << "\t\t" << _atom.getType()->getSymbol() << " [ ";
280 {
281 std::stringstream posstream;
282 posstream << std::setprecision(12) << recentered[0] << "\t" << recentered[1] << "\t" << recentered[2];
283 *out << posstream.str();
284 }
285 *out << " ]" << std::endl;
286};
287
288
289/** Saves all atoms and data into a MPQC config file.
290 * \param *file output stream
291 * \param atoms atoms to store
292 */
293void FormatParser< mpqc >::save(ostream *file, const std::vector<const atom *> &atoms)
294{
295 Vector center;
296// vector<const atom *> allatoms = const_cast<const World &>(World::getInstance()).
297// getAllAtoms();
298
299 // calculate center
300// for (std::vector<const atom *>::const_iterator runner = atoms.begin();runner != atoms.end(); ++runner)
301// center += (*runner)->getPosition();
302// center.Scale(1./(double)atoms.size());
303 center.Zero();
304
305 // first without hessian
306 if (file->fail()) {
307 ELOG(1, "Cannot open mpqc output file.");
308 } else {
309 *file << "% Created by MoleCuilder" << endl;
310 *file << "mpqc: (" << endl;
311 *file << "\tcheckpoint = no" << endl;
312 *file << "\tsavestate = " << getParams().getParameter(MpqcParser_Parameters::savestateParam) << endl;
313 *file << "\tdo_gradient = " << getParams().getParameter(MpqcParser_Parameters::do_gradientParam) << endl;
314 if (Converter(getParams().getParameter(MpqcParser_Parameters::hessianParam))) {
315 *file << "\tfreq<MolecularFrequencies>: (" << endl;
316 *file << "\t\tmolecule=$:molecule" << endl;
317 *file << "\t)" << endl;
318 }
319 const std::string theory = getParams().getParameter(MpqcParser_Parameters::theoryParam);
320 if (theory == getParams().getTheoryName(MpqcParser_Parameters::CLHF)) {
321 *file << "\tmole<" << getParams().getParameter(MpqcParser_Parameters::theoryParam) << ">: (" << endl;
322 *file << "\t\tmolecule = $:molecule" << endl;
323 *file << "\t\t" << getParams().getParameterName(MpqcParser_Parameters::basisParam) << " = $:basis" << endl;
324 *file << "\t\t" << getParams().getParameterName(MpqcParser_Parameters::maxiterParam)
325 << " = " << getParams().getParameter(MpqcParser_Parameters::maxiterParam)<< endl;
326 *file << "\t\t" << getParams().getParameterName(MpqcParser_Parameters::memoryParam)
327 << " = " << getParams().getParameter(MpqcParser_Parameters::memoryParam) << endl;
328 *file << "\t)" << endl;
329 } else if (theory == getParams().getTheoryName(MpqcParser_Parameters::CLKS)) {
330 *file << "\tmole<" << getParams().getParameter(MpqcParser_Parameters::theoryParam) << ">: (" << endl;
331 *file << "\t\tfunctional<StdDenFunctional>:(name=B3LYP)" << endl;
332 *file << "\t\tmolecule = $:molecule" << endl;
333 *file << "\t\t" << getParams().getParameterName(MpqcParser_Parameters::basisParam) << " = $:basis" << endl;
334 *file << "\t\t" << getParams().getParameterName(MpqcParser_Parameters::maxiterParam)
335 << " = " << getParams().getParameter(MpqcParser_Parameters::maxiterParam)<< endl;
336 *file << "\t\t" << getParams().getParameterName(MpqcParser_Parameters::memoryParam)
337 << " = " << getParams().getParameter(MpqcParser_Parameters::memoryParam) << endl;
338 *file << "\t)" << endl;
339 } else if (theory == getParams().getTheoryName(MpqcParser_Parameters::MBPT2)) {
340 *file << "\tmole<" << getParams().getParameter(MpqcParser_Parameters::theoryParam) << ">: (" << endl;
341 *file << "\t\t" << getParams().getParameterName(MpqcParser_Parameters::basisParam) << " = $:basis" << endl;
342 *file << "\t\tmolecule = $:molecule" << endl;
343 *file << "\t\t" << getParams().getParameterName(MpqcParser_Parameters::memoryParam)
344 << " = " << getParams().getParameter(MpqcParser_Parameters::memoryParam) << endl;
345 *file << "\t\treference<CLHF>: (" << endl;
346 *file << "\t\t\t" << getParams().getParameterName(MpqcParser_Parameters::maxiterParam)
347 << " = " << getParams().getParameter(MpqcParser_Parameters::maxiterParam)<< endl;
348 *file << "\t\t\t" << getParams().getParameterName(MpqcParser_Parameters::basisParam) << " = $:basis" << endl;
349 *file << "\t\t\tmolecule = $:molecule" << endl;
350 *file << "\t\t\t" << getParams().getParameterName(MpqcParser_Parameters::memoryParam)
351 << " = " << getParams().getParameter(MpqcParser_Parameters::memoryParam) << endl;
352 *file << "\t\t)" << endl;
353 *file << "\t)" << endl;
354 } else if (theory == getParams().getTheoryName(MpqcParser_Parameters::MBPT2_R12)) {
355 *file << "\tmole<" << getParams().getParameter(MpqcParser_Parameters::theoryParam) << ">: (" << endl;
356 *file << "\t\tmolecule = $:molecule" << endl;
357 *file << "\t\t" << getParams().getParameterName(MpqcParser_Parameters::basisParam) << " = $:basis" << endl;
358 *file << "\t\t" << getParams().getParameterName(MpqcParser_Parameters::aux_basisParam) << " = $:abasis" << endl;
359 *file << "\t\t" << getParams().getParameterName(MpqcParser_Parameters::stdapproxParam)
360 << " = \"" << getParams().getParameter(MpqcParser_Parameters::stdapproxParam) << "\"" << endl;
361 *file << "\t\t" << getParams().getParameterName(MpqcParser_Parameters::nfzcParam)
362 << " = " << getParams().getParameter(MpqcParser_Parameters::nfzcParam) << endl;
363 *file << "\t\t" << getParams().getParameterName(MpqcParser_Parameters::memoryParam)
364 << " = " << getParams().getParameter(MpqcParser_Parameters::memoryParam) << endl;
365 *file << "\t\tintegrals<IntegralCints>:()" << endl;
366 *file << "\t\treference<CLHF>: (" << endl;
367 *file << "\t\t\tmolecule = $:molecule" << endl;
368 *file << "\t\t\t" << getParams().getParameterName(MpqcParser_Parameters::basisParam) << " = $:basis" << endl;
369 *file << "\t\t\tmaxiter = " << getParams().getParameter(MpqcParser_Parameters::maxiterParam) << endl;
370 *file << "\t\t\tmemory = " << getParams().getParameter(MpqcParser_Parameters::memoryParam) << endl;
371 *file << "\t\t\tintegrals<" << getParams().getParameter(MpqcParser_Parameters::integrationParam) << ">:()" << endl;
372 *file << "\t\t)" << endl;
373 *file << "\t)" << endl;
374 } else {
375 ELOG(0, "Unknown level of theory requested for MPQC output file.");
376 }
377 const std::string jobtype = getParams().getParameter(MpqcParser_Parameters::jobtypeParam);
378 if (jobtype == getParams().getJobtypeName(MpqcParser_Parameters::Optimization)) {
379 *file << "\t% optimizer object for the molecular geometry" << endl;
380 *file << "\topt<QNewtonOpt>: (" << endl;
381 *file << "\t\tfunction = $..:mole" << endl;
382 *file << "\t\tupdate<BFGSUpdate>: ()" << endl;
383 *file << "\t\tconvergence<MolEnergyConvergence>: (" << endl;
384 *file << "\t\t\tcartesian = yes" << endl;
385 *file << "\t\t\tenergy = $..:..:mole" << endl;
386 *file << "\t\t)" << endl;
387 *file << "\t)" << endl;
388 }
389 *file << ")" << endl;
390 *file << "molecule<Molecule>: (" << endl;
391 *file << "\tunit = " << (World::getInstance().getConfig()->GetIsAngstroem() ? "angstrom" : "bohr" ) << endl;
392 *file << "\t{ atoms geometry } = {" << endl;
393 // output of atoms
394 BOOST_FOREACH(const atom *_atom, atoms) {
395 OutputMPQCLine(file, *_atom, &center);
396 }
397 *file << "\t}" << endl;
398 *file << ")" << endl;
399 *file << "basis<GaussianBasisSet>: (" << endl;
400 *file << "\tname = \"" << getParams().getParameter(MpqcParser_Parameters::basisParam) << "\"" << endl;
401 *file << "\tmolecule = $:molecule" << endl;
402 *file << ")" << endl;
403 if (theory == getParams().getTheoryName(MpqcParser_Parameters::MBPT2_R12)) {
404 *file << "% auxiliary basis set specification" << endl;
405 *file << "\tabasis<GaussianBasisSet>: (" << endl;
406 *file << "\tname = \"" << getParams().getParameter(MpqcParser_Parameters::aux_basisParam) << "\"" << endl;
407 *file << "\tmolecule = $:molecule" << endl;
408 *file << ")" << endl;
409 }
410 }
411}
412
413
Note: See TracBrowser for help on using the repository browser.