ampsci
c++ program for high-precision atomic structure calculations of single-valence systems
Loading...
Searching...
No Matches
AsymptoticSpinor.hpp
1#pragma once
2#include "Physics/PhysConst_constants.hpp"
3#include "qip/Maths.hpp"
4#include <array>
5#include <cassert>
6#include <cmath>
7
8namespace DiracODE {
9
11template <std::size_t Nx = 15>
13private:
14 int kappa;
15 double Zeff, en, alpha, eps_target;
16 double kappa2, alpha2, c, c2, lambda, sigma, Ren;
17 double m_mass;
18 std::array<double, Nx> bx; // bx must be first
19 std::array<double, Nx> ax; // ax depends on bx
20
21public:
22 AsymptoticSpinor(int in_kappa, double in_Zeff, double in_en,
23 double in_alpha = PhysConst::alpha,
24 double in_eps_target = 1.0e-14, double m = 1.0)
25 : kappa(in_kappa),
26 Zeff(in_Zeff),
27 en(in_en),
28 alpha(in_alpha),
29 eps_target(in_eps_target),
30 kappa2(double(kappa * kappa)),
31 alpha2(alpha * alpha),
32 c(1.0 / alpha),
33 c2(c * c),
34 lambda(std::sqrt(-en * (2.0 + en * alpha2 / m))),
35 sigma((m + en * alpha2) * (Zeff / lambda)),
36 Ren(en + m * c2),
37 m_mass(m),
38 bx(make_bx()),
39 ax(make_ax()) {
40 // assert(en < 0.0 && "Must have en<0 in AsymptoticSpinor");
41 }
42
44
58 std::pair<double, double> fg(double r) const {
59 // See Johnson (2007), Eqs. (2.170) -- (2.171)
60 // Notation difference:
61 // P(r) = f(r)
62 // Q(r) = -g(r)
63 // There appears to by typo in Eq. (2.171)
64
65 const double A_large = std::sqrt(1.0 + 0.5 * en * alpha2 / m_mass);
66 const double A_small = std::sqrt(-0.5 * en) * alpha;
67
68 const double rfac = 2.0 * std::pow(r, sigma) * std::exp(-lambda * r);
69 double fs = 1.0;
70 double gs = 0.0;
71 double rk = 1.0;
72 // Continue the expansion until reach eps, or Nx
73 for (std::size_t k = 0; k < Nx; k++) {
74 rk *= r;
75 fs += (ax[k] / rk);
76 gs += (bx[k] / rk);
77 const auto eps =
78 std::max(std::abs(ax[k] / fs), std::abs(bx[k] / gs)) / rk;
79 if (eps < eps_target) {
80 break;
81 }
82 }
83 return {rfac * (A_large * fs + A_small * gs),
84 rfac * (A_large * gs - A_small * fs)};
85 }
86
87private:
88 std::array<double, Nx> make_bx() const {
89 // See Johnson (2007), Eqs. (2.172) -- (2.173)
90 std::array<double, Nx> tbx;
91 const auto Zalpha2 = Zeff * Zeff * alpha2;
92 tbx[0] = (kappa + (Zeff / lambda)) * (0.5 * alpha);
93 for (std::size_t i = 1; i < Nx; i++) {
94 tbx[i] = (kappa2 - qip::pow<2>((double(i) - sigma)) - Zalpha2) *
95 tbx[i - 1] / (double(2 * i) * lambda);
96 }
97 return tbx;
98 }
99
100 std::array<double, Nx> make_ax() const {
101 // See Johnson (2007), Eq. (2.174)
102 // bx must already be initialised
103 std::array<double, Nx> tax;
104 const auto RenAlpha2 = 1.0 + en * alpha2;
105 for (std::size_t i = 0; i < Nx; i++) {
106 tax[i] = (kappa + (double(i + 1) - sigma) * RenAlpha2 -
107 Zeff * lambda * alpha2) *
108 (bx[i] * c) / (double(i + 1) * lambda);
109 }
110 return tax;
111 }
112};
113
114} // namespace DiracODE
Performs asymptotic expansion for f and g at large r, up to order Nx in (1/r)
Definition AsymptoticSpinor.hpp:12
std::pair< double, double > fg(double r) const
Performs asymptotic expansion for f and g at large r, up to order Nx in (1/r)
Definition AsymptoticSpinor.hpp:58
Functions and classes used to solve the Dirac equation.
Definition AsymptoticSpinor.hpp:8
constexpr double alpha
Fine-structure constant: alpha = 1/137.035 999 177(21) [CODATA 2022].
Definition PhysConst_constants.hpp:24
constexpr double c
speed of light in a.u. (=1/alpha)
Definition PhysConst_constants.hpp:63