![]() |
|
High-precision calculations for one- and two-valence atomic systems
|
Functions and classes used to solve the Dirac equation.
Classes | |
| class | AsymptoticSpinor |
| Performs asymptotic expansion for f and g at large r, up to order Nx in (1/r). More... | |
| class | AsymptoticSpinorContinuum |
| Large-r Dirac-Coulomb oscillating tail spinors of a continuum (en > 0) state, energy-normalised. More... | |
| struct | ContinuumTailSpinors |
| Pair of oscillating continuum spinor values at one radius: the regular (F) and irregular (G) large-r Dirac-Coulomb solutions. More... | |
| struct | DiracContinuumDerivative |
| H-like Dirac derivative matrix for continuum states at large r. More... | |
| struct | FreeDiracParameters |
| Momentum, normalisation, and resolved extent of the free (V = 0) Dirac waves at one energy on a grid; see freeDirac(). More... | |
| struct | GridRequirements |
| Grid requirements returned by RequiredContinuumGrid. More... | |
Functions | |
| void | boundState (DiracSpinor &Fa, const double en0, const std::vector< double > &v, const std::vector< double > &H_off_diag={}, const double alpha=PhysConst::alpha, double eps=1.0e-14, const DiracSpinor *const VxFa=nullptr, const DiracSpinor *const Fa0=nullptr, double zion=1, double mass=1.0) |
| Solves bound-state problem for local potential (en < 0). | |
| void | regularAtOrigin (DiracSpinor &Fa, const double en, const std::vector< double > &v, const std::vector< double > &H_off_diag, const double alpha, const DiracSpinor *const VxFa=nullptr, const DiracSpinor *const Fa0=nullptr, double zion=1, double mass=1.0) |
| For given energy en, solves DE with correct boundary conditions at the origin. | |
| void | regularAtInfinity (DiracSpinor &Fa, const double en, const std::vector< double > &v, const std::vector< double > &H_off_diag, const double alpha, const DiracSpinor *const VxFa=nullptr, const DiracSpinor *const Fa0=nullptr, double zion=1, double mass=1.0) |
| For given energy en, solves (local) DE with correct boundary conditions at infinity. | |
| DiracSpinor | boundState (int n, int kappa, const double en0, const std::shared_ptr< const Grid > &gr, const std::vector< double > &v, const std::vector< double > &H_off_diag={}, const double alpha=PhysConst::alpha, double eps=1.0e-14, const DiracSpinor *const VxFa=nullptr, const DiracSpinor *const Fa0=nullptr, double zion=1, double mass=1.0) |
| Factory overload: constructs a DiracSpinor(n, kappa, gr) and calls boundState(). | |
| void | regularAtOrigin_C (DiracSpinor &FaR, DiracSpinor &FaI, const std::complex< double > en, const std::vector< double > &v, const std::vector< double > &H_off_diag, const double alpha) |
| For given complex energy en, solves Dirac equation with correct boundary conditions at the origin. | |
| void | regularAtInfinity_C (DiracSpinor &FaR, DiracSpinor &FaI, const std::complex< double > en, const std::vector< double > &v, const std::vector< double > &H_off_diag, const double alpha) |
| For given complex energy en, solves Dirac equation with correct boundary conditions at infinity. | |
| void | solveContinuum (DiracSpinor &Fa, double en, const std::vector< double > &v, double alpha, const DiracSpinor *const VxFa=nullptr, const DiracSpinor *const Fa0=nullptr, bool average_tail=false) |
| Solves Dirac equation for a continuum state (en > 0) with energy normalisation. | |
| GridRequirements | RequiredContinuumGrid (double en, const Grid &gr, double N_ppw=20.0, double alpha=PhysConst::alpha) |
| Grid parameters required to safely store (pointwise) a continuum state of energy en on the entire grid. | |
| std::size_t | averageTail (DiracSpinor &Fa, const std::vector< double > &v, double alpha) |
| Optionally fills the zeroed high-r tail of a continuum state with a locally-averaged solution, so radial integrals against smooth functions remain accurate. | |
| void | solveContinuumIrregular (DiracSpinor &Firr, const DiracSpinor &Freg, double en, const std::vector< double > &v, double alpha) |
| Builds the irregular continuum partner F_irr of a regular continuum orbital F_reg. | |
| double | solveContinuumForward (DiracSpinor &phi, const DiracSpinor &Freg, const DiracSpinor &Firr, double en, const std::vector< double > &v, double alpha, const DiracSpinor &Sr) |
| Solves the inhomogeneous continuum equation (h_r - en) phi = S (en > 0) with the standing-wave boundary condition, by outward integration plus subtraction of the regular solution. | |
| std::pair< double, double > | numerical_f_amplitude (double en, int kappa, double alpha, double Zeff, double f_final, double g_final, double r_final, double dr) |
| Finds the numerical amplitude of f(r) for a continuum Dirac solution at large r. | |
| double | analytic_f_amplitude (double en, double alpha) |
| Analytic amplitude of f(r) at very large r for an H-like Dirac continuum state. | |
| double | fitQuadratic (double x1, double x2, double x3, double y1, double y2, double y3) |
| Fits a quadratic to three points and returns the interpolated maximum. | |
| std::vector< DiracSpinor > | freeDirac (double en, int min_l, int max_l, std::shared_ptr< const Grid > grid, double alpha) |
| Free (V = 0) Dirac spherical waves at energy en, for every kappa with l in [min_l, max_l]; energy normalised. | |
| DiracSpinor | freeDirac (double en, int kappa, std::shared_ptr< const Grid > grid, double alpha) |
| Free (V = 0) Dirac spherical wave of a single kappa; see the all-l overload of freeDirac() | |
| DiracSpinor | solve_inhomog (const int kappa, const double en, const std::vector< double > &v, const std::vector< double > &H_mag, const double alpha, const DiracSpinor &source, const DiracSpinor *const VxFa=nullptr, const DiracSpinor *const Fa0=nullptr, double zion=1, double mass=1.0) |
| Solves the inhomogeneous Dirac equation, returning the solution spinor. | |
| void | solve_inhomog (DiracSpinor &Fa, const double en, const std::vector< double > &v, const std::vector< double > &H_mag, const double alpha, const DiracSpinor &source, const DiracSpinor *const VxFa=nullptr, const DiracSpinor *const Fa0=nullptr, double zion=1, double mass=1.0) |
| Solves the inhomogeneous Dirac equation, overwriting Fa. | |
| void | solve_inhomog (DiracSpinor &Fa, DiracSpinor &Fzero, DiracSpinor &Finf, const double en, const std::vector< double > &v, const std::vector< double > &H_mag, const double alpha, const DiracSpinor &source, const DiracSpinor *const VxFa=nullptr, const DiracSpinor *const Fa0=nullptr, double zion=1, double mass=1.0) |
| Solves the inhomogeneous Dirac equation, overwriting Fa and exposing the homogeneous solutions. | |
| struct DiracODE::ContinuumTailSpinors |
| struct DiracODE::GridRequirements |
| void DiracODE::boundState | ( | DiracSpinor & | Fa, |
| const double | en0, | ||
| const std::vector< double > & | v, | ||
| const std::vector< double > & | H_off_diag = {}, |
||
| const double | alpha = PhysConst::alpha, |
||
| double | eps = 1.0e-14, |
||
| const DiracSpinor *const | VxFa = nullptr, |
||
| const DiracSpinor *const | Fa0 = nullptr, |
||
| double | zion = 1, |
||
| double | mass = 1.0 |
||
| ) |
Solves bound-state problem for local potential (en < 0).
Solves \( (H_0 + v - \epsilon_a)F_a = 0 \) for the bound state. en0 is the initial energy guess (must be reasonably good). eps is the convergence target for the energy.
v is the local potential (e.g., v = v_dir + v_nuc)H_off_diag is an optional off-diagonal potentialalpha: \( \alpha = \lambda\alpha_0 \) is the effective fine-structure constant | void DiracODE::regularAtOrigin | ( | DiracSpinor & | Fa, |
| const double | en, | ||
| const std::vector< double > & | v, | ||
| const std::vector< double > & | H_mag, | ||
| const double | alpha, | ||
| const DiracSpinor *const | VxFa, | ||
| const DiracSpinor *const | Fa0, | ||
| double | zion, | ||
| double | mass | ||
| ) |
For given energy en, solves DE with correct boundary conditions at the origin.
| void DiracODE::regularAtInfinity | ( | DiracSpinor & | Fa, |
| const double | en, | ||
| const std::vector< double > & | v, | ||
| const std::vector< double > & | H_mag, | ||
| const double | alpha, | ||
| const DiracSpinor *const | VxFa, | ||
| const DiracSpinor *const | Fa0, | ||
| double | zion, | ||
| double | mass | ||
| ) |
For given energy en, solves (local) DE with correct boundary conditions at infinity.
|
inline |
Factory overload: constructs a DiracSpinor(n, kappa, gr) and calls boundState().
| void DiracODE::regularAtOrigin_C | ( | DiracSpinor & | FaR, |
| DiracSpinor & | FaI, | ||
| const std::complex< double > | en, | ||
| const std::vector< double > & | v, | ||
| const std::vector< double > & | H_mag, | ||
| const double | alpha | ||
| ) |
For given complex energy en, solves Dirac equation with correct boundary conditions at the origin.
| void DiracODE::regularAtInfinity_C | ( | DiracSpinor & | FaR, |
| DiracSpinor & | FaI, | ||
| const std::complex< double > | en, | ||
| const std::vector< double > & | v, | ||
| const std::vector< double > & | H_mag, | ||
| const double | alpha | ||
| ) |
For given complex energy en, solves Dirac equation with correct boundary conditions at infinity.
| void DiracODE::solveContinuum | ( | DiracSpinor & | Fa, |
| double | en, | ||
| const std::vector< double > & | v, | ||
| double | alpha, | ||
| const DiracSpinor *const | VxFa = nullptr, |
||
| const DiracSpinor *const | Fa0 = nullptr, |
||
| bool | average_tail = false |
||
| ) |
Solves Dirac equation for a continuum state (en > 0) with energy normalisation.
Normalisation is achieved by continuing the ODE integration to very large r and comparing the asymptotic amplitude to that of the analytic solution. Only the solution on the regular grid is kept; the extended part is discarded. The solution is solved and stored only up to the radius where the grid resolves the oscillations (at least ~10 points per wavelength); Fa.max_pt() is set accordingly and the tail is zeroed. For high energies this may be well inside the grid; for low energies it is the entire grid.
| Fa | Output spinor (result stored here). |
| en | Continuum energy (must be > 0). |
| v | Local potential v(r). |
| alpha | Fine-structure constant. |
| VxFa | Optional exchange potential. If nullptr, ignored. |
| Fa0 | Optional inhomogeneous source spinor. If nullptr, ignored. |
| average_tail | Optionally fill the unresolved (zeroed) tail with a local average (see averageTail()). |
| GridRequirements DiracODE::RequiredContinuumGrid | ( | double | en, |
| const Grid & | gr, | ||
| double | N_ppw = 20.0, |
||
| double | alpha = PhysConst::alpha |
||
| ) |
Grid parameters required to safely store (pointwise) a continuum state of energy en on the entire grid.
A continuum state is stored pointwise only where the grid spacing gives at least N_ppw points per wavelength; beyond that solveContinuum() zeroes the solution (see Fa.max_pt()). This checks the grid against the largest spacing (the last point) - the constraint is always at large r, where the grid is coarsest. Each returned value assumes the other grid parameters are unchanged. The b formula assumes a loglinear grid; b is clamped from below at 0.05 (below that, even a nearly-linear grid is too coarse) - when clamped, num_points_b (the num_points required at the clamped b) will exceed the current num_points. Uses the relativistic wavelength, 2*pi/k with k^2 = en*(2 + alpha^2*en); at high energy this is much shorter than the non-relativistic estimate (e.g., 1.9x shorter at en = 1e5 au).
| en | Continuum energy (should be the largest energy required). |
| gr | The radial grid. |
| N_ppw | Required points per wavelength (default 20, as used by solveContinuum). |
| alpha | Fine-structure constant. |
| std::size_t DiracODE::averageTail | ( | DiracSpinor & | Fa, |
| const std::vector< double > & | v, | ||
| double | alpha | ||
| ) |
Optionally fills the zeroed high-r tail of a continuum state with a locally-averaged solution, so radial integrals against smooth functions remain accurate.
solveContinuum() stores the solution only up to the radius where the grid resolves the oscillations (Fa.max_pt()), and zeroes the rest; radial integrals then silently omit any contribution from beyond that radius. This routine replaces the tail with the local Gaussian average of a finely-integrated solution. The average is smooth enough to store on the coarse grid, and preserves radial integrals against functions that are smooth on the oscillation scale (bound orbitals, r^k, ...), since Int[B f_avg] = Int[B_avg f] ~ Int[B f]. It does not preserve integrals against co-factors that oscillate on a comparable scale (e.g. jL(qr) with q ~ k), and the stored tail is a local average, not the pointwise wavefunction. Exchange is neglected in the tail. Sets Fa.max_pt() to num_points.
| Fa | Continuum state from solveContinuum() (modified in place). |
| v | Local potential v(r) (as used to solve Fa). |
| alpha | Fine-structure constant. |
| void DiracODE::solveContinuumIrregular | ( | DiracSpinor & | Firr, |
| const DiracSpinor & | Freg, | ||
| double | en, | ||
| const std::vector< double > & | v, | ||
| double | alpha | ||
| ) |
Builds the irregular continuum partner F_irr of a regular continuum orbital F_reg.
Given the regular (energy-normalised) continuum orbital F_reg at energy en > 0 in the local potential v, constructs the linearly independent irregular solution F_irr of the same homogeneous equation: the quarter-wave phase-shifted partner (F_reg ~ sin, F_irr ~ -cos at large r), so that
\[ F_reg + i F_irr \]
is the outgoing wave.
It plays the role of the "regular at infinity" solution of the continuum Green's function, in place of the decaying bound solution.
The outermost grid points are seeded by projecting F_reg onto the energy-normalised asymptotic Dirac-Coulomb pair {F^C, G^C} ( AsymptoticSpinorContinuum ), F_reg = a F^C + b G^C, so
\[ F_irr = b F^C - a G^C \]
(the short-range phase shift is in a, b); the homogeneous equation is then integrated inwards to the origin. If the asymptotic series has not converged at the box edge (a barely-open channel, small p*r_max), F_reg is first continued outward on a fine grid with the Coulomb tail potential until it has; F_irr is seeded there and integrated back to the box. As a last resort (non-Coulomb tail) the seed is the leading-order component swap, f_irr = -g_reg/beta, g_irr = beta f_reg.
The result has the Wronskian f_reg g_irr - f_irr g_reg = alpha/pi (times a^2 + b^2, which is 1 when the projection is exact). It need not be normalised: the overall scale cancels in the Green's-function prefactor.
| Firr | Output: the irregular partner (kappa from Freg). |
| Freg | The regular, energy-normalised continuum orbital. |
| en | Continuum energy (> 0; should equal Freg.en()). |
| v | Local potential (as used to solve Freg); its tail sets the residual-ion charge of the Coulomb series. |
| alpha | Fine-structure constant. |
| double DiracODE::solveContinuumForward | ( | DiracSpinor & | phi, |
| const DiracSpinor & | Freg, | ||
| const DiracSpinor & | Firr, | ||
| double | en, | ||
| const std::vector< double > & | v, | ||
| double | alpha, | ||
| const DiracSpinor & | Sr | ||
| ) |
Solves the inhomogeneous continuum equation (h_r - en) phi = S (en > 0) with the standing-wave boundary condition, by outward integration plus subtraction of the regular solution.
Outward integration from the origin with regular initial conditions gives a particular solution, determined only up to an admixture of F_reg (itself regular at the origin). Beyond the (short-ranged) source it equals c F_reg + K F_irr exactly; c and K are read off pointwise over an outer window from the two spinor components (local Wronskian; no phase fit) and averaged, and then
\[ \varphi = \tilde\varphi - c\,F_{\rm reg} \to K\,F_{\rm irr} , \]
the Green's-function solution with the standing-wave Green's function. The outgoing solution is phi - i K F_reg.
Where the main grid no longer resolves the oscillations (high energy), phi is continued through that band by variation of parameters on the pair, phi = u F_reg + w F_irr, with the quadratures done on the grid; the extraction window lies inside the resolved region.
| phi | Output: the standing-wave particular solution (kappa from Freg). |
| Freg | Regular homogeneous solution at en (energy-normalised). |
| Firr | Irregular partner (see solveContinuumIrregular). |
| en | Continuum energy (> 0). |
| v | Local potential (as used for Freg and Firr). |
| alpha | Fine-structure constant. |
| Sr | Source spinor S. |
| std::pair< double, double > DiracODE::numerical_f_amplitude | ( | double | en, |
| int | kappa, | ||
| double | alpha, | ||
| double | Zeff, | ||
| double | f_final, | ||
| double | g_final, | ||
| double | r_final, | ||
| double | dr | ||
| ) |
Finds the numerical amplitude of f(r) for a continuum Dirac solution at large r.
Continues ODE integration beyond the regular grid, assuming an H-like potential (-Zeff/r) and a linearly-spaced extension grid with step dr. The amplitude estimate sqrt(f^2 + c_g^2 g^2) is averaged over full oscillation cycles (delimited by zero-crossings of f, located to sub-step accuracy), and the cycle means are extrapolated to r -> infinity by fitting A_inf + c2/r^2 + c3/r^3 + c4/r^4. Converged when the extrapolated estimates from the full and half integration ranges agree.
| en | Continuum energy. |
| kappa | Orbital kappa quantum number. |
| alpha | Fine-structure constant. |
| Zeff | Effective nuclear charge. |
| f_final | Value of f at the end of the regular grid. |
| g_final | Value of g at the end of the regular grid. |
| r_final | Radial position at the end of the regular grid. |
| dr | Step size for the extended linear grid. |
| double DiracODE::analytic_f_amplitude | ( | double | en, |
| double | alpha | ||
| ) |
Analytic amplitude of f(r) at very large r for an H-like Dirac continuum state.
| en | Continuum energy. |
| alpha | Fine-structure constant. |
| double DiracODE::fitQuadratic | ( | double | x1, |
| double | x2, | ||
| double | x3, | ||
| double | y1, | ||
| double | y2, | ||
| double | y3 | ||
| ) |
Fits a quadratic to three points and returns the interpolated maximum.
Assumes |y2| = max(|y1|, |y2|, |y3|); used to find the amplitude of a sinusoidal oscillation. The three points must be close to the maximum.
| x1,x2,x3 | x-coordinates of the three points. |
| y1,y2,y3 | y-coordinates of the three points. |
| std::vector< DiracSpinor > DiracODE::freeDirac | ( | double | en, |
| int | min_l, | ||
| int | max_l, | ||
| std::shared_ptr< const Grid > | grid, | ||
| double | alpha | ||
| ) |
Free (V = 0) Dirac spherical waves at energy en, for every kappa with l in [min_l, max_l]; energy normalised.
Exact solutions of the free Dirac equation, regular at the origin,
\[ \begin{align} f(r) &= N\, r\, j_l(kr), \\ g(r) &= \frac{\kappa}{|\kappa|}\, N\, \frac{k\alpha}{2 + \alpha^2\en}\, r\, j_{\tilde l}(kr), \end{align} \]
with
\[ \begin{align} k &= \sqrt{\en(2 + \alpha^2\en)}, \\ \tilde l &= l(-\kappa), \\ N &= k D = \sqrt{\frac{k\,(\en + 2mc^2)}{\pi c^2}}, \end{align} \]
( \( \tilde l \) is l+1 for kappa < 0, l-1 for kappa > 0), where D is the energy-normalised large-r amplitude (analytic_f_amplitude()),
\[ f \to D\sin(kr - l\pi/2), \]
so that
\[ \int (f_\en f_{\en'} + g_\en g_{\en'})\,dr = \delta(\en - \en'). \]
Same (f, g) convention as solveContinuum(); the non-relativistic limit of f is DiracContinuum::P_el with zero charge. Standing waves (not outgoing): only |amplitude|^2 summed over channels is meaningful.
As solveContinuum(), the solution is stored only where the grid resolves the oscillations (at least ~10 points per wavelength): max_pt() is set accordingly and the tail zeroed, so that free and distorted waves at the same energy are truncated alike (as required when completing a truncated multipole sum with plane waves).
j_l(kr) for l = 0..max_l+1 is evaluated once per grid point and shared by every kappa; for a single kappa use the (en, kappa) overload.
| en | Continuum (kinetic) energy, > 0, in au. |
| min_l | Minimum orbital l. |
| max_l | Maximum orbital l. |
| grid | Radial grid. |
| alpha | Fine-structure constant. |
| DiracSpinor DiracODE::freeDirac | ( | double | en, |
| int | kappa, | ||
| std::shared_ptr< const Grid > | grid, | ||
| double | alpha | ||
| ) |
Free (V = 0) Dirac spherical wave of a single kappa; see the all-l overload of freeDirac()
| DiracSpinor DiracODE::solve_inhomog | ( | const int | kappa, |
| const double | en, | ||
| const std::vector< double > & | v, | ||
| const std::vector< double > & | H_mag, | ||
| const double | alpha, | ||
| const DiracSpinor & | source, | ||
| const DiracSpinor *const | VxFa = nullptr, |
||
| const DiracSpinor *const | Fa0 = nullptr, |
||
| double | zion = 1, |
||
| double | mass = 1.0 |
||
| ) |
Solves the inhomogeneous Dirac equation, returning the solution spinor.
Solves \( (H_0 + v - \epsilon_a) F_a = S \) for \( \psi_\kappa \) using Green's method (see Methods documentation). Note the sign convention for S.
| kappa | Angular momentum kappa of the solution. |
| en | Orbital energy \( \epsilon \). |
| v | Local potential v(r). |
| H_mag | Off-diagonal (magnetic) potential. |
| alpha | Fine-structure constant. |
| source | Inhomogeneous source term S. |
| VxFa | Optional exchange potential. If nullptr, ignored. |
| Fa0 | Optional inhomogeneous source spinor. If nullptr, ignored. |
| zion | Effective ionic charge (default 1). |
| mass | Effective particle mass in atomic units (default 1 = m_e). |
| void DiracODE::solve_inhomog | ( | DiracSpinor & | Fa, |
| const double | en, | ||
| const std::vector< double > & | v, | ||
| const std::vector< double > & | H_mag, | ||
| const double | alpha, | ||
| const DiracSpinor & | source, | ||
| const DiracSpinor *const | VxFa = nullptr, |
||
| const DiracSpinor *const | Fa0 = nullptr, |
||
| double | zion = 1, |
||
| double | mass = 1.0 |
||
| ) |
Solves the inhomogeneous Dirac equation, overwriting Fa.
As above; kappa is taken from Fa.
| void DiracODE::solve_inhomog | ( | DiracSpinor & | Fa, |
| DiracSpinor & | Fzero, | ||
| DiracSpinor & | Finf, | ||
| const double | en, | ||
| const std::vector< double > & | v, | ||
| const std::vector< double > & | H_mag, | ||
| const double | alpha, | ||
| const DiracSpinor & | source, | ||
| const DiracSpinor *const | VxFa = nullptr, |
||
| const DiracSpinor *const | Fa0 = nullptr, |
||
| double | zion = 1, |
||
| double | mass = 1.0 |
||
| ) |
Solves the inhomogeneous Dirac equation, overwriting Fa and exposing the homogeneous solutions.
As above, but also returns the homogeneous solutions Fzero (regular at origin) and Finf (regular at infinity), which satisfy \( (H_0 + v - \epsilon)F = 0 \). The first two overloads discard these; this one keeps them for potential reuse. Fzero and Finf are out parameters – they are overwritten internally and do not need to be initialised before calling.