ampsci
High-precision calculations for one- and two-valence atomic systems
Ek.hpp
1#pragma once
2#include "DiracOperator/TensorOperator.hpp"
3#include "IO/InputBlock.hpp"
4#include "Wavefunction/Wavefunction.hpp"
5
6namespace DiracOperator {
7
8//==============================================================================
9//! E^k (electric multipole) operator, length form, with (qr<<1) approximation
10/*! @details
11 \f[ h = -|e|r^k = -e r^k \f]
12 \f[<a||d||b> = R C^k_{ab}\f]
13 \f[R = -e \int r^k (f_a f_b + g_a g_b) \, dr\f]
14
15 - This has (qr<<1) approximation; Bessel functions not explicit
16 - See @ref EM_multipole operator for full operators
17*/
18class Ek : public TensorOperator {
19public:
20 Ek(const Grid &gr, const int k)
21 : TensorOperator(k, Angular::evenQ(k) ? Parity::even : Parity::odd, -1.0,
22 gr.rpow(k)),
23 m_k(k) {}
24 double angularF(const int ka, const int kb) const override final {
25 return Angular::Ck_kk(m_k, ka, kb);
26 }
27 std::string name() const override {
28 return std::string("E") + std::to_string(m_k);
29 }
30 std::string units() const override {
31 return m_k == 1 ? "|e|aB" : std::string("|e|aB^") + std::to_string(m_k);
32 }
33
34private:
35 int m_k;
36};
37
38//==============================================================================
39//! Electric dipole operator: -|e|r = -er
40/*! @details
41\f[<a||d||b> = R (-1)^{ja+1/2} \sqrt{[ja][jb]} \, tjs(ja,jb,1, -1/2,1/2,0)\f]
42\f[<a||d||b> = R <k_a||C^k||k_b>\f]
43\f[R = -e \int r(f_a f_b + g_a g_b) \, dr\f]
44*/
45class E1 final : public Ek {
46public:
47 E1(const Grid &gr) : Ek(gr, 1) {}
48};
49
50//==============================================================================
51//! Odd-parity rank-0 operator with radial function r (sigma_r)
52class sigma_r final : public ScalarOperator {
53public:
54 sigma_r(const Grid &rgrid) : ScalarOperator(Parity::odd, -1.0, rgrid.r()) {}
55 std::string name() const override final { return "s.r"; }
56 std::string units() const override final { return "aB"; }
57};
58
59//==============================================================================
60//! @brief Electric dipole operator, v-form:
61//! \f$ \frac{ie}{\omega \alpha} \vec{\alpha}\f$
62/*! @details
63\f[ <a||d_v||b> = R \f]
64\f[ R = -\frac{2e}{\omega \alpha}
65\int( f_ag_b <ka||s||-kb> - g_af_b <-ka||s||kb>)\,dr \f]
66*/
67class E1v final : public TensorOperator
68// d_v = (ie/w alpha) v{alpha} [v{a} = g0v{g}]\f$
69// <a||dv||b> = -2e/(w alpha) Int[ fagb <ka||s||-kb> - gafb <-ka||s||kb>]
70{
71public:
72 E1v(const double alpha, const double omega = 0.0)
73 : TensorOperator(1, Parity::odd, -0.0, {}, Realness::real, true),
74 m_alpha(alpha) {
75 updateFrequency(omega);
76 }
77 std::string name() const override final { return "E1v"; }
78 std::string units() const override final { return "|e|aB"; }
79
80 double angularF(const int ka, const int kb) const override final {
81 // return 1;
82 return Angular::Ck_kk(1, ka, kb);
83 }
84
85 double angularCff(int, int) const override final { return 0; }
86 double angularCgg(int, int) const override final { return 0; }
87 double angularCfg(int ka, int kb) const override final {
88 // return Angular::S_kk(ka, -kb);
89 return ka - kb - 1;
90 }
91 double angularCgf(int ka, int kb) const override final {
92 // return -Angular::S_kk(-ka, kb);
93 return ka - kb + 1;
94 }
95
96 //! @note At omega=0 (static limit) falls back to m_constant = -1.0;
97 //! the velocity-form operator diverges as 1/omega and is not physically
98 //! meaningful at zero frequency.
99 void updateFrequency(const double omega) override final {
100 // m_constant = std::abs(omega) > 1.0e-10 ? -2.0 / (m_alpha * omega) : 1.0;
101 m_constant = std::abs(omega) > 1.0e-10 ? -1.0 / (m_alpha * omega) : -1.0;
102 }
103
104private:
105 double m_alpha; // (including var-alpha)
106};
107
108//==============================================================================
109//! @brief i\vec{\alpha} matrix element: propto Electric dipole operator.
110//! i factored so that ME is real
111class ialpha final : public TensorOperator {
112public:
113 ialpha() : TensorOperator(1, Parity::odd, 1.0, {}, Realness::real, true) {}
114
115 std::string name() const override final { return "i*alpha"; }
116 std::string units() const override final { return "au"; }
117
118 double angularF(const int ka, const int kb) const override final {
119 return Angular::Ck_kk(1, ka, kb);
120 }
121
122 double angularCff(int, int) const override final { return 0; }
123 double angularCgg(int, int) const override final { return 0; }
124 double angularCfg(int ka, int kb) const override final { return ka - kb - 1; }
125 double angularCgf(int ka, int kb) const override final { return ka - kb + 1; }
126};
127
128//==============================================================================
129
130inline std::unique_ptr<DiracOperator::TensorOperator>
131generate_sigma_r(const IO::InputBlock &input, const Wavefunction &wf) {
132 using namespace DiracOperator;
133 input.check({{"no options", ""}});
134 if (input.has_option("help")) {
135 return nullptr;
136 }
137 return std::make_unique<sigma_r>(wf.grid());
138}
139
140inline std::unique_ptr<DiracOperator::TensorOperator>
141generate_E1(const IO::InputBlock &input, const Wavefunction &wf) {
142 using namespace DiracOperator;
143 input.check({{"no options", ""}});
144 if (input.has_option("help")) {
145 return nullptr;
146 }
147 return std::make_unique<E1>(wf.grid());
148}
149
150inline std::unique_ptr<DiracOperator::TensorOperator>
151generate_E1v(const IO::InputBlock &input, const Wavefunction &wf) {
152 using namespace DiracOperator;
153 input.check({{"no options", ""}});
154 if (input.has_option("help")) {
155 return nullptr;
156 }
157 return std::make_unique<E1v>(wf.alpha(), 0.0);
158}
159
160inline std::unique_ptr<DiracOperator::TensorOperator>
161generate_E2(const IO::InputBlock &input, const Wavefunction &wf) {
162 using namespace DiracOperator;
163 input.check({{"no options", ""}});
164 if (input.has_option("help")) {
165 return nullptr;
166 }
167 return std::make_unique<Ek>(wf.grid(), 2);
168}
169
170inline std::unique_ptr<DiracOperator::TensorOperator>
171generate_ialpha(const IO::InputBlock &input, const Wavefunction &) {
172 using namespace DiracOperator;
173 input.check({{"no options", ""}});
174 if (input.has_option("help")) {
175 return nullptr;
176 }
177 return std::make_unique<ialpha>();
178}
179
180//------------------------------------------------------------------------------
181inline std::unique_ptr<DiracOperator::TensorOperator>
182generate_Ek(const IO::InputBlock &input, const Wavefunction &wf) {
183 using namespace DiracOperator;
184 input.check({{"k", "Rank: k=1 for E1, =2 for E2 etc. [1]"}});
185 if (input.has_option("help")) {
186 return nullptr;
187 }
188 const auto k = input.get("k", 1);
189 return std::make_unique<Ek>(wf.grid(), k);
190}
191
192} // namespace DiracOperator
Electric dipole operator: -|e|r = -er.
Definition Ek.hpp:45
Electric dipole operator, v-form: .
Definition Ek.hpp:70
double angularCgg(int, int) const override final
Angular coefficient C_gg for the g_a*g_b term of the radial integral.
Definition Ek.hpp:86
double angularF(const int ka, const int kb) const override final
Angular factor A_ab linking the radial integral to the RME.
Definition Ek.hpp:80
std::string name() const override final
Returns "name" of operator (e.g., 'E1')
Definition Ek.hpp:77
double angularCfg(int ka, int kb) const override final
Angular coefficient C_fg for the f_a*g_b term of the radial integral.
Definition Ek.hpp:87
double angularCgf(int ka, int kb) const override final
Angular coefficient C_gf for the g_a*f_b term of the radial integral.
Definition Ek.hpp:91
std::string units() const override final
Returns units of operator as a string (usually au, may be MHz, etc.)
Definition Ek.hpp:78
double angularCff(int, int) const override final
Angular coefficient C_ff for the f_a*f_b term of the radial integral.
Definition Ek.hpp:85
E^k (electric multipole) operator, length form, with (qr<<1) approximation.
Definition Ek.hpp:18
std::string name() const override
Returns "name" of operator (e.g., 'E1')
Definition Ek.hpp:27
double angularF(const int ka, const int kb) const override final
Angular factor A_ab linking the radial integral to the RME.
Definition Ek.hpp:24
std::string units() const override
Returns units of operator as a string (usually au, may be MHz, etc.)
Definition Ek.hpp:30
Rank-0 (scalar) tensor operator; derives from TensorOperator with k=0.
Definition TensorOperator.hpp:560
General tensor operator (virtual base class); all single-particle (one-body) tenosor operators derive...
Definition TensorOperator.hpp:197
virtual void updateFrequency(const double)
Updates the operator for a new frequency omega.
Definition TensorOperator.hpp:295
Odd-parity rank-0 operator with radial function r (sigma_r)
Definition Ek.hpp:52
std::string name() const override final
Returns "name" of operator (e.g., 'E1')
Definition Ek.hpp:55
std::string units() const override final
Returns units of operator as a string (usually au, may be MHz, etc.)
Definition Ek.hpp:56
Holds grid, including type + Jacobian (dr/du)
Definition Grid.hpp:31
const std::vector< double > & r() const
Grid points, r.
Definition Grid.hpp:75
std::vector< double > rpow(double k) const
Calculates+returns vector of 1/r.
Definition Grid.cpp:120
Holds list of Options, and a list of other InputBlocks. Can be initialised with a list of options,...
Definition InputBlock.hpp:153
bool check(std::initializer_list< std::string > blocks, const std::vector< std::pair< std::string, std::string > > &list, bool print=false) const
Check all the options and blocks in this; if any of them are not present in 'list',...
Definition InputBlock.hpp:606
bool has_option(std::string_view key) const
Check is option is present (even if not set) in current block.
Definition InputBlock.hpp:212
T get(std::string_view key, T default_value) const
If 'key' exists in the options, returns value. Else, returns default_value. Note: If two keys with sa...
Definition InputBlock.hpp:428
Stores Wavefunction (set of valence orbitals, grid, HF etc.)
Definition Wavefunction.hpp:37
const Grid & grid() const
Returns a const reference to the radial grid.
Definition Wavefunction.hpp:82
double alpha() const
Local value of fine-structure constant.
Definition Wavefunction.hpp:88
constexpr bool evenQ(int a)
Returns true if a is even - for integer values.
Definition Wigner369j.hpp:233
double Ck_kk(int k, int ka, int kb)
Reduced relativistic angular ME: <ka||C^k||kb>. Takes kappa values.
Definition Wigner369j.hpp:486
Dirac operators: TensorOperator base class and derived implementations for single-particle (one-body)...
Definition GenerateOperator.cpp:3
Parity
Parity of operator.
Definition TensorOperator.hpp:57