votca 2024.2-dev
Loading...
Searching...
No Matches
molden.cc
Go to the documentation of this file.
1#include <sstream>
2
4#include "votca/xtp/molden.h"
5#include <boost/algorithm/string.hpp>
6
7namespace votca {
8namespace xtp {
9
10void Molden::writeAtoms(const Orbitals& orbitals,
11 std::ofstream& outFile) const {
12 for (const auto& atom : orbitals.QMAtoms()) {
13 const Eigen::Vector3d& pos = atom.getPos();
14 outFile << boost::format("%-4s %5d %5d %22.12e %22.10e %22.10e\n") %
15 atom.getElement() % (atom.getId() + 1) %
16 atom.getElementNumber() % pos[0] % pos[1] % pos[2];
17 }
18}
19
20void Molden::writeMOs(const Orbitals& orbitals, std::ofstream& outFile) const {
21 Eigen::VectorXd energies = orbitals.MOs().eigenvalues();
22 bool fromVotcaToExternal = true;
23 OrbReorder reorder(reorderList_, multipliers_, fromVotcaToExternal);
24 Eigen::MatrixXd moCoefficients = orbitals.MOs().eigenvectors();
25 reorder.reorderOrbitals(moCoefficients, orbitals.getDftBasis());
26
27 for (Index i = 0; i < orbitals.getBasisSetSize(); i++) { // over columns
28 outFile << "Sym= \n";
29 outFile << boost::format("Ene= %-20.12e\n") % energies[i];
30 outFile << "Spin= Alpha\n";
31 outFile << boost::format("Occup= %-5.2f\n") %
32 (2 * (i < orbitals.getLumo()));
33 for (Index j = 0; j < orbitals.getBasisSetSize(); j++) {
34 outFile << boost::format("%5d %22.12e\n") % (j + 1) %
35 moCoefficients(j, i);
36 }
37 }
38}
39
40void Molden::writeBasisSet(const Orbitals& orbitals,
41 std::ofstream& outFile) const {
42 AOBasis basis = orbitals.getDftBasis();
43 for (const auto& atom : orbitals.QMAtoms()) {
44 // The 0 in the format string of the next line is meaningless it
45 // is included for backwards compatibility of molden files
46 outFile << boost::format("%4d 0 \n") % (atom.getId() + 1);
47 const std::vector<const AOShell*> shells =
48 basis.getShellsofAtom(atom.getId());
49 for (const AOShell* shell : shells) {
50 // The 1.0 at the end of the next line is meaningless it
51 // is included for backwards compatibility of molden files
52 outFile << boost::format("%-3s %4d %3.1f \n") %
53 boost::to_lower_copy(EnumToString(shell->getL())) %
54 shell->getSize() % 1.0;
55 for (const AOGaussianPrimitive& gaussian : *shell) {
56 outFile << boost::format("%22.10e %22.10e\n") % gaussian.getDecay() %
57 gaussian.getContraction();
58 }
59 }
60 outFile << " \n";
61 }
62}
63
64void Molden::WriteFile(const std::string& filename,
65 const Orbitals& orbitals) const {
66 if (!orbitals.hasDFTbasisName()) {
67 throw std::runtime_error(".orb file does not contain a basisset name");
68 }
69
70 std::ofstream outFile(filename);
71 if (outFile.is_open()) {
72
73 XTP_LOG(Log::error, log_) << "Writing data to " << filename << std::flush;
74
75 // print Header
76 outFile << "[Molden Format]\n";
77 outFile << "[Title]\n";
78 outFile << "Molden file created by VOTCA-XTP\n";
79 outFile << " \n";
80
81 outFile << "[Atoms] AU\n";
82 writeAtoms(orbitals, outFile);
83
84 outFile << "[GTO] \n";
85 writeBasisSet(orbitals, outFile);
86
87 // indicate spherical D F and G functions
88 outFile << "[5D] \n[7F] \n[9G] \n";
89
90 outFile << "[MO]\n";
91 writeMOs(orbitals, outFile);
93 << "Finished writing to molden file." << std::flush;
94 }
95}
96
97std::string Molden::readAtoms(QMMolecule& mol, const std::string& units,
98 std::ifstream& input_file) const {
99 std::string line;
100 std::istringstream iss(" ");
101 while (std::getline(input_file, line)) {
102 boost::trim(line);
103 if (line == "" || line[0] == '[') {
104 return line;
105 }
106 iss.str(line);
107 iss.clear();
108
109 // extract data
110 double x, y, z;
111 Index atom_id;
112 std::string junk;
113 std::string atom_type;
114 iss >> atom_type >> atom_id >> junk >> x >> y >> z;
115 atom_id =
116 atom_id - 1; // molden uses indexing from 1, we use indexing from 0
117
118 // Add data to orbitals object
119 Eigen::Vector3d pos(x, y, z);
120 if (units == "Angs") {
121 pos = tools::conv::ang2bohr * pos;
122 }
123 mol.push_back(QMAtom(atom_id, atom_type, pos));
124 }
125 return "";
126}
127
128// The returned string contains the line with the next section header
129// or, if it is the last section, an empty string.
130std::string Molden::readMOs(Orbitals& orbitals,
131 std::ifstream& input_file) const {
132
133 // setup space to store everything
134 Index basis_size = orbitals.getBasisSetSize();
135 if (basis_size == 0) {
136 throw std::runtime_error(
137 "Basis size not set, atoms were not parsed first.");
138 }
139 orbitals.MOs().eigenvalues().resize(basis_size);
140 orbitals.MOs().eigenvectors().resize(basis_size, basis_size);
141 orbitals.Occupations() = Eigen::MatrixXd::Zero(basis_size, 2);
142
143 // only if open-shell
144 if (orbitals.isOpenShell()) {
145 orbitals.MOs_beta().eigenvalues().resize(basis_size);
146 orbitals.MOs_beta().eigenvectors().resize(basis_size, basis_size);
147 }
148
149 // actual parsing
150 std::string line;
151 std::string tempStr;
152 double tempDouble;
153 Index tempIndex;
154 std::istringstream iss(" ");
155 for (Index i = 0; i < basis_size; i++) { // loop over mo's
156 std::getline(input_file, line); // skip symmetry label
157 // energy line
158 std::getline(input_file, line);
159 iss.str(line);
160 iss.clear();
161 iss >> tempStr >> tempDouble;
162 orbitals.MOs().eigenvalues()[i] = tempDouble;
163 // spin channel line
164 std::getline(input_file, line);
165 iss.str(line);
166 iss.clear();
167 iss >> tempStr >> tempStr;
168 // occupation line
169 std::getline(input_file, line);
170 iss.str(line);
171 iss.clear();
172 iss >> tempStr >> tempDouble;
173 if ((int)tempDouble == 1 && !orbitals.isOpenShell()) {
174 throw std::runtime_error(
175 "Encountered occupation 1 for a closed-shell calculation.");
176 }
177 orbitals.Occupations()(i, 0) = tempDouble;
178
179 // MO coefficients
180 for (int j = 0; j < basis_size; j++) { // loop over ao's
181 std::getline(input_file, line);
182 iss.str(line);
183 iss.clear();
184 iss >> tempIndex >> tempDouble;
185 orbitals.MOs().eigenvectors()(j, i) = tempDouble;
186 }
187 }
188
189 if (orbitals.isOpenShell()) {
190 // read Spin Beta, if OpenShell
191 for (Index i = 0; i < basis_size; i++) { // loop over mo's
192 std::getline(input_file, line); // skip symmetry label
193 // energy line
194 std::getline(input_file, line);
195 iss.str(line);
196 iss.clear();
197 iss >> tempStr >> tempDouble;
198 orbitals.MOs_beta().eigenvalues()[i] = tempDouble;
199 // spin channel line
200 std::getline(input_file, line);
201 iss.str(line);
202 iss.clear();
203 iss >> tempStr >> tempStr;
204 // occupation line
205 std::getline(input_file, line);
206 iss.str(line);
207 iss.clear();
208 iss >> tempStr >> tempDouble;
209 if ((int)tempDouble == 2) {
210 throw std::runtime_error(
211 "Encountered occupation 2 in an open-shell calculation.");
212 }
213 orbitals.Occupations()(i, 1) = tempDouble;
214 // MO coefficients
215 for (int j = 0; j < basis_size; j++) { // loop over ao's
216 std::getline(input_file, line);
217 iss.str(line);
218 iss.clear();
219 iss >> tempIndex >> tempDouble;
220 orbitals.MOs_beta().eigenvectors()(j, i) = tempDouble;
221 }
222 }
223 }
224
226 reorder.reorderOrbitals(orbitals.MOs().eigenvectors(),
227 orbitals.getDftBasis());
228
229 if (orbitals.isOpenShell()) {
230 reorder.reorderOrbitals(orbitals.MOs_beta().eigenvectors(),
231 orbitals.getDftBasis());
232 }
233
234 getline(input_file, line);
235 return line;
236}
237
238void Molden::addBasissetInfo(Orbitals& orbitals) const {
240 if (aux_basisset_name_ != "") {
242 }
243}
244
245void Molden::parseMoldenFile(const std::string& filename,
246 Orbitals& orbitals) const {
247
248 if (basisset_name_ == "") {
249 throw std::runtime_error(
250 "Basisset names should be set before reading the molden file.");
251 }
252
253 std::ifstream input_file(filename);
254 // Check if succesfull
255 if (input_file.fail()) {
256 throw std::runtime_error("Could not open molden file with name: " +
257 filename);
258 }
259
260 std::string line;
261 std::getline(input_file, line);
262 while (input_file) {
263 boost::trim(line);
264 if (line[0] != '[') { // ignore non-relevant lines
265 std::getline(input_file, line);
266 continue;
267 }
268
269 // Extract the part between square brackets
270 long unsigned close = line.find("]");
271 std::string sectionType = line.substr(1, close - 1);
272
273 // Import data from relevant sections
274 if (sectionType == "Atoms") {
275 std::string units = line.substr(close + 1);
276 boost::trim(units);
278 << "Reading atoms using " << units << " units." << std::flush;
279 orbitals.QMAtoms().clearAtoms();
280 if (orbitals.QMAtoms().size() == 0) {
281 line = readAtoms(orbitals.QMAtoms(), units, input_file);
282 } else {
283 throw std::runtime_error(
284 "Could not clear QMAtoms while reading Molden file.");
285 }
286 addBasissetInfo(orbitals);
287 } else if (sectionType == "GTO") {
289 << "Basisset specification is ignored." << std::flush;
291 << "Basissets are specified via the mol2orb.xml options file."
292 << std::flush;
293 std::getline(input_file, line);
294 } else if (sectionType == "MO") {
295 if (orbitals.QMAtoms().size() == 0) {
296 throw std::runtime_error(
297 "Atoms should be specified before MO coefficients.");
298 } else {
300 << "Reading molecular orbital coefficients" << std::flush;
301 line = readMOs(orbitals, input_file);
302 }
303 } else if (sectionType == "STO") {
304 throw std::runtime_error(
305 "Slater Type Orbitals (STOs) are not supported in VOTCA-XTP.");
306 } else {
307 std::getline(input_file, line);
308 }
309 }
310
311 XTP_LOG(Log::error, log_) << "Done parsing molden file" << std::flush;
312}
313
314} // namespace xtp
315} // namespace votca
const Eigen::VectorXd & eigenvalues() const
Definition eigensystem.h:30
const Eigen::MatrixXd & eigenvectors() const
Definition eigensystem.h:33
Container to hold Basisfunctions for all atoms.
Definition aobasis.h:42
const std::vector< const AOShell * > getShellsofAtom(Index AtomId) const
Definition aobasis.cc:63
void push_back(const T &atom)
std::string readMOs(Orbitals &orbitals, std::ifstream &input_file) const
Definition molden.cc:130
std::string basisset_name_
Definition molden.h:72
void WriteFile(const std::string &filename, const Orbitals &orbitals) const
Definition molden.cc:64
std::string aux_basisset_name_
Definition molden.h:73
std::string readAtoms(QMMolecule &mol, const std::string &units, std::ifstream &input_file) const
Definition molden.cc:97
void writeAtoms(const Orbitals &orbitals, std::ofstream &outFile) const
Definition molden.cc:10
void writeMOs(const Orbitals &orbitals, std::ofstream &outFile) const
Definition molden.cc:20
void addBasissetInfo(Orbitals &orbitals) const
Definition molden.cc:238
Logger & log_
Definition molden.h:51
void parseMoldenFile(const std::string &filename, Orbitals &orbitals) const
Definition molden.cc:245
void writeBasisSet(const Orbitals &orbitals, std::ofstream &outFile) const
Definition molden.cc:40
std::array< Index, 49 > reorderList_
Definition molden.h:62
std::array< Index, 49 > multipliers_
Definition molden.h:53
void reorderOrbitals(Eigen::MatrixXd &moCoefficients, const AOBasis &basis)
Definition orbreorder.cc:74
container for molecular orbitals
Definition orbitals.h:46
const tools::EigenSystem & MOs_beta() const
Definition orbitals.h:128
const Eigen::MatrixXd & Occupations() const
Definition orbitals.h:125
void SetupAuxBasis(std::string aux_basis_name)
Definition orbitals.cc:99
Index getBasisSetSize() const
Definition orbitals.h:64
const tools::EigenSystem & MOs() const
Definition orbitals.h:122
const QMMolecule & QMAtoms() const
Definition orbitals.h:172
bool hasDFTbasisName() const
Definition orbitals.h:198
void SetupDftBasis(std::string basis_name)
Definition orbitals.cc:90
bool isOpenShell() const
Definition orbitals.h:168
const AOBasis & getDftBasis() const
Definition orbitals.h:208
Index getLumo() const
Definition orbitals.h:66
container for QM atoms
Definition qmatom.h:37
#define XTP_LOG(level, log)
Definition logger.h:40
const double ang2bohr
Definition constants.h:48
std::istream & getline(std::istream &is, std::string &str)
Wrapper for a getline function.
Definition getline.h:35
std::string EnumToString(L l)
Definition basisset.cc:60
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26