ampsci
High-precision calculations for one- and two-valence atomic systems
RadPot.hpp
1#pragma once
2#include "FGRadPot.hpp"
3#include "IO/FRW_fileReadWrite.hpp"
4#include "IO/InputBlock.hpp"
5#include "Maths/Interpolator.hpp"
6#include "Physics/PhysConst_constants.hpp"
7#include "qip/Vector.hpp"
8#include <algorithm>
9#include <vector>
10
11namespace QED {
12
13//==============================================================================
14//! Class holds Flambaum-Ginges QED Radiative Potential
15class RadPot {
16
17public:
18 //============================================================================
19 //! Scale factors for Uehling, high, low, magnetic, Wickman-Kroll
20 struct Scale {
21 double u, h, l, m, wk;
22 };
23
24 //============================================================================
25 //! Extra fitting for s,p,d etc. states.
26 /*! @details Will assume factor for higher l's same as last one.
27 e.g., {1,1} => 1,1,1,1,...
28 e.g., {1,0} => 1,0,0,0,...
29 */
30 struct Xl {
31
32 private:
33 std::vector<double> m_x;
34
35 public:
36 Xl();
37 Xl(std::vector<double> x);
38
39 double operator()(int l) const;
40 };
41
42 //============================================================================
43private:
44 double m_Z, m_rN, m_rcut;
45 Scale m_f;
46 Xl m_xl;
47 bool print;
48
49 std::vector<double> mVu{}; // Uehling
50 std::vector<double> mVh{}; // High-freq electric SE (without A)
51 std::vector<double> mVl{}; // Low-freq electric SE (without B)
52 std::vector<double> mHm{}; // Magnetic FF
53 std::vector<double> mVwk{}; // Approx Wickman-Kroll
54
55public:
56 //! Empty constructor
57 RadPot();
58
59 //! Constructor: will build potential
60 /*! @details
61 rcut is maxum radius (atomic units) to calc potential for.
62 */
63 RadPot(const std::vector<double> &r, double Z, double rN = 0.0,
64 double rcut = 0.0, Scale f = {1.0, 1.0, 1.0, 1.0, 0.0}, Xl xl = {},
65 bool tprint = true, bool do_readwrite = true,
66 const std::string &label = "");
67
68 bool read_write(const std::vector<double> &r, IO::FRW::RoW rw,
69 const std::string &label_x = "");
70
71 void form_potentials(const std::vector<double> &r);
72
73 //! Returns entire electric part of potential
74 std::vector<double> Vel(int l = 0) const;
75 //! Returns H_mag
76 std::vector<double> Hmag(int) const;
77 std::vector<double> Vu(int l = 0) const;
78 std::vector<double> Vl(int l = 0) const;
79 std::vector<double> Vh(int l = 0) const;
80
81 template <typename Func>
82 std::vector<double> fill(Func f, const std::vector<double> &r);
83
84 template <typename Func>
85 std::vector<double> fill(Func f, const std::vector<double> &r,
86 std::size_t stride);
87};
88
89//============================================================================
90//==============================================================================
91template <typename Func>
92std::vector<double> RadPot::fill(Func f, const std::vector<double> &r) {
93 std::vector<double> v;
94 v.resize(r.size());
95
96 const auto rcut = m_rcut == 0.0 ? r.back() : m_rcut;
97
98 // index for r cut-off
99 const auto icut = std::size_t(std::distance(
100 begin(r),
101 std::find_if(begin(r), end(r), [rcut](auto ri) { return ri > rcut; })));
102
103#pragma omp parallel for
104 for (auto i = 0ul; i < icut; ++i) {
105 // nb: Use H -> H+V (instead of H-> H-V), so change sign!
106 v[i] = -f(m_Z, r[i], m_rN);
107 }
108 return v;
109}
110
111//==============================================================================
112template <typename Func>
113std::vector<double> RadPot::fill(Func f, const std::vector<double> &r,
114 std::size_t stride) {
115
116 const auto rcut = m_rcut == 0.0 ? r.back() : m_rcut;
117
118 // index for r cut-off
119 const auto icut =
120 std::size_t(std::distance(
121 begin(r),
122 std::find_if(begin(r), end(r), [rcut](auto ri) { return ri > rcut; }))) /
123 stride;
124
125 std::vector<double> tv, tr;
126 tv.resize(icut);
127 tr.resize(icut);
128
129#pragma omp parallel for
130 for (auto i = 0ul; i < icut; ++i) {
131 // nb: Use H -> H+V (instead of H-> H-V), so change sign!
132 tv[i] = -f(m_Z, r[i * stride], m_rN);
133 tr[i] = r[i * stride];
134 }
135 return stride == 1 ? tv : Interpolator::interpolate(tr, tv, r);
136}
137
138//==============================================================================
139//! Function constructs a Radiative potential with given input parameters; rN_au is nuclear radius (not rms radius), in atomic units
140RadPot ConstructRadPot(const std::vector<double> &r, double Z_eff, double rN_au,
141 const IO::InputBlock &input = {}, bool print = true,
142 bool do_readwrite = true);
143
144} // namespace QED
Holds list of Options, and a list of other InputBlocks. Can be initialised with a list of options,...
Definition InputBlock.hpp:142
Class holds Flambaum-Ginges QED Radiative Potential.
Definition RadPot.hpp:15
std::vector< double > Vel(int l=0) const
Returns entire electric part of potential.
Definition RadPot.cpp:155
RadPot()
Empty constructor.
Definition RadPot.cpp:26
std::vector< double > Hmag(int) const
Returns H_mag.
Definition RadPot.cpp:164
Scale factors for Uehling, high, low, magnetic, Wickman-Kroll.
Definition RadPot.hpp:20
double f(RaB r, PrincipalQN n, DiracQN k, Zeff z, AlphaFS a)
Upper radial component.
Definition DiracHydrogen.cpp:71
std::vector< double > interpolate(const std::vector< double > &x_in, const std::vector< double > &y_in, const std::vector< double > &x_out, Method method=Method::cspline)
Performs interpolation using GSL (GNU Scientific Library)
Definition Interpolator.hpp:162
void QED(const IO::InputBlock &input, const Wavefunction &wf)
Calculates QED corrections to energies and matrix elements.
Definition qed.cpp:20
Extra fitting for s,p,d etc. states.
Definition RadPot.hpp:30