31 const Eigen::VectorXd& gwaenergies,
52 Index qpmax = qpmin + gwsize - 1;
59 energies_.head(qpmin).array() -= max_correction_occ;
66 Index range = max - min + 1;
67 Eigen::VectorXd corrections =
70 return (corrections.cwiseAbs()).maxCoeff();
80 const double freq2 = frequency * frequency;
89#pragma omp for schedule(dynamic)
90 for (
Index m_level = 0; m_level < n_occ; m_level++) {
91 const double qp_energy_m =
energies_(m_level);
93 Eigen::MatrixXd Mmn_RPA =
Mmn_[m_level].bottomRows(n_unocc);
95 const Eigen::ArrayXd deltaE =
96 energies_.tail(n_unocc).array() - qp_energy_m;
97 Eigen::VectorXd denom;
99 denom = 4 * deltaE / (deltaE.square() + freq2);
101 Eigen::ArrayXd deltEf = deltaE - frequency;
102 Eigen::ArrayXd sum = deltEf / (deltEf.square() + eta2);
103 deltEf = deltaE + frequency;
104 sum += deltEf / (deltEf.square() + eta2);
108 transform.
A_TDA(denom, threadid);
112 result.diagonal().array() += 1.0;
131#pragma omp for schedule(dynamic)
132 for (
Index m_level = 0; m_level < n_occ; m_level++) {
134 const double qp_energy_m =
energies_(m_level);
135 Eigen::MatrixXd Mmn_RPA =
Mmn_[m_level].bottomRows(n_unocc);
137 const Eigen::ArrayXd deltaE =
138 energies_.tail(n_unocc).array() - qp_energy_m;
140 Eigen::ArrayXd deltaEm = frequency.real() - deltaE;
141 Eigen::ArrayXd deltaEp = frequency.real() + deltaE;
143 double sigma_1 = std::pow(frequency.imag() +
eta_, 2);
144 double sigma_2 = std::pow(frequency.imag() -
eta_, 2);
146 Eigen::VectorXd chi =
147 deltaEm * (deltaEm.cwiseAbs2() + sigma_1).cwiseInverse() -
148 deltaEp * (deltaEp.cwiseAbs2() + sigma_2).cwiseInverse();
149 transform.
A_TDA(chi, threadid);
153 result.diagonal().array() += 1.0;
161 const Index rpasize = n_occ * n_unocc;
170 Eigen::MatrixXd& C = ApB;
171 C.applyOnTheLeft(AmB.cwiseSqrt().asDiagonal());
172 C.applyOnTheRight(AmB.cwiseSqrt().asDiagonal());
177 sol.
omega = Eigen::VectorXd::Zero(es.eigenvalues().size());
178 sol.
omega = es.eigenvalues().cwiseSqrt();
182 <<
" Lowest neutral excitation energy (eV): "
193 sol.
XpY = Eigen::MatrixXd(rpasize, rpasize);
195 Eigen::VectorXd AmB_sqrt = AmB.cwiseSqrt();
196 Eigen::VectorXd Omega_sqrt_inv = sol.
omega.cwiseSqrt().cwiseInverse();
197 for (
int s = 0; s < rpasize; s++) {
199 Omega_sqrt_inv(s) * AmB_sqrt.cwiseProduct(es.eigenvectors().col(s));
209 const Index rpasize = n_occ * n_unocc;
211 Eigen::VectorXd AmB = Eigen::VectorXd::Zero(rpasize);
212 for (
Index v = 0; v < n_occ; v++) {
214 AmB.segment(i, n_unocc) =
224 const Index rpasize = n_occ * n_unocc;
226 Eigen::MatrixXd ApB = Eigen::MatrixXd::Zero(rpasize, rpasize);
227#pragma omp parallel for schedule(guided)
228 for (
Index v2 = 0; v2 < n_occ; v2++) {
230 const Eigen::MatrixXd Mmn_v2T =
231 Mmn_[v2].middleRows(n_occ, n_unocc).transpose();
232 for (
Index v1 = v2; v1 < n_occ; v1++) {
235 ApB.block(i1, i2, n_unocc, n_unocc) =
236 2 * 2 *
Mmn_[v1].middleRows(n_occ, n_unocc) * Mmn_v2T;
244 const Eigen::MatrixXd& C)
const {
246 <<
TimeStamp() <<
" Diagonalizing two-particle Hamiltonian "
248 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(C);
250 <<
TimeStamp() <<
" Diagonalization done " << std::flush;
251 double minCoeff = es.eigenvalues().minCoeff();
252 if (minCoeff <= 0.0) {
254 <<
TimeStamp() <<
" Detected non-positive eigenvalue: " << minCoeff
256 throw std::runtime_error(
"Detected non-positive eigenvalue.");
void A_TDA(const Eigen::VectorXd &vec, Index OpenmpThread)
Eigen::MatrixXd getReductionVar()
void createTemporaries(Index rows, Index cols)
void PushMatrix(const Eigen::MatrixXd &mat, Index OpenmpThread)
Eigen::MatrixXd Calculate_H2p_ApB() const
void ShiftUncorrectedEnergies(const Eigen::VectorXd &dftenergies, Index qpmin, Index gwsize)
Eigen::VectorXd energies_
Eigen::MatrixXd calculate_epsilon(double frequency) const
Eigen::MatrixXd calculate_epsilon_r(double frequency) const
const TCMatrix_gwbse & Mmn_
Eigen::VectorXd Calculate_H2p_AmB() const
Eigen::SelfAdjointEigenSolver< Eigen::MatrixXd > Diagonalize_H2p_C(const Eigen::MatrixXd &C) const
rpa_eigensolution Diagonalize_H2p() const
void UpdateRPAInputEnergies(const Eigen::VectorXd &dftenergies, const Eigen::VectorXd &gwaenergies, Index qpmin)
double getMaxCorrection(const Eigen::VectorXd &dftenergies, Index min, Index max) const
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 I(Index v, Index c) const
#define XTP_LOG(level, log)
base class for all analysis tools