44 const Eigen::MatrixXd& Hqp_in) {
62 const Eigen::VectorXd& RPAInputEnergies) {
67 Eigen::MatrixXd Hqp_BSE = Eigen::MatrixXd::Zero(hqp_size, hqp_size);
72 Hqp_BSE = Hqp.block(start, start, hqp_size, hqp_size);
74 Index virtoffset = gwsize - start;
75 Hqp_BSE.topLeftCorner(virtoffset, virtoffset) =
76 Hqp.block(start, start, virtoffset, virtoffset);
79 Hqp_BSE.diagonal().tail(virt_extra) =
80 RPAInputEnergies.segment(RPAoffset + virtoffset, virt_extra);
86 Hqp_BSE.diagonal().head(occ_extra) =
87 RPAInputEnergies.segment(RPAoffset, occ_extra);
89 Hqp_BSE.block(occ_extra, occ_extra, gwsize, gwsize) = Hqp;
92 Index virtoffset = occ_extra + gwsize;
94 Hqp_BSE.diagonal().tail(virt_extra) =
95 RPAInputEnergies.segment(RPAoffset + virtoffset, virt_extra);
103 const Eigen::VectorXd& RPAInputEnergies,
double energy) {
108 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(
113 for (
Index i = 0; i < es.eigenvalues().size(); ++i) {
114 if (es.eigenvalues()(i) > 1
e-8) {
120template <
typename BSE_OPERATOR>
162 <<
TimeStamp() <<
" Setup TDA singlet hamiltonian " << flush;
180template <
typename BSE_OPERATOR>
183 std::chrono::time_point<std::chrono::system_clock> start =
184 std::chrono::system_clock::now();
199 std::chrono::time_point<std::chrono::system_clock> end =
200 std::chrono::system_clock::now();
201 std::chrono::duration<double> elapsed_time = end - start;
204 << elapsed_time.count() <<
" secs" << flush;
215 <<
TimeStamp() <<
" Setup Full singlet hamiltonian " << flush;
225 <<
TimeStamp() <<
" Setup Full triplet hamiltonian " << flush;
229template <
typename BSE_OPERATOR_A,
typename BSE_OPERATOR_B>
231 BSE_OPERATOR_B& Bop)
const {
232 std::chrono::time_point<std::chrono::system_clock> start =
233 std::chrono::system_clock::now();
251 Eigen::MatrixXd tmpX = DS.
eigenvectors().topRows(Aop.rows());
252 Eigen::MatrixXd tmpY = DS.
eigenvectors().bottomRows(Bop.rows());
255 Eigen::VectorXd normX = tmpX.colwise().squaredNorm();
256 Eigen::VectorXd normY = tmpY.colwise().squaredNorm();
258 Eigen::ArrayXd sqinvnorm = (normX - normY).array().inverse().cwiseSqrt();
260 result.
eigenvectors() = tmpX * sqinvnorm.matrix().asDiagonal();
261 result.
eigenvectors2() = tmpY * sqinvnorm.matrix().asDiagonal();
263 std::chrono::time_point<std::chrono::system_clock> end =
264 std::chrono::system_clock::now();
265 std::chrono::duration<double> elapsed_time = end - start;
268 << elapsed_time.count() <<
" secs" << flush;
276 double dq = frag.value().H[state] + frag.value().E[state];
277 double qeff = dq + frag.value().Gs;
280 " Fragment %1$4d -- hole: %2$5.1f%% electron: "
281 "%3$5.1f%% dQ: %4$+5.2f Qeff: %5$+5.2f") %
282 int(frag.getId()) % (100.0 * frag.value().
H[state]) %
283 (-100.0 * frag.value().E[state]) % dq % qeff
292 double weight = weights(i_bse);
295 << format(
" HOMO-%1$-3d -> LUMO+%2$-3d : %3$3.1f%%") %
313 if (fragments.size() > 0) {
322 <<
" ====== singlet energies (eV) ====== " << flush;
324 Eigen::VectorXd weights =
330 double osc = oscs[i];
333 " S = %1$4d Omega = %2$+1.12f eV lamdba = %3$+3.2f nm <FT> "
334 "= %4$+1.4f <K_x> = %5$+1.4f <K_d> = %6$+1.4f") %
335 (i + 1) % (hrt2ev * energies(i)) %
336 (1240.0 / (hrt2ev * energies(i))) %
345 " TrDipole length gauge[e*bohr] dx = %1$+1.4f dy = "
346 "%2$+1.4f dz = %3$+1.4f |d|^2 = %4$+1.4f f = %5$+1.4f") %
347 trdip[0] % trdip[1] % trdip[2] % (trdip.squaredNorm()) % osc
351 if (fragments.size() > 0) {
366 if (fragments.size() > 0) {
373 <<
" ====== triplet energies (eV) ====== " << flush;
375 Eigen::VectorXd weights =
383 " T = %1$4d Omega = %2$+1.12f eV lamdba = %3$+3.2f nm <FT> "
384 "= %4$+1.4f <K_d> = %5$+1.4f") %
392 if (fragments.size() > 0) {
401Eigen::VectorXd
ExpValue(
const Eigen::MatrixXd& state1, OP OPxstate2) {
402 return state1.cwiseProduct(OPxstate2.eval()).colwise().sum().transpose();
405Eigen::VectorXd
ExpValue(
const Eigen::MatrixXd& state1,
406 const Eigen::MatrixXd& OPxstate2) {
407 return state1.cwiseProduct(OPxstate2).colwise().sum().transpose();
410template <
typename BSE_OPERATOR>
428 expectation_values.
cross_term = Eigen::VectorXd::Zero(0);
430 return expectation_values;
433template <
typename BSE_OPERATOR>
443 const Eigen::MatrixXd BSECoefs_state =
446 const Eigen::MatrixXd temp =
H * BSECoefs_state;
451 const Eigen::MatrixXd BSECoefs2_state =
455 ExpValue(BSECoefs2_state,
H * BSECoefs2_state);
458 expectation_values.
cross_term = Eigen::VectorXd::Zero(0);
461 return expectation_values;
535 Eigen::VectorXd Hd_static_contribution = expectation_values.
direct_term;
540 Hd_static_contribution += expectation_values.
cross_term;
543 const Eigen::VectorXd& BSEenergies = BSECoefs.
eigenvalues();
546 Eigen::VectorXd BSEenergies_dynamic = BSEenergies;
549 for (
Index i_exc = 0; i_exc < BSEenergies.size(); i_exc++) {
551 <<
" static " << BSEenergies(i_exc) << flush;
556 double old_energy = BSEenergies_dynamic(i_exc);
562 QMState state(type, i_exc,
false);
564 Eigen::VectorXd Hd_dynamic_contribution = expectation_values.
direct_term;
570 Hd_dynamic_contribution += expectation_values.
cross_term;
574 BSEenergies_dynamic(i_exc) = BSEenergies(i_exc) +
575 Hd_static_contribution(i_exc) -
576 Hd_dynamic_contribution(0);
579 <<
"Dynamical Screening BSE, excitation " << i_exc <<
" iteration "
580 << iter <<
" dynamic " << BSEenergies_dynamic(i_exc) << flush;
583 if (std::abs(BSEenergies_dynamic(i_exc) - old_energy) <
dyn_tolerance_) {
594 "dynamical screening (eV) ====== "
598 double osc = oscs[i];
601 " S(dynamic) = %1$4d Omega = %2$+1.12f eV lamdba = %3$+3.2f "
604 (i + 1) % (hrt2ev * BSEenergies_dynamic(i)) %
605 (1240.0 / (hrt2ev * BSEenergies_dynamic(i))) %
606 (osc * BSEenergies_dynamic(i) / BSEenergies(i))
613 "dynamical screening (eV) ====== "
618 " T(dynamic) = %1$4d Omega = %2$+1.12f eV lamdba = %3$+3.2f "
620 (i + 1) % (hrt2ev * BSEenergies_dynamic(i)) %
621 (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)
void MultiplyRightWithAuxMatrix(const Eigen::MatrixXd &matrix)
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)
Eigen::VectorXd ExpValue(const Eigen::MatrixXd &state1, OP OPxstate2)
base class for all analysis tools
Eigen::VectorXd direct_term
Eigen::VectorXd cross_term
Eigen::VectorXd qp_contrib
Eigen::VectorXd exchange_contrib
Eigen::VectorXd direct_contrib
std::string davidson_tolerance
std::string davidson_update
std::string davidson_correction