source: src/Parser/MpqcParser.cpp@ 87d6bd

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 87d6bd was 30f2815, checked in by Frederik Heber <heber@…>, 12 years ago

MpqcParser now also understands "_n_ atoms geometry" lines.

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