ampsci
c++ program for high-precision atomic structure calculations of single-valence systems
Loading...
Searching...
No Matches
meTable.hpp
1#pragma once
2#include "Physics/AtomData.hpp"
3#include "QkTable.hpp"
4#include "Wavefunction/DiracSpinor.hpp"
5#include <cstdint>
6#include <unordered_map>
7
8namespace Coulomb {
9
11using nk2Index = uint32_t;
12
16template <typename T = double>
17class meTable {
18
19private:
20 std::unordered_map<nk2Index, T> m_data{};
21
22public:
23 auto operator->() { return &m_data; }
24
27 void add(const DiracSpinor &a, const DiracSpinor &b, T value) {
28 m_data.insert({FormIndex(a.nk_index(), b.nk_index()), std::move(value)});
29 }
32 void add(DiracSpinor::Index a, DiracSpinor::Index b, T value) {
33 m_data.insert({FormIndex(a, b), std::move(value)});
34 }
35
37 void add(const meTable<T> &other) {
38 m_data.insert(other.cbegin(), other.cend());
39 }
40
42 void update(const DiracSpinor &a, const DiracSpinor &b, T value) {
43 m_data.insert_or_assign(FormIndex(a.nk_index(), b.nk_index()),
44 std::move(value));
45 }
47 void update(DiracSpinor::Index a, DiracSpinor::Index b, T value) {
48 m_data.insert_or_assign(FormIndex(a, b), std::move(value));
49 }
50
52 [[nodiscard]] bool contains(const DiracSpinor &a,
53 const DiracSpinor &b) const {
54 return m_data.find(FormIndex(a.nk_index(), b.nk_index())) != m_data.cend();
55 }
57 [[nodiscard]] bool contains(DiracSpinor::Index a,
58 DiracSpinor::Index b) const {
59 return m_data.find(FormIndex(a, b)) != m_data.cend();
60 }
61
64 [[nodiscard]] const T *get(const DiracSpinor &a, const DiracSpinor &b) const {
65 const auto map_it = m_data.find(FormIndex(a.nk_index(), b.nk_index()));
66 return (map_it == m_data.cend()) ? nullptr : &(map_it->second);
67 }
70 [[nodiscard]] const T *get(DiracSpinor::Index a, DiracSpinor::Index b) const {
71 const auto map_it = m_data.find(FormIndex(a, b));
72 return (map_it == m_data.cend()) ? nullptr : &(map_it->second);
73 }
74
77 [[nodiscard]] T *get(const DiracSpinor &a, const DiracSpinor &b) {
78 const auto map_it = m_data.find(FormIndex(a.nk_index(), b.nk_index()));
79 return (map_it == m_data.cend()) ? nullptr : &(map_it->second);
80 }
83 [[nodiscard]] T *get(DiracSpinor::Index a, DiracSpinor::Index b) {
84 const auto map_it = m_data.find(FormIndex(a, b));
85 return (map_it == m_data.cend()) ? nullptr : &(map_it->second);
86 }
87
90 [[nodiscard]] T getv(const DiracSpinor &a, const DiracSpinor &b) const {
91 const auto ptr = get(a, b);
92 return ptr ? *ptr : T{};
93 }
96 [[nodiscard]] T getv(DiracSpinor::Index a, DiracSpinor::Index b) const {
97 const auto ptr = get(a, b);
98 return ptr ? *ptr : T{};
99 }
100
103 [[nodiscard]] const T *get(const std::string &a, const std::string &b) const {
104 const auto [na, ka] = AtomData::parse_symbol(a);
105 const auto [nb, kb] = AtomData::parse_symbol(b);
106 const auto a_index =
107 static_cast<Coulomb::nkIndex>(Angular::nk_to_index(na, ka));
108 const auto b_index =
109 static_cast<Coulomb::nkIndex>(Angular::nk_to_index(nb, kb));
110 const auto map_it = m_data.find(FormIndex(a_index, b_index));
111 return (map_it == m_data.cend()) ? nullptr : &(map_it->second);
112 }
113
115 auto begin() { return m_data.begin(); }
116 auto end() { return m_data.end(); }
117 auto cbegin() const { return m_data.cbegin(); }
118 auto cend() const { return m_data.cend(); }
119
120 static std::pair<std::string, std::string> index_to_symbols(nk2Index index) {
121 const auto [a, b] = unFormIndex(index);
122 const auto [na, ka] = Angular::index_to_nk(int(a));
123 const auto [nb, kb] = Angular::index_to_nk(int(b));
124 return {AtomData::shortSymbol(na, ka), AtomData::shortSymbol(nb, kb)};
125 }
126
127 // private:
128 // Converts given set of nkIndex's (in any order) to nk4Index
129 [[nodiscard]] static nk2Index FormIndex(nkIndex a, nkIndex b) {
130 static_assert(sizeof(nk2Index) == 2 * sizeof(nkIndex));
131 static_assert(sizeof(nkIndex) * 8 == 16);
132 return (nk2Index)b + ((nk2Index)a << 16);
133 }
134
135 [[nodiscard]] static std::pair<nkIndex, nkIndex> unFormIndex(nk2Index index) {
136 std::pair<nkIndex, nkIndex> out;
137 auto &[a, b] = out;
138 b = static_cast<nkIndex>(index);
139 // nb: this relies on specific encoding, and may fail?
140 a = static_cast<nkIndex>((index - static_cast<nk2Index>(b)) >> 16);
141 assert(FormIndex(a, b) == index);
142 return out;
143 }
144};
145
146} // namespace Coulomb
Look-up table for matrix elements. Note: does not assume any symmetry: (a,b) is stored independantly ...
Definition meTable.hpp:17
void add(DiracSpinor::Index a, DiracSpinor::Index b, T value)
Adds new element to table. If already exists, does nothing (does not update)
Definition meTable.hpp:32
T * get(DiracSpinor::Index a, DiracSpinor::Index b)
Gets pointer to mutable requested element. If element not present, returns nullptr.
Definition meTable.hpp:83
T * get(const DiracSpinor &a, const DiracSpinor &b)
Gets pointer to mutable requested element. If element not present, returns nullptr.
Definition meTable.hpp:77
void update(const DiracSpinor &a, const DiracSpinor &b, T value)
Updates given element in table. If element not yet present, adds it.
Definition meTable.hpp:42
auto begin()
Provide iterators.
Definition meTable.hpp:115
const T * get(const std::string &a, const std::string &b) const
Gets pointer to const requested element. If element not present, returns nullptr. Overload for string...
Definition meTable.hpp:103
bool contains(DiracSpinor::Index a, DiracSpinor::Index b) const
Checks if given element is in the table.
Definition meTable.hpp:57
bool contains(const DiracSpinor &a, const DiracSpinor &b) const
Checks if given element is in the table.
Definition meTable.hpp:52
T getv(const DiracSpinor &a, const DiracSpinor &b) const
Gets value of requested element. If element not present, returns zero (or default constructed T)
Definition meTable.hpp:90
void add(const meTable< T > &other)
Adds elements from one Table into another (by copy)
Definition meTable.hpp:37
void update(DiracSpinor::Index a, DiracSpinor::Index b, T value)
Updates given element in table. If element not yet present, adds it.
Definition meTable.hpp:47
const T * get(DiracSpinor::Index a, DiracSpinor::Index b) const
Gets pointer to const requested element. If element not present, returns nullptr.
Definition meTable.hpp:70
T getv(DiracSpinor::Index a, DiracSpinor::Index b) const
Gets value of requested element. If element not present, returns zero (or default constructed T)
Definition meTable.hpp:96
void add(const DiracSpinor &a, const DiracSpinor &b, T value)
Adds new element to table. If already exists, does nothing (does not update)
Definition meTable.hpp:27
const T * get(const DiracSpinor &a, const DiracSpinor &b) const
Gets pointer to const requested element. If element not present, returns nullptr.
Definition meTable.hpp:64
Stores radial Dirac spinor: F_nk = (f, g)
Definition DiracSpinor.hpp:41
Index nk_index() const
(n,kappa) index (see AtomData)
Definition DiracSpinor.hpp:97
constexpr int nk_to_index(int n, int k)
return nk_index given {n, kappa}: nk_index(n,k) := n^2 - 2n + 1 + kappa_index
Definition Wigner369j.hpp:73
std::pair< int, int > index_to_nk(int index)
return {n, kappa} given nk_index:
Definition Wigner369j.hpp:78
std::pair< int, int > parse_symbol(std::string_view symbol)
Parses electron 'symbol' or 'shortSymbol' to {n,kappa}, e.g., "6s+" -> {6,-1}; "6p-" -> {6,...
Definition AtomData.cpp:148
std::string shortSymbol(int n, int kappa)
Returns shortSymbol, given n and kappa: (6,-1)->"6s+".
Definition AtomData.cpp:128
Functions (+classes) for computing Coulomb integrals.
Definition Coulomb.hpp:8
uint32_t nk2Index
index type for set of 2 orbitals {nk,nk} -> nk4Index
Definition meTable.hpp:11
uint16_t nkIndex
index type for each {nk} (orbital)
Definition QkTable.hpp:19