ampsci
c++ program for high-precision atomic structure calculations of single-valence systems
QkTable.hpp
1 #pragma once
2 #include "Angular/SixJTable.hpp"
3 #include "Wavefunction/DiracSpinor.hpp"
4 #include "YkTable.hpp"
5 #include <array>
6 #include <cstdint>
7 #include <functional>
8 #include <unordered_map>
9 
10 namespace Coulomb {
11 
13 enum class Symmetry { Qk, Wk, Lk, none };
15 using Real = double;
17 using nk4Index = uint64_t;
19 using nkIndex = uint16_t;
20 
21 static_assert(sizeof(nkIndex) == sizeof(DiracSpinor::Index));
22 
26  std::function<double(int, const DiracSpinor &a, const DiracSpinor &b,
27  const DiracSpinor &c, const DiracSpinor &d)>;
28 
32  std::function<bool(int, const DiracSpinor &a, const DiracSpinor &b,
33  const DiracSpinor &c, const DiracSpinor &d)>;
34 
35 //==============================================================================
56 template <Symmetry S>
57 class CoulombTable {
58 
59 private:
60  // each vector element corresponds to a 'k'
61  std::vector<std::unordered_map<nk4Index, Real>> m_data{};
62 
63 public:
64  // 'Rule of zero' (except virtual destructor)
65  // virtual ~CoulombTable() = default;
66 
70  void fill(const std::vector<DiracSpinor> &basis, const YkTable &yk,
71  int k_cut = -1, bool print = true);
72 
77  void fill_if(const std::vector<DiracSpinor> &basis, const YkTable &yk,
78  const SelectionRules &SelectionFunction, int k_cut = -1,
79  bool print = true);
80 
81  void fill(const std::vector<DiracSpinor> &basis, const CoulombFunction &Fk,
82  const SelectionRules &Fk_SR, int k_cut = -1, bool print = true);
83 
85  auto operator->() { return &m_data; }
86 
88  void summary() const;
90  std::size_t count() const;
91 
93  void add(int k, const DiracSpinor &a, const DiracSpinor &b,
94  const DiracSpinor &c, const DiracSpinor &d, Real value);
96  void add(int k, nkIndex a, nkIndex b, nkIndex c, nkIndex d, Real value);
98  void add(int k, nk4Index index, Real value);
99 
101  void update(int k, const DiracSpinor &a, const DiracSpinor &b,
102  const DiracSpinor &c, const DiracSpinor &d, Real value);
104  void update(int k, nkIndex a, nkIndex b, nkIndex c, nkIndex d, Real value);
106  void update(int k, nk4Index index, Real value);
107 
109  bool contains(int k, const DiracSpinor &a, const DiracSpinor &b,
110  const DiracSpinor &c, const DiracSpinor &d) const;
112  bool contains(int k, nkIndex a, nkIndex b, nkIndex c, nkIndex d) const;
114  bool contains(int k, nk4Index index) const;
115 
117  bool emptyQ() const {
118  return (m_data.size() == 0);
119  // nb: possible to be empty if size > 0... (but doesn't matter..)
120  }
121 
124  Real Q(int k, const DiracSpinor &a, const DiracSpinor &b,
125  const DiracSpinor &c, const DiracSpinor &d) const;
128 
129  Real Q(int k, nkIndex a, nkIndex b, nkIndex c, nkIndex d) const;
132  Real Q(int k, nk4Index index) const;
133 
135  Real R(int k, const DiracSpinor &a, const DiracSpinor &b,
136  const DiracSpinor &c, const DiracSpinor &d) const;
138  Real R(int k, nkIndex a, nkIndex b, nkIndex c, nkIndex d) const;
139 
142  Real P(int k, const DiracSpinor &a, const DiracSpinor &b,
143  const DiracSpinor &c, const DiracSpinor &d,
144  const Angular::SixJTable *const sj = nullptr) const;
147  Real P(int k, nkIndex a, nkIndex b, nkIndex c, nkIndex d,
148  const Angular::SixJTable *const sj = nullptr) const;
149 
152  Real P2(int k, const DiracSpinor &a, const DiracSpinor &b,
153  const DiracSpinor &c, const DiracSpinor &d,
154  const Angular::SixJTable &sj, const std::vector<double> &fk) const;
155 
158  Real W(int k, const DiracSpinor &a, const DiracSpinor &b,
159  const DiracSpinor &c, const DiracSpinor &d,
160  const Angular::SixJTable *const sj = nullptr) const;
163  Real W(int k, nkIndex a, nkIndex b, nkIndex c, nkIndex d,
164  const Angular::SixJTable *const sj = nullptr) const;
165 
167  Real g(const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c,
168  const DiracSpinor &d, int tma, int tmb, int tmc, int tmd) const;
169 
172  nk4Index NormalOrder(const DiracSpinor &a, const DiracSpinor &b,
173  const DiracSpinor &c, const DiracSpinor &d) const;
177 
179  bool is_NormalOrdered(nkIndex a, nkIndex b, nkIndex c, nkIndex d) const {
180  return NormalOrder(a, b, c, d) == CurrentOrder(a, b, c, d);
181  }
183  bool is_NormalOrdered(const DiracSpinor &a, const DiracSpinor &b,
184  const DiracSpinor &c, const DiracSpinor &d) const {
185  return NormalOrder(a, b, c, d) == CurrentOrder(a, b, c, d);
186  }
187 
189  void write(const std::string &fname) const;
191  bool read(const std::string &fname);
192 
194  double *get(int k, nk4Index index);
195 
198  nk4Index CurrentOrder(const DiracSpinor &a, const DiracSpinor &b,
199  const DiracSpinor &c, const DiracSpinor &d) const;
200 
204 
206  static nk4Index FormIndex(nkIndex a, nkIndex b, nkIndex c, nkIndex d);
207 
209  std::array<nkIndex, 4> UnFormIndex(const nk4Index &index) const;
210 
211 private:
212  // Returns the "NormalOrder" nk4Index for given set. Implemented by
213  // specific symmetries
214  static inline nk4Index NormalOrder_impl(nkIndex a, nkIndex b, nkIndex c,
215  nkIndex d);
216 };
217 
226 
227 } // namespace Coulomb
228 
229 #include "QkTable.ipp"
Lookup table for Wigner 6J symbols.
Definition: SixJTable.hpp:24
Base (pure virtual) class to store Coulomb integrals, and similar. 3 derived classes,...
Definition: QkTable.hpp:57
Real P2(int k, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d, const Angular::SixJTable &sj, const std::vector< double > &fk) const
'Exchange-only', defined via W = Q + P. Optionally, takes pointer to 6J table (faster eval of 6J symb...
Definition: QkTable.ipp:229
double * get(int k, nk4Index index)
Directly gets one of the stored elements, given normal-ordered nk4Index.
Definition: QkTable.ipp:115
void fill_if(const std::vector< DiracSpinor > &basis, const YkTable &yk, const SelectionRules &SelectionFunction, int k_cut=-1, bool print=true)
Takes a constructed YkTable, and fills Coulomb table with all possible non-zero Qk Coulomb integrals ...
Definition: QkTable.ipp:586
Real P(int k, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d, const Angular::SixJTable *const sj=nullptr) const
'Exchange-only', defined via W = Q + P. Optionally, takes pointer to 6J table (faster eval of 6J symb...
Definition: QkTable.ipp:220
bool is_NormalOrdered(nkIndex a, nkIndex b, nkIndex c, nkIndex d) const
Checks if set {a,b,c,d} are already in NormalOrder.
Definition: QkTable.hpp:179
bool read(const std::string &fname)
Reads coulomb integrals to disk. Returns false if none read in.
Definition: QkTable.ipp:862
bool is_NormalOrdered(const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d) const
Checks if set {a,b,c,d} are already in NormalOrder.
Definition: QkTable.hpp:183
void update(int k, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d, Real value)
Updates value in table. If not present, adds new value.
Definition: QkTable.ipp:71
auto operator->()
Gives arrow access to all underlying vector<unordered_map> functions.
Definition: QkTable.hpp:85
bool contains(int k, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d) const
Checks if given {k,a,b,c,d} is in the table.
Definition: QkTable.ipp:97
nk4Index NormalOrder(const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d) const
Creates single 'nk4Index' corresponding to 'NormalOrder' symmetry of {a,b,c,d}.
Definition: QkTable.ipp:394
nk4Index CurrentOrder(const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d) const
Creates single 'nk4Index', WITHOUT accounting for 'NormalOrder'. Can be used to check if {a,...
Definition: QkTable.ipp:407
static nk4Index FormIndex(nkIndex a, nkIndex b, nkIndex c, nkIndex d)
Converts given set of nkIndex's (in any order) to nk4Index.
Definition: QkTable.ipp:416
Real R(int k, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d) const
Returns 'R', defined via: R := Q / (angular_coef)
Definition: QkTable.ipp:178
std::array< nkIndex, 4 > UnFormIndex(const nk4Index &index) const
Breaks nk4Index back into {ia,ib,ic,id}. Not used.
Definition: QkTable.ipp:439
void fill(const std::vector< DiracSpinor > &basis, const YkTable &yk, int k_cut=-1, bool print=true)
Takes a constructed YkTable, and fills Coulomb table with all possible non-zero Qk Coulomb integrals,...
Definition: QkTable.ipp:455
void write(const std::string &fname) const
Writes coulomb integrals to disk.
Definition: QkTable.ipp:838
void summary() const
For testing: prints details of coulomb integrals stored.
Definition: QkTable.ipp:15
Real g(const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d, int tma, int tmb, int tmc, int tmd) const
Returns 'g_abcd'.
Definition: QkTable.ipp:271
void add(int k, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d, Real value)
adds a new value. Note: does nothing if {k,a,b,c,d} already exists
Definition: QkTable.ipp:45
Real Q(int k, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d) const
Retrieve a stored Q. If not present, returns 0. (Returns exactly as stored in table....
Definition: QkTable.ipp:141
Real W(int k, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d, const Angular::SixJTable *const sj=nullptr) const
W^k_abcd = Q^k_abcd + \sum_l [k] 6j * Q^l_abdc. Optionally, takes pointer to 6J table (faster eval of...
Definition: QkTable.ipp:257
std::size_t count() const
Returns number of stored integrals.
Definition: QkTable.ipp:29
bool emptyQ() const
Returns true if table is empty.
Definition: QkTable.hpp:117
Calculates + stores Hartree Y functions + Angular (w/ look-up), taking advantage of symmetry.
Definition: YkTable.hpp:26
Stores radial Dirac spinor: F_nk = (f, g)
Definition: DiracSpinor.hpp:41
Functions (+classes) for computing Coulomb integrals.
Definition: Coulomb.hpp:8
double Real
Data type used to store integrals.
Definition: QkTable.hpp:15
std::function< bool(int, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d)> SelectionRules
Function type for determining Coulomb(-like) integral selection rules. Takes k and 4 DiracSpinors,...
Definition: QkTable.hpp:33
uint64_t nk4Index
index type for set of 4 orbitals {nk,nk,nk,nk} -> nk4Index
Definition: QkTable.hpp:17
uint16_t nkIndex
index type for each {nk} (orbital)
Definition: QkTable.hpp:19
Symmetry
Symmetry (state index order) for tables.
Definition: QkTable.hpp:13
std::function< double(int, const DiracSpinor &a, const DiracSpinor &b, const DiracSpinor &c, const DiracSpinor &d)> CoulombFunction
Function type for calculating Coulomb(-like) integrals. Takes k and 4 DiracSpinors,...
Definition: QkTable.hpp:27