14 const std::vector<DiracSpinor> &core,
const std::vector<DiracSpinor> &excited,
15 int max_l_internal, std::optional<double> ev) {
17 static_assert(std::is_same_v<CoulombIntegral, Coulomb::QkTable> ||
18 std::is_same_v<CoulombIntegral, Coulomb::YkTable>);
22 const auto e_v = ev ? *ev : 0.5 * (v.
en() + w.
en());
31 if (max_l_internal < 0)
34 double sum_direct = 0.0;
35 double sum_exchange = 0.0;
36#pragma omp parallel for reduction(+ : sum_direct, sum_exchange) collapse(2) \
38 for (
auto ia = 0ul; ia < core.size(); ia++) {
39 for (
auto in = 0ul; in < excited.size(); in++) {
41 const auto &a = core[ia];
42 const auto &n = excited[in];
44 if (a.l() > max_l_internal || n.l() > max_l_internal)
47 const auto de_an = a.en() - n.en();
50 for (
const auto &m : excited) {
51 if (m.l() > max_l_internal)
54 const auto inv_de = 1.0 / (e_v + de_an - m.en());
57 for (
int k = k0; k <= k1; k += 2) {
58 const auto Qk_vamn = qk.Q(k, v, a, m, n);
59 const auto Qk_wamn = (v == w) ? Qk_vamn : qk.Q(k, w, a, m, n);
60 const auto Pk_wamn = qk.P(k, w, a, m, n);
61 sum_direct += Qk_vamn * Qk_wamn * inv_de / (2.0 * k + 1.0);
62 sum_exchange += Qk_vamn * Pk_wamn * inv_de / (2.0 * k + 1.0);
67 for (
const auto &b : core) {
68 if (b.l() > max_l_internal)
71 const auto inv_de = 1.0 / (e_v - de_an - b.en());
74 for (
int k = k0; k <= k1; k += 2) {
75 const auto Qk_vnba = qk.Q(k, v, n, b, a);
76 const auto Qk_wnba = (v == w) ? Qk_vnba : qk.Q(k, w, n, b, a);
77 const auto Pk_wnba = qk.P(k, w, n, b, a);
78 sum_direct += Qk_vnba * Qk_wnba * inv_de / (2.0 * k + 1.0);
79 sum_exchange += Qk_vnba * Pk_wnba * inv_de / (2.0 * k + 1.0);
85 const auto factor = 1.0 / v.
twojp1();
86 return {sum_direct * factor, sum_exchange * factor};
94 const CoulombIntegral &qk,
const std::vector<DiracSpinor> &core,
95 const std::vector<DiracSpinor> &excited,
int max_l_internal,
96 std::optional<double> ev) {
97 const auto [direct, exchange] =
99 return direct + exchange;
105 const CoulombIntegral &qk,
106 const std::vector<DiracSpinor> &core,
107 const std::vector<DiracSpinor> &excited,
double ev,
108 int max_l_internal,
double delta) {
109 const auto Sp =
Sigma_vw(v, w, qk, core, excited, max_l_internal, ev + delta);
110 const auto Sm =
Sigma_vw(v, w, qk, core, excited, max_l_internal, ev - delta);
111 return (Sp - Sm) / (2.0 * delta);
std::pair< int, int > k_minmax_Q(const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d)
Returns min and max k (multipolarity) allowed for Q^k_abcd. Parity rule is included,...
Definition CoulombIntegrals.hpp:146
double dSigma_dE_vw(const DiracSpinor &v, const DiracSpinor &w, const CoulombIntegral &qk, const std::vector< DiracSpinor > &core, const std::vector< DiracSpinor > &excited, double ev, int max_l_internal=99, double delta=0.01)
Energy derivative of the one-body correlation correction.
Definition Sigma2.ipp:104
double Sigma_vw(const DiracSpinor &v, const DiracSpinor &w, const CoulombIntegral &qk, const std::vector< DiracSpinor > &core, const std::vector< DiracSpinor > &excited, int max_l_internal=99, std::optional< double > ev=std::nullopt)
Matrix element of the 1-body Sigma (2nd-order correlation) operator.
Definition Sigma2.ipp:93
std::pair< double, double > Sigma_vw_direct_exchange(const DiracSpinor &v, const DiracSpinor &w, const CoulombIntegral &qk, const std::vector< DiracSpinor > &core, const std::vector< DiracSpinor > &excited, int max_l_internal=99, std::optional< double > ev=std::nullopt)
Direct and exchange parts of Sigma_vw(), returned separately.
Definition Sigma2.ipp:12