Skip to main content

Module table

Module table 

Source
Expand description

Energy-grid elastic tables: the radial-Dirac solver of the parent module run over a log energy grid for every element of a Material, stored as an electron::data::CrossSectionTable with SamplingAxis::ElasticPolarAngle (issue #90, step 2 of the Mott elastic model).

§Independent-atom approximation

A compound or mixture is treated as a set of independent atoms: the macroscopic differential cross section is the number-density-weighted sum of the atomic ones, n dσ/dΩ = Σ_z n_z dσ_z/dΩ. Chemical bonding, the solid-state potential and coherent (diffraction) effects between atoms are ignored. This is an approximation; condensed-phase (muffin-tin) potentials are follow-up work. Consequently

  • the inverse mean free path is λ⁻¹(E) = Σ_z n_z σ_el,z(E), with n_z from Material::number_density_of and σ_el,z the solver’s total elastic cross section (PartialWaves::sigma_el);
  • the forward cumulative distribution of the polar angle is F(θ) = Σ_z n_z S_z(θ) / Σ_z n_z S_z(π), with S_z(θ) = 2π ∫_0^θ dσ_z/dΩ sin θ' dθ'.

The stored quantiles are the inverse of that F: they do not add linearly between elements, the forward CDF does.

§Angular distribution: exact Legendre form

The Mott DCS |f|² + |g|² of a phase-shift set cut at l_max is a polynomial of degree 2 l_max in x = cos θ (the parent module documents the amplitudes). Its Legendre coefficients c_L = (2L+1)/2 ∫ DCS(x) P_L(x) dx, L = 0..=2 l_max, are therefore obtained exactly (to rounding) with a 2 l_max + 2-point Gauss-Legendre rule, and the cumulative cross section follows in closed form from the Legendre identity (2L+1) P_L = P'_{L+1} - P'_{L-1}. That identity is DLMF 18.9.7 ((n+λ) C_n^(λ) = λ (C_n^(λ+1) - C_{n-2}^(λ+1))) at λ = 1/2, with C_n^(1/2) = P_n (DLMF 18.7.9) and d/dx C_{n+1}^(1/2) = C_n^(3/2) (DLMF 18.9.19); NIST Digital Library of Mathematical Functions, https://dlmf.nist.gov/18.9, read 2026-10-07. The unit tests also check it numerically against direct quadrature:

S(θ) = 2π ∫_x^1 DCS dx' = 2π [ c_0 (1 - x) + Σ_{L>=1} c_L (P_{L-1}(x) - P_{L+1}(x)) / (2L+1) ]

with the complementary form (integral from -1 to x) used for cumulative probabilities above 1/2, so the backward tail keeps its relative precision. S(π) = 4π c_0. No angular grid of the DCS is interpolated anywhere: the only discretisation in a table is the probability grid of the stored inverse CDF.

§Inverse CDF

At each energy the quantile θ_j with F(θ_j) = u_j is found by a safeguarded Newton iteration (bisection fallback) on the exact F, after bracketing on a fixed coarse angle grid. u = 0 maps to θ = 0 and u = 1 to θ = π. The probability grid is shared by all rows and must resolve both tails: the Mott DCS is strongly forward peaked at high energy, so most of the first transport cross section σ_tr1 = σ_el ⟨1 - cos θ⟩ sits in the large-angle tail at 1 - u far below 1e-3. The starting grid (default_probability_grid) is uniform in the logistic variable t = ln(u/(1-u)), which is geometric in u near 0 and in 1 - u near 1.

A fixed grid of that kind is not enough. At intermediate energies the DCS has deep diffraction minima, where θ(u) is steep, and linear interpolation there biases ⟨1 - cos θ⟩. Measured with the Thomas-Fermi Yukawa stand-in on the default energy grid (Z = 1, 6, 14, 29, 79, 92), the worst relative error of the recovered σ_tr1 was 2e-2 for a logistic step of 0.4, 3e-3 for a step of 0.1 and still 1.3e-3 for a step of 0.05 (1109 points). The grid is therefore refined adaptively: shared by all rows of a table and split where any row needs it (see refine in the source). With the defaults (step 0.4, tolerance DEFAULT_REFINE_TOLERANCE) the same measurement gives a worst error of 9.4e-5 or less, with 939 to 1604 probability points. The tests hold the recovered σ_tr1 to 1e-3 at every grid energy.

§Potentials

The atomic potential comes from a caller-supplied PotentialSource. SalvatDhfsTable gives the Salvat et al. (1987) DHFS potentials (Table I, Z = 1..92, see the parent module and docs/data-provenance.md); most tests and the benchmarks use ThomasFermiYukawa, a stand-in Yukawa potential with the Thomas-Fermi length. The table’s model and provenance strings name the potential, so a stand-in table never reads as DHFS.

The optional exchange and correlation-polarization corrections (super::corrections) enter through AtomicElastic::compute_corrected, which rebuilds the corrected potential at each grid energy; the caller’s description then names the corrections too.

§Determinism

Energies are solved in parallel with rayon and collected in grid order; every per-energy computation is serial and in a fixed order (the solver’s own partial-wave parallelism is already order-preserving). Errors are reported for the lowest failing energy, whatever the thread count. Tables are bit-identical on any number of threads (tested).

Structs§

AtomicElastic
Partial-wave results of one element over an energy grid.
AtomicElasticRow
Partial-wave results of one element at one energy, with the DCS in exact Legendre form (see the module docs). Cross sections in bohr².
ElasticTableOptions
Grids and solver settings of a table build.
SalvatDhfsTable
The Salvat et al. (1987) DHFS potentials via SalvatDhfs::for_element (Table I, Z = 1..92; docs/data-provenance.md).
ThomasFermiYukawa
Stand-in potential: a Yukawa (single exponential) screened Coulomb potential V = -(Z/r) exp(-r/a) with the Thomas-Fermi length a = 0.8853 a0 Z^(-1/3) (thomas_fermi_constant, Firsov 1958 / Lindhard, Scharff & Schiott 1963, see docs/data-provenance.md). It is not an atomic DHFS potential; it was the only potential while the Salvat et al. (1987) coefficients were missing, and remains a cheap one for tests and benchmarks.

Enums§

ElasticTableError
Errors from the table builder.

Constants§

DEFAULT_LOGISTIC_STEP
Default step of the probability grid in the logistic variable t = ln(u/(1-u)). Chosen by measurement, see the module docs.
DEFAULT_MAX_ENERGY_EV
Highest energy of the default grid, eV.
DEFAULT_MIN_ENERGY_EV
Lowest energy of the default grid, eV.
DEFAULT_POINTS_PER_DECADE
Minimum number of energy points per decade of the default grid.
DEFAULT_PROBABILITY_TAIL
Default probability tails: the first and last interior probability points are DEFAULT_PROBABILITY_TAIL and 1 - DEFAULT_PROBABILITY_TAIL.
DEFAULT_REFINE_TOLERANCE
Default target of the probability-grid refinement, relative to ⟨1 - cos θ⟩ (see ElasticTableOptions::refine_tolerance).
MAX_GRID_INTERVALS
Most intervals log_energy_grid will build. A guard against an input whose points_per_decade would otherwise request an unbounded allocation (found by the malformed-input corpus in tests/input_robustness.rs); the default grid uses a few hundred.
MAX_PROBABILITY_POINTS
Upper bound on the refined probability grid.

Traits§

PotentialSource
Supplies the atomic screened potential of each element.

Functions§

build_elastic_table
Build the elastic table of material with potentials from source. Components with a zero atom fraction are skipped (their potential is not requested).
combine
Combine atomic results into the elastic table of material by independent-atom additivity (module docs). atoms must hold every component of material with a non-zero atom fraction, all on the same energy grid, potential and solver settings. probability is the probability grid, used as given when refine_tolerance is None and as the starting grid of the adaptive refinement otherwise (see ElasticTableOptions::refine_tolerance).
default_energy_grid
The default energy grid: DEFAULT_MIN_ENERGY_EV to DEFAULT_MAX_ENERGY_EV with at least DEFAULT_POINTS_PER_DECADE points per decade.
default_probability_grid
The default probability grid: logistic_probability_grid with DEFAULT_PROBABILITY_TAIL and DEFAULT_LOGISTIC_STEP.
log_energy_grid
A log-spaced energy grid from min_ev to max_ev (both included exactly) with at least points_per_decade points per decade.
logistic_probability_grid
A probability grid uniform in the logistic variable t = ln(u/(1-u)) between u = tail and u = 1 - tail with step at most step, plus the end points 0 and 1.
mean_one_minus_cos
⟨1 - cos θ⟩ of a stored inverse-CDF row, integrated exactly over the piecewise-linear θ(u) that CrossSectionTable::inverse_cdf interpolates. σ_tr1 = σ_el ⟨1 - cos θ⟩.