source: src/Parser/Psi3Parser.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 1f693d, checked in by Frederik Heber <heber@…>, 12 years ago

Wrapped Bond::BondDegree in getter.

  • Property mode set to 100644
File size: 11.6 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 * Psi3Parser.cpp
25 *
26 * Created on: Oct 04, 2011
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35#include <iostream>
36#include <boost/foreach.hpp>
37#include <boost/tokenizer.hpp>
38#include <string>
39
40#include "CodePatterns/MemDebug.hpp"
41
42#include "Psi3Parser.hpp"
43#include "Psi3Parser_Parameters.hpp"
44
45#include "Atom/atom.hpp"
46#include "Bond/bond.hpp"
47#include "CodePatterns/Log.hpp"
48#include "CodePatterns/toString.hpp"
49#include "Element/element.hpp"
50#include "Element/periodentafel.hpp"
51#include "LinearAlgebra/Vector.hpp"
52#include "molecule.hpp"
53#include "MoleculeListClass.hpp"
54#include "World.hpp"
55
56// declare specialized static variables
57const std::string FormatParserTrait<psi3>::name = "psi3";
58const std::string FormatParserTrait<psi3>::suffix = "psi";
59const ParserTypes FormatParserTrait<psi3>::type = psi3;
60
61// a converter we often need
62ConvertTo<bool> FormatParser<psi3>::Converter;
63
64/** Constructor of Psi3Parser.
65 *
66 */
67FormatParser< psi3 >::FormatParser() :
68 FormatParser_common(new Psi3Parser_Parameters())
69{}
70
71/** Destructor of Psi3Parser.
72 *
73 */
74FormatParser< psi3 >::~FormatParser()
75{}
76
77/** Load an PSI3 config file into the World.
78 * \param *file input stream
79 */
80void FormatParser< psi3 >::load(istream *file)
81{
82 bool Psi3Section = false;
83 bool GeometrySection = false;
84 char line[MAXSTRINGSIZE];
85 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
86 boost::char_separator<char> sep("()");
87 boost::char_separator<char> angularsep("<>");
88 boost::char_separator<char> equalitysep(" =");
89 boost::char_separator<char> whitesep(" \t");
90 ConvertTo<double> toDouble;
91
92 molecule *newmol = World::getInstance().createMolecule();
93 newmol->ActiveFlag = true;
94 // TODO: Remove the insertion into molecule when saving does not depend on them anymore. Also, remove molecule.hpp include
95 World::getInstance().getMolecules()->insert(newmol);
96 while (file->good()) {
97 file->getline(line, MAXSTRINGSIZE-1);
98 std::string linestring(line);
99 LOG(3, "INFO: Current line is: " << line);
100 if ((linestring.find(")") != string::npos) && (linestring.find("(") == string::npos)) {
101 LOG(3, "INFO: Line contains ')' and no '(' (end of section): " << line);
102 // ends a section which do not overlap
103 if (GeometrySection)
104 GeometrySection = false;
105 else
106 Psi3Section = false;
107 }
108 if (GeometrySection) { // we have an atom
109 tokenizer tokens(linestring, sep);
110// if (tokens.size() != 2)
111// throw Psi3ParseException;
112 tokenizer::iterator tok_iter = tokens.begin();
113 ASSERT(tok_iter != tokens.end(),
114 "FormatParser< psi3 >::load() - missing token for MoleculeSection in line "+linestring+"!");
115 std::stringstream whitespacefilter(*++tok_iter);
116 std::string element;
117 whitespacefilter >> ws >> element;
118 LOG(2, "INFO: element of atom is " << element);
119 ASSERT(tok_iter != tokens.end(),
120 "FormatParser< psi3 >::load() - missing token for MoleculeSection in line "+linestring+"!");
121 std::string vector = *tok_iter;
122 tokenizer vectorcomponents(vector, whitesep);
123 Vector X;
124// if (vectorcomponents.size() != NDIM)
125// throw Psi3ParseException;
126 tok_iter = vectorcomponents.begin();
127 ++tok_iter;
128 for (int i=0; i<NDIM; ++i) {
129 LOG(4, "INFO: Current value is " << *tok_iter << ".");
130 X[i] = toDouble(*tok_iter++);
131 }
132 LOG(2, "INFO: position of atom is " << X);
133 // create atom
134 atom *newAtom = World::getInstance().createAtom();
135 newAtom->setType(World::getInstance().getPeriode()->FindElement(element));
136 newAtom->setPosition(X);
137 newmol->AddAtom(newAtom);
138 LOG(1, "Adding atom " << *newAtom);
139 }
140 if ((Psi3Section) && (!GeometrySection)) {
141 if (linestring.find("=") != string::npos) { // get param value
142 tokenizer tokens(linestring, equalitysep);
143 tokenizer::iterator tok_iter = tokens.begin();
144 ASSERT(tok_iter != tokens.end(),
145 "FormatParser< psi3 >::load() - missing token before '=' for Psi3Section in line "+linestring+"!");
146 std::stringstream whitespacefilter(*tok_iter);
147 std::string key;
148 whitespacefilter >> ws >> key;
149 //LOG(2, "INFO: key to check is: " << key);
150 if (getParams().haveParameter(key)) {
151 //LOG(2, "INFO: Line submitted to parameter is: " << linestring);
152 std::stringstream linestream(linestring);
153 linestream >> getParams();
154 } else { // unknown keys are simply ignored as long as parser is incomplete
155 LOG(3, "INFO: '"+key+"' is unknown and ignored.");
156 }
157 }
158 }
159 if ((linestring.find("geometry") != string::npos) && (linestring.find("(") != string::npos)) {
160 LOG(3, "INFO: Line contains geometry and '(': " << line);
161 GeometrySection = true;
162 }
163 if ((linestring.find("psi:") != string::npos) && (linestring.find("(") != string::npos)) {
164 LOG(3, "INFO: Line contains psi: and '(': " << line);
165 Psi3Section = true;
166 }
167 }
168 // refresh atom::nr and atom::name
169 newmol->getAtomCount();
170}
171
172void FormatParser< psi3 >::OutputPsi3Line(ostream * const out, const atom &_atom, const Vector *center) const
173{
174 Vector recentered(_atom.getPosition());
175 recentered -= *center;
176 *out << "\t( " << _atom.getType()->getSymbol() << "\t" << recentered[0] << "\t" << recentered[1] << "\t" << recentered[2] << " )" << endl;
177};
178
179
180/** Saves all atoms and data into a PSI3 config file.
181 * \param *file output stream
182 * \param atoms atoms to store
183 */
184void FormatParser< psi3 >::save(ostream *file, const std::vector<atom *> &atoms)
185{
186 Vector center;
187// vector<atom *> allatoms = World::getInstance().getAllAtoms();
188
189 // calculate center
190 for (std::vector<atom *>::const_iterator runner = atoms.begin();runner != atoms.end(); ++runner)
191 center += (*runner)->getPosition();
192 center.Scale(1./(double)atoms.size());
193
194 // first without hessian
195 if (file->fail()) {
196 ELOG(1, "Cannot open psi3 output file.");
197 } else {
198 *file << "% Created by MoleCuilder" << std::endl;
199 *file << "psi: (" << std::endl;
200 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::labelParam)
201 << " = \"" << getParams().getParameter(Psi3Parser_Parameters::labelParam) << "\"" << std::endl;
202 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::jobtypeParam)
203 << " = " << getParams().getParameter(Psi3Parser_Parameters::jobtypeParam) << std::endl;
204 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::wavefunctionParam)
205 << " = " << getParams().getParameter(Psi3Parser_Parameters::wavefunctionParam) << std::endl;
206 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::maxiterParam)
207 << " = " << getParams().getParameter(Psi3Parser_Parameters::maxiterParam) << std::endl;
208 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::referenceParam)
209 << " = " << getParams().getParameter(Psi3Parser_Parameters::referenceParam) << std::endl;
210 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::basisParam)
211 << " = \"" << getParams().getParameter(Psi3Parser_Parameters::basisParam) << "\"" << std::endl;
212 const std::string reference = getParams().getParameter(Psi3Parser_Parameters::referenceParam);
213// if (reference == getParams().getReferenceName(Psi3Parser_Parameters::RHF)) {
214// }
215// if (reference == getParams().getReferenceName(Psi3Parser_Parameters::ROHF)) {
216// }
217 if ((reference == getParams().getReferenceName(Psi3Parser_Parameters::UHF))
218 || (reference == getParams().getReferenceName(Psi3Parser_Parameters::TWOCON))) {
219 const unsigned int multiplicity = calculateMultiplicity(atoms);
220 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::multiplicityParam)
221 << " = " << multiplicity << std::endl;
222// << " = " << getParams().getParameter(Psi3Parser_Parameters::multiplicityParam) << std::endl;
223 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::chargeParam)
224 << " = " << getParams().getParameter(Psi3Parser_Parameters::chargeParam) << std::endl;
225 }
226 if (reference == getParams().getReferenceName(Psi3Parser_Parameters::TWOCON)) {
227 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::soccParam)
228 << " = " << getParams().getParameter(Psi3Parser_Parameters::soccParam) << std::endl;
229 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::doccParam)
230 << " = " << getParams().getParameter(Psi3Parser_Parameters::doccParam) << std::endl;
231 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::subgroupParam)
232 << " = " << getParams().getParameter(Psi3Parser_Parameters::subgroupParam) << std::endl;
233 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::unique_axisParam)
234 << " = " << getParams().getParameter(Psi3Parser_Parameters::unique_axisParam) << std::endl;
235 }
236 if ((reference != getParams().getReferenceName(Psi3Parser_Parameters::RHF))
237 && (reference != getParams().getReferenceName(Psi3Parser_Parameters::ROHF))
238 && (reference != getParams().getReferenceName(Psi3Parser_Parameters::UHF))
239 && (reference != getParams().getReferenceName(Psi3Parser_Parameters::TWOCON)))
240 {
241 ELOG(0, "Unknown level of reference requested for Psi3 output file.");
242 }
243 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::freeze_coreParam)
244 << " = " << getParams().getParameter(Psi3Parser_Parameters::freeze_coreParam) << std::endl;
245 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::unitsParam)
246 << " = " << getParams().getParameter(Psi3Parser_Parameters::unitsParam) << std::endl;
247 *file << "\tgeometry = (" << std::endl;
248 // output of atoms
249 BOOST_FOREACH(const atom *_atom, atoms) {
250 OutputPsi3Line(file, *_atom, &center);
251 }
252 *file << "\t)" << std::endl;
253 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::originParam)
254 << " = " << getParams().getParameter(Psi3Parser_Parameters::originParam) << std::endl;
255 *file << ")" << std::endl;
256 }
257}
258
259unsigned int FormatParser< psi3 >::calculateMultiplicity(const std::vector<atom *> &atoms) const
260{
261 // add up the number of electrons
262 double valencies = 0.;
263 BOOST_FOREACH(atom *_atom, atoms) {
264 valencies += _atom->getType()->getAtomicNumber();
265 }
266
267 // add doubly up all bond degrees (two electrons per bond)
268 unsigned int degrees = 0;
269 BOOST_FOREACH(atom *_atom, atoms) {
270 BOOST_FOREACH(bond::ptr _bond, _atom->getListOfBonds()) {
271 degrees += 2*_bond->getDegree();
272 }
273 }
274
275 // return difference+1 as multiplicity
276 return (int)fabs(valencies-degrees)+1;
277}
Note: See TracBrowser for help on using the repository browser.