source: src/Parser/Psi3Parser.cpp@ f01769

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 f01769 was 5aaa43, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: Fixed new copyright line since start of 2013 in CodeChecks test.

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