ampsci
High-precision calculations for one- and two-valence atomic systems
CoulombIntegrals.hpp
1#pragma once
2#include "Angular/include.hpp"
3#include "Wavefunction/DiracSpinor.hpp"
4#include <optional>
5#include <vector>
6
7//! Functions (+classes) for computing Coulomb integrals
8namespace Coulomb {
9
10//! Calculates Hartree Screening functions \f$y^k_{ab}(r)\f$
11//! @details maxi is max point to calculate; blank or zero means all the way
12std::vector<double> yk_ab(const int k, const DiracSpinor &Fa,
13 const DiracSpinor &Fb, const std::size_t maxi = 0);
14
15//! Overload: does not allocate ykab
16void yk_ab(const int k, const DiracSpinor &Fa, const DiracSpinor &Fb,
17 std::vector<double> &ykab, const std::size_t maxi = 0);
18
19//==============================================================================
20
21//! Calculates R^k_abcd for given k. From scratch (calculates y)
22double Rk_abcd(const int k, const DiracSpinor &Fa, const DiracSpinor &Fb,
23 const DiracSpinor &Fc, const DiracSpinor &Fd);
24
25//! Overload for when y^k_bd already exists [much faster]
26double Rk_abcd(const DiracSpinor &Fa, const DiracSpinor &Fc,
27 const std::vector<double> &ykbd);
28
29//! "Right-hand-side" R^k{v}_bcd [i.e., without Fv integral]
30DiracSpinor Rkv_bcd(const int k, const int kappa_v, const DiracSpinor &Fb,
31 const DiracSpinor &Fc, const DiracSpinor &Fd);
32
33//! Overload for when y^k_bd already exists [much faster]
34DiracSpinor Rkv_bcd(const int kappa_v, const DiracSpinor &Fc,
35 const std::vector<double> &ykbd);
36
37//! Overload for when spinor exists. Rkv is overwritten
38void Rkv_bcd(DiracSpinor *const Rkv, const DiracSpinor &Fc,
39 const std::vector<double> &ykbd);
40
41//==============================================================================
42
43//! Calculates Q^k_abcd for given k. From scratch (calculates y) [see YkTable
44//! version if already have YkTable]
45double Qk_abcd(const int k, const DiracSpinor &Fa, const DiracSpinor &Fb,
46 const DiracSpinor &Fc, const DiracSpinor &Fd);
47
48//! Calculates Q^k(v)_bcd for given k,kappa_v. From scratch (calculates y) [see
49//! YkTable version if already have YkTable]
50DiracSpinor Qkv_bcd(const int k, int kappa_v, const DiracSpinor &Fb,
51 const DiracSpinor &Fc, const DiracSpinor &Fd);
52
53//==============================================================================
54//! Calculates g from scratch - not used often
55double g_abcd(const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c,
56 const DiracSpinor &d, int tma, int tmb, int tmc, int tmd);
57
58//==============================================================================
59//! Just selection rule for Qk_abcd
60bool Qk_abcd_SR(int k, const DiracSpinor &Fa, const DiracSpinor &Fb,
61 const DiracSpinor &Fc, const DiracSpinor &Fd);
62//! Just selection rule for Qk_abcd
63bool Qk_abcd_SR(int k, int ka, int kb, int kc, int kd);
64
65//! Just selection rule for Pk_abcd
66bool Pk_abcd_SR(int k, const DiracSpinor &Fa, const DiracSpinor &Fb,
67 const DiracSpinor &Fc, const DiracSpinor &Fd);
68
69//! Just selection rule for Pk_abcd
70bool Pk_abcd_SR(int k, int ka, int kb, int kc, int kd);
71
72//==============================================================================
73
74//! Exchange only version of W (W-Q): W = Q + P [see Qk above]
75double Pk_abcd(const int k, const DiracSpinor &Fa, const DiracSpinor &Fb,
76 const DiracSpinor &Fc, const DiracSpinor &Fd);
77
78//! Exchange only version of W (W-Q): W = Q + P [see Qk above]
79DiracSpinor Pkv_bcd(const int k, int kappa_v, const DiracSpinor &Fb,
80 const DiracSpinor &Fc, const DiracSpinor &Fd);
81
82//==============================================================================
83
84//! Calculates W^k_abcd for given k. From scratch (calculates y)
85/*! @details
86 \f[ W^k_{abcd} = Q^k_{abcd} + \sum_l [k]
87 \begin{Bmatrix}a&c&k\\b&d&l\end{Bmatrix} * Q^l_{abdc} \f]
88 \f[ W^k_{abcd} = Q^k_{abcd} + P^k_{abcd} \f]
89 */
90double Wk_abcd(const int k, const DiracSpinor &Fa, const DiracSpinor &Fb,
91 const DiracSpinor &Fc, const DiracSpinor &Fd);
92
93DiracSpinor Wkv_bcd(const int k, int kappa_v, const DiracSpinor &Fb,
94 const DiracSpinor &Fc, const DiracSpinor &Fd);
95
96//==============================================================================
97
98//! Returns min and max k (multipolarity) allowed for C^k_ab, accounting for
99//! parity (used by k_minmax_Q)
100std::pair<int, int> k_minmax_Ck(const DiracSpinor &a, const DiracSpinor &b);
101//! Returns min and max k (multipolarity) allowed for C^k_ab, accounting for
102//! parity (used by k_minmax_Q)
103std::pair<int, int> k_minmax_Ck(int kappa_a, int kappa_b);
104
105//! Returns min and max k (multipolarity) allowed for Triangle(k,a,b),
106//! NOT accounting for parity (2j only, not kappa/l) (used by k_minmax_P,W)
107std::pair<int, int> k_minmax_tj(int tja, int tjb);
108
109//! Returns min and max k (multipolarity) allowed for Q^k_abcd.
110//! Parity rule is included, so you may safely call k+=2.
111//! Guaranteed to be non-zero *at* min and max, and every 2nd inbetween.
112std::pair<int, int> k_minmax_Q(const DiracSpinor &a, const DiracSpinor &b,
113 const DiracSpinor &c, const DiracSpinor &d);
114
115//! Returns min and max k (multipolarity) allowed for Q^k_abcd.
116//! Parity rule is included, so you may safely call k+=2.
117//! Guaranteed to be non-zero *at* min and max, and every 2nd inbetween.
118std::pair<int, int> k_minmax_Q(int kappa_a, int kappa_b, int kappa_c,
119 int kappa_d);
120
121//! Returns min and max k (multipolarity) allowed for P^k_abcd.
122//! DOES NOT contain parity rules (6j only) - so NOT safe to call k+=2.
123//! Guaranteed to be non-zero *at* min and max.
124std::pair<int, int> k_minmax_P(const DiracSpinor &a, const DiracSpinor &b,
125 const DiracSpinor &c, const DiracSpinor &d);
126
127//! Returns min and max k (multipolarity) allowed for W^k_abcd.
128//! DOES NOT contain parity rules (6j only) - so NOT safe to call k+=2.
129//! Cannot guarantee non-zero, since when a=b or c=d, sometimes have P=-Q.
130//! But when a!=b and c!=d, guaranteed to be non-zero *at* min and max.
131std::pair<int, int> k_minmax_W(const DiracSpinor &a, const DiracSpinor &b,
132 const DiracSpinor &c, const DiracSpinor &d);
133
134//==============================================================================
135
136//! Returns number of orbitals that are below Fermi level. Used for Qk selection
137int number_below_Fermi(const DiracSpinor &i, const DiracSpinor &j,
138 const DiracSpinor &k, const DiracSpinor &l,
139 double eFermi);
140
141//==============================================================================
142
143template <class A>
144static int twojk(const A &a) {
145 if constexpr (std::is_same_v<A, DiracSpinor>) {
146 return a.twoj();
147 } else {
148 static_assert(std::is_same_v<A, int>);
149 return 2 * a;
150 }
151}
152
153template <class A>
154static std::optional<int> twojknull(const A &a) {
155 if constexpr (std::is_same_v<A, DiracSpinor>) {
156 return a.twoj();
157 } else if constexpr (std::is_same_v<A, int>) {
158 static_assert(std::is_same_v<A, int>);
159 return 2 * a;
160 } else {
161 return std::nullopt;
162 }
163}
164
165template <class A, class B, class C, class D, class E, class F>
166static double sixj(const A &a, const B &b, const C &c, const D &d, const E &e,
167 const F &f) {
168 return Angular::sixj_2(twojk(a), twojk(b), twojk(c), twojk(d), twojk(e),
169 twojk(f));
170}
171
172template <class A = std::optional<int>, class B = std::optional<int>,
173 class C = std::optional<int>, class D = std::optional<int>,
174 class E = std::optional<int>, class F = std::optional<int>>
175static bool sixjTriads(const A &a, const B &b, const C &c, const D &d,
176 const E &e, const F &f) {
177 return Angular::sixjTriads(twojknull(a), twojknull(b), twojknull(c),
178 twojknull(d), twojknull(e), twojknull(f));
179}
180
181template <class A, class B, class C>
182static bool triangle(const A &a, const B &b, const C &c) {
183 return Angular::triangle(twojk(a), twojk(b), twojk(c));
184}
185
186} // namespace Coulomb
Stores radial Dirac spinor: F_nk = (f, g)
Definition DiracSpinor.hpp:42
double sixj_2(int two_j1, int two_j2, int two_j3, int two_j4, int two_j5, int two_j6)
Wigner 6j symbol {j1 j2 j3 | j4 j5 j6}. Inputs are 2*j as integers.
Definition Wigner369j.hpp:431
int twojk(const A &a)
Returns 2*k if a is an integer, or 2*j if a is a DiracSpinor.
Definition SixJTable.hpp:20
constexpr int triangle(int j1, int j2, int J)
Returns 1 if triangle rule is satisfied. nb: works with j OR twoj!
Definition Wigner369j.hpp:249
bool sixjTriads(std::optional< int > a, std::optional< int > b, std::optional< int > c, std::optional< int > d, std::optional< int > e, std::optional< int > f)
Checks 6j triangle conditions with optional arguments (wildcards). Inputs are 2*j.
Definition Wigner369j.hpp:395
Functions (+classes) for computing Coulomb integrals.
Definition CoulombBreit.cpp:13
std::pair< int, int > k_minmax_tj(int tja, int tjb)
Returns min and max k (multipolarity) allowed for Triangle(k,a,b), NOT accounting for parity (2j only...
Definition CoulombIntegrals.cpp:491
DiracSpinor Qkv_bcd(const int k, const int kappa_a, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd)
Calculates Q^k(v)_bcd for given k,kappa_v. From scratch (calculates y) [see YkTable version if alread...
Definition CoulombIntegrals.cpp:322
bool Pk_abcd_SR(int k, int ka, int kb, int kc, int kd)
Just selection rule for Pk_abcd.
Definition CoulombIntegrals.cpp:312
std::pair< int, int > k_minmax_Ck(const DiracSpinor &a, const DiracSpinor &b)
Returns min and max k (multipolarity) allowed for C^k_ab, accounting for parity (used by k_minmax_Q)
Definition CoulombIntegrals.cpp:459
double g_abcd(const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d, int tma, int tmb, int tmc, int tmd)
Calculates g from scratch - not used often.
Definition CoulombIntegrals.cpp:415
double Rk_abcd(const int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd)
Calculates R^k_abcd for given k. From scratch (calculates y)
Definition CoulombIntegrals.cpp:224
double Qk_abcd(const int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd)
Calculates Q^k_abcd for given k. From scratch (calculates y) [see YkTable version if already have YkT...
Definition CoulombIntegrals.cpp:281
DiracSpinor Rkv_bcd(const int k, const int kappa_a, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd)
"Right-hand-side" R^k{v}_bcd [i.e., without Fv integral]
Definition CoulombIntegrals.cpp:244
int number_below_Fermi(const DiracSpinor &i, const DiracSpinor &j, const DiracSpinor &k, const DiracSpinor &l, double eFermi)
Returns number of orbitals that are below Fermi level. Used for Qk selection.
Definition CoulombIntegrals.cpp:443
bool Qk_abcd_SR(int k, int ka, int kb, int kc, int kd)
Just selection rule for Qk_abcd.
Definition CoulombIntegrals.cpp:303
double Pk_abcd(const int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd)
Exchange only version of W (W-Q): W = Q + P [see Qk above].
Definition CoulombIntegrals.cpp:352
std::pair< int, int > k_minmax_P(const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d)
Returns min and max k (multipolarity) allowed for P^k_abcd. DOES NOT contain parity rules (6j only) -...
Definition CoulombIntegrals.cpp:531
DiracSpinor Pkv_bcd(const int k, int kappa_a, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd)
Exchange only version of W (W-Q): W = Q + P [see Qk above].
Definition CoulombIntegrals.cpp:373
double Wk_abcd(const int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd)
Calculates W^k_abcd for given k. From scratch (calculates y)
Definition CoulombIntegrals.cpp:408
std::pair< int, int > k_minmax_W(const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d)
Returns min and max k (multipolarity) allowed for W^k_abcd. DOES NOT contain parity rules (6j only) -...
Definition CoulombIntegrals.cpp:551
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.cpp:496
std::vector< double > yk_ab(const int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const std::size_t maxi)
Calculates Hartree Screening functions .
Definition CoulombIntegrals.cpp:182