61 const Eigen::MatrixXd::ConstRowXpr& Imx_row,
double delta,
63 std::complex<double> delta_eta(delta, eta);
65 Eigen::MatrixXd DielMxInv =
rpa_.calculate_epsilon_r(delta_eta);
67 DielMxInv.partialPivLu().solve(Imx_row.transpose()) - Imx_row.transpose();
69 return x.dot(Imx_row.transpose());
89 Index gw_level)
const {
91 Index rpatotal = rpa_energies.size();
95 double sigma_c_tail = 0.0;
97 Index lumo = homo + 1;
98 double fermi_rpa = (rpa_energies(lumo) + rpa_energies(homo)) / 2.0;
100 double min_abs_delta = std::numeric_limits<double>::infinity();
101 double sum_abs_contributions = 0.0;
102 double sum_signed_contributions = 0.0;
104 const Eigen::MatrixXd& Imx =
Mmn_[gw_level_offset];
106 for (
Index i = 0; i < rpatotal; ++i) {
107 double delta = rpa_energies(i) - frequency;
108 double abs_delta = std::abs(delta);
109 min_abs_delta = std::min(min_abs_delta, abs_delta);
113 if (std::abs(factor) > kResidueFactorTol) {
115 double contribution = factor * diag;
116 sigma_c += contribution;
118 sum_abs_contributions += std::abs(contribution);
119 sum_signed_contributions += contribution;
122 if (abs_delta > kResidueFactorTol) {
125 sigma_c_tail += tail;
130 sum_abs_contributions / (std::abs(sum_signed_contributions) + kTiny);
132 if (min_abs_delta < kCdaWarnMinDelta || kappa > kCdaWarnKappa) {
133 std::cout <<
"\nWarning: CDA may be unreliable for " << SpinName(
spin_)
134 <<
" GW level " << (gw_level +
opt_.qpmin)
135 <<
" at omega = " << frequency
136 <<
" Ha: min |e_m - omega| = " << min_abs_delta
137 <<
" Ha, cancellation metric = " << kappa << std::flush;
140 return sigma_c + sigma_c_tail;