ampsci
c++ program for high-precision atomic structure calculations of single-valence systems
Loading...
Searching...
No Matches
FGRadPot.hpp
1#pragma once
2#include <array>
3#include <cassert>
4#include <cmath>
5#include <functional>
6#include <vector>
7
9
25namespace FGRP {
26
27// Fine structure constant:
28constexpr double alpha = 1.0 / 137.035999084;
29// electron reduced compton wavelength (atomic units)
30constexpr double lam_c = alpha;
31
32//==============================================================================
34double V_Uehling(double Z, double r, double rN = 0.0);
35
37double H_Magnetic(double Z, double r, double rN = 0.0);
38
40double V_SEh(double Z, double r, double rN = 0.0);
41
43double V_SEl(double Z, double r, double rN = 0.0);
44
46double V_WK(double Z, double r, double);
47
48//==============================================================================
50namespace Fit {
51// static const auto a01 = std::vector{1.071, 0.0, -1.976, -2.128, 0.169};
52static const auto a01 = std::vector{1.071, 0.0, -1.976, -2.128, 0.169};
53static const auto b01 = std::vector{0.074, 0.35};
54static const auto b2 = std::vector{0.056, 0.050, 0.195};
55
57double A(double Z, int l = 0);
59double B(double Z, int l = 0);
60
61} // namespace Fit
62
63//==============================================================================
65double t_integral(double (*f)(double, void *), std::vector<double> params,
66 double eps = 1.0e-6);
67
68enum class IntType { Linear, Log };
69
71template <IntType IT = IntType::Linear>
72double r_integral(std::function<double(double)> f, double a, double b,
73 long unsigned n_pts = 1000);
74
75//==============================================================================
76// Helper functions:
77
78namespace Uehling {
79double G_Ueh(double xn, double x);
80// Form of function required by GSL integrations; p is {r, Rn}
81double J_Ueh_gsl(double t, void *p);
82} // namespace Uehling
83
84namespace Magnetic {
85double G_mag(double xn, double x);
86// Form of function required by GSL integrations; p is {r, Rn}
87double J_mag_gsl(double t, void *p);
88} // namespace Magnetic
89
90namespace SE {
91double xi(double x);
92double F_SEl(double Z, double r, double rN);
93double I1(double Z, double t);
94double I2(double Z, double r, double rn, double t);
95// Form of function required by GSL integrations; p is {r, Rn, Z}
96double J_SE_gsl(double t, void *p);
97} // namespace SE
98
99//==============================================================================
100// Implementation:
101template <IntType IT>
102double r_integral(std::function<double(double)> f, double a, double b,
103 long unsigned n_pts) {
104
105 static constexpr std::array w{475.0 / 1440, 1902.0 / 1440, 1104.0 / 1440,
106 1586.0 / 1440, 1413.0 / 1440};
107
108 const auto dt = (IT == IntType::Linear) ? (b - a) / double(n_pts - 1) :
109 std::log(b / a) / double(n_pts - 1);
110
111 const auto x = [=](auto i) {
112 if constexpr (IT == IntType::Linear) {
113 return a + double(i) * dt;
114 } else {
115 assert(a != 0.0);
116 return a * std::exp(double(i) * dt);
117 }
118 };
119 const auto dxdt = [=](auto i) {
120 if constexpr (IT == IntType::Linear) {
121 (void)i; // suppress unused variable warning on older gcc compilers
122 return 1.0;
123 } else {
124 return x(i); // dxdt = x(t) for log
125 }
126 };
127
128 double Rint = 0.0;
129 for (long unsigned i = 0; i < w.size(); i++) {
130 Rint += w[i] * (f(x(i)) + f(x(n_pts - 1 - i))) * dxdt(i);
131 }
132
133 for (auto i = w.size(); i < n_pts - w.size(); i++) {
134 Rint += f(x(i)) * dxdt(i);
135 }
136
137 return Rint * dt;
138}
139
140//==============================================================================
141//==============================================================================
143double Q_MLVP(double r, double rN = 0.0);
144namespace Helper {
145// Magnetic-loop vacuum polarisation, Q = Int(Qt, {t,1,infty}).
146double Qt_MLVP(double t, void *p);
147} // namespace Helper
148
149// struct to pass the parameters to the GSL function
150struct MLVP_params {
151 // simple struct that only stores current point on the radial grid and the
152 // nuclear radius
153 double r, rN;
154};
155
156} // 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:102
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