source: src/Parser/Psi3Parser.cpp@ ff4fff9

CombiningParticlePotentialParsing
Last change on this file since ff4fff9 was 2affd1, checked in by Frederik Heber <heber@…>, 9 years ago

Removed molecules_deprecated from World and unnecessary includes of MoleculeListClass and all insert/erase.

  • this goes along the lines of removing "remove me when we don't need MoleculeCistClass anymore".
  • Property mode set to 100644
File size: 11.5 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 "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 while (file->good()) {
95 file->getline(line, MAXSTRINGSIZE-1);
96 std::string linestring(line);
97 LOG(3, "INFO: Current line is: " << line);
98 if ((linestring.find(")") != string::npos) && (linestring.find("(") == string::npos)) {
99 LOG(3, "INFO: Line contains ')' and no '(' (end of section): " << line);
100 // ends a section which do not overlap
101 if (GeometrySection)
102 GeometrySection = false;
103 else
104 Psi3Section = false;
105 }
106 if (GeometrySection) { // we have an atom
107 tokenizer tokens(linestring, sep);
108// if (tokens.size() != 2)
109// throw Psi3ParseException;
110 tokenizer::iterator tok_iter = tokens.begin();
111 ASSERT(tok_iter != tokens.end(),
112 "FormatParser< psi3 >::load() - missing token for MoleculeSection in line "+linestring+"!");
113 std::stringstream whitespacefilter(*++tok_iter);
114 std::string element;
115 whitespacefilter >> ws >> element;
116 LOG(2, "INFO: element of atom is " << element);
117 ASSERT(tok_iter != tokens.end(),
118 "FormatParser< psi3 >::load() - missing token for MoleculeSection in line "+linestring+"!");
119 std::string vector = *tok_iter;
120 tokenizer vectorcomponents(vector, whitesep);
121 Vector X;
122// if (vectorcomponents.size() != NDIM)
123// throw Psi3ParseException;
124 tok_iter = vectorcomponents.begin();
125 ++tok_iter;
126 for (int i=0; i<NDIM; ++i) {
127 LOG(4, "INFO: Current value is " << *tok_iter << ".");
128 X[i] = toDouble(*tok_iter++);
129 }
130 LOG(2, "INFO: position of atom is " << X);
131 // create atom
132 atom *newAtom = World::getInstance().createAtom();
133 newAtom->setType(World::getInstance().getPeriode()->FindElement(element));
134 newAtom->setPosition(X);
135 newmol->AddAtom(newAtom);
136 LOG(1, "Adding atom " << *newAtom);
137 }
138 if ((Psi3Section) && (!GeometrySection)) {
139 if (linestring.find("=") != string::npos) { // get param value
140 tokenizer tokens(linestring, equalitysep);
141 tokenizer::iterator tok_iter = tokens.begin();
142 ASSERT(tok_iter != tokens.end(),
143 "FormatParser< psi3 >::load() - missing token before '=' for Psi3Section in line "+linestring+"!");
144 std::stringstream whitespacefilter(*tok_iter);
145 std::string key;
146 whitespacefilter >> ws >> key;
147 //LOG(2, "INFO: key to check is: " << key);
148 if (getParams().haveParameter(key)) {
149 //LOG(2, "INFO: Line submitted to parameter is: " << linestring);
150 std::stringstream linestream(linestring);
151 linestream >> getParams();
152 } else { // unknown keys are simply ignored as long as parser is incomplete
153 LOG(3, "INFO: '"+key+"' is unknown and ignored.");
154 }
155 }
156 }
157 if ((linestring.find("geometry") != string::npos) && (linestring.find("(") != string::npos)) {
158 LOG(3, "INFO: Line contains geometry and '(': " << line);
159 GeometrySection = true;
160 }
161 if ((linestring.find("psi:") != string::npos) && (linestring.find("(") != string::npos)) {
162 LOG(3, "INFO: Line contains psi: and '(': " << line);
163 Psi3Section = true;
164 }
165 }
166 // refresh atom::nr and atom::name
167 newmol->getAtomCount();
168}
169
170void FormatParser< psi3 >::OutputPsi3Line(ostream * const out, const atom &_atom, const Vector *center) const
171{
172 Vector recentered(_atom.getPosition());
173 recentered -= *center;
174 *out << "\t( " << _atom.getType()->getSymbol() << "\t" << recentered[0] << "\t" << recentered[1] << "\t" << recentered[2] << " )" << endl;
175};
176
177
178/** Saves all atoms and data into a PSI3 config file.
179 * \param *file output stream
180 * \param atoms atoms to store
181 */
182void FormatParser< psi3 >::save(ostream *file, const std::vector<const atom *> &atoms)
183{
184 Vector center;
185// vector<atom *> allatoms = World::getInstance().getAllAtoms();
186
187 // calculate center
188 for (std::vector<const atom *>::const_iterator runner = atoms.begin();runner != atoms.end(); ++runner)
189 center += (*runner)->getPosition();
190 center.Scale(1./(double)atoms.size());
191
192 // first without hessian
193 if (file->fail()) {
194 ELOG(1, "Cannot open psi3 output file.");
195 } else {
196 *file << "% Created by MoleCuilder" << std::endl;
197 *file << "psi: (" << std::endl;
198 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::labelParam)
199 << " = \"" << getParams().getParameter(Psi3Parser_Parameters::labelParam) << "\"" << std::endl;
200 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::jobtypeParam)
201 << " = " << getParams().getParameter(Psi3Parser_Parameters::jobtypeParam) << std::endl;
202 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::wavefunctionParam)
203 << " = " << getParams().getParameter(Psi3Parser_Parameters::wavefunctionParam) << std::endl;
204 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::maxiterParam)
205 << " = " << getParams().getParameter(Psi3Parser_Parameters::maxiterParam) << std::endl;
206 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::referenceParam)
207 << " = " << getParams().getParameter(Psi3Parser_Parameters::referenceParam) << std::endl;
208 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::basisParam)
209 << " = \"" << getParams().getParameter(Psi3Parser_Parameters::basisParam) << "\"" << std::endl;
210 const std::string reference = getParams().getParameter(Psi3Parser_Parameters::referenceParam);
211// if (reference == getParams().getReferenceName(Psi3Parser_Parameters::RHF)) {
212// }
213// if (reference == getParams().getReferenceName(Psi3Parser_Parameters::ROHF)) {
214// }
215 if ((reference == getParams().getReferenceName(Psi3Parser_Parameters::UHF))
216 || (reference == getParams().getReferenceName(Psi3Parser_Parameters::TWOCON))) {
217 const unsigned int multiplicity = calculateMultiplicity(atoms);
218 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::multiplicityParam)
219 << " = " << multiplicity << std::endl;
220// << " = " << getParams().getParameter(Psi3Parser_Parameters::multiplicityParam) << std::endl;
221 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::chargeParam)
222 << " = " << getParams().getParameter(Psi3Parser_Parameters::chargeParam) << std::endl;
223 }
224 if (reference == getParams().getReferenceName(Psi3Parser_Parameters::TWOCON)) {
225 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::soccParam)
226 << " = " << getParams().getParameter(Psi3Parser_Parameters::soccParam) << std::endl;
227 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::doccParam)
228 << " = " << getParams().getParameter(Psi3Parser_Parameters::doccParam) << std::endl;
229 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::subgroupParam)
230 << " = " << getParams().getParameter(Psi3Parser_Parameters::subgroupParam) << std::endl;
231 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::unique_axisParam)
232 << " = " << getParams().getParameter(Psi3Parser_Parameters::unique_axisParam) << std::endl;
233 }
234 if ((reference != getParams().getReferenceName(Psi3Parser_Parameters::RHF))
235 && (reference != getParams().getReferenceName(Psi3Parser_Parameters::ROHF))
236 && (reference != getParams().getReferenceName(Psi3Parser_Parameters::UHF))
237 && (reference != getParams().getReferenceName(Psi3Parser_Parameters::TWOCON)))
238 {
239 ELOG(0, "Unknown level of reference requested for Psi3 output file.");
240 }
241 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::freeze_coreParam)
242 << " = " << getParams().getParameter(Psi3Parser_Parameters::freeze_coreParam) << std::endl;
243 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::unitsParam)
244 << " = " << getParams().getParameter(Psi3Parser_Parameters::unitsParam) << std::endl;
245 *file << "\tgeometry = (" << std::endl;
246 // output of atoms
247 BOOST_FOREACH(const atom *_atom, atoms) {
248 OutputPsi3Line(file, *_atom, &center);
249 }
250 *file << "\t)" << std::endl;
251 *file << "\t" << getParams().getParameterName(Psi3Parser_Parameters::originParam)
252 << " = " << getParams().getParameter(Psi3Parser_Parameters::originParam) << std::endl;
253 *file << ")" << std::endl;
254 }
255}
256
257unsigned int FormatParser< psi3 >::calculateMultiplicity(
258 const std::vector<const atom *> &atoms) const
259{
260 // add up the number of electrons
261 double valencies = 0.;
262 BOOST_FOREACH(const atom *_atom, atoms) {
263 valencies += _atom->getType()->getAtomicNumber();
264 }
265
266 // add doubly up all bond degrees (two electrons per bond)
267 unsigned int degrees = 0;
268 BOOST_FOREACH(const atom *_atom, atoms) {
269 BOOST_FOREACH(bond::ptr _bond, _atom->getListOfBonds()) {
270 degrees += 2*_bond->getDegree();
271 }
272 }
273
274 // return difference+1 as multiplicity
275 return (int)fabs(valencies-degrees)+1;
276}
Note: See TracBrowser for help on using the repository browser.