ampsci
High-precision calculations for one- and two-valence atomic systems
CkTable.hpp
1#pragma once
2#include "Angular/Wigner369j.hpp"
3#include <algorithm>
4#include <iostream>
5#include <vector>
6
7namespace Angular {
8
9//==============================================================================
10// "Helper" functions
11//! Converts jindex to 2*j [helper function]
12constexpr int twoj(int jindex) { return 2 * jindex + 1; }
13//! Converts 2*j to jindex {1/2, 3/2, 5/2} -> {0, 1, 2} [helper function]
14constexpr int jindex(int twoj) { return (twoj - 1) / 2; }
15//! Converts kappa to jindex {-1, 1, -2} -> {0, 0, 1} [helper function]
16constexpr int jindex_kappa(int ka) { return (ka > 0) ? ka - 1 : -ka - 1; }
17
18//==============================================================================
19/*!
20@brief Lookup table for C^k and 3j symbols (special m=1/2, q=0 case)
21@details
22 - Builds 3j symbol lookup table for given maximum k and maximum j (2j)
23 - 3j symbols, special case: (ja jb k \\ -1/2, 1/2, 0)
24 - Ckab : \f$C^k_{ab} = \langle k_a||C^k||k_b \rangle\f$
25 [symmetric up to +/- sign]
26 - TildeCkab : \f$\widetilde C^k_{ab} = (-1)^{ja+1/2} C^k_{ab}\f$ [symmetric]
27 - Slightly faster than calculating on-the-fly, but adds some overhead
28\par Construction
29 - Needs maximum two*j values. Will build look-up tables for all possible
30symbols.
31\par Mutable versions
32 - Some functions come with '_mutable' versions
33 - These will calculate (+ store) values if they don't exist yet
34 - '_mutable' versions are NOT thread safe (non-mutable are)
35 - The non-mutable versions: must not be called if symbol hasn't been
36 calculated. This is undefined behaviour
37 - You can check which symbols exist by calling max_tj() and max_k()
38 - All "lower" symbols are calculated [max_tj, max_k defined all]
39\par Usage
40 - Note: Functions take k and kappa_a, kappa_b as input!
41*/
42class CkTable {
43
44public:
45 //! Calculates and stored all Ck/3j symbols up to given maximum 2j
46 CkTable(const int in_max_twoj = 0) { fill(in_max_twoj); }
47
48public:
49 //! Extends existing look-up table to new twoj.
50 /*!
51 @details
52 nb: called on construction automatically, you only need to call this if you
53 need to extend the table after original construction (rare)
54 */
55 void fill(const int in_max_twoj);
56
57 //! Ckab. mutable: will calculate if needed. Not thread safe
58 double get_Ckab_mutable(int k, int ka, int kb);
59 //! tildeCkab. mutable: will calculate if needed. Not thread safe
60 double get_tildeCkab_mutable(int k, int ka, int kb);
61 //! special 3j(k, ka, kb). mutable: will calculate if needed. Not thread safe
62 double get_3jkab_mutable(int k, int ka, int kb);
63
64 //! Ckab. Undefined if k, ka, or kb are out-of-bounds [check with max_tj()].
65 double get_Ckab(int k, int ka, int kb) const;
66 //! tildeCkab. Undefined if k, ka, or kb are out-of-bounds
67 double get_tildeCkab(int k, int ka, int kb) const;
68 //! special 3j(k, ka, kb). Undefined if k, ka, or kb are out-of-bounds
69 double get_3jkab(int k, int ka, int kb) const;
70
71 //! Operator overload: returns Ckab
72 double operator()(int k, int ka, int kb) const { return get_Ckab(k, ka, kb); }
73
74 //! Lambda^k_ij := 3js((ji,jj,k),(-1/2,1/2,0))^2 * parity(li+lj+k)
75 double get_Lambdakab(int k, int ka, int kb) const;
76
77 //! Maximum value for 2j currently stored in tables
78 int max_tj() const { return twoj(m_max_jindex_sofar); }
79 //! Maximum value for k currently stored in tables
80 int max_k() const { return m_max_k_sofar; }
81
82private:
83 std::vector<std::vector<std::vector<double>>> m_3j_k_a_b = {};
84 std::vector<std::vector<double>> m_Rjab_a_b = {}; // Sqrt([ja][jb])
85 int m_max_jindex_sofar = -1;
86 int m_max_k_sofar = -1;
87};
88
89} // namespace Angular
Lookup table for C^k and 3j symbols (special m=1/2, q=0 case)
Definition CkTable.hpp:42
double get_Ckab(int k, int ka, int kb) const
Ckab. Undefined if k, ka, or kb are out-of-bounds [check with max_tj()].
Definition CkTable.cpp:96
double get_tildeCkab(int k, int ka, int kb) const
tildeCkab. Undefined if k, ka, or kb are out-of-bounds
Definition CkTable.cpp:67
int max_tj() const
Maximum value for 2j currently stored in tables.
Definition CkTable.hpp:78
int max_k() const
Maximum value for k currently stored in tables.
Definition CkTable.hpp:80
double get_tildeCkab_mutable(int k, int ka, int kb)
tildeCkab. mutable: will calculate if needed. Not thread safe
Definition CkTable.cpp:52
double get_Lambdakab(int k, int ka, int kb) const
Lambda^k_ij := 3js((ji,jj,k),(-1/2,1/2,0))^2 * parity(li+lj+k)
Definition CkTable.cpp:119
double get_3jkab_mutable(int k, int ka, int kb)
special 3j(k, ka, kb). mutable: will calculate if needed. Not thread safe
Definition CkTable.cpp:102
double get_3jkab(int k, int ka, int kb) const
special 3j(k, ka, kb). Undefined if k, ka, or kb are out-of-bounds
Definition CkTable.cpp:111
double get_Ckab_mutable(int k, int ka, int kb)
Ckab. mutable: will calculate if needed. Not thread safe.
Definition CkTable.cpp:91
void fill(const int in_max_twoj)
Extends existing look-up table to new twoj.
Definition CkTable.cpp:9
double operator()(int k, int ka, int kb) const
Operator overload: returns Ckab.
Definition CkTable.hpp:72
CkTable(const int in_max_twoj=0)
Calculates and stored all Ck/3j symbols up to given maximum 2j.
Definition CkTable.hpp:46
Angular provides functions and classes for calculating and storing angular factors (3,...
Definition CkTable.cpp:7
constexpr int jindex(int twoj)
Converts 2*j to jindex {1/2, 3/2, 5/2} -> {0, 1, 2} [helper function].
Definition CkTable.hpp:14
constexpr int jindex_kappa(int ka)
Converts kappa to jindex {-1, 1, -2} -> {0, 0, 1} [helper function].
Definition CkTable.hpp:16
constexpr int twoj(int jindex)
Converts jindex to 2*j [helper function].
Definition CkTable.hpp:12