71 const Eigen::MatrixXd::ConstRowXpr& Imx_row,
double delta,
73 std::complex<double> delta_eta(delta, eta);
75 Eigen::MatrixXd DielMxInv =
rpa_.calculate_epsilon_r(delta_eta);
77 DielMxInv.partialPivLu().solve(Imx_row.transpose()) - Imx_row.transpose();
79 return x.dot(Imx_row.transpose());
99 Index gw_level)
const {
101 Index rpatotal = rpa_energies.size();
104 double sigma_c = 0.0;
105 double sigma_c_tail = 0.0;
107 Index lumo = homo + 1;
108 double fermi_rpa = (rpa_energies(lumo) + rpa_energies(homo)) / 2.0;
110 double min_abs_delta = std::numeric_limits<double>::infinity();
111 double sum_abs_contributions = 0.0;
112 double sum_signed_contributions = 0.0;
114 const Eigen::MatrixXd& Imx =
Mmn_[gw_level_offset];
116 for (
Index i = 0; i < rpatotal; ++i) {
117 double delta = rpa_energies(i) - frequency;
118 double abs_delta = std::abs(delta);
119 min_abs_delta = std::min(min_abs_delta, abs_delta);
123 if (std::abs(factor) > kResidueFactorTol) {
125 double contribution = factor * diag;
126 sigma_c += contribution;
128 sum_abs_contributions += std::abs(contribution);
129 sum_signed_contributions += contribution;
132 if (abs_delta > kResidueFactorTol) {
135 sigma_c_tail += tail;
140 sum_abs_contributions / (std::abs(sum_signed_contributions) + kTiny);
142 if (min_abs_delta < kCdaWarnMinDelta || kappa > kCdaWarnKappa) {
143 std::cout <<
"\nWarning: CDA may be unreliable for " << SpinName(
spin_)
144 <<
" GW level " << (gw_level +
opt_.qpmin)
145 <<
" at omega = " << frequency
146 <<
" Ha: min |e_m - omega| = " << min_abs_delta
147 <<
" Ha, cancellation metric = " << kappa << std::flush;
150 return sigma_c + sigma_c_tail;