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 (static) approximation
10/*! @details
11 \f[
12 h_k = -|e|r^k = -e r^k
13 \f]
14 \f[
15 \redmatel{a}{h_k}{b} = R C^k_{ab}
16 \f]
17 \f[
18 R = -e \int r^k (f_a f_b + g_a g_b) \, dr
19 \f]
20
21 - This has \f$ qr \\ 1\f$ (static) approximation;
22 - That is, no bessel functions
23 - See @ref EM_multipole operator for full operators
24*/
25class Ek : public TensorOperator {
26public:
27 Ek(const Grid &gr, const int k)
28 : TensorOperator(k, Angular::evenQ(k) ? Parity::even : Parity::odd, -1.0,
29 gr.rpow(k)),
30 m_k(k) {}
31
32 std::unique_ptr<TensorOperator> clone() const override {
33 return std::make_unique<Ek>(*this);
34 }
35
36 std::string name() const override {
37 return std::string("E") + std::to_string(m_k);
38 }
39 std::string units() const override {
40 return m_k == 1 ? "|e|aB" : std::string("|e|aB^") + std::to_string(m_k);
41 }
42
43 double angularF(const int ka, const int kb) const override final {
44 return Angular::Ck_kk(m_k, ka, kb);
45 }
46
47 static std::unique_ptr<TensorOperator> generate(const IO::InputBlock &input,
48 const Wavefunction &wf) {
49 input.check({{"k", "Rank: k=1 for E1, =2 for E2 etc. [1]"}});
50 if (input.has_option("help"))
51 return nullptr;
52 const auto k = input.get("k", 1);
53 return std::make_unique<Ek>(wf.grid(), k);
54 }
55
56private:
57 int m_k;
58};
59
60//==============================================================================
61//! Electric dipole operator: -|e|r = -er
62/*! @details
63\f[<a||d||b> = R (-1)^{ja+1/2} \sqrt{[ja][jb]} \, tjs(ja,jb,1, -1/2,1/2,0)\f]
64\f[<a||d||b> = R <k_a||C^k||k_b>\f]
65\f[R = -e \int r(f_a f_b + g_a g_b) \, dr\f]
66*/
67class E1 final : public Ek {
68public:
69 E1(const Grid &gr) : Ek(gr, 1) {}
70
71 std::unique_ptr<TensorOperator> clone() const override final {
72 return std::make_unique<E1>(*this);
73 }
74
75 static std::unique_ptr<TensorOperator> generate(const IO::InputBlock &input,
76 const Wavefunction &wf) {
77 input.check({{"no options", ""}});
78 if (input.has_option("help"))
79 return nullptr;
80 return std::make_unique<E1>(wf.grid());
81 }
82};
83
84//==============================================================================
85//! Odd-parity rank-0 operator with radial function r (sigma_r)
86class sigma_r final : public ScalarOperator {
87public:
88 sigma_r(const Grid &rgrid) : ScalarOperator(Parity::odd, -1.0, rgrid.r()) {}
89 std::string name() const override final { return "s.r"; }
90 std::string units() const override final { return "aB"; }
91
92 std::unique_ptr<TensorOperator> clone() const override final {
93 return std::make_unique<sigma_r>(*this);
94 }
95
96 static std::unique_ptr<TensorOperator> generate(const IO::InputBlock &input,
97 const Wavefunction &wf) {
98 input.check({{"no options", ""}});
99 if (input.has_option("help"))
100 return nullptr;
101 return std::make_unique<sigma_r>(wf.grid());
102 }
103};
104
105//==============================================================================
106//! @brief Electric dipole operator, v-form:
107//! \f$ \frac{ie}{\omega \alpha} \vec{\alpha}\f$
108/*! @details
109\f[ <a||d_v||b> = R \f]
110\f[ R = -\frac{2e}{\omega \alpha}
111\int( f_ag_b <ka||s||-kb> - g_af_b <-ka||s||kb>)\,dr \f]
112*/
113class E1v final : public TensorOperator
114// d_v = (ie/w alpha) v{alpha} [v{a} = g0v{g}]\f$
115// <a||dv||b> = -2e/(w alpha) Int[ fagb <ka||s||-kb> - gafb <-ka||s||kb>]
116{
117public:
118 E1v(const double alpha, const double omega = 0.0)
119 : TensorOperator(1, Parity::odd, -0.0, {}, Realness::real, true),
120 m_alpha(alpha) {
121 updateFrequency(omega);
122 }
123 std::string name() const override final { return "E1v"; }
124 std::string units() const override final { return "|e|aB"; }
125
126 double angularF(const int ka, const int kb) const override final {
127 // return 1;
128 return Angular::Ck_kk(1, ka, kb);
129 }
130
131 double angularCff(int, int) const override final { return 0; }
132 double angularCgg(int, int) const override final { return 0; }
133 double angularCfg(int ka, int kb) const override final {
134 // return Angular::S_kk(ka, -kb);
135 return ka - kb - 1;
136 }
137 double angularCgf(int ka, int kb) const override final {
138 // return -Angular::S_kk(-ka, kb);
139 return ka - kb + 1;
140 }
141
142 //! @note At omega=0 (static limit) falls back to m_constant = -1.0;
143 //! the velocity-form operator diverges as 1/omega and is not physically
144 //! meaningful at zero frequency.
145 void updateFrequency(const double omega) override final {
146 m_omega = omega;
147 // m_constant = std::abs(omega) > 1.0e-10 ? -2.0 / (m_alpha * omega) : 1.0;
148 m_constant = std::abs(omega) > 1.0e-10 ? -1.0 / (m_alpha * omega) : -1.0;
149 }
150
151 std::unique_ptr<TensorOperator> clone() const override final {
152 return std::make_unique<E1v>(*this);
153 }
154
155 static std::unique_ptr<TensorOperator> generate(const IO::InputBlock &input,
156 const Wavefunction &wf) {
157 input.check({{"no options", ""}});
158 if (input.has_option("help"))
159 return nullptr;
160 return std::make_unique<E1v>(wf.alpha(), 0.0);
161 }
162
163private:
164 double m_alpha; // (including var-alpha)
165};
166
167//==============================================================================
168//! @brief i\vec{\alpha} matrix element: propto Electric dipole operator.
169//! i factored so that ME is real
170class ialpha final : public TensorOperator {
171public:
172 ialpha() : TensorOperator(1, Parity::odd, 1.0, {}, Realness::real, false) {}
173
174 std::string name() const override final { return "i*alpha"; }
175 std::string units() const override final { return "au"; }
176
177 double angularF(const int ka, const int kb) const override final {
178 return Angular::Ck_kk(1, ka, kb);
179 }
180
181 double angularCff(int, int) const override final { return 0; }
182 double angularCgg(int, int) const override final { return 0; }
183 double angularCfg(int ka, int kb) const override final { return ka - kb - 1; }
184 double angularCgf(int ka, int kb) const override final { return ka - kb + 1; }
185
186 std::unique_ptr<TensorOperator> clone() const override final {
187 return std::make_unique<ialpha>(*this);
188 }
189
190 static std::unique_ptr<TensorOperator> generate(const IO::InputBlock &input,
191 const Wavefunction &) {
192 input.check({{"no options", ""}});
193 if (input.has_option("help"))
194 return nullptr;
195 return std::make_unique<ialpha>();
196 }
197};
198
199//==============================================================================
200//! @brief Electric quadrupole operator: -|e|r^2
201class E2 final : public Ek {
202public:
203 E2(const Grid &gr) : Ek(gr, 2) {}
204
205 std::unique_ptr<TensorOperator> clone() const override final {
206 return std::make_unique<E2>(*this);
207 }
208
209 static std::unique_ptr<TensorOperator> generate(const IO::InputBlock &input,
210 const Wavefunction &wf) {
211 input.check({{"no options", ""}});
212 if (input.has_option("help"))
213 return nullptr;
214 return std::make_unique<E2>(wf.grid());
215 }
216};
217
218} // namespace DiracOperator
Electric dipole operator: -|e|r = -er.
Definition Ek.hpp:67
std::unique_ptr< TensorOperator > clone() const override final
Creates a polymorphic copy of the operator at its current state, or nullptr if cloning is not support...
Definition Ek.hpp:71
Electric dipole operator, v-form: .
Definition Ek.hpp:116
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:132
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:126
std::string name() const override final
Returns "name" of operator (e.g., 'E1')
Definition Ek.hpp:123
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:133
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:137
std::unique_ptr< TensorOperator > clone() const override final
Creates a polymorphic copy of the operator at its current state, or nullptr if cloning is not support...
Definition Ek.hpp:151
std::string units() const override final
Returns units of operator as a string (usually au, may be MHz, etc.)
Definition Ek.hpp:124
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:131
E^k (electric multipole) operator, length form, with qr<<1 (static) approximation.
Definition Ek.hpp:25
std::string name() const override
Returns "name" of operator (e.g., 'E1')
Definition Ek.hpp:36
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:43
std::string units() const override
Returns units of operator as a string (usually au, may be MHz, etc.)
Definition Ek.hpp:39
std::unique_ptr< TensorOperator > clone() const override
Creates a polymorphic copy of the operator at its current state, or nullptr if cloning is not support...
Definition Ek.hpp:32
Rank-0 (scalar) tensor operator; derives from TensorOperator with k=0.
Definition TensorOperator.hpp:587
General tensor operator (virtual base class); all single-particle (one-body) tenosor operators derive...
Definition TensorOperator.hpp:198
virtual void updateFrequency(const double)
Updates the operator for a new frequency omega.
Definition TensorOperator.hpp:305
Odd-parity rank-0 operator with radial function r (sigma_r)
Definition Ek.hpp:86
std::string name() const override final
Returns "name" of operator (e.g., 'E1')
Definition Ek.hpp:89
std::unique_ptr< TensorOperator > clone() const override final
Creates a polymorphic copy of the operator at its current state, or nullptr if cloning is not support...
Definition Ek.hpp:92
std::string units() const override final
Returns units of operator as a string (usually au, may be MHz, etc.)
Definition Ek.hpp:90
Non-uniform radial grid with Jacobian, suitable for atomic structure calculations.
Definition Grid.hpp:85
const std::vector< double > & r() const
Full grid vector r.
Definition Grid.hpp:131
std::vector< double > rpow(double k) const
Returns a vector of r^k for each grid point.
Definition Grid.cpp:120
Holds a named list of key=value options and nested InputBlocks.
Definition InputBlock.hpp:154
bool check(std::initializer_list< std::string > blocks, const std::vector< std::pair< std::string, std::string > > &list, bool print=false) const
Validates options and sub-blocks against an allowed list.
Definition InputBlock.hpp:649
bool has_option(std::string_view key) const
Returns true if key is present in this block's option list, even if unset.
Definition InputBlock.hpp:247
T get(std::string_view key, T default_value) const
Returns the value of key, or default_value if not found.
Definition InputBlock.hpp:471
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:6
std::unique_ptr< DiracOperator::TensorOperator > generate(std::string_view operator_name, const IO::InputBlock &input, const Wavefunction &wf)
Constructs and returns a TensorOperator by name.
Definition GenerateOperator.cpp:10
Parity
Parity of operator.
Definition TensorOperator.hpp:57