33#pragma omp parallel for schedule(dynamic)
41 double frequency)
const {
43 const double eta2 =
opt_.eta *
opt_.eta;
50 const Eigen::ArrayXd res_12 =
residues_[gw_level].col(s).cwiseAbs2();
51 Eigen::ArrayXd temp = -
rpa_.getRPAInputEnergies().array() + frequency;
52 temp.segment(0, n_occ) += eigenvalue;
53 temp.segment(n_occ, n_unocc) -= eigenvalue;
54 const Eigen::ArrayXd denom = temp.abs2() + eta2;
55 sigma += (res_12 * temp / denom).sum();
61 Index gw_level,
double frequency)
const {
62 const double eta2 =
opt_.eta *
opt_.eta;
66 double dsigma_domega = 0.0;
69 const Eigen::ArrayXd res_12 =
residues_[gw_level].col(s).cwiseAbs2();
70 Eigen::ArrayXd temp = -
rpa_.getRPAInputEnergies().array() + frequency;
71 temp.segment(0, n_occ) += eigenvalue;
72 temp.segment(n_occ, n_unocc) -= eigenvalue;
73 const Eigen::ArrayXd denom = temp.abs2() + eta2;
74 dsigma_domega += ((eta2 - temp.abs2()) * res_12 / denom.abs2()).sum();
76 return 2 * dsigma_domega;
82 double frequency2)
const {
83 const double eta2 =
opt_.eta *
opt_.eta;
89 for (
Index s = 0; s < rpasize; s++) {
91 const Eigen::VectorXd& res1 =
residues_[gw_level1].col(s);
92 const Eigen::VectorXd& res2 =
residues_[gw_level2].col(s);
93 const Eigen::VectorXd res_12 = res1.cwiseProduct(res2);
94 Eigen::ArrayXd temp1 = -
rpa_.getRPAInputEnergies().array();
95 temp1.segment(0, n_occ) += eigenvalue;
96 temp1.segment(n_occ, n_unocc) -= eigenvalue;
97 const Eigen::ArrayXd temp2 = temp1 + frequency2;
99 const Eigen::ArrayXd numer1 = res_12.array() * temp1;
100 const Eigen::ArrayXd numer2 = res_12.array() * temp2;
101 const Eigen::ArrayXd denom1 = temp1.abs2() + eta2;
102 const Eigen::ArrayXd denom2 = temp2.abs2() + eta2;
103 sigma_c += 0.5 * ((numer1 / denom1) + (numer2 / denom2)).sum();
106 return 2.0 * sigma_c;
110 const Eigen::MatrixXd& XpY)
const {
114 const Index rpasize = n_occ * n_unocc;
117 const Eigen::MatrixXd& Mmn_i =
Mmn_[gw_level + qpoffset];
118 Eigen::MatrixXd res = Eigen::MatrixXd::Zero(
rpatotal_, rpasize);
122 const Index qp_offset_m_res =
127 qp_offset_m_res + qptotal_res)
130 for (
Index v = 0; v < n_occ; v++) {
131 Eigen::MatrixXd Mmn_v_virt;
132 if (
qsgw_U_ !=
nullptr && v >= qp_offset_m_res && v < qp_end_occ_res) {
133 const Index v_qp = v - qp_offset_m_res;
134 Mmn_v_virt = Eigen::MatrixXd::Zero(n_unocc,
Mmn_.auxsize());
135 for (
Index vp = 0; vp < qptotal_res; vp++) {
136 Mmn_v_virt.noalias() +=
137 (*qsgw_U_)(vp, v_qp) *
138 Mmn_[vp + qp_offset_m_res].middleRows(n_occ, n_unocc);
141 Mmn_v_virt =
Mmn_[v].middleRows(n_occ, n_unocc);
143 auto fc = Mmn_v_virt * Mmn_i.transpose();
144 auto XpY_v = XpY.middleRows(vc.
I(v, 0), n_unocc);
145 res += fc.transpose() * XpY_v;
Eigen::MatrixXd CalcResidues(Index gw_level, const Eigen::MatrixXd &XpY) const
std::vector< Eigen::MatrixXd > residues_
double CalcCorrelationDiagElementDerivative(Index gw_level, double frequency) const final
void PrepareScreening() final
double CalcCorrelationDiagElement(Index gw_level, double frequency) const final
Eigen::VectorXd rpa_omegas_
double CalcCorrelationOffDiagElement(Index gw_level1, Index gw_level2, double frequency1, double frequency2) const final
const Eigen::MatrixXd * qsgw_U_
void CountDiagEval() const
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
Charge transport classes.
Provides a means for comparing floating point numbers.