33 const Eigen::VectorXd& gwaenergies,
55 use(
Mmn_[m_level].bottomRows(n_unocc));
72 const double freq2 = frequency * frequency;
74 Eigen::MatrixXd result =
76 const Eigen::ArrayXd deltaE =
79 denom = 4 * deltaE / (deltaE.square() + freq2);
81 Eigen::ArrayXd deltEf = deltaE - frequency;
82 Eigen::ArrayXd sum = deltEf / (deltEf.square() + eta2);
83 deltEf = deltaE + frequency;
84 sum += deltEf / (deltEf.square() + eta2);
88 result.diagonal().array() += 1.0;
97 const double sigma_1 = std::pow(frequency.imag() +
eta_, 2);
98 const double sigma_2 = std::pow(frequency.imag() -
eta_, 2);
99 Eigen::MatrixXd result =
101 const Eigen::ArrayXd deltaE =
103 const Eigen::ArrayXd deltaEm = frequency.real() - deltaE;
104 const Eigen::ArrayXd deltaEp = frequency.real() + deltaE;
106 chi = -2.0 * (deltaEm * (deltaEm.abs2() + sigma_1).inverse() -
107 deltaEp * (deltaEp.abs2() + sigma_2).inverse());
109 result.diagonal().array() += 1.0;
117 const Index rpasize = n_occ * n_unocc;
126 Eigen::MatrixXd& C = ApB;
127 C.applyOnTheLeft(AmB.cwiseSqrt().asDiagonal());
128 C.applyOnTheRight(AmB.cwiseSqrt().asDiagonal());
133 sol.
omega = Eigen::VectorXd::Zero(es.
values.size());
138 std::ostringstream oss;
139 oss <<
TimeStamp() <<
" RKS H2p poles (first 20, eV): ";
140 const Index nprint = std::min<Index>(20, sol.
omega.size());
141 for (
Index i = 0; i < nprint; ++i) {
142 oss << std::fixed << std::setprecision(6)
144 if (i + 1 < nprint) {
152 <<
" Lowest neutral excitation energy (eV): "
163 sol.
XpY = Eigen::MatrixXd(rpasize, rpasize);
165 Eigen::VectorXd AmB_sqrt = AmB.cwiseSqrt();
166 Eigen::VectorXd Omega_sqrt_inv = sol.
omega.cwiseSqrt().cwiseInverse();
167 for (
int s = 0; s < rpasize; s++) {
169 Omega_sqrt_inv(s) * AmB_sqrt.cwiseProduct(es.
vectors.col(s));
179 const Index rpasize = n_occ * n_unocc;
181 Eigen::VectorXd AmB = Eigen::VectorXd::Zero(rpasize);
182 for (
Index v = 0; v < n_occ; v++) {
184 AmB.segment(i, n_unocc) =
194 const Index rpasize = n_occ * n_unocc;
196 Eigen::MatrixXd ApB = Eigen::MatrixXd::Zero(rpasize, rpasize);
197#pragma omp parallel for schedule(guided)
198 for (
Index v2 = 0; v2 < n_occ; v2++) {
200 const Eigen::MatrixXd Mmn_v2T =
201 Mmn_[v2].middleRows(n_occ, n_unocc).transpose();
202 for (
Index v1 = v2; v1 < n_occ; v1++) {
205 ApB.block(i1, i2, n_unocc, n_unocc) =
206 2 * 2 *
Mmn_[v1].middleRows(n_occ, n_unocc) * Mmn_v2T;
215 <<
TimeStamp() <<
" Diagonalizing two-particle Hamiltonian "
219 <<
TimeStamp() <<
" Diagonalization done " << std::flush;
220 double minCoeff = es.
values.minCoeff();
221 if (minCoeff <= 0.0) {
223 <<
TimeStamp() <<
" Detected non-positive eigenvalue: " << minCoeff
225 throw std::runtime_error(
"Detected non-positive eigenvalue.");
Eigen::MatrixXd Calculate_H2p_ApB() const
void ShiftUncorrectedEnergies(const Eigen::VectorXd &dftenergies, Index qpmin, Index gwsize)
Eigen::MatrixXd ResponseSum(const WeightedGram::WeightsFn &weights) const
OutOfWindowShift out_of_window_
Eigen::VectorXd energies_
void VisitHoleVirtualRows(Index m_level, const WeightedGram::RowsVisitor &use) const
Eigen::MatrixXd calculate_epsilon(double frequency) const
Eigen::MatrixXd calculate_epsilon_r(double frequency) const
const TCMatrix_gwbse & Mmn_
SymmetricEigenSystem Diagonalize_H2p_C(const Eigen::MatrixXd &C) const
Eigen::VectorXd Calculate_H2p_AmB() const
rpa_eigensolution Diagonalize_H2p() const
void UpdateRPAInputEnergies(const Eigen::VectorXd &dftenergies, const Eigen::VectorXd &gwaenergies, Index qpmin)
Timestamp returns the current time as a string Example: cout << TimeStamp().
std::function< void(Index m, Eigen::VectorXd &w)> WeightsFn
Writes the weights of block m; their number is the number of rows.
std::function< void(const Eigen::Ref< const Eigen::MatrixXd > &)> RowsVisitor
Calls use(R_m); R_m may be a block of stored data or a temporary.
static Eigen::MatrixXd Compute(Index nblocks, Index ncols, const WeightsFn &weights, const RowsFn &rows)
This class transforms a pair of indices v,c into a compound index I, via I=ctotal*v+c the fast dimens...
Index I(Index v, Index c) const
#define XTP_LOG(level, log)
Charge transport classes.
SymmetricEigenSystem SymmetricEigen(const Eigen::MatrixXd &A, bool vectors=true)
With vectors = false only the eigenvalues are computed.
Provides a means for comparing floating point numbers.