43 const Eigen::MatrixXd& Hqp_in) {
52 if (
opt_.use_Hqp_offdiag) {
61 const Eigen::VectorXd& RPAInputEnergies) {
66 Eigen::MatrixXd Hqp_BSE = Eigen::MatrixXd::Zero(hqp_size, hqp_size);
71 Hqp_BSE = Hqp.block(start, start, hqp_size, hqp_size);
73 Index virtoffset = gwsize - start;
74 Hqp_BSE.topLeftCorner(virtoffset, virtoffset) =
75 Hqp.block(start, start, virtoffset, virtoffset);
78 Hqp_BSE.diagonal().tail(virt_extra) =
79 RPAInputEnergies.segment(RPAoffset + virtoffset, virt_extra);
85 Hqp_BSE.diagonal().head(occ_extra) =
86 RPAInputEnergies.segment(RPAoffset, occ_extra);
88 Hqp_BSE.block(occ_extra, occ_extra, gwsize, gwsize) = Hqp;
91 Index virtoffset = occ_extra + gwsize;
93 Hqp_BSE.diagonal().tail(virt_extra) =
94 RPAInputEnergies.segment(RPAoffset + virtoffset, virt_extra);
102 const Eigen::VectorXd& RPAInputEnergies,
double energy) {
107 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(
109 Mmn_.MultiplyRightWithAuxMatrix(es.eigenvectors());
112 for (
Index i = 0; i < es.eigenvalues().size(); ++i) {
113 if (es.eigenvalues()(i) > 1
e-8) {
119template <
typename BSE_OPERATOR>
161 <<
TimeStamp() <<
" Setup TDA singlet hamiltonian " << flush;
179template <
typename BSE_OPERATOR>
182 std::chrono::time_point<std::chrono::system_clock> start =
183 std::chrono::system_clock::now();
198 std::chrono::time_point<std::chrono::system_clock> end =
199 std::chrono::system_clock::now();
200 std::chrono::duration<double> elapsed_time = end - start;
203 << elapsed_time.count() <<
" secs" << flush;
214 <<
TimeStamp() <<
" Setup Full singlet hamiltonian " << flush;
224 <<
TimeStamp() <<
" Setup Full triplet hamiltonian " << flush;
228template <
typename BSE_OPERATOR_A,
typename BSE_OPERATOR_B>
230 BSE_OPERATOR_B& Bop)
const {
231 std::chrono::time_point<std::chrono::system_clock> start =
232 std::chrono::system_clock::now();
250 Eigen::MatrixXd tmpX = DS.
eigenvectors().topRows(Aop.rows());
251 Eigen::MatrixXd tmpY = DS.
eigenvectors().bottomRows(Bop.rows());
254 Eigen::VectorXd normX = tmpX.colwise().squaredNorm();
255 Eigen::VectorXd normY = tmpY.colwise().squaredNorm();
257 Eigen::ArrayXd sqinvnorm = (normX - normY).array().inverse().cwiseSqrt();
259 result.
eigenvectors() = tmpX * sqinvnorm.matrix().asDiagonal();
260 result.
eigenvectors2() = tmpY * sqinvnorm.matrix().asDiagonal();
262 std::chrono::time_point<std::chrono::system_clock> end =
263 std::chrono::system_clock::now();
264 std::chrono::duration<double> elapsed_time = end - start;
267 << elapsed_time.count() <<
" secs" << flush;
275 double dq = frag.value().H[state] + frag.value().E[state];
276 double qeff = dq + frag.value().Gs;
279 " Fragment %1$4d -- hole: %2$5.1f%% electron: "
280 "%3$5.1f%% dQ: %4$+5.2f Qeff: %5$+5.2f") %
281 int(frag.getId()) % (100.0 * frag.value().
H[state]) %
282 (-100.0 * frag.value().E[state]) % dq % qeff
291 double weight = weights(i_bse);
292 if (weight >
opt_.min_print_weight) {
294 << boost::format(
" HOMO-%1$-3d -> LUMO+%2$-3d : %3$3.1f%%") %
295 (
opt_.homo - vc.
v(i_bse)) % (vc.
c(i_bse) -
opt_.homo - 1) %
312 if (fragments.size() > 0) {
321 <<
" ====== singlet energies (eV) ====== " << flush;
323 Eigen::VectorXd weights =
329 double osc = oscs[i];
332 " S = %1$4d Omega = %2$+1.12f eV lamdba = %3$+3.2f nm <FT> "
333 "= %4$+1.4f <K_x> = %5$+1.4f <K_d> = %6$+1.4f") %
334 (i + 1) % (hrt2ev * energies(i)) %
335 (1240.0 / (hrt2ev * energies(i))) %
344 " TrDipole length gauge[e*bohr] dx = %1$+1.4f dy = "
345 "%2$+1.4f dz = %3$+1.4f |d|^2 = %4$+1.4f f = %5$+1.4f") %
346 trdip[0] % trdip[1] % trdip[2] % (trdip.squaredNorm()) % osc
350 if (fragments.size() > 0) {
365 if (fragments.size() > 0) {
372 <<
" ====== triplet energies (eV) ====== " << flush;
374 Eigen::VectorXd weights =
382 " T = %1$4d Omega = %2$+1.12f eV lamdba = %3$+3.2f nm <FT> "
383 "= %4$+1.4f <K_d> = %5$+1.4f") %
391 if (fragments.size() > 0) {
400Eigen::VectorXd
ExpValue(
const Eigen::MatrixXd& state1, OP OPxstate2) {
401 return state1.cwiseProduct(OPxstate2.eval()).colwise().sum().transpose();
404Eigen::VectorXd
ExpValue(
const Eigen::MatrixXd& state1,
405 const Eigen::MatrixXd& OPxstate2) {
406 return state1.cwiseProduct(OPxstate2).colwise().sum().transpose();
409template <
typename BSE_OPERATOR>
427 expectation_values.
cross_term = Eigen::VectorXd::Zero(0);
429 return expectation_values;
432template <
typename BSE_OPERATOR>
442 const Eigen::MatrixXd BSECoefs_state =
445 const Eigen::MatrixXd temp =
H * BSECoefs_state;
450 const Eigen::MatrixXd BSECoefs2_state =
454 ExpValue(BSECoefs2_state,
H * BSECoefs2_state);
457 expectation_values.
cross_term = Eigen::VectorXd::Zero(0);
460 return expectation_values;
534 Eigen::VectorXd Hd_static_contribution = expectation_values.
direct_term;
539 Hd_static_contribution += expectation_values.
cross_term;
542 const Eigen::VectorXd& BSEenergies = BSECoefs.
eigenvalues();
545 Eigen::VectorXd BSEenergies_dynamic = BSEenergies;
548 for (
Index i_exc = 0; i_exc < BSEenergies.size(); i_exc++) {
550 <<
" static " << BSEenergies(i_exc) << flush;
555 double old_energy = BSEenergies_dynamic(i_exc);
561 QMState state(type, i_exc,
false);
563 Eigen::VectorXd Hd_dynamic_contribution = expectation_values.
direct_term;
569 Hd_dynamic_contribution += expectation_values.
cross_term;
573 BSEenergies_dynamic(i_exc) = BSEenergies(i_exc) +
574 Hd_static_contribution(i_exc) -
575 Hd_dynamic_contribution(0);
578 <<
"Dynamical Screening BSE, excitation " << i_exc <<
" iteration "
579 << iter <<
" dynamic " << BSEenergies_dynamic(i_exc) << flush;
582 if (std::abs(BSEenergies_dynamic(i_exc) - old_energy) <
dyn_tolerance_) {
593 "dynamical screening (eV) ====== "
597 double osc = oscs[i];
600 " S(dynamic) = %1$4d Omega = %2$+1.12f eV lamdba = %3$+3.2f "
603 (i + 1) % (hrt2ev * BSEenergies_dynamic(i)) %
604 (1240.0 / (hrt2ev * BSEenergies_dynamic(i))) %
605 (osc * BSEenergies_dynamic(i) / BSEenergies(i))
612 "dynamical screening (eV) ====== "
617 " T(dynamic) = %1$4d Omega = %2$+1.12f eV lamdba = %3$+3.2f "
619 (i + 1) % (hrt2ev * BSEenergies_dynamic(i)) %
620 (1240.0 / (hrt2ev * BSEenergies_dynamic(i)))
void Solve_singlets(Orbitals &orb) const
void printFragInfo(const std::vector< QMFragment< BSE_Population > > &frags, Index state) const
void PrintWeights(const Eigen::VectorXd &weights) const
void Analyze_singlets(std::vector< QMFragment< BSE_Population > > fragments, const Orbitals &orb) const
tools::EigenSystem Solve_triplets_BTDA() const
TripletOperator_TDA getTripletOperator_TDA() const
SingletOperator_TDA getSingletOperator_TDA() const
ExpectationValues ExpectationValue_Operator_State(const QMState &state, const Orbitals &orb, const BSE_OPERATOR &H) const
tools::EigenSystem Solve_singlets_BTDA() const
void Perturbative_DynamicalScreening(const QMStateType &type, Orbitals &orb)
void Analyze_triplets(std::vector< QMFragment< BSE_Population > > fragments, const Orbitals &orb) const
void SetupDirectInteractionOperator(const Eigen::VectorXd &DFTenergies, double energy)
void configure(const options &opt, const Eigen::VectorXd &RPAEnergies, const Eigen::MatrixXd &Hqp_in)
Eigen::VectorXd epsilon_0_inv_
ExpectationValues ExpectationValue_Operator(const QMStateType &type, const Orbitals &orb, const BSE_OPERATOR &H) const
Interaction Analyze_eh_interaction(const QMStateType &type, const Orbitals &orb) const
tools::EigenSystem Solve_singlets_TDA() const
void configureBSEOperator(BSE_OPERATOR &H) const
tools::EigenSystem solve_hermitian(BSE_OPERATOR &h) const
void Solve_triplets(Orbitals &orb) const
tools::EigenSystem Solve_nonhermitian_Davidson(BSE_OPERATOR_A &Aop, BSE_OPERATOR_B &Bop) const
Eigen::MatrixXd AdjustHqpSize(const Eigen::MatrixXd &Hqp_in, const Eigen::VectorXd &RPAInputEnergies)
tools::EigenSystem Solve_triplets_TDA() const
Use Davidson algorithm to solve A*V=E*V.
void set_max_search_space(Index N)
Eigen::VectorXd eigenvalues() const
void solve(const MatrixReplacement &A, Index neigen, Index size_initial_guess=0)
void set_iter_max(Index N)
void set_matrix_type(std::string mt)
void set_correction(std::string method)
void set_size_update(std::string update_size)
void set_tolerance(std::string tol)
Eigen::MatrixXd eigenvectors() const
container for molecular orbitals
const tools::EigenSystem & BSETriplets() const
void CalcCoupledTransition_Dipoles()
const tools::EigenSystem & BSESinglets() const
bool getTDAApprox() const
Eigen::VectorXd Oscillatorstrengths() const
const std::vector< Eigen::Vector3d > & TransitionDipoles() const
const Eigen::VectorXd & RPAInputEnergies() const
const Eigen::VectorXd & BSETriplets_dynamic() const
void setTDAApprox(bool usedTDA)
const Eigen::VectorXd & BSESinglets_dynamic() const
void CalcChargeperFragment(std::vector< QMFragment< BSE_Population > > &frags, const Orbitals &orbitals, QMStateType type) const
Identifier for QMstates. Strings like S1 are converted into enum +zero indexed int.
const QMStateType & Type() const
void setRPAInputEnergies(const Eigen::VectorXd &rpaenergies)
Eigen::MatrixXd calculate_epsilon_r(double frequency) const
void configure(Index homo, Index rpamin, Index rpamax)
Timestamp returns the current time as a string Example: cout << TimeStamp()
This class transforms a pair of indices v,c into a compound index I, via I=ctotal*v+c the fast dimens...
Index c(Index index) const
Index v(Index index) const
#define XTP_LOG(level, log)
Charge transport classes.
Eigen::VectorXd ExpValue(const Eigen::MatrixXd &state1, OP OPxstate2)
BSE_OPERATOR< 1, 0, 0, 0 > HqpOperator
BSE_OPERATOR< 0, 0, 1, 0 > HdOperator
BSE_OPERATOR< 0, 0, 0, 1 > Hd2Operator
BSE_OPERATOR< 1, 2, 1, 0 > SingletOperator_TDA
Populationanalysis< true > Lowdin
BSE_OPERATOR< 1, 0, 1, 0 > TripletOperator_TDA
BSE_OPERATOR< 0, 2, 0, 1 > SingletOperator_BTDA_B
BSE_OPERATOR< 0, 1, 0, 0 > HxOperator
Provides a means for comparing floating point numbers.
Eigen::VectorXd direct_term
Eigen::VectorXd cross_term
Eigen::VectorXd qp_contrib
Eigen::VectorXd exchange_contrib
Eigen::VectorXd direct_contrib