ampsci
c++ program for high-precision atomic structure calculations of single-valence systems
Breit.hpp
1 #pragma once
2 #include "Coulomb/meTable.hpp"
3 #include "Wavefunction/DiracSpinor.hpp"
4 #include "qip/Vector.hpp"
5 #include <cassert>
6 #include <utility>
7 #include <vector>
8 
9 namespace HF {
10 
11 // namespace hidden {
12 // struct Breit_Bk_ba; // forward decl
13 // }
14 
15 //==============================================================================
16 namespace Breit_gb {
17 
18 struct single_k_mop {
19  // Class to hold the Breit-Coulomb integrals, for single k
20 public:
21  single_k_mop() {}
22  single_k_mop(const DiracSpinor &Fi, const DiracSpinor &Fj, int k) {
23  calculate(Fi, Fj, k);
24  }
25 
26  void calculate(const DiracSpinor &Fi, const DiracSpinor &Fj, int k);
27  std::vector<double> b0_minus{}, bi_minus{};
28  std::vector<double> b0_plus{}, bi_plus{};
29  std::vector<double> g0_minus{}, gi_minus{};
30  std::vector<double> g0_plus{}, gi_plus{};
31 };
32 
33 struct single_k_n {
34  // Class to hold the Breit-Coulomb integrals, for single k
35 public:
36  single_k_n() {}
37  single_k_n(const DiracSpinor &Fi, const DiracSpinor &Fj, int k) {
38  calculate(Fi, Fj, k);
39  }
40 
41  void calculate(const DiracSpinor &Fi, const DiracSpinor &Fj, int k);
42  std::vector<double> g{};
43 
44 private:
45  std::vector<double> gi{};
46 };
47 
48 } // namespace Breit_gb
49 
50 //==============================================================================
52 class Breit {
53  double m_scale;
54 
55  // Scaling factors for each term (mainly for tests). {M,N}=Gaunt; {O,P} rtrd
56  double m_M{1.0}, m_N{1.0}, m_O{1.0}, m_P{1.0};
57 
58  // For speedy lookup, when only full integral is required
59  std::vector<Coulomb::meTable<Breit_gb::single_k_mop>> m_gb{};
60  std::vector<Coulomb::meTable<Breit_gb::single_k_n>> m_gb_N{};
61 
62 public:
64  Breit(double in_scale = 1.0) : m_scale(in_scale) {}
65 
67  void update_scale(double t_scale = 1.0, double t_M = 1.0, double t_N = 1.0,
68  double t_O = 1.0, double t_P = 1.0) {
69  m_scale = t_scale;
70  m_M = t_M;
71  m_N = t_N;
72  m_O = t_O;
73  m_P = t_P;
74  }
75 
76  static bool Bk_SR(int k, const DiracSpinor &v, const DiracSpinor &w,
77  const DiracSpinor &x, const DiracSpinor &y) {
78 
79  const auto have_mop = Angular::Ck_kk_SR(k, v.kappa(), x.kappa()) &&
80  Angular::Ck_kk_SR(k, w.kappa(), y.kappa()) &&
81  v != x && w != y;
82 
83  const auto have_n = Angular::Ck_kk_SR(k, -v.kappa(), x.kappa()) &&
84  Angular::Ck_kk_SR(k, -w.kappa(), y.kappa()) &&
85  (v.kappa() + x.kappa() != 0) &&
86  (w.kappa() + y.kappa() != 0);
87 
88  return (have_mop || have_n);
89  }
90 
91  static std::pair<int, int> k_minmax(const DiracSpinor &a,
92  const DiracSpinor &b,
93  const DiracSpinor &c,
94  const DiracSpinor &d) {
95  const auto [k1, k2] = Coulomb::k_minmax_tj(a.twoj(), c.twoj());
96  const auto [k3, k4] = Coulomb::k_minmax_tj(b.twoj(), d.twoj());
97  return {std::max({1, k1, k3}), std::min(k2, k4)};
98  }
99 
100  static std::pair<int, int> k_minmax_tj(int tja, int tjb, int tjc, int tjd) {
101  const auto [k1, k2] = Coulomb::k_minmax_tj(tja, tjc);
102  const auto [k3, k4] = Coulomb::k_minmax_tj(tjb, tjd);
103  return {std::max({1, k1, k3}), std::min(k2, k4)};
104  }
105 
106  void fill_gb(const std::vector<DiracSpinor> &basis, int t_max_k = 99);
107 
109  double scale_factor() const { return m_scale; };
110 
112  DiracSpinor VbrFa(const DiracSpinor &Fa,
113  const std::vector<DiracSpinor> &core) const;
114 
119  DiracSpinor dV_Br(int kappa, int K, const DiracSpinor &Fa,
120  const DiracSpinor &Fb, const DiracSpinor &Xbeta,
121  const DiracSpinor &Ybeta) const;
122 
124  double Bk_abcd(int k, const DiracSpinor &Fa, const DiracSpinor &Fb,
125  const DiracSpinor &Fc, const DiracSpinor &Fd) const;
126 
129  double Bk_abcd_2(int k, const DiracSpinor &Fa, const DiracSpinor &Fb,
130  const DiracSpinor &Fc, const DiracSpinor &Fd) const;
131 
133  double BPk_abcd(int k, const DiracSpinor &Fa, const DiracSpinor &Fb,
134  const DiracSpinor &Fc, const DiracSpinor &Fd) const;
135 
138  double BPk_abcd_2(int k, const DiracSpinor &Fa, const DiracSpinor &Fb,
139  const DiracSpinor &Fc, const DiracSpinor &Fd) const;
140 
143  double BWk_abcd(int k, const DiracSpinor &Fa, const DiracSpinor &Fb,
144  const DiracSpinor &Fc, const DiracSpinor &Fd) const;
145 
148  double BWk_abcd_2(int k, const DiracSpinor &Fa, const DiracSpinor &Fb,
149  const DiracSpinor &Fc, const DiracSpinor &Fd) const;
150 
152  DiracSpinor Bkv_bcd(int k, int kappa_v, const DiracSpinor &Fb,
153  const DiracSpinor &Fc, const DiracSpinor &Fd) const;
155  DiracSpinor BPkv_bcd(int k, int kappa_v, const DiracSpinor &Fb,
156  const DiracSpinor &Fc, const DiracSpinor &Fd) const;
158  DiracSpinor BWkv_bcd(int k, int kappa_v, const DiracSpinor &Fb,
159  const DiracSpinor &Fc, const DiracSpinor &Fd) const;
160 
163  double de2_HF(const DiracSpinor &Fv, const std::vector<DiracSpinor> &holes,
164  const std::vector<DiracSpinor> &excited) const;
165 
167  double de2(const DiracSpinor &Fv, const std::vector<DiracSpinor> &holes,
168  const std::vector<DiracSpinor> &excited) const;
169 };
170 
171 } // namespace HF
Stores radial Dirac spinor: F_nk = (f, g)
Definition: DiracSpinor.hpp:41
int kappa() const
Dirac quantum number, kappa.
Definition: DiracSpinor.hpp:84
Breit (Hartree-Fock Breit) interaction potential.
Definition: Breit.hpp:52
DiracSpinor Bkv_bcd(int k, int kappa_v, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd) const
Bkv_bcd defined: B^k_abcd = <a|Bkv_bcd> (direct part)
Definition: Breit.cpp:60
double Bk_abcd(int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd) const
Reduced Breit integral (analogue of Coulomb Q^k).
Definition: Breit.cpp:341
Breit(double in_scale=1.0)
Constructs Breit operator; scale is overall scaling factor, 1.0 typical.
Definition: Breit.hpp:64
double Bk_abcd_2(int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd) const
Reduced Breit integral (analogue of Coulomb Q^k), faster version. Can only use if fill_gb() has been ...
Definition: Breit.cpp:168
void update_scale(double t_scale=1.0, double t_M=1.0, double t_N=1.0, double t_O=1.0, double t_P=1.0)
Allows one to update scaling factor(s)
Definition: Breit.hpp:67
DiracSpinor BPkv_bcd(int k, int kappa_v, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd) const
BPkv_bcd defined: P(B)^k_abcd = <a|BPkv_bcd> (exchange part)
Definition: Breit.cpp:283
double de2_HF(const DiracSpinor &Fv, const std::vector< DiracSpinor > &holes, const std::vector< DiracSpinor > &excited) const
Hartree-Fock (one-particle) part of second-order Breit correction. With Breit-Coulomb Hartree-Fock,...
Definition: Breit.cpp:372
double BWk_abcd_2(int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd) const
Reduced anti-symmetrised Breit integral (analogue of Coulomb W^k), faster. Can only use if fill_gb() ...
Definition: Breit.cpp:354
DiracSpinor VbrFa(const DiracSpinor &Fa, const std::vector< DiracSpinor > &core) const
Calculates V_br*Fa [Breit part of HF-Breit pot.].
Definition: Breit.cpp:12
DiracSpinor BWkv_bcd(int k, int kappa_v, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd) const
BWkv_bcd defined: W(B)^k_abcd = B^k_abcd + P(B)^k_abcd= <a|BWkv_bcd>
Definition: Breit.cpp:334
double de2(const DiracSpinor &Fv, const std::vector< DiracSpinor > &holes, const std::vector< DiracSpinor > &excited) const
Sigma (two-particle) part of second-order Breit correction.
Definition: Breit.cpp:395
double BPk_abcd_2(int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd) const
Reduced exchange Breit integral (analogue of Coulomb P^k), faster version. Can only use if fill_gb() ...
Definition: Breit.cpp:311
double scale_factor() const
Resturns scaling factor.
Definition: Breit.hpp:109
double BWk_abcd(int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd) const
Reduced anti-symmetrised Breit integral (analogue of Coulomb W^k). BWk_abcd = Bk_abcd + BPk_abcd.
Definition: Breit.cpp:349
double BPk_abcd(int k, const DiracSpinor &Fa, const DiracSpinor &Fb, const DiracSpinor &Fc, const DiracSpinor &Fd) const
Reduced exchange Breit integral (analogue of Coulomb P^k).
Definition: Breit.cpp:345
DiracSpinor dV_Br(int kappa, int K, const DiracSpinor &Fa, const DiracSpinor &Fb, const DiracSpinor &Xbeta, const DiracSpinor &Ybeta) const
dV_b*Fa, dV_b is the RPA correction arising due to Fb -> Fb + dFb
Definition: Breit.cpp:360
bool Ck_kk_SR(int k, int ka, int kb)
Ck selection rule only. Returns false if C^k=0, true if non-zero.
Definition: Wigner369j.hpp:293
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:551
double g(RaB r, PrincipalQN n, DiracQN k, Zeff z, AlphaFS a)
Lower (small) radial component.
Definition: DiracHydrogen.cpp:83
Functions and classes for Hartree-Fock.
Definition: CI_Integrals.hpp:12