21#include <boost/format.hpp>
52 coupling.
setAttribute(
"j", (format(
"%1$1.6e") % J).str());
83 if (std::abs(MOEnergies(orbital.
getHomo()) - MOEnergies(orbital.
getLumo())) <
85 throw std::runtime_error(
86 "Homo Lumo Gap is smaller than degeneracy. "
87 "Either your degeneracy is too large or your Homo and Lumo are "
95 minimal = *std::min_element(deg_min.begin(), deg_min.end());
98 maximal = *std::max_element(deg_max.begin(), deg_max.end());
100 std::pair<Index, Index> result;
101 result.first = minimal;
102 result.second = maximal - minimal + 1;
113 std::vector<Index> list_levelsA =
115 std::vector<Index> list_levelsB =
120 for (
Index iA : list_levelsA) {
122 for (
Index iB : list_levelsB) {
124 double JAB_one_level =
JAB(indexA, indexB);
125 JAB_sq += JAB_one_level * JAB_one_level;
128 return std::sqrt(JAB_sq /
129 double(list_levelsA.size() * list_levelsB.size())) *
156 if ((basisA == 0) || (basisB == 0)) {
157 throw std::runtime_error(
"Basis set size is not stored in monomers");
167 <<
"Levels:Basis A[" << levelsA <<
":" << basisA <<
"]"
168 <<
" B[" << levelsB <<
":" << basisB <<
"]" << flush;
170 if ((levelsA == 0) || (levelsB == 0)) {
171 throw std::runtime_error(
172 "No information about number of occupied/unoccupied levels is stored");
184 Eigen::MatrixXd overlap =
188 <<
"Projecting monomers onto dimer orbitals" << flush;
189 Eigen::MatrixXd A_AB = MOsA.transpose() * overlap.topRows(basisA);
190 Eigen::MatrixXd B_AB = MOsB.transpose() * overlap.bottomRows(basisB);
191 Eigen::VectorXd mag_A = A_AB.rowwise().squaredNorm();
192 if (mag_A.any() < 0.95) {
195 <<
"Projection of orbitals of monomer A on dimer is insufficient,mag="
196 << mag_A.minCoeff() << flush;
198 Eigen::VectorXd mag_B = B_AB.rowwise().squaredNorm();
199 if (mag_B.any() < 0.95) {
202 <<
"Projection of orbitals of monomer B on dimer is insufficient,mag="
203 << mag_B.minCoeff() << flush;
206 Eigen::MatrixXd psi_AxB_dimer_basis(A_AB.rows() + B_AB.rows(), A_AB.cols());
207 psi_AxB_dimer_basis.topRows(A_AB.rows()) = A_AB;
208 psi_AxB_dimer_basis.bottomRows(B_AB.rows()) = B_AB;
211 <<
"Projecting the Fock matrix onto the dimer basis" << flush;
212 Eigen::MatrixXd JAB_dimer = psi_AxB_dimer_basis *
214 psi_AxB_dimer_basis.transpose();
216 Eigen::MatrixXd S_AxB = psi_AxB_dimer_basis * psi_AxB_dimer_basis.transpose();
217 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(S_AxB);
218 Eigen::MatrixXd Sm1 = es.operatorInverseSqrt();
220 << es.eigenvalues()(0) << flush;
221 JAB = Sm1 * JAB_dimer * Sm1;
Eigen::MatrixXd CalculateOverlapMatrix(const Orbitals &orbitalsAB) const
void CheckAtomCoordinates(const Orbitals &orbitalsA, const Orbitals &orbitalsB, const Orbitals &orbitalsAB) const
void WriteToProperty(tools::Property &type_summary, const Orbitals &orbitalsA, const Orbitals &orbitalsB, Index a, Index b) const
std::pair< Index, Index > Range_orbA
std::pair< Index, Index > DetermineRangeOfStates(const Orbitals &orbital, Index numberofstates) const
void Initialize(tools::Property &) override
double getCouplingElement(Index levelA, Index levelB, const Orbitals &orbitalsA, const Orbitals &orbitalsB) const
void Addoutput(tools::Property &type_summary, const Orbitals &orbitalsA, const Orbitals &orbitalsB) const override
std::pair< Index, Index > Range_orbB
void CalculateCouplings(const Orbitals &orbitalsA, const Orbitals &orbitalsB, const Orbitals &orbitalsAB) override
evaluates electronic couplings
std::string Identify() const
container for molecular orbitals
std::vector< Index > CheckDegeneracy(Index level, double energy_difference) const
Index getBasisSetSize() const
const tools::EigenSystem & MOs() const
const std::string & getDFTbasisName() const
#define XTP_LOG(level, log)
base class for all analysis tools