ampsci
High-precision calculations for one- and two-valence atomic systems
Coulomb Namespace Reference

Detailed Description

Functions (+classes) for computing Coulomb integrals.

Classes

class  CoulombTable
 Base class template to store Coulomb integrals, and similar. 3 specific cases (by template instantiation), account for specific symmetrs. More...
 
class  meTable
 Look-up table for matrix elements. Note: does not assume any symmetry: (a,b) is stored independantly of (b,a). In general, maps a pair of DiracSpinors to a single value (of any type, T). More...
 
class  YkTable
 Calculates + stores Hartree Y functions + Angular (w/ look-up), taking advantage of symmetry. More...
 

Typedefs

using nk2Index = uint32_t
 index type for set of 2 orbitals {nk,nk} -> nk4Index
 
using Real = double
 Data type used to store integrals.
 
using nk4Index = uint64_t
 index type for set of 4 orbitals {nk,nk,nk,nk} -> nk4Index [max n: 256]
 
using nkIndex = uint16_t
 index type for each {nk} (orbital) [max n: 256]
 
using CoulombFunction = std::function< double(int, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d)>
 Function type for calculating Coulomb(-like) integrals. Takes k and 4 DiracSpinors, returns a double.
 
using SelectionRules = std::function< bool(int, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d)>
 Function type for determining Coulomb(-like) integral selection rules. Takes k and 4 DiracSpinors, returns a true if integral is allowed.
 
using QkTable = CoulombTable< Symmetry::Qk >
 Coulomb integral table with 8-fold Qk symmetry.
 
using WkTable = CoulombTable< Symmetry::Wk >
 Coulomb integral table with 4-fold Wk symmetry.
 
using LkTable = CoulombTable< Symmetry::Lk >
 Coulomb integral table with 2-fold Lk symmetry.
 
using NkTable = CoulombTable< Symmetry::none >
 Coulomb integral table with no assumed symmetry.
 

Enumerations

enum class  Symmetry { Qk , Wk , Lk , none }
 Symmetry (state index order) for tables. More...
 

Functions

void bk_ab (const int k, const DiracSpinor &Fa, const DiracSpinor &Fb, std::vector< double > &b0, std::vector< double > &binf, const std::size_t maxi=0)
 Breit b^k function: (0,r) and (r,inf) part stored sepperately (in/out)
 
void gk_ab (const int k, const DiracSpinor &Fa, const DiracSpinor &Fb, std::vector< double > &g0, std::vector< double > &ginf, const std::size_t maxi=0)
 Breit g^k function: (0,r) + (r,inf) part stored together (in/out)
 
void gk_ab_freqw (const int k, const DiracSpinor &Fa, const DiracSpinor &Fb, std::vector< double > &g0, std::vector< double > &ginf, const std::size_t maxi=0, const double w=0.0)
 Frequency-dependent Breit screening function g^k_ab(r,w), X_ab density.
 
void hk_ab_freqw (const int k, const DiracSpinor &Fa, const DiracSpinor &Fb, std::vector< double > &g0, std::vector< double > &ginf, const std::size_t maxi=0, const double w=0.0)
 Frequency-dependent Breit screening function h^k_ab(r,w), Y_ab density.
 
void vk_ab_freqw (const int k, const DiracSpinor &Fi, const DiracSpinor &Fj, const Grid &gr, std::vector< double > &v1, std::vector< double > &v2, std::vector< double > &v3, std::vector< double > &v4, std::size_t maxi, const double w)
 Frequency-dependent Breit v^k_ab(r,w): four partial screening integrals.
 
std::vector< double > yk_ab (const int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const std::size_t maxi=0)
 Calculates Hartree Screening functions \(y^k_{ab}(r)\).
 
void yk_ab (const int k, const DiracSpinor &Fa, const DiracSpinor &Fb, std::vector< double > &ykab, const std::size_t maxi=0)
 Overload: does not allocate ykab.
 
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)
 
double Rk_abcd (const DiracSpinor &Fa, const DiracSpinor &Fc, const std::vector< double > &ykbd)
 Overload for when y^k_bd already exists [much faster].
 
DiracSpinor Rkv_bcd (const int k, const int kappa_v, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd)
 "Right-hand-side" R^k{v}_bcd [i.e., without Fv integral]
 
DiracSpinor Rkv_bcd (const int kappa_v, const DiracSpinor &Fc, const std::vector< double > &ykbd)
 Overload for when y^k_bd already exists [much faster].
 
void Rkv_bcd (DiracSpinor *const Rkv, const DiracSpinor &Fc, const std::vector< double > &ykbd)
 Overload for when spinor exists. Rkv is overwritten.
 
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 YkTable].
 
bool Qk_abcd_SR (int k, int ka, int kb, int kc, int kd)
 Just selection rule for Qk_abcd.
 
bool Qk_abcd_SR (int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd)
 Just selection rule for Qk_abcd.
 
bool Pk_abcd_SR (int k, int ka, int kb, int kc, int kd)
 Just selection rule for Pk_abcd.
 
bool Pk_abcd_SR (int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd)
 Just selection rule for Pk_abcd.
 
DiracSpinor Qkv_bcd (const int k, int kappa_v, 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 already have YkTable].
 
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].
 
DiracSpinor Pkv_bcd (const int k, int kappa_v, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd)
 Exchange only version of W (W-Q): W = Q + P [see Qk above].
 
DiracSpinor Wkv_bcd (const int k, int kappa_v, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd)
 
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)
 
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.
 
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.
 
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)
 
std::pair< int, int > k_minmax_Ck (int kappa_a, int kappa_b)
 Returns min and max k (multipolarity) allowed for C^k_ab, accounting for parity (used by k_minmax_Q)
 
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, not kappa/l) (used by k_minmax_P,W)
 
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, so you may safely call k+=2. Guaranteed to be non-zero at min and max, and every 2nd inbetween.
 
std::pair< int, int > k_minmax_Q (int kappa_a, int kappa_b, int kappa_c, int kappa_d)
 Returns min and max k (multipolarity) allowed for Q^k_abcd. Parity rule is included, so you may safely call k+=2. Guaranteed to be non-zero at min and max, and every 2nd inbetween.
 
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) - so NOT safe to call k+=2. Guaranteed to be non-zero at min and max.
 
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) - so NOT safe to call k+=2. Cannot guarantee non-zero, since when a=b or c=d, sometimes have P=-Q. But when a!=b and c!=d, guaranteed to be non-zero at min and max.
 
void estimate_memory_usage (const std::string &basis_string, const std::string &core_string, int k_cut=999)
 Estimate memory required for a QkTable for a given basis.
 
double estimate_memory_GB (std::size_t number_of_integrals, double efficiency=0.65)
 Estimate memory required for a Qk table.
 
std::string_view to_string (Symmetry s)
 Convert Symmetry to string.
 

Typedef Documentation

◆ nk2Index

using Coulomb::nk2Index = typedef uint32_t

index type for set of 2 orbitals {nk,nk} -> nk4Index

◆ Real

using Coulomb::Real = typedef double

Data type used to store integrals.

◆ nk4Index

using Coulomb::nk4Index = typedef uint64_t

index type for set of 4 orbitals {nk,nk,nk,nk} -> nk4Index [max n: 256]

Warning
Requires 0<n<256, see Angular::nk_to_index

◆ nkIndex

using Coulomb::nkIndex = typedef uint16_t

index type for each {nk} (orbital) [max n: 256]

Warning
Requires 0<n<256, see Angular::nk_to_index

◆ CoulombFunction

using Coulomb::CoulombFunction = typedef std::function<double(int, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d)>

Function type for calculating Coulomb(-like) integrals. Takes k and 4 DiracSpinors, returns a double.

◆ SelectionRules

using Coulomb::SelectionRules = typedef std::function<bool(int, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d)>

Function type for determining Coulomb(-like) integral selection rules. Takes k and 4 DiracSpinors, returns a true if integral is allowed.

◆ QkTable

using Coulomb::QkTable = typedef CoulombTable<Symmetry::Qk>

Coulomb integral table with 8-fold Qk symmetry.

Stores Q^k_abcd assuming the symmetry:

  • {abcd} = cbad = adcb = cdab = badc = bcda = dabc = dcba.

Normal ordering is the lexicographically smallest arrangement among these 8 equivalents.

Note
See CoulombTable note regarding selection rules assumptions

◆ WkTable

using Coulomb::WkTable = typedef CoulombTable<Symmetry::Wk>

Coulomb integral table with 4-fold Wk symmetry.

Stores integrals assuming the symmetry: {abcd} = badc = cdab = dcba.

◆ LkTable

using Coulomb::LkTable = typedef CoulombTable<Symmetry::Lk>

Coulomb integral table with 2-fold Lk symmetry.

Stores integrals assuming the symmetry: {abcd} = badc.

◆ NkTable

using Coulomb::NkTable = typedef CoulombTable<Symmetry::none>

Coulomb integral table with no assumed symmetry.

Each {k,a,b,c,d} is treated as a unique entry; no normal ordering is applied.

Enumeration Type Documentation

◆ Symmetry

enum class Coulomb::Symmetry
strong

Symmetry (state index order) for tables.

Function Documentation

◆ bk_ab()

void Coulomb::bk_ab ( const int  k,
const DiracSpinor Fa,
const DiracSpinor Fb,
std::vector< double > &  b0,
std::vector< double > &  binf,
std::size_t  maxi 
)

Breit b^k function: (0,r) and (r,inf) part stored sepperately (in/out)

◆ gk_ab()

void Coulomb::gk_ab ( const int  k,
const DiracSpinor Fa,
const DiracSpinor Fb,
std::vector< double > &  g0,
std::vector< double > &  ginf,
const std::size_t  maxi 
)

Breit g^k function: (0,r) + (r,inf) part stored together (in/out)

◆ gk_ab_freqw()

void Coulomb::gk_ab_freqw ( const int  k,
const DiracSpinor Fa,
const DiracSpinor Fb,
std::vector< double > &  g0,
std::vector< double > &  ginf,
const std::size_t  maxi = 0,
const double  w = 0.0 
)

Frequency-dependent Breit screening function g^k_ab(r,w), X_ab density.

Computes the frequency-dependent Breit screening function using the X_ab radial density arXiv:2602.17129:

\[ X_{ab}(r) = f_a(r)\,g_b(r) + g_a(r)\,f_b(r). \]

The static radial kernel \(r_<^k/r_>^{k+1}\) is replaced by the frequency-dependent form:

\[ \frac{r_<^k}{r_>^{k+1}} \to -\omega(2k+1)\,j_k(\omega r_<)\,y_k(\omega r_>), \]

where \(j_k\) and \(y_k\) are spherical Bessel functions of the first and second kind. This screening function enters the frequency-dependent \(u^k_{abcd}\) integral. The \((0,r)\) and \((r,\infty)\) parts of the inner integral are stored separately in g0 and ginf.

Refer to arXiv:2602.17129 for details.

◆ hk_ab_freqw()

void Coulomb::hk_ab_freqw ( const int  k,
const DiracSpinor Fa,
const DiracSpinor Fb,
std::vector< double > &  g0,
std::vector< double > &  ginf,
const std::size_t  maxi = 0,
const double  w = 0.0 
)

Frequency-dependent Breit screening function h^k_ab(r,w), Y_ab density.

Same as gk_ab_freqw but uses the Y_ab radial density arXiv:2602.17129:

\[ Y_{ab}(r) = f_a(r)\,g_b(r) - g_a(r)\,f_b(r), \]

with the same frequency-dependent kernel replacement:

\[ \frac{r_<^k}{r_>^{k+1}} \to -\omega(2k+1)\,j_k(\omega r_<)\,y_k(\omega r_>). \]

Together with gk_ab_freqw, this is used to construct the \(P^k\) and \(Q^k\) screening functions that enter the \(s^k_{abcd}\) and \(t^k_{abcd}\) radial integrals. The \((0,r)\) and \((r,\infty)\) parts are stored separately in g0 and ginf.

Refer to arXiv:2602.17129 for details.

◆ vk_ab_freqw()

void Coulomb::vk_ab_freqw ( const int  k,
const DiracSpinor Fi,
const DiracSpinor Fj,
const Grid gr,
std::vector< double > &  v1,
std::vector< double > &  v2,
std::vector< double > &  v3,
std::vector< double > &  v4,
std::size_t  maxi,
const double  w 
)

Frequency-dependent Breit v^k_ab(r,w): four partial screening integrals.

Computes the frequency-dependent replacement of the \(v^k_{abcd}\) radial integral arXiv:2602.17129. The \(P^k_{ij}\) and \(Q^k_{ij}\) densities are constructed internally from Fi and Fj:

\[ P^k_{ij}(r) = \frac{\kappa_i-\kappa_j}{k}\,X_{ij}(r) - Y_{ij}(r), \qquad Q^k_{ij}(r) = \frac{\kappa_i-\kappa_j}{k+1}\,X_{ij}(r) + Y_{ij}(r). \]

The four outputs correspond to the four double-integral terms:

\begin{align*} &-2\!\int_0^\infty\!\!dr_1\!\int_0^{r_1}\!\!dr_2 \left\{\left[\omega j_{k-1}(\omega r_<)y_{k+1}(\omega r_>) + \tfrac{2k+1}{\omega^2}\tfrac{r_<^{k-1}}{r_>^{k+2}}\right] Q^k_{ac}(r_1)P^k_{ij}(r_2) + \omega j_{k+1}(\omega r_<)y_{k-1}(\omega r_>) P^k_{ac}(r_1)Q^k_{ij}(r_2)\right\}\\ &-2\!\int_0^\infty\!\!dr_1\!\int_{r_1}^{\infty}\!\!dr_2 \left\{\left[\omega j_{k-1}(\omega r_<)y_{k+1}(\omega r_>) + \tfrac{2k+1}{\omega^2}\tfrac{r_<^{k-1}}{r_>^{k+2}}\right] P^k_{ac}(r_1)Q^k_{ij}(r_2) + \omega j_{k+1}(\omega r_<)y_{k-1}(\omega r_>) Q^k_{ac}(r_1)P^k_{ij}(r_2)\right\}, \end{align*}

split as screening functions of \(r_1\) (with \(r_2\) integrated out):

  • v1: \((0,r)\) integral over \(P^k_{ij}\); contracted externally with \(Q^k_{ac}(r)\)
  • v2: \((0,r)\) integral over \(Q^k_{ij}\); contracted externally with \(P^k_{ac}(r)\)
  • v3: \((r,\infty)\) integral over \(Q^k_{ij}\); contracted externally with \(P^k_{ac}(r)\)
  • v4: \((r,\infty)\) integral over \(P^k_{ij}\); contracted externally with \(Q^k_{ac}(r)\)

Refer to arXiv:2602.17129 for details.

Note
For \(\omega \leq \alpha\), a low- \(\omega\) Taylor expansion of the Bessel functions is used to avoid numerical cancellation from divergent leading-order Bessel behaviour as \(\omega\to 0\).

◆ yk_ab() [1/2]

std::vector< double > Coulomb::yk_ab ( const int  k,
const DiracSpinor Fa,
const DiracSpinor Fb,
const std::size_t  maxi = 0 
)

Calculates Hartree Screening functions \(y^k_{ab}(r)\).

maxi is max point to calculate; blank or zero means all the way

◆ yk_ab() [2/2]

void Coulomb::yk_ab ( const int  k,
const DiracSpinor Fa,
const DiracSpinor Fb,
std::vector< double > &  vabk,
const std::size_t  maxi 
)

Overload: does not allocate ykab.

◆ Rk_abcd() [1/2]

double Coulomb::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)

◆ Rk_abcd() [2/2]

double Coulomb::Rk_abcd ( const DiracSpinor Fa,
const DiracSpinor Fc,
const std::vector< double > &  yk_bd 
)

Overload for when y^k_bd already exists [much faster].

◆ Rkv_bcd() [1/3]

DiracSpinor Coulomb::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]

◆ Rkv_bcd() [2/3]

DiracSpinor Coulomb::Rkv_bcd ( const int  kappa_a,
const DiracSpinor Fc,
const std::vector< double > &  ykbd 
)

Overload for when y^k_bd already exists [much faster].

◆ Rkv_bcd() [3/3]

void Coulomb::Rkv_bcd ( DiracSpinor *const  Rkv,
const DiracSpinor Fc,
const std::vector< double > &  ykbd 
)

Overload for when spinor exists. Rkv is overwritten.

◆ Qk_abcd()

double Coulomb::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 YkTable].

◆ Qk_abcd_SR() [1/2]

bool Coulomb::Qk_abcd_SR ( int  k,
int  ka,
int  kb,
int  kc,
int  kd 
)

Just selection rule for Qk_abcd.

◆ Qk_abcd_SR() [2/2]

bool Coulomb::Qk_abcd_SR ( int  k,
const DiracSpinor a,
const DiracSpinor b,
const DiracSpinor c,
const DiracSpinor d 
)

Just selection rule for Qk_abcd.

◆ Pk_abcd_SR() [1/2]

bool Coulomb::Pk_abcd_SR ( int  k,
int  ka,
int  kb,
int  kc,
int  kd 
)

Just selection rule for Pk_abcd.

◆ Pk_abcd_SR() [2/2]

bool Coulomb::Pk_abcd_SR ( int  k,
const DiracSpinor a,
const DiracSpinor b,
const DiracSpinor c,
const DiracSpinor d 
)

Just selection rule for Pk_abcd.

◆ Qkv_bcd()

DiracSpinor Coulomb::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 already have YkTable].

◆ Pk_abcd()

double Coulomb::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].

◆ Pkv_bcd()

DiracSpinor Coulomb::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].

◆ Wk_abcd()

double Coulomb::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)

\[ W^k_{abcd} = Q^k_{abcd} + \sum_l [k] \begin{Bmatrix}a&c&k\\b&d&l\end{Bmatrix} * Q^l_{abdc} \]

\[ W^k_{abcd} = Q^k_{abcd} + P^k_{abcd} \]

◆ g_abcd()

double Coulomb::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.

◆ number_below_Fermi()

int Coulomb::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.

◆ k_minmax_Ck() [1/2]

std::pair< int, int > Coulomb::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)

◆ k_minmax_Ck() [2/2]

std::pair< int, int > Coulomb::k_minmax_Ck ( int  kappa_a,
int  kappa_b 
)

Returns min and max k (multipolarity) allowed for C^k_ab, accounting for parity (used by k_minmax_Q)

◆ k_minmax_tj()

std::pair< int, int > Coulomb::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, not kappa/l) (used by k_minmax_P,W)

◆ k_minmax_Q() [1/2]

std::pair< int, int > Coulomb::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, so you may safely call k+=2. Guaranteed to be non-zero at min and max, and every 2nd inbetween.

◆ k_minmax_Q() [2/2]

std::pair< int, int > Coulomb::k_minmax_Q ( int  kap_a,
int  kap_b,
int  kap_c,
int  kap_d 
)

Returns min and max k (multipolarity) allowed for Q^k_abcd. Parity rule is included, so you may safely call k+=2. Guaranteed to be non-zero at min and max, and every 2nd inbetween.

◆ k_minmax_P()

std::pair< int, int > Coulomb::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) - so NOT safe to call k+=2. Guaranteed to be non-zero at min and max.

◆ k_minmax_W()

std::pair< int, int > Coulomb::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) - so NOT safe to call k+=2. Cannot guarantee non-zero, since when a=b or c=d, sometimes have P=-Q. But when a!=b and c!=d, guaranteed to be non-zero at min and max.

◆ estimate_memory_usage()

void Coulomb::estimate_memory_usage ( const std::string &  basis_string,
const std::string &  core_string,
int  k_cut = 999 
)

Estimate memory required for a QkTable for a given basis.

Given the basis_string, counts the number of non-zero Coulomb integrals using Qk symmetry and angular selection rules. Reports the estimated memory usage in GB for three subsets:

  • All possible Q^k integrals (e.g., structure radiation)
  • Excited-only integrals (all four orbitals above the Fermi level) [CI]
  • Core-Excited integrals (1 or 2 orbitals below Fermi level) [MBPT]
  • And CoulombTable::count_non_zero_integrals() to count integrals
  • Uses estimate_memory_GB() to convert integral counts to memory estimates.
Note
count_non_zero_integrals() takes non-trivial time for large basis
Parameters
basis_stringBasis specification string (e.g., "20spdf").
core_stringCore configuration string (e.g., "[Xe]"). Used to determine the Fermi level. Pass an empty string for no core.
k_cutMaximum multipolarity k to consider.

◆ estimate_memory_GB()

double Coulomb::estimate_memory_GB ( std::size_t  number_of_integrals,
double  load_factor 
)

Estimate memory required for a Qk table.

◆ to_string()

std::string_view Coulomb::to_string ( Symmetry  s)
inline

Convert Symmetry to string.