21#include <boost/format.hpp>
40 string spintype = options.
get(
"spin").
as<std::string>();
41 if (spintype ==
"all") {
44 }
else if (spintype ==
"triplet") {
47 }
else if (spintype ==
"singlet") {
51 throw std::runtime_error(
53 "Choice % for type not known. Available singlet,triplet,all") %
78 const std::string& name,
79 const Eigen::MatrixXd& mat,
84 for (
Index i = 0; i < mat.rows(); i++) {
86 for (
Index j = 0; j < mat.cols(); j++) {
87 if (j > 0) row_str +=
" ";
88 row_str += (format(
"%1$1.6e") % (mat(i, j) * conversion)).str();
90 mat_prop.
setAttribute(
"row_" + std::to_string(i), row_str);
101 Property& coupling_summary = summary.
add(
"coupling",
"");
117 coupling_summary.
setAttribute(
"j_pert", (format(
"%1$1.6e") % JAB_pert).str());
118 coupling_summary.
setAttribute(
"j_diag", (format(
"%1$1.6e") % JAB_diag).str());
132 string algorithm =
"j_diag";
134 algorithm =
"j_pert";
138 auto WriteSpinChannel = [&](
const std::string& spin_name,
139 const Eigen::MatrixXd& J_dimer,
140 const Eigen::MatrixXd& S_dimer,
142 const Eigen::VectorXd& monA_energies,
143 const Eigen::VectorXd& monB_energies,
144 const std::vector<Eigen::Vector3d>& tdipsA,
145 const std::vector<Eigen::Vector3d>& tdipsB,
147 Property& spin_summary = bsecoupling.
add(spin_name,
"");
151 for (
Index stateA = 0; stateA <
levA_; ++stateA) {
153 for (
Index stateB = 0; stateB <
levB_; ++stateB) {
165 Property& mono_prop = spin_summary.
add(
"monomer_energies",
"");
167 for (
Index i = 0; i < monA_energies.size(); i++) {
169 QMState st(spin_type, i,
false);
171 e.setAttribute(
"eV", (format(
"%1$1.6e") % monA_energies(i)).str());
172 if (i <
static_cast<Index>(tdipsA.size())) {
173 e.setAttribute(
"tdx", (format(
"%1$1.6e") % tdipsA[i].x()).str());
174 e.setAttribute(
"tdy", (format(
"%1$1.6e") % tdipsA[i].y()).str());
175 e.setAttribute(
"tdz", (format(
"%1$1.6e") % tdipsA[i].z()).str());
179 for (
Index i = 0; i < monB_energies.size(); i++) {
181 QMState st(spin_type, i,
false);
183 e.setAttribute(
"eV", (format(
"%1$1.6e") % monB_energies(i)).str());
184 if (i <
static_cast<Index>(tdipsB.size())) {
185 e.setAttribute(
"tdx", (format(
"%1$1.6e") % tdipsB[i].x()).str());
186 e.setAttribute(
"tdy", (format(
"%1$1.6e") % tdipsB[i].y()).str());
187 e.setAttribute(
"tdz", (format(
"%1$1.6e") % tdipsB[i].z()).str());
194 Property& diag_prop = spin_summary.
add(
"diagnostics",
"");
195 diag_prop.
setAttribute(
"xi", (format(
"%1$1.4f") % diag.xi).str());
197 "pt_rm_discrepancy_eV",
202 diag.downfolding_safe ?
"true" :
"false");
209 Index ct = J_dimer.rows() - bse_exc;
211 Property& tb_prop = spin_summary.
add(
"tb_matrices",
"");
220 J_dimer.topLeftCorner(bse_exc, bse_exc),
223 S_dimer.topLeftCorner(bse_exc, bse_exc));
227 J_dimer.topRightCorner(bse_exc, ct),
230 S_dimer.topRightCorner(bse_exc, ct));
232 J_dimer.bottomRightCorner(ct, ct),
235 S_dimer.bottomRightCorner(ct, ct));
252 const std::vector<Eigen::Vector3d> empty_dipoles;
256 empty_dipoles, empty_dipoles,
262 Index methodindex)
const {
268 Index methodindex)
const {
276 const Eigen::MatrixXd& A_AB,
277 const Eigen::MatrixXd& B_AB)
const {
280 Index bseAB_size = bseAB_vtotal * bseAB_ctotal;
281 Eigen::MatrixXd CTstates = Eigen::MatrixXd::Zero(bseAB_size, noAB + noBA);
283 auto A_occ = A_AB.middleCols(bseA_vtotal -
occA_,
occA_);
284 auto A_unocc = A_AB.middleCols(bseA_vtotal,
unoccA_);
285 auto B_occ = B_AB.middleCols(bseB_vtotal -
occB_,
occB_);
286 auto B_unocc = B_AB.middleCols(bseB_vtotal,
unoccB_);
288 const Eigen::MatrixXd A_occ_occ = A_occ.topRows(bseAB_vtotal);
289 const Eigen::MatrixXd B_unocc_unocc = B_unocc.bottomRows(bseAB_ctotal);
293 <<
TimeStamp() <<
" Setting up CT-states" << flush;
295#pragma omp parallel for
296 for (
Index a_occ = 0; a_occ <
occA_; a_occ++) {
299 Eigen::MatrixXd Coeff =
300 B_unocc_unocc.col(b_unocc) * A_occ_occ.col(a_occ).transpose();
301 CTstates.col(index) =
302 Eigen::Map<Eigen::VectorXd>(Coeff.data(), bseAB_size);
306 <<
TimeStamp() <<
" " << noBA <<
" CT states A+B- created" << flush;
308 const Eigen::MatrixXd A_unocc_unocc = A_unocc.bottomRows(bseAB_ctotal);
309 const Eigen::MatrixXd B_occ_occ = B_occ.topRows(bseAB_vtotal);
311#pragma omp parallel for
312 for (
Index b_occ = 0; b_occ <
occB_; b_occ++) {
315 Eigen::MatrixXd Coeff =
316 A_unocc_unocc.col(a_unocc) * B_occ_occ.col(b_occ).transpose();
317 CTstates.col(index) =
318 Eigen::Map<Eigen::VectorXd>(Coeff.data(), bseAB_size);
322 <<
TimeStamp() <<
" " << noBA <<
" CT states A-B+ created" << flush;
327 const Eigen::MatrixXd& BSE_Coeffs,
const Eigen::MatrixXd& X_AB,
329 Index bseAB_ctotal)
const {
330 Index bseAB_size = bseAB_vtotal * bseAB_ctotal;
331 auto X_occ = X_AB.leftCols(bseX_vtotal);
332 auto X_unocc = X_AB.rightCols(bseX_ctotal);
333 const Eigen::MatrixXd X_occ_occ = X_occ.topRows(bseAB_vtotal);
334 const Eigen::MatrixXd X_unocc_unocc = X_unocc.bottomRows(bseAB_ctotal);
335 Eigen::MatrixXd result = Eigen::MatrixXd::Zero(bseAB_size, BSE_Coeffs.cols());
337 for (
Index i = 0; i < BSE_Coeffs.cols(); i++) {
338 Eigen::VectorXd coeff = BSE_Coeffs.col(i);
339 Eigen::Map<Eigen::MatrixXd> coeffmatrix =
340 Eigen::Map<Eigen::MatrixXd>(coeff.data(), bseX_ctotal, bseX_vtotal);
341 Eigen::MatrixXd proj = X_unocc_unocc * coeffmatrix * X_occ_occ.transpose();
342 result.col(i) = Eigen::Map<Eigen::VectorXd>(proj.data(), proj.size());
350 }
else if (value > 0) {
361 <<
TimeStamp() <<
" Calculating exciton couplings" << flush;
369 if ((basisA == 0) || (basisB == 0)) {
370 throw std::runtime_error(
"Basis set size is not stored in monomers");
378 Index bseA_vtotal = bseA_vmax - bseA_vmin + 1;
379 Index bseA_ctotal = bseA_cmax - bseA_cmin + 1;
380 Index bseA_total = bseA_vtotal + bseA_ctotal;
381 Index bseA_size = bseA_vtotal * bseA_ctotal;
386 <<
TimeStamp() <<
" molecule A has " << bseA_singlet_exc
387 <<
" singlet excitons with dimension " << bseA_size << flush;
389 <<
TimeStamp() <<
" molecule A has " << bseA_triplet_exc
390 <<
" triplet excitons with dimension " << bseA_size << flush;
397 Index bseB_vtotal = bseB_vmax - bseB_vmin + 1;
398 Index bseB_ctotal = bseB_cmax - bseB_cmin + 1;
399 Index bseB_total = bseB_vtotal + bseB_ctotal;
400 Index bseB_size = bseB_vtotal * bseB_ctotal;
405 <<
TimeStamp() <<
" molecule B has " << bseB_singlet_exc
406 <<
" singlet excitons with dimension " << bseB_size << flush;
408 <<
TimeStamp() <<
" molecule B has " << bseB_triplet_exc
409 <<
" triplet excitons with dimension " << bseB_size << flush;
412 if (
levA_ > bseA_singlet_exc) {
414 <<
" Number of excitons you want is greater "
415 "than stored for molecule "
416 "A. Setting to max number available"
418 levA_ = bseA_singlet_exc;
420 if (
levB_ > bseB_singlet_exc) {
422 <<
" Number of excitons you want is greater "
423 "than stored for molecule "
424 "B. Setting to max number available"
426 levB_ = bseB_singlet_exc;
430 if (
levA_ > bseA_triplet_exc) {
433 <<
" Number of Frenkel states you want is greater than stored for "
434 "molecule A. Setting to max number available"
436 levA_ = bseA_triplet_exc;
438 if (
levB_ > bseB_triplet_exc) {
441 <<
" Number of Frenkel states you want is greater than stored for "
442 "molecule B. Setting to max number available"
444 levB_ = bseB_triplet_exc;
450 <<
" Number of unoccupied orbitals in molecule A for CT creation "
451 "exceeds number of KS-orbitals in BSE"
458 <<
" Number of unoccupied orbitals in molecule B for CT creation "
459 "exceeds number of KS-orbitals in BSE"
466 <<
" Number of occupied orbitals in molecule A for CT creation "
467 "exceeds number of KS-orbitals in BSE"
474 <<
" Number of occupied orbitals in molecule B for CT creation "
475 "exceeds number of KS-orbitals in BSE"
485 Index bseAB_vtotal = bseAB_vmax - bseAB_vmin + 1;
486 Index bseAB_ctotal = bseAB_cmax - bseAB_cmin + 1;
487 Index bseAB_total = bseAB_vtotal + bseAB_ctotal;
488 Index bseAB_size = bseAB_vtotal * bseAB_ctotal;
491 <<
TimeStamp() <<
" levels used for BSE of molA: " << bseA_vmin
492 <<
" to " << bseA_cmax <<
" total: " << bseA_total << flush;
494 <<
TimeStamp() <<
" levels used for BSE of molB: " << bseB_vmin
495 <<
" to " << bseB_cmax <<
" total: " << bseB_total << flush;
497 <<
TimeStamp() <<
" levels used for BSE of dimer AB: " << bseAB_vmin
498 <<
" to " << bseAB_cmax <<
" total: " << bseAB_total << flush;
500 Eigen::MatrixXd MOsA =
502 Eigen::MatrixXd MOsB =
504 Eigen::MatrixXd MOsAB =
508 <<
TimeStamp() <<
" Calculating overlap matrix for basisset: "
513 <<
TimeStamp() <<
" Projecting monomers onto dimer orbitals" << flush;
515 Eigen::MatrixXd A_AB = overlap.topRows(basisA).transpose() * MOsA;
516 Eigen::MatrixXd B_AB = overlap.bottomRows(basisB).transpose() * MOsB;
517 Eigen::VectorXd mag_A = A_AB.colwise().squaredNorm();
518 if (mag_A.any() < 0.95) {
521 <<
"Projection of orbitals of monomer A on dimer is insufficient,mag="
522 << mag_A.minCoeff() << flush;
524 Eigen::VectorXd mag_B = B_AB.colwise().squaredNorm();
525 if (mag_B.any() < 0.95) {
528 <<
"Projection of orbitals of monomer B on dimer is insufficient,mag="
529 << mag_B.minCoeff() << flush;
541 Eigen::MatrixXd Hqp = qpcoeff *
561 <<
TimeStamp() <<
" Evaluating singlets" << flush;
563 <<
TimeStamp() <<
" Setup Hamiltonian" << flush;
575 Eigen::MatrixXd FE_AB = Eigen::MatrixXd::Zero(bseAB_size,
levA_ +
levB_);
576 const Eigen::MatrixXd bseA =
579 bseA, A_AB, bseA_vtotal, bseA_ctotal, bseAB_vtotal, bseAB_ctotal);
580 const Eigen::MatrixXd bseB =
583 bseB, B_AB, bseB_vtotal, bseB_ctotal, bseAB_vtotal, bseAB_ctotal);
585 bseA_vtotal, bseB_vtotal, bseAB_vtotal, bseAB_ctotal, A_AB, B_AB);
590 <<
TimeStamp() <<
" calculated singlet couplings " << flush;
594 <<
TimeStamp() <<
" Evaluating triplets" << flush;
604 Eigen::MatrixXd FE_AB = Eigen::MatrixXd::Zero(bseAB_size,
levA_ +
levB_);
605 const Eigen::MatrixXd bseA =
608 bseA, A_AB, bseA_vtotal, bseA_ctotal, bseAB_vtotal, bseAB_ctotal);
609 const Eigen::MatrixXd bseB =
612 bseB, B_AB, bseB_vtotal, bseB_ctotal, bseAB_vtotal, bseAB_ctotal);
614 bseA_vtotal, bseB_vtotal, bseAB_vtotal, bseAB_ctotal, A_AB, B_AB);
619 <<
TimeStamp() <<
" calculated triplet couplings " << flush;
622 <<
TimeStamp() <<
" Done with exciton couplings" << flush;
648 Eigen::MatrixXd& CTStates)
const {
649 Index ct = CTStates.cols();
651 Index bseAB_size = FE_AB.rows();
657 Eigen::VectorXd norm = CTStates.colwise().norm();
658 Index minstateindex = 0;
659 double minnorm = norm.minCoeff(&minstateindex);
660 if (minnorm < 0.95) {
662 <<
TimeStamp() <<
" WARNING: CT-state " << minstateindex
663 <<
" norm is only " << minnorm
664 <<
" -- near-linear dependence in projection basis" << flush;
668 <<
" CT states into projection (no pre-orthogonalization)" << flush;
671 Eigen::MatrixXd projection(bseAB_size, bse_exc + ct);
673 <<
TimeStamp() <<
" merging projections into one vector " << flush;
674 projection.leftCols(bse_exc) = FE_AB;
677 projection.rightCols(ct) = CTStates;
679 CTStates.resize(0, 0);
691template <
class BSE_OPERATOR>
693 Eigen::MatrixXd& projection,
694 Eigen::MatrixXd& J_dimer_out,
695 Eigen::MatrixXd& S_dimer_out)
const {
697 <<
TimeStamp() <<
" Setting up coupling matrix size "
698 << projection.cols() << flush;
701 J_dimer_out = projection.transpose() * (
H * projection).eval();
704 <<
TimeStamp() <<
" Setting up overlap matrix size "
705 << projection.cols() << flush;
706 S_dimer_out = projection.transpose() * projection;
708 projection.resize(0, 0);
711 <<
"---------------------------------------" << flush;
717 <<
"---------------------------------------" << flush;
719 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(S_dimer_out);
721 <<
TimeStamp() <<
" Smallest value of dimer overlapmatrix is "
722 << es.eigenvalues()(0) << flush;
724 Eigen::MatrixXd Sm1 = es.operatorInverseSqrt();
725 Eigen::MatrixXd J_ortho = Sm1 * J_dimer_out * Sm1;
728 <<
"---------------------------------------" << flush;
734 <<
"---------------------------------------" << flush;
750 const Eigen::MatrixXd& J_dimer,
const Eigen::MatrixXd& J_pert,
751 const Eigen::MatrixXd& J_diag)
const {
753 Index ct = J_dimer.rows() - bse_exc;
757 for (
Index i = 0; i < bse_exc; i++) {
758 double Ei = J_dimer(i, i);
759 for (
Index k = bse_exc; k < bse_exc + ct; k++) {
760 double Ek = J_dimer(k, k);
761 double dE = std::abs(Ei - Ek);
762 double coupling = std::abs(J_dimer(i, k));
764 diag.
xi = std::max(diag.
xi, coupling / dE);
767 diag.
xi = std::numeric_limits<double>::infinity();
777 double diff = std::abs(J_pert(i, jd) - J_diag(i, jd));
795template <
class BSE_OPERATOR>
797 Eigen::MatrixXd& FE_AB, Eigen::MatrixXd& CTStates,
BSE_OPERATOR H,
798 Eigen::MatrixXd& J_dimer_out, Eigen::MatrixXd& S_dimer_out,
802 Eigen::MatrixXd J_ortho =
805 std::array<Eigen::MatrixXd, 2> J;
807 <<
TimeStamp() <<
" Running Perturbation algorithm" << flush;
810 <<
TimeStamp() <<
" Running Projection algorithm" << flush;
816 <<
TimeStamp() <<
" Diagnostics: xi=" << diag_out.
xi
822 <<
"---------------------------------------" << flush;
828 <<
"---------------------------------------" << flush;
841 const Eigen::MatrixXd& J_dimer)
const {
843 Index ct = J_dimer.rows() - bse_exc;
844 Eigen::MatrixXd J_result = J_dimer;
846 Eigen::MatrixXd transformation =
847 Eigen::MatrixXd::Identity(J_dimer.rows(), J_dimer.cols());
848 Eigen::MatrixXd Ct = J_dimer.bottomRightCorner(ct, ct);
849 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(Ct);
850 transformation.bottomRightCorner(ct, ct) = es.eigenvectors();
855 << J_dimer.topLeftCorner(bse_exc, bse_exc) << flush;
859 J_result = transformation.transpose() * J_dimer * transformation;
861 <<
"---------------------------------------" << flush;
865 <<
"---------------------------------------" << flush;
868 Eigen::MatrixXd Jmatrix = Eigen::MatrixXd::Zero(bse_exc, bse_exc);
869 for (
Index stateA = 0; stateA <
levA_; stateA++) {
870 double Ea = J_result(stateA, stateA);
871 for (
Index stateB = 0; stateB <
levB_; stateB++) {
874 <<
TimeStamp() <<
" Calculating coupling between exciton A"
875 << stateA + 1 <<
" and exciton B" << stateB + 1 << flush;
876 double J = J_result(stateA, stateBd);
877 double Eb = J_result(stateBd, stateBd);
878 for (
Index k = bse_exc; k < (bse_exc + ct); k++) {
879 double Eab = J_result(k, k);
880 if (std::abs(Eab - Ea) < 0.001) {
882 <<
TimeStamp() <<
"Energydifference between state A "
883 << stateA + 1 <<
"and CT state " << k + 1 <<
" is " << Eab - Ea
886 if (std::abs(Eab - Eb) < 0.001) {
888 <<
TimeStamp() <<
"Energydifference between state B "
889 << stateB + 1 <<
"and CT state " << k + 1 <<
" is " << Eab - Eb
895 J += 0.5 * J_result(k, stateA) * J_result(k, stateBd) *
896 (1.0 / (Ea - Eab) + 1.0 / (Eb - Eab));
898 Jmatrix(stateA, stateBd) = J;
899 Jmatrix(stateBd, stateA) = J;
916 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(J_dimer);
918 <<
"---------------------------------------" << flush;
924 <<
"---------------------------------------" << flush;
926 Eigen::MatrixXd Jmat = Eigen::MatrixXd::Zero(bse_exc, bse_exc);
927 for (
Index stateA = 0; stateA <
levA_; stateA++) {
928 for (
Index stateB = 0; stateB <
levB_; stateB++) {
931 <<
TimeStamp() <<
" Calculating coupling between exciton A"
932 << stateA + 1 <<
" and exciton B" << stateB + 1 << flush;
934 std::array<int, 2> indexes;
935 std::array<int, 2> signs;
938 es.eigenvectors().row(stateA).cwiseAbs().maxCoeff(&indexes[0]);
939 es.eigenvectors().row(stateBd).cwiseAbs().maxCoeff(&indexes[1]);
940 if (indexes[0] == indexes[1]) {
942 Eigen::RowVectorXd stateamplitudes =
943 es.eigenvectors().row(stateBd).cwiseAbs();
944 stateamplitudes[indexes[1]] = 0.0;
945 stateamplitudes.maxCoeff(&indexes[1]);
948 signs[0] =
GetSign(es.eigenvectors()(stateA, indexes[0]));
949 signs[1] =
GetSign(es.eigenvectors()(stateBd, indexes[1]));
952 <<
TimeStamp() <<
" Order is: [Initial state n->nth eigenvalue]"
955 <<
"->" << indexes[0] + 1 <<
" ";
957 <<
"->" << indexes[1] + 1 <<
" " << flush;
961 Eigen::Matrix2d Emat = Eigen::Matrix2d::Zero();
962 Eigen::Matrix2d Tmat = Eigen::Matrix2d::Zero();
963 for (
Index i = 0; i < 2; i++) {
964 Index k = indexes[i];
965 double sign = signs[i];
966 Tmat(0, i) = sign * es.eigenvectors()(stateA, k);
967 Tmat(1, i) = sign * es.eigenvectors()(stateBd, k);
968 Emat(i, i) = es.eigenvalues()(k);
970 Tmat.colwise().normalize();
972 if (Tmat.determinant() < 0) {
974 <<
" Reduced state matrix is not in a right handed basis, "
975 "multiplying second eigenvector by -1 "
981 <<
"---------------------------------------" << flush;
986 Eigen::Matrix2d S_small = Tmat * Tmat.transpose();
990 Eigen::SelfAdjointEigenSolver<Eigen::Matrix2d> ss(S_small);
991 Eigen::Matrix2d sm1 = ss.operatorInverseSqrt();
992 Emat = sm1 * Emat * sm1;
995 <<
TimeStamp() <<
" Smallest value of dimer overlapmatrix is "
996 << ss.eigenvalues()(0) << flush;
1006 <<
"---------------------------------------" << flush;
1009 Eigen::Matrix2d J_small = Tmat * Emat * Tmat.transpose();
1013 Jmat(stateA, stateBd) = J_small(0, 1);
1014 Jmat(stateBd, stateA) = J_small(1, 0);
Container to hold Basisfunctions for all atoms.
Index AOBasisSize() const
Eigen::VectorXd monomerA_energies_triplet_
Eigen::MatrixXd J_dimer_triplet_
double getSingletCouplingElement(Index levelA, Index levelB, Index methodindex) const
Eigen::VectorXd monomerB_energies_singlet_
double getTripletCouplingElement(Index levelA, Index levelB, Index methodindex) const
Diagnostics diag_triplet_
bool output_perturbation_
std::string Identify() const
void CalculateCouplings(const Orbitals &orbitalsA, const Orbitals &orbitalsB, const Orbitals &orbitalsAB) override
evaluates electronic couplings
void Addoutput(tools::Property &type_summary, const Orbitals &orbitalsA, const Orbitals &orbitalsB) const override
void WriteToProperty(tools::Property &summary, const QMState &stateA, const QMState &stateB) const
Diagnostics ComputeDiagnostics(const Eigen::MatrixXd &J_dimer, const Eigen::MatrixXd &J_pert, const Eigen::MatrixXd &J_diag) const
Compute diagnostics from raw J_dimer and the two effective coupling matrices.
std::array< Eigen::MatrixXd, 2 > JAB_triplet
Eigen::MatrixXd Perturbation(const Eigen::MatrixXd &J_dimer) const
Eigen::VectorXd monomerB_energies_triplet_
std::array< Eigen::MatrixXd, 2 > ProjectExcitons(Eigen::MatrixXd &FE_AB, Eigen::MatrixXd &CTStates, BSE_OPERATOR H, Eigen::MatrixXd &J_dimer_out, Eigen::MatrixXd &S_dimer_out, Diagnostics &diag_out) const
Compute J_pert and J_diag, and store raw J_dimer/S_dimer and diagnostics for later output.
void Initialize(tools::Property &options) override
Eigen::MatrixXd S_dimer_singlet_
Eigen::VectorXd monomerA_energies_singlet_
Eigen::MatrixXd S_dimer_triplet_
std::array< Eigen::MatrixXd, 2 > JAB_singlet
Eigen::MatrixXd ProjectFrenkelExcitons(const Eigen::MatrixXd &BSE_Coeffs, const Eigen::MatrixXd &X_AB, Index bseX_vtotal, Index bseX_ctotal, Index bseAB_vtotal, Index bseAB_ctotal) const
static void WriteMatrixToProperty(tools::Property &prop, const std::string &name, const Eigen::MatrixXd &mat, double conversion=1.0)
Write an Eigen matrix as rows of space-separated values into an XML property node....
Eigen::MatrixXd SetupCTStates(Index bseA_vtotal, Index bseB_vtotal, Index bseAB_vtotal, Index bseAB_ctotal, const Eigen::MatrixXd &A_AB, const Eigen::MatrixXd &B_AB) const
Diagnostics diag_singlet_
Eigen::MatrixXd Fulldiag(const Eigen::MatrixXd &J_dimer) const
Eigen::MatrixXd CalcJ_dimer(BSE_OPERATOR &H, Eigen::MatrixXd &projection, Eigen::MatrixXd &J_dimer_out, Eigen::MatrixXd &S_dimer_out) const
Form J_dimer and S_dimer from the projection, then Lowdin orthogonalize to produce J_ortho.
Eigen::MatrixXd OrthogonalizeCTs(Eigen::MatrixXd &FE_AB, Eigen::MatrixXd &CTStates) const
Merge FE and CT projection vectors into a single projection matrix without pre-orthogonalization.
Eigen::MatrixXd J_dimer_singlet_
TripletOperator_TDA getTripletOperator_TDA() const
SingletOperator_TDA getSingletOperator_TDA() const
void configure(const options &opt, const Eigen::VectorXd &RPAEnergies, const Eigen::MatrixXd &Hqp_in)
Eigen::MatrixXd CalculateOverlapMatrix(const Orbitals &orbitalsAB) const
void CheckAtomCoordinates(const Orbitals &orbitalsA, const Orbitals &orbitalsB, const Orbitals &orbitalsAB) const
Container for molecular orbitals and derived one-particle data.
Index getBSEvmax() const
Return the highest valence orbital included in BSE.
const tools::EigenSystem & BSETriplets() const
Return read-only access to triplet BSE eigenpairs.
bool GetFlagUseHqpOffdiag() const
Index getBSEcmin() const
Return the lowest conduction orbital included in BSE.
const tools::EigenSystem & QPdiag() const
Return read-only access to the diagonalized quasiparticle representation.
Index getHomo() const
Return the default HOMO index used by spin-agnostic callers.
const tools::EigenSystem & BSESinglets() const
Return read-only access to singlet BSE eigenpairs.
Index getBSEcmax() const
Return the highest conduction orbital included in BSE.
const AOBasis & getAuxBasis() const
Return the auxiliary AO basis, throwing if it has not been initialized.
Index getBSEvmin() const
Return the lowest valence orbital included in BSE.
Index getRPAmax() const
Return the upper RPA orbital index.
const std::vector< Eigen::Vector3d > & TransitionDipoles() const
Return the stored transition dipole moments.
Index getBasisSetSize() const
Return the number of AO basis functions in the DFT basis.
const Eigen::VectorXd & RPAInputEnergies() const
Return read-only access to the RPA input energies.
Index getGWAmin() const
Return the lower GW orbital index.
const tools::EigenSystem & MOs() const
Return read-only access to alpha/restricted molecular orbitals.
Index getGWAmax() const
Return the upper GW orbital index.
const std::string & getDFTbasisName() const
Return the DFT basis-set name.
Index getRPAmin() const
Return the lower RPA orbital index.
const AOBasis & getDftBasis() const
Return the DFT AO basis, throwing if it has not been initialized.
Identifier for QMstates. Strings like S1 are converted into enum +zero indexed int.
std::string ToString() const
const QMStateType & Type() const
void Fill(const AOBasis &auxbasis, const AOBasis &dftbasis, const Eigen::MatrixXd &dft_orbitals)
void Initialize(Index basissize, Index mmin, Index mmax, Index nmin, Index nmax)
Timestamp returns the current time as a string Example: cout << TimeStamp().
#define XTP_LOG(level, log)
void Cite(const std::string &key)
marks a reference as used (thread safe; unknown keys are printed as such)
Charge transport classes.
int GetSign(double value)
Provides a means for comparing floating point numbers.
Diagnostic quantities for assessing whether CT downfolding is safe.