ampsci
c++ program for high-precision atomic structure calculations of single-valence systems
Ek.hpp
1 #pragma once
2 #include "DiracOperator/TensorOperator.hpp"
3 #include "IO/InputBlock.hpp"
4 #include "Wavefunction/Wavefunction.hpp"
5 
6 namespace DiracOperator {
7 
8 //==============================================================================
10 
15 class Ek : public TensorOperator {
16 public:
17  Ek(const Grid &gr, const int k)
18  : TensorOperator(k, Angular::evenQ(k) ? Parity::even : Parity::odd, -1.0,
19  gr.rpow(k), 0),
20  m_k(k) {}
21  double angularF(const int ka, const int kb) const override final {
22  return Angular::Ck_kk(m_k, ka, kb);
23  }
24  std::string name() const override {
25  return std::string("E") + std::to_string(m_k);
26  }
27  std::string units() const override {
28  return m_k == 1 ? "|e|aB" : std::string("|e|aB^") + std::to_string(m_k);
29  }
30 
31 private:
32  int m_k;
33 };
34 
35 //==============================================================================
37 
42 class E1 final : public Ek {
43 public:
44  E1(const Grid &gr) : Ek(gr, 1) {}
45 };
46 
47 //==============================================================================
48 class sigma_r final : public ScalarOperator {
49 public:
50  sigma_r(const Grid &rgrid) : ScalarOperator(Parity::odd, -1.0, rgrid.r()) {}
51  std::string name() const override final { return "s.r"; }
52  std::string units() const override final { return "aB"; }
53 };
54 
55 //==============================================================================
58 
63 class E1v final : public TensorOperator
64 // d_v = (ie/w alpha) v{alpha} [v{a} = g0v{g}]\f$
65 // <a||dv||b> = -2e/(w alpha) Int[ fagb <ka||s||-kb> - gafb <-ka||s||kb>]
66 {
67 public:
68  E1v(const double alpha, const double omega = 0.0)
69  : TensorOperator(1, Parity::odd, -0.0, {}, 0, Realness::real, true),
70  m_alpha(alpha) {
71  updateFrequency(omega);
72  }
73  std::string name() const override final { return "E1v"; }
74  std::string units() const override final { return "|e|aB"; }
75 
76  double angularF(const int, const int) const override final { return 1.0; }
77 
78  double angularCff(int, int) const override final { return 0; }
79  double angularCgg(int, int) const override final { return 0; }
80  double angularCfg(int ka, int kb) const override final {
81  return Angular::S_kk(ka, -kb);
82  }
83  double angularCgf(int ka, int kb) const override final {
84  return -Angular::S_kk(-ka, kb);
85  }
86 
87  void updateFrequency(const double omega) override final {
88  m_constant = std::abs(omega) > 1.0e-10 ? -2.0 / (m_alpha * omega) : 1.0;
89  }
90 
91 private:
92  double m_alpha; // (including var-alpha)
93 };
94 
95 //==============================================================================
96 
97 inline std::unique_ptr<DiracOperator::TensorOperator>
98 generate_sigma_r(const IO::InputBlock &input, const Wavefunction &wf) {
99  using namespace DiracOperator;
100  input.check({{"no options", ""}});
101  if (input.has_option("help")) {
102  return nullptr;
103  }
104  return std::make_unique<sigma_r>(wf.grid());
105 }
106 
107 inline std::unique_ptr<DiracOperator::TensorOperator>
108 generate_E1(const IO::InputBlock &input, const Wavefunction &wf) {
109  using namespace DiracOperator;
110  input.check({{"no options", ""}});
111  if (input.has_option("help")) {
112  return nullptr;
113  }
114  return std::make_unique<E1>(wf.grid());
115 }
116 
117 inline std::unique_ptr<DiracOperator::TensorOperator>
118 generate_E1v(const IO::InputBlock &input, const Wavefunction &wf) {
119  using namespace DiracOperator;
120  input.check({{"no options", ""}});
121  if (input.has_option("help")) {
122  return nullptr;
123  }
124  return std::make_unique<E1v>(wf.alpha(), 0.0);
125 }
126 
127 inline std::unique_ptr<DiracOperator::TensorOperator>
128 generate_E2(const IO::InputBlock &input, const Wavefunction &wf) {
129  using namespace DiracOperator;
130  input.check({{"no options", ""}});
131  if (input.has_option("help")) {
132  return nullptr;
133  }
134  return std::make_unique<Ek>(wf.grid(), 2);
135 }
136 
137 //------------------------------------------------------------------------------
138 inline std::unique_ptr<DiracOperator::TensorOperator>
139 generate_Ek(const IO::InputBlock &input, const Wavefunction &wf) {
140  using namespace DiracOperator;
141  input.check({{"k", "Rank: k=1 for E1, =2 for E2 etc. [1]"}});
142  if (input.has_option("help")) {
143  return nullptr;
144  }
145  const auto k = input.get("k", 1);
146  return std::make_unique<Ek>(wf.grid(), k);
147 }
148 
149 } // namespace DiracOperator
Electric dipole operator: -|e|r = -er.
Definition: Ek.hpp:42
Electric dipole operator, v-form: .
Definition: Ek.hpp:66
void updateFrequency(const double omega) override final
Update frequency for frequency-dependant operators.
Definition: Ek.hpp:87
double angularF(const int, const int) const override final
angularF: links radiation integral to RME. RME = <a||h||b> = angularF(a,b) * radial_int(a,...
Definition: Ek.hpp:76
std::string name() const override final
Returns "name" of operator (e.g., 'E1')
Definition: Ek.hpp:73
std::string units() const override final
Returns units of operator (usually au, may be MHz, etc.)
Definition: Ek.hpp:74
E^k (electric multipole) operator.
Definition: Ek.hpp:15
std::string name() const override
Returns "name" of operator (e.g., 'E1')
Definition: Ek.hpp:24
double angularF(const int ka, const int kb) const override final
angularF: links radiation integral to RME. RME = <a||h||b> = angularF(a,b) * radial_int(a,...
Definition: Ek.hpp:21
std::string units() const override
Returns units of operator (usually au, may be MHz, etc.)
Definition: Ek.hpp:27
Speacial case for scalar operator.
Definition: TensorOperator.hpp:233
General operator (virtual base class); operators derive from this.
Definition: TensorOperator.hpp:110
Holds grid, including type + Jacobian (dr/du)
Definition: Grid.hpp:31
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:142
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:594
bool has_option(std::string_view key) const
Check is option is present (even if not set) in current block.
Definition: InputBlock.hpp:201
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:417
Stores Wavefunction (set of valence orbitals, grid, HF etc.)
Definition: Wavefunction.hpp:36
const Grid & grid() const
Returns a const reference to the radial grid.
Definition: Wavefunction.hpp:81
double alpha() const
Local value of fine-structure constant.
Definition: Wavefunction.hpp:87
double S_kk(int ka, int kb)
Reduced spin angular ME: (for spin 1/2): <ka||S||kb>
Definition: Wigner369j.hpp:340
constexpr bool evenQ(int a)
Returns true if a is even - for integer values.
Definition: Wigner369j.hpp:115
double Ck_kk(int k, int ka, int kb)
Reduced (relativistic) angular ME: <ka||C^k||kb> [takes k and kappa].
Definition: Wigner369j.hpp:267
Dirac Operators: General + derived.
Definition: GenerateOperator.cpp:12