High-precision calculations for one- and two-valence atomic systems
FGRadPot.hpp
1#pragma once
2#include <array>
3#include <cassert>
4#include <cmath>
5#include <functional>
6#include <vector>
7
8//! Flambaum-Ginges Radiative potential
9/*! @details
10
11First introduced in:
12 * V. V. Flambaum and J. S. M. Ginges, Phys. Rev. A 72, 052115 (2005).
13
14With finite-nuclear-size corrections, and updated fitting factors, from;
15 * J. S. M. Ginges and J. C. Berengut, Phys. Rev. A 93, 052509 (2016).
16 * J. S. M. Ginges and J. C. Berengut, J. Phys. B 49, 095001 (2016).
17
18Note:
19 * High- and low- frequency V(r) do NOT include A or B fitting coeficients.
20 * All radii (r and rN) are given in atomic units
21 * Sign convention: H -> H - V_rad
22 * V_rad = V_Uehling + V_SEh + V_SEl + V_WK + i(g.n())H_Magnetic
23*/
24namespace FGRP {
25
26// Fine structure constant:
27constexpr double alpha = 1.0 / 137.035999084;
28// electron reduced compton wavelength (atomic units)
29constexpr double lam_c = alpha;
30
31//==============================================================================
32//! Uehling potential (r, rN in atomic units)
33double V_Uehling(double Z, double r, double rN = 0.0);
34
35//! Magnetic form-factor (r, rN in atomic units)
36double H_Magnetic(double Z, double r, double rN = 0.0);
37
38//! High-freq electric SE (NOT including Al) (r, rN in atomic units)
39double V_SEh(double Z, double r, double rN = 0.0);
40
41//! Low-freq electric SE (NOT including Bl) (r, rN in atomic units)
42double V_SEl(double Z, double r, double rN = 0.0);
43
44//! Effective Wickman-Kroll; not including FNS corrections
45double V_WK(double Z, double r, double);
46
47//==============================================================================
48//! Fitting factors from Ginges Berengut, Phys. Rev. A 93, 052509 (2016).
49namespace Fit {
50// static const auto a01 = std::vector{1.071, 0.0, -1.976, -2.128, 0.169};
51static const auto a01 = std::vector{1.071, 0.0, -1.976, -2.128, 0.169};
52static const auto b01 = std::vector{0.074, 0.35};
53static const auto b2 = std::vector{0.056, 0.050, 0.195};
54
55//! Al(Z) fitting function [PRA 93, 052509 (2016)]
56double A(double Z, int l = 0);
57//! Bl(Z) fitting function [PRA 93, 052509 (2016)]
58double B(double Z, int l = 0);
59
60} // namespace Fit
61
62//==============================================================================
63//! Function that performs the t integral over [1,infinity)
64double t_integral(double (*f)(double, void *), std::vector<double> params,
65 double eps = 1.0e-6);
66
67enum class IntType { Linear, Log };
68
69//! Function that performs the r integral over [a,b] using mixed-quadrature
70template <IntType IT = IntType::Linear>
71double r_integral(std::function<double(double)> f, double a, double b,
72 long unsigned n_pts = 1000);
73
74//==============================================================================
75// Helper functions:
76
77namespace Uehling {
78double G_Ueh(double xn, double x);
79// Form of function required by GSL integrations; p is {r, Rn}
80double J_Ueh_gsl(double t, void *p);
81} // namespace Uehling
82
83namespace Magnetic {
84double G_mag(double xn, double x);
85// Form of function required by GSL integrations; p is {r, Rn}
86double J_mag_gsl(double t, void *p);
87} // namespace Magnetic
88
89namespace SE {
90double xi(double x);
91double F_SEl(double Z, double r, double rN);
92double I1(double Z, double t);
93double I2(double Z, double r, double rn, double t);
94// Form of function required by GSL integrations; p is {r, Rn, Z}
95double J_SE_gsl(double t, void *p);
96} // namespace SE
97
98//==============================================================================
99// Implementation:
100template <IntType IT>
101double r_integral(std::function<double(double)> f, double a, double b,
102 long unsigned n_pts) {
103
104 static constexpr std::array w{475.0 / 1440, 1902.0 / 1440, 1104.0 / 1440,
105 1586.0 / 1440, 1413.0 / 1440};
106
107 const auto dt = (IT == IntType::Linear) ? (b - a) / double(n_pts - 1) :
108 std::log(b / a) / double(n_pts - 1);
109
110 const auto x = [=](auto i) {
111 if constexpr (IT == IntType::Linear) {
112 return a + double(i) * dt;
113 } else {
114 assert(a != 0.0);
115 return a * std::exp(double(i) * dt);
116 }
117 };
118 const auto dxdt = [=](auto i) {
119 if constexpr (IT == IntType::Linear) {
120 (void)i; // suppress unused variable warning on older gcc compilers
121 return 1.0;
122 } else {
123 return x(i); // dxdt = x(t) for log
124 }
125 };
126
127 double Rint = 0.0;
128 for (long unsigned i = 0; i < w.size(); i++) {
129 Rint += w[i] * (f(x(i)) + f(x(n_pts - 1 - i))) * dxdt(i);
130 }
131
132 for (auto i = w.size(); i < n_pts - w.size(); i++) {
133 Rint += f(x(i)) * dxdt(i);
134 }
135
136 return Rint * dt;
137}
138
139//==============================================================================
140//==============================================================================
141//! Magnetic-loop vacuum polarisation, includes finite-nuclear size
142double Q_MLVP(double r, double rN = 0.0);
143namespace Helper {
144// Magnetic-loop vacuum polarisation, Q = Int(Qt, {t,1,infty}).
145double Qt_MLVP(double t, void *p);
146} // namespace Helper
147
148// struct to pass the parameters to the GSL function
149struct MLVP_params {
150 // simple struct that only stores current point on the radial grid and the
151 // nuclear radius
152 double r, rN;
153};
154
155} // namespace FGRP
double B(double Z, int l=0)
Bl(Z) fitting function [PRA 93, 052509 (2016)].
Definition FGRadPot.cpp:132
double A(double Z, int l=0)
Al(Z) fitting function [PRA 93, 052509 (2016)].
Definition FGRadPot.cpp:121
Flambaum-Ginges Radiative potential.
Definition FGRadPot.cpp:10
double V_WK(double Z, double r, double)
Effective Wickman-Kroll; not including FNS corrections.
Definition FGRadPot.cpp:65
double V_Uehling(double Z, double r, double rN)
Uehling potential (r, rN in atomic units)
Definition FGRadPot.cpp:36
double r_integral(std::function< double(double)> f, double a, double b, long unsigned n_pts=1000)
Function that performs the r integral over [a,b] using mixed-quadrature.
Definition FGRadPot.hpp:101
double V_SEl(double Z, double r, double rN)
Low-freq electric SE (NOT including Bl) (r, rN in atomic units)
Definition FGRadPot.cpp:49
double V_SEh(double Z, double r, double rN)
High-freq electric SE (NOT including Al) (r, rN in atomic units)
Definition FGRadPot.cpp:57
double t_integral(double(*f)(double, void *), std::vector< double > params, double eps)
Function that performs the t integral over [1,infinity)
Definition FGRadPot.cpp:78
double H_Magnetic(double Z, double r, double rN)
Magnetic form-factor (r, rN in atomic units)
Definition FGRadPot.cpp:43
double Q_MLVP(double r, double rN)
Magnetic-loop vacuum polarisation, includes finite-nuclear size.
Definition FGRadPot.cpp:280
constexpr double alpha
Fine-structure constant: alpha = 1/137.035 999 177(21) [CODATA 2022].
Definition PhysConst_constants.hpp:24