source: src/Parser/MpqcParser.cpp@ 54b42e

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 54b42e was 311da7b, checked in by Frederik Heber <heber@…>, 14 years ago

FIX: Changed MpqcParser.

  • some ASSERTs were missing and showed up failure in parsings.
  • in MpqcSection keywords molecule and basis are now ignored.
  • BUGFIX: due to missing whitespacefilter most of the keys were actually not really parsed which lead to strange "A'" and ""A'"" behavior, because in unit test key was without whitespace, hence recognized (and there we switch theories from CLHF parsed file only), whereas in regression test key was not recognized.
  • TESTFIX: ParserMpqcUnitTest - now checks whether MpqcParser_Parameters:: getInt() throws and also if ::operator>> throws in case of debugging.
  • Property mode set to 100644
File size: 12.8 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * MpqcParser.cpp
10 *
11 * Created on: 12.06.2010
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include <iostream>
21#include <boost/tokenizer.hpp>
22#include <string>
23
24#include "CodePatterns/MemDebug.hpp"
25
26#include "MpqcParser.hpp"
27
28#include "atom.hpp"
29#include "config.hpp"
30#include "element.hpp"
31#include "molecule.hpp"
32#include "CodePatterns/Log.hpp"
33#include "CodePatterns/toString.hpp"
34#include "CodePatterns/Verbose.hpp"
35#include "LinearAlgebra/Vector.hpp"
36#include "periodentafel.hpp"
37#include "World.hpp"
38
39
40/** Constructor of MpqcParser.
41 *
42 */
43MpqcParser::MpqcParser()
44{}
45
46/** Destructor of MpqcParser.
47 *
48 */
49MpqcParser::~MpqcParser()
50{}
51
52/** Load an MPQC config file into the World.
53 * \param *file input stream
54 */
55void MpqcParser::load(istream *file)
56{
57 bool MpqcSection = false;
58 bool MoleculeSection = false;
59 bool GeometrySection = false;
60 bool BasisSection = false;
61 bool AuxBasisSection = false;
62 char line[MAXSTRINGSIZE];
63 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
64 boost::char_separator<char> sep("[]");
65 boost::char_separator<char> angularsep("<>");
66 boost::char_separator<char> equalitysep(" =");
67 boost::char_separator<char> whitesep(" \t");
68 ConvertTo<double> toDouble;
69
70 molecule *newmol = World::getInstance().createMolecule();
71 newmol->ActiveFlag = true;
72 // TODO: Remove the insertion into molecule when saving does not depend on them anymore. Also, remove molecule.hpp include
73 World::getInstance().getMolecules()->insert(newmol);
74 while (file->good()) {
75 file->getline(line, MAXSTRINGSIZE-1);
76 std::string linestring(line);
77 if ((linestring.find("atoms geometry") == string::npos) && (linestring.find("}") != string::npos)) {
78 GeometrySection = false;
79 }
80 if ((linestring.find(")") != string::npos)) { // ends a section which do not overlap
81 MpqcSection = false;
82 MoleculeSection = false;
83 BasisSection = false;
84 AuxBasisSection = false;
85 }
86 if (MoleculeSection) {
87 if (GeometrySection) { // we have an atom
88 tokenizer tokens(linestring, sep);
89 // if (tokens.size() != 2)
90 // throw MpqcParseException;
91 tokenizer::iterator tok_iter = tokens.begin();
92 ASSERT(tok_iter != tokens.end(),
93 "MpqcParser::load() - missing token for MoleculeSection in line "+linestring+"!");
94 std::stringstream whitespacefilter(*tok_iter++);
95 std::string element;
96 whitespacefilter >> ws >> element;
97 ASSERT(tok_iter != tokens.end(),
98 "MpqcParser::load() - missing token for MoleculeSection in line "+linestring+"!");
99 std::string vector = *tok_iter;
100 tokenizer vectorcomponents(vector, whitesep);
101 Vector X;
102 // if (vectorcomponents.size() != NDIM)
103 // throw MpqcParseException;
104 tok_iter = vectorcomponents.begin();
105 for (int i=0; i<NDIM; ++i) {
106 X[i] = toDouble(*tok_iter++);
107 }
108 // create atom
109 atom *newAtom = World::getInstance().createAtom();
110 newAtom->setType(World::getInstance().getPeriode()->FindElement(element));
111 newAtom->setPosition(X);
112 newmol->AddAtom(newAtom);
113 DoLog(1) && (Log() << Verbose(1) << "Adding atom " << *newAtom << std::endl);
114 }
115 }
116 if (MpqcSection) {
117 if (linestring.find("mole<") != string::npos) { // get theory
118 tokenizer tokens(linestring, angularsep);
119 tokenizer::iterator tok_iter = tokens.begin();
120 ++tok_iter;
121 ASSERT(tok_iter != tokens.end(),
122 "MpqcParser::load() - missing token in brackets<> for mole< in line "+linestring+"!");
123 std::string value(*tok_iter);
124 std::stringstream linestream("theory = "+value);
125 linestream >> params;
126 } else if (linestring.find("integrals<") != string::npos) { // get theory
127 tokenizer tokens(linestring, angularsep);
128 tokenizer::iterator tok_iter = tokens.begin();
129 ++tok_iter;
130 ASSERT(tok_iter != tokens.end(),
131 "MpqcParser::load() - missing token in brackets<> for integrals< in line "+linestring+"!");
132 std::string value(*tok_iter);
133 std::stringstream linestream("integration = "+value);
134 linestream >> params;
135 } else if ((linestring.find("molecule") == string::npos) && (linestring.find("basis") == string::npos)){
136 // molecule and basis must not be parsed in this section
137 tokenizer tokens(linestring, equalitysep);
138 tokenizer::iterator tok_iter = tokens.begin();
139 ASSERT(tok_iter != tokens.end(),
140 "MpqcParser::load() - missing token before '=' for MpqcSection in line "+linestring+"!");
141 std::stringstream whitespacefilter(*tok_iter);
142 std::string key;
143 whitespacefilter >> ws >> key;
144 if (params.haveParam(key)) {
145 std::stringstream linestream(linestring);
146 linestream >> params;
147 } else { // unknown keys are simply ignored as long as parser is incomplete
148 DoLog(2) && (Log() << Verbose(2) << "INFO: '"+key+"' is unknown and ignored." << std::endl);
149 }
150 }
151 }
152 if (BasisSection) {
153 tokenizer tokens(linestring, equalitysep);
154 tokenizer::iterator tok_iter = tokens.begin();
155 ASSERT(tok_iter != tokens.end(),
156 "MpqcParser::load() - missing token for BasisSection in line "+linestring+"!");
157 std::string key(*tok_iter++);
158 ASSERT(tok_iter != tokens.end(),
159 "MpqcParser::load() - missing value for BasisSection after key "+key+" in line "+linestring+"!");
160 std::string value(*tok_iter);
161 tok_iter++;
162 // TODO: use exception instead of ASSERT
163 ASSERT(tok_iter == tokens.end(),
164 "MpqcParser::load() - more than (key = value) on line "+linestring+".");
165 if (key == "name") {
166 std::stringstream linestream("basis = "+value);
167 linestream >> params;
168 }
169 }
170 if (AuxBasisSection) {
171 tokenizer tokens(linestring, equalitysep);
172 tokenizer::iterator tok_iter = tokens.begin();
173 ASSERT(tok_iter != tokens.end(),
174 "MpqcParser::load() - missing token for AuxBasisSection in line "+linestring+"!");
175 std::string key(*tok_iter++);
176 ASSERT(tok_iter != tokens.end(),
177 "MpqcParser::load() - missing value for BasisSection after key "+key+" in line "+linestring+"!");
178 std::string value(*tok_iter);
179 tok_iter++;
180 // TODO: use exception instead of ASSERT
181 ASSERT(tok_iter == tokens.end(),
182 "MpqcParser::load() - more than (key = value) on line "+linestring+".");
183 if (key == "name") {
184 std::stringstream linestream("aux_basis = "+value);
185 linestream >> params;
186 }
187 }
188 // set some scan flags
189 if (linestring.find("mpqc:") != string::npos) {
190 MpqcSection = true;
191 }
192 if (linestring.find("molecule<Molecule>:") != string::npos) {
193 MoleculeSection = true;
194 }
195 if (linestring.find("atoms geometry") != string::npos) {
196 GeometrySection = true;
197 }
198 if ((linestring.find("basis<GaussianBasisSet>:") != string::npos) && ((linestring.find("abasis<") == string::npos))) {
199 BasisSection = true;
200 }
201 if (linestring.find("abasis<") != string::npos) {
202 AuxBasisSection = true;
203 }
204 }
205}
206
207/** Saves all atoms and data into a MPQC config file.
208 * \param *file output stream
209 * \param atoms atoms to store
210 */
211void MpqcParser::save(ostream *file, const std::vector<atom *> &atoms)
212{
213 Vector center;
214 vector<atom *> allatoms = World::getInstance().getAllAtoms();
215
216 // calculate center
217 for (vector<atom *>::iterator runner = allatoms.begin();runner != allatoms.end(); ++runner)
218 center += (*runner)->getPosition();
219 center.Scale(1./(double)allatoms.size());
220
221 // first without hessian
222 if (file->fail()) {
223 DoeLog(1) && (eLog()<< Verbose(1) << "Cannot open mpqc output file." << endl);
224 } else {
225 *file << "% Created by MoleCuilder" << endl;
226 *file << "mpqc: (" << endl;
227 *file << "\tsavestate = " << params.getString(MpqcParser_Parameters::savestateParam) << endl;
228 *file << "\tdo_gradient = " << params.getString(MpqcParser_Parameters::do_gradientParam) << endl;
229 if (params.getBool(MpqcParser_Parameters::hessianParam)) {
230 *file << "\tfreq<MolecularFrequencies>: (" << endl;
231 *file << "\t\tmolecule=$:molecule" << endl;
232 *file << "\t)" << endl;
233 }
234 switch (params.getTheory()) {
235 case MpqcParser_Parameters::CLHF:
236 *file << "\tmole<" << params.getString(MpqcParser_Parameters::theoryParam) << ">: (" << endl;
237 *file << "\t\tmolecule = $:molecule" << endl;
238 *file << "\t\tbasis = $:basis" << endl;
239 *file << "\t\tmaxiter = " << toString(params.getInt(MpqcParser_Parameters::maxiterParam))<< endl;
240 *file << "\t\tmemory = " << toString(params.getInt(MpqcParser_Parameters::memoryParam)) << endl;
241 *file << "\t)" << endl;
242 break;
243 case MpqcParser_Parameters::CLKS:
244 *file << "\tmole<" << params.getString(MpqcParser_Parameters::theoryParam) << ">: (" << endl;
245 *file << "\t\tfunctional<StdDenFunctional>:(name=B3LYP)" << endl;
246 *file << "\t\tmolecule = $:molecule" << endl;
247 *file << "\t\tbasis = $:basis" << endl;
248 *file << "\t\tmaxiter = " << toString(params.getInt(MpqcParser_Parameters::maxiterParam))<< endl;
249 *file << "\t\tmemory = " << toString(params.getInt(MpqcParser_Parameters::memoryParam)) << endl;
250 *file << "\t)" << endl;
251 break;
252 case MpqcParser_Parameters::MBPT2:
253 *file << "\tmole<" << params.getString(MpqcParser_Parameters::theoryParam) << ">: (" << endl;
254 *file << "\t\tbasis = $:basis" << endl;
255 *file << "\t\tmolecule = $:molecule" << endl;
256 *file << "\t\tmemory = " << toString(params.getInt(MpqcParser_Parameters::memoryParam)) << endl;
257 *file << "\t\treference<CLHF>: (" << endl;
258 *file << "\t\t\tmaxiter = " << toString(params.getInt(MpqcParser_Parameters::maxiterParam))<< endl;
259 *file << "\t\t\tbasis = $:basis" << endl;
260 *file << "\t\t\tmolecule = $:molecule" << endl;
261 *file << "\t\t\tmemory = " << toString(params.getInt(MpqcParser_Parameters::memoryParam)) << endl;
262 *file << "\t\t)" << endl;
263 *file << "\t)" << endl;
264 break;
265 case MpqcParser_Parameters::MBPT2_R12:
266 *file << "\tmole<" << params.getString(MpqcParser_Parameters::theoryParam) << ">: (" << endl;
267 *file << "\t\tmolecule = $:molecule" << endl;
268 *file << "\t\tbasis = $:basis" << endl;
269 *file << "\t\taux_basis = $:abasis" << endl;
270 *file << "\t\tstdapprox = \"" << params.getString(MpqcParser_Parameters::stdapproxParam) << "\"" << endl;
271 *file << "\t\tnfzc = " << toString(params.getInt(MpqcParser_Parameters::nfzcParam)) << endl;
272 *file << "\t\tmemory = " << toString(params.getInt(MpqcParser_Parameters::memoryParam)) << endl;
273 *file << "\t\tintegrals<IntegralCints>:()" << endl;
274 *file << "\t\treference<CLHF>: (" << endl;
275 *file << "\t\t\tmolecule = $:molecule" << endl;
276 *file << "\t\t\tbasis = $:basis" << endl;
277 *file << "\t\t\tmaxiter = " << toString(params.getInt(MpqcParser_Parameters::maxiterParam)) << endl;
278 *file << "\t\t\tmemory = " << toString(params.getInt(MpqcParser_Parameters::memoryParam)) << endl;
279 *file << "\t\t\tintegrals<" << params.getString(MpqcParser_Parameters::integrationParam) << ">:()" << endl;
280 *file << "\t\t)" << endl;
281 *file << "\t)" << endl;
282 break;
283 default:
284 DoeLog(0) && (eLog() << Verbose(0)
285 << "Unknown level of theory requested for MPQC output file." << std::endl);
286 break;
287 }
288 *file << ")" << endl;
289 *file << "molecule<Molecule>: (" << endl;
290 *file << "\tunit = " << (World::getInstance().getConfig()->GetIsAngstroem() ? "angstrom" : "bohr" ) << endl;
291 *file << "\t{ atoms geometry } = {" << endl;
292 // output of atoms
293 for (vector<atom *>::iterator AtomRunner = allatoms.begin(); AtomRunner != allatoms.end(); ++AtomRunner) {
294 (*AtomRunner)->OutputMPQCLine(file, &center);
295 }
296 *file << "\t}" << endl;
297 *file << ")" << endl;
298 *file << "basis<GaussianBasisSet>: (" << endl;
299 *file << "\tname = \"" << params.getString(MpqcParser_Parameters::basisParam) << "\"" << endl;
300 *file << "\tmolecule = $:molecule" << endl;
301 *file << ")" << endl;
302 if (params.getTheory() == MpqcParser_Parameters::MBPT2_R12) {
303 *file << "% auxiliary basis set specification" << endl;
304 *file << "\tabasis<GaussianBasisSet>: (" << endl;
305 *file << "\tname = \"" << params.getString(MpqcParser_Parameters::aux_basisParam) << "\"" << endl;
306 *file << "\tmolecule = $:molecule" << endl;
307 *file << ")" << endl;
308 }
309 }
310}
311
312MpqcParser_Parameters & MpqcParser::getParams()
313{
314 return params;
315}
316
Note: See TracBrowser for help on using the repository browser.