Skip to content
This repository has been archived by the owner on Sep 28, 2021. It is now read-only.

Gaussian checkpoint writer #649

Merged
merged 27 commits into from
Jan 20, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
faa1fb5
created classes and tool for fchk filewriter
rubengerritsen Jan 15, 2021
557e9ee
Halfway done
rubengerritsen Jan 15, 2021
81d8fc5
Only the MOs left
rubengerritsen Jan 15, 2021
c440690
Merge branch 'master' into gaussianCheckpointWriter
rubengerritsen Jan 15, 2021
9af7b03
added MOs, multipliers still wrong
rubengerritsen Jan 15, 2021
ea08dc1
fixed ordering issue
rubengerritsen Jan 18, 2021
c2e158f
added density
rubengerritsen Jan 18, 2021
4532376
Format code using clang-format version 11.0.0 (Fedora 11.0.0-2.fc33)
votca-bot Jan 18, 2021
19972b8
Update copyright
votca-bot Jan 18, 2021
a73ed21
Merge branch 'master' into gaussianCheckpointWriter
JensWehner Jan 18, 2021
5971f9d
Merge branch 'master' into gaussianCheckpointWriter
JensWehner Jan 18, 2021
261d62c
Merge branch 'master' into gaussianCheckpointWriter
rubengerritsen Jan 19, 2021
b30202b
small improvements
rubengerritsen Jan 19, 2021
eccfa5e
fixed bug
rubengerritsen Jan 19, 2021
f311d3e
Update src/libxtp/tools/orb2fchk.cc
rubengerritsen Jan 19, 2021
0358e1b
Update src/libxtp/tools/orb2fchk.h
rubengerritsen Jan 19, 2021
8bff251
Update CHANGELOG.rst
votca-bot Jan 19, 2021
d916f23
Format code using clang-format version 11.0.0 (Fedora 11.0.0-2.fc33)
votca-bot Jan 19, 2021
8bc85b6
Added Unit Test
rubengerritsen Jan 19, 2021
170dab9
Merge branch 'gaussianCheckpointWriter' of github.com:votca/xtp into …
rubengerritsen Jan 19, 2021
394b486
added option to print excited state densities
rubengerritsen Jan 20, 2021
f496f8e
enhanced test output
rubengerritsen Jan 20, 2021
c530a21
fixed intel compiler issue
rubengerritsen Jan 20, 2021
f91d518
Format code using clang-format version 11.0.0 (Fedora 11.0.0-2.fc33)
votca-bot Jan 20, 2021
8da3834
Improved excitated states
rubengerritsen Jan 20, 2021
e539d2c
merge with remote
rubengerritsen Jan 20, 2021
9900a92
fixed bad merge
rubengerritsen Jan 20, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/votca/xtp/aobasis.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ class AOBasis {

Index getNumofShells() const { return Index(_aoshells.size()); }

Index getNumberOfPrimitives() const {
Index totalPrimitives = 0;
for (const AOShell& shell : _aoshells) {
totalPrimitives += shell.getSize();
}
return totalPrimitives;
}

Index getMaxNprim() const;

Index getMaxL() const;
Expand Down
51 changes: 51 additions & 0 deletions include/votca/xtp/gaussianwriter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2009-2020 The VOTCA Development Team
* (http://www.votca.org)
*
* Licensed under the Apache License, Version 2.0 (the "License")
*
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

#pragma once
#ifndef VOTCA_XTP_GAUSSIANWRITER_H
#define VOTCA_XTP_GAUSSIANWRITER_H

// Local VOTCA includes
#include "votca/xtp/logger.h"
#include "votca/xtp/orbitals.h"
#include "votca/xtp/orbreorder.h"
#include "votca/xtp/qmtool.h"
#include <fstream>

namespace votca {
namespace xtp {
class GaussianWriter {
public:
GaussianWriter(Logger& log) : _log(log){};

~GaussianWriter() = default;

void WriteFile(const std::string& filename, const Orbitals& orbitals) const;

private:
Logger& _log;
Index toGaussianL(L l) const;
std::string reorderedMOCoefficients(const Orbitals& orbitals) const;
std::string densityMatrixToString(const Orbitals& orbitals) const;
};

} // namespace xtp
} // namespace votca

#endif
5 changes: 5 additions & 0 deletions share/xtp/xml/orb2fchk.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0"?>
<options>
<orb2fchk help="Converts orb files to gaussian fchk files.">
</orb2fchk>
</options>
2 changes: 2 additions & 0 deletions src/libxtp/factories/toolfactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "tools/log2mps.h"
#include "tools/mol2orb.h"
#include "tools/molpol.h"
#include "tools/orb2fchk.h"
#include "tools/orb2mol.h"
#include "tools/partialcharges.h"
#include "tools/qmsandbox.h"
Expand All @@ -53,6 +54,7 @@ void QMToolFactory::RegisterAll(void) {
QMTools().Register<APDFT>("apdft");
QMTools().Register<Mol2Orb>("mol2orb");
QMTools().Register<Orb2Mol>("orb2mol");
QMTools().Register<Orb2Fchk>("orb2fchk");
}

} // namespace xtp
Expand Down
307 changes: 307 additions & 0 deletions src/libxtp/gaussianwriter.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,307 @@
#include "votca/xtp/gaussianwriter.h"
rubengerritsen marked this conversation as resolved.
Show resolved Hide resolved
#include "votca/xtp/basisset.h"
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
#include <sstream>
#include <votca/tools/eigenio_matrixmarket.h>

namespace votca {
namespace xtp {

/*
* This function converts VOTCA's L enum to the gaussian equivalent.
* Gaussian uses a minus sign to indicate spherical shells.
*/
Index GaussianWriter::toGaussianL(L l) const {
switch (l) {
case L::S:
return 0;
case L::P:
return 1;
default:
return -1 * static_cast<Index>(l);
JensWehner marked this conversation as resolved.
Show resolved Hide resolved
}
}

std::string GaussianWriter::reorderedMOCoefficients(
const Orbitals& orbitals) const {
// Setup the reordering parameters
std::array<Index, 49> multipliers;
multipliers.fill(-1);
// clang-format off
// the ordering of the m quantumnumbers for every shell in gaussian
std::array<Index, 49> gaussianOrder={{
0, //s
1,-1,0, //p
0,1,-1,2,-2, //d
0,1,-1,2,-2,3,-3, //f
0,1,-1,2,-2,3,-3,4,-4, //g
0,1,-1,2,-2,3,-3,4,-4,5,-5, // h
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6 // i
}};
// clang-format on
OrbReorder reorder(gaussianOrder, multipliers, true);
Eigen::MatrixXd moCoefficients = orbitals.MOs().eigenvectors();
reorder.reorderOrbitals(moCoefficients, orbitals.SetupDftBasis());

// put the reordered mos in a string
std::stringstream mos_string;

int temp_int = 1;
for (Index i = 0; i < moCoefficients.rows(); ++i) {
for (Index j = 0; j < moCoefficients.cols(); ++j) {
mos_string << boost::format("%16.8e") % moCoefficients(j, i);
if (temp_int % 5 == 0) {
mos_string << "\n";
}
temp_int++;
}
}
mos_string << ((temp_int - 1) % 5 == 0 ? "" : "\n");

return mos_string.str();
}

std::string GaussianWriter::densityMatrixToString(
const Orbitals& orbitals) const {

// Setup the reordering parameters
std::array<Index, 49> multipliers;
multipliers.fill(-1);
// clang-format off
// the ordering of the m quantumnumbers for every shell in gaussian
std::array<Index, 49> gaussianOrder={{
0, //s
1,-1,0, //p
0,1,-1,2,-2, //d
0,1,-1,2,-2,3,-3, //f
0,1,-1,2,-2,3,-3,4,-4, //g
0,1,-1,2,-2,3,-3,4,-4,5,-5, // h
0,1,-1,2,-2,3,-3,4,-4,5,-5,6,-6 // i
}};
// clang-format on
OrbReorder reorder(gaussianOrder, multipliers, true);
Eigen::MatrixXd density = orbitals.DensityMatrixGroundState();
reorder.reorderOperator(density, orbitals.SetupDftBasis());

votca::tools::EigenIO_MatrixMarket::WriteMatrix("density.mm", density);
rubengerritsen marked this conversation as resolved.
Show resolved Hide resolved

// put the reordered mos in a string
std::stringstream density_string;

int temp_int = 1;

for (Index i = 0; i < density.rows(); ++i) {
for (Index j = 0; j <= i; ++j) {
density_string << boost::format("%16.8e") % density(i, j);
if (temp_int % 5 == 0) {
density_string << "\n";
}
temp_int++;
}
}
density_string << ((temp_int - 1) % 5 == 0 ? "" : "\n");

return density_string.str();
}

void GaussianWriter::WriteFile(const std::string& basename,
const Orbitals& orbitals) const {
if (!orbitals.hasDFTbasisName()) {
throw std::runtime_error(".orb file does not contain a basisset name");
}

AOBasis basis = orbitals.SetupDftBasis();

std::ofstream outFile(basename + ".fchk");
if (outFile.is_open()) {
int temp_int;
// job description
outFile << basename << ", fchk created by VOTCA-XTP\n";
outFile << "DUMMY_TYPE DUMMY_METHOD " << orbitals.getDFTbasisName()
<< "\n";

// clang-format off
rubengerritsen marked this conversation as resolved.
Show resolved Hide resolved
outFile << boost::format("%-43s%-2s%15d\n") % "number of atoms" % "I" % orbitals.QMAtoms().size();
outFile << boost::format("%-43s%-2s%15d\n") % "Charge" % "I" % 0;
outFile << boost::format("%-43s%-2s%15d\n") % "Multiplicity" % "I" % 1;
outFile << boost::format("%-43s%-2s%15d\n") % "Number of electrons" % "I" % (2*orbitals.getNumberOfAlphaElectrons());
outFile << boost::format("%-43s%-2s%15d\n") % "Number of alpha electrons" % "I" % orbitals.getNumberOfAlphaElectrons();
outFile << boost::format("%-43s%-2s%15d\n") % "Number of beta electrons" % "I" % orbitals.getNumberOfAlphaElectrons();
outFile << boost::format("%-43s%-2s%15d\n") % "Number of basis functions" % "I" % basis.AOBasisSize();
outFile << boost::format("%-43s%-2s%15d\n") % "Number of independent functions" % "I" % basis.AOBasisSize();
// clang-format on
// ATOMIC NUMBERS
outFile << boost::format("%-43s%-2s N= %10d\n") % "Atomic numbers" % "I" %
orbitals.QMAtoms().size();
temp_int = 1;
for (const auto& atom : orbitals.QMAtoms()) {
outFile << boost::format("%12d") % atom.getElementNumber();
if (temp_int % 6 == 0) {
outFile << "\n";
}
temp_int++;
}
outFile << ((temp_int - 1) % 6 == 0 ? "" : "\n");
// NUCLEAR CHARGES
outFile << boost::format("%-43s%-2s N= %10d\n") % "Nuclear charges" % "R" %
orbitals.QMAtoms().size();
temp_int = 1;
for (const auto& atom : orbitals.QMAtoms()) {
outFile << boost::format("%16.8e") % (double)atom.getNuccharge();
if (temp_int % 5 == 0) {
outFile << "\n";
}
temp_int++;
}
outFile << ((temp_int - 1) % 5 == 0 ? "" : "\n");
// CURRENT CARTESIAN COORDINATES
outFile << boost::format("%-43s%-2s N= %10d\n") %
"Current cartesian coordinates" % "R" %
(3 * orbitals.QMAtoms().size());
temp_int = 1;
for (const auto& atom : orbitals.QMAtoms()) {
for (int i = 0; i < 3; ++i) {
outFile << boost::format("%16.8e") % atom.getPos()(i);
if (temp_int % 5 == 0) {
outFile << "\n";
}
temp_int++;
}
}
outFile << ((temp_int - 1) % 5 == 0 ? "" : "\n");
// NUMBER OF PRIMITIVE SHELLS
outFile << boost::format("%-43s%-2s%15d\n") % "Number of primitive shells" %
"I" % basis.getNumberOfPrimitives();
// NUMBER OF CONTRACTED SHELLS
outFile << boost::format("%-43s%-2s%15d\n") %
"Number of contracted shells" % "I" % basis.getNumofShells();
// PURE/CARTESIAN D
outFile << boost::format("%-43s%-2s%15d\n") % "Pure/Cartesian d shells " %
"I" % 0;
// PURE/CARTESIAN F
outFile << boost::format("%-43s%-2s%15d\n") % "Pure/Cartesian f shells " %
"I" % 0;
// HIGHEST ANGULAR MOMENTUM
outFile << boost::format("%-43s%-2s%15d\n") % "Highest angular momentum " %
"I" % basis.getMaxL();
// HIGHEST ANGULAR MOMENTUM
outFile << boost::format("%-43s%-2s%15d\n") %
"Largest degree of contraction " % "I" % basis.getMaxNprim();
// SHELL TYPES
outFile << boost::format("%-43s%-2s N= %10d\n") % "Shell types" % "I" %
(basis.getNumofShells());
temp_int = 1;
for (const auto& shell : basis) {
outFile << boost::format("%12d") % toGaussianL(shell.getL());
if (temp_int % 6 == 0) {
outFile << "\n";
}
temp_int++;
}
outFile << ((temp_int - 1) % 6 == 0 ? "" : "\n");
// NR OF PRIMITIVES PER SHELL
outFile << boost::format("%-43s%-2s N= %10d\n") %
"Number of primitives per shell" % "I" %
(basis.getNumofShells());
temp_int = 1;
for (const AOShell& shell : basis) {
outFile << boost::format("%12d") % shell.getSize();
if (temp_int % 6 == 0) {
outFile << "\n";
}
temp_int++;
}
outFile << ((temp_int - 1) % 6 == 0 ? "" : "\n");
// SHELL TO ATOM MAP
outFile << boost::format("%-43s%-2s N= %10d\n") % "Shell to atom map" %
"I" % (basis.getNumofShells());
temp_int = 1;
for (const AOShell& shell : basis) {
// Gaussian indices start at 1, hence the + 1
outFile << boost::format("%12d") % (shell.getAtomIndex() + 1);
if (temp_int % 6 == 0) {
outFile << "\n";
}
temp_int++;
}
outFile << ((temp_int - 1) % 6 == 0 ? "" : "\n");
// PRIMITIVE EXPONENTS
outFile << boost::format("%-43s%-2s N= %10d\n") % "Primitive exponents" %
"R" % basis.getNumberOfPrimitives();
temp_int = 1;
for (const AOShell& shell : basis) {
for (const AOGaussianPrimitive& prim : shell) {
outFile << boost::format("%16.8e") % prim.getDecay();
if (temp_int % 5 == 0) {
outFile << "\n";
}
temp_int++;
}
}
outFile << ((temp_int - 1) % 5 == 0 ? "" : "\n");
// CONTRACTION COEFFICIENTS
outFile << boost::format("%-43s%-2s N= %10d\n") %
"Contraction coefficients" % "R" %
basis.getNumberOfPrimitives();
temp_int = 1;
for (const AOShell& shell : basis) {
for (const AOGaussianPrimitive& prim : shell) {
outFile << boost::format("%16.8e") % prim.getContraction();
if (temp_int % 5 == 0) {
outFile << "\n";
}
temp_int++;
}
}
outFile << ((temp_int - 1) % 5 == 0 ? "" : "\n");
// SHELL COORDINATES
outFile << boost::format("%-43s%-2s N= %10d\n") %
"Coordinates of each shell" % "R" %
(3 * basis.getNumofShells());
temp_int = 1;
for (const AOShell& shell : basis) {
for (int i = 0; i < 3; ++i) {
outFile << boost::format("%16.8e") % shell.getPos()(i);
if (temp_int % 5 == 0) {
outFile << "\n";
}
temp_int++;
}
}
outFile << ((temp_int - 1) % 5 == 0 ? "" : "\n");
// TOTAL ENERGY
outFile << boost::format("%-43s%-2s%22.15e\n") % "Total Energy" % "R" %
orbitals.getDFTTotalEnergy();
// ALPHA ORBITAL ENERGIES
outFile << boost::format("%-43s%-2s N= %10d\n") %
"Alpha Orbital Energies" % "R" %
orbitals.MOs().eigenvalues().size();
temp_int = 1;
for (Index i = 0; i < orbitals.MOs().eigenvalues().size(); ++i) {
outFile << boost::format("%16.8e") % orbitals.MOs().eigenvalues()[i];
if (temp_int % 5 == 0) {
outFile << "\n";
}
temp_int++;
}
outFile << ((temp_int - 1) % 5 == 0 ? "" : "\n");
// ALPHA ORBITAL ENERGIES
outFile << boost::format("%-43s%-2s N= %10d\n") % "Alpha MO coefficients" %
"R" %
(orbitals.MOs().eigenvalues().size() *
orbitals.MOs().eigenvalues().size());
outFile << reorderedMOCoefficients(orbitals);
// DENSITY MATRIX
outFile << boost::format("%-43s%-2s N= %10d\n") % "Total SCF Density" %
"R" %
((orbitals.MOs().eigenvalues().size() *
(orbitals.MOs().eigenvalues().size() - 1)) /
2 +
orbitals.MOs().eigenvalues().size());
outFile << densityMatrixToString(orbitals);
}
}

} // namespace xtp
} // namespace votca
Loading