ffm

Frequency Fluctuation Model utilities for adding ion dynamics to a static Stark-Zeeman transition set. In the Sherman-Morrison form used by the fast solver, the profile is

\[I(\omega) = \frac{r^2}{\pi}\,\operatorname{Re} \left[\frac{S(\omega)}{1-\nu_i S(\omega)}\right],\]

where

\[S(\omega) = \sum_k \frac{p_k}{\nu_i + \gamma_k + i(\omega - \omega_k)}.\]

Here \(p_k\) are normalized Stark-dressed transition weights, \(\gamma_k\) are electron-impact widths, and \(\nu_i\) is the ion microfield fluctuation rate.

starkzee.ffm.calculate_ion_fluctuation_rate(Ne_m3, Ti_ev, Z_ion, A_ion)[source]

Return the ion fluctuation (jumping) rate ν_i [eV].

The FFM treats the ion microfield as a stochastic process that switches between field configurations at rate ν_i. This rate is estimated as the inverse of the mean time for an ion to cross the inter-ion distance r_i at its thermal velocity:

N_i = N_e / Z_ion r_i = (3 / 4π N_i)^{1/3} — mean inter-ion spacing [m] v_th = √(2 k_B T_i / m_i) — most-probable ion speed [m s⁻¹] ν_i = (v_th / r_i) × ħ / e — converted to eV

A larger ν_i (high density, high T_i, light ions) pushes the profile toward the dynamical (motional) narrowing limit; ν_i → 0 recovers the static Holtsmark profile.

Parameters:
  • Ne_m3 (float) – Electron number density [m⁻³].

  • Ti_ev (float) – Ion temperature [eV].

  • Z_ion (int) – Ion charge number (used to derive ion density N_i = N_e / Z_ion).

  • A_ion (float) – Ion atomic mass number (e.g. 1 for H⁺, 2 for D⁺).

Returns:

Ion fluctuation rate ν_i [eV].

Return type:

float

Notes

The most-probable speed v_th = √(2 k_B T_i / m_i) is used here. Ferri et al. (2022) do not specify the ion v_th prefactor explicitly; this should be verified against Calisti et al., Phys. Rev. A 42, 5433 (1990).

starkzee.ffm.calculate_ffm_profile(n_u, n_l, Z, B, Ne_m3, Te_ev, Ti_ev, A_ion, energies_ev, num_f=30, num_mu=10, use_screening=True, quadratic_zeeman=True, fine_structure=True, numerical_inversion=False, use_empirical_data=False, atom='H', electron_model='pppb', parallel_stark=False, apply_doppler=True)[source]

Compute the dynamical Stark-Zeeman line profile using the Frequency Fluctuation Model.

The FFM treats the ion microfield as a Markov jump process between Stark-dressed field configurations. At each quadrature point (field magnitude F, angle μ = cos θ) the Stark-Zeeman Hamiltonian is diagonalized to obtain the dressed-state transition frequencies ω_k and weights d_k. These form the Stark-Dressed Transitions (SDTs). The FFM then solves the Markov master equation to obtain a profile that interpolates between the quasi-static limit (ν_i → 0, identical to the static profile) and the motional-narrowing limit (ν_i → ∞, single Lorentzian).

Sherman-Morrison solver (default, numerical_inversion=False):

I(ω) = (R²/π) Re [ S(ω) / (1 − ν_i S(ω)) ]

S(ω) = Σ_k p_k / (ν_i + γ_k + i(ω − ω_k))

where p_k = d_k² / Σ d_k² are the normalized SDT weights and γ_k is the electron-impact half-width. This analytical result is exact for a Markov jump process with uniform jumping rate ν_i and O(N) per frequency point.

Full matrix inversion (numerical_inversion=True): Solves the Liouville-space Markov equation A x = b directly for each frequency point, which is O(N³) but handles non-uniform jumping rates or more complex correlation structures.

Parameters:
  • n_u (int) – Upper and lower principal quantum numbers.

  • n_l (int) – Upper and lower principal quantum numbers.

  • Z (int) – Nuclear charge.

  • B (float) – Magnetic field [T]. B = 0 is fully supported.

  • Ne_m3 (float) – Electron number density [m⁻³].

  • Te_ev (float) – Electron temperature [eV]. Used for Debye screening and electron impact width.

  • Ti_ev (float) – Ion (emitter) temperature [eV]. Used both to compute the ion fluctuation rate ν_i and, when apply_doppler=True, as the emitter thermal velocity for Doppler broadening.

  • A_ion (float) – Atomic mass number of the perturbing ion species (e.g. 1 for H⁺, 2 for D⁺). Also used as the emitter mass for the Doppler width (same-species assumption).

  • energies_ev (array-like) – Photon energies at which to evaluate the profile [eV].

  • num_f (int, optional) – Number of microfield quadrature points (default 30). Ferri et al. (2022) recommend ~50; 30 is sufficient for hydrogen but should be increased for multi-electron atoms (future: set dynamically by atom type).

  • num_mu (int, optional) – Number of Gauss-Legendre points for the field-angle integration over μ = cos θ ∈ [0, 1] (default 10). Ferri et al. (2022) recommend ~30; 10 is sufficient for hydrogen but should be increased for multi-electron atoms (future: set dynamically by atom type).

  • use_screening (bool, optional) – Use the Hooper screened microfield distribution (default True).

  • quadratic_zeeman (bool, optional) – Include the diamagnetic quadratic Zeeman term (default True).

  • fine_structure (bool, optional) – Include mass-velocity and Darwin corrections (default True).

  • numerical_inversion (bool, optional) – If True, solve the full Markov matrix by direct inversion instead of the Sherman-Morrison approximation (default False). Falls back to Sherman-Morrison if the matrix is singular.

  • use_empirical_data (bool, optional) – Use NIST empirical level energies (default False); forwarded to solve_starkzee().

  • atom (str, optional) – Atom identifier for empirical data (default "H"); forwarded to solve_starkzee().

  • electron_model (str, optional) – Electron-impact width prescription, forwarded to electron_impact_width_model(). 'pppb' (default) is the PPPB model; 'zest', 'zest-lee', 'zest-dufty' select the ZEST model with the GBK, Lee, or Dufty RPA G-function. Note the FFM applies a single resonance width to all SDTs.

  • parallel_stark (bool, optional) – If True, use the parallel-Stark approximation: only the field component parallel to B (Fz = F·μ) enters the Stark Hamiltonian; the perpendicular component Fx is set to zero. This matches the parallel_stark=True convention of the ZEST code (Ferri et al. 2022). Default is False.

  • apply_doppler (bool, optional) – If True (default), convolve the accumulated profile with a Gaussian thermal Doppler kernel of 1/e half-width σ_D = E₀ √(T_i / m_ion c²), using Ti_ev and A_ion. Set to False to obtain the purely Stark-Zeeman-broadened FFM profile without Doppler.

Returns:

  • profile_pi (ndarray, shape like *energies_ev*) – π polarization component (Δm = 0).

  • profile_sig_plus (ndarray) – σ+ polarization component (Δm = +1).

  • profile_sig_minus (ndarray) – σ− polarization component (Δm = −1).

Notes

Static vs FFM guidance: use the static profile (calculate_static_profile()) when B ≥ 50 T or N_e < 10²¹ m⁻³, where ion dynamics are negligible. For lower B or higher densities (especially Hβ, Hδ at N_e ≥ 10²³ m⁻³) FFM is needed to reproduce the correct central dip depth and peak structure.

B = 0 note: the π/σ decomposition is physically meaningless at B = 0 (no preferred axis); all three components are equal by symmetry and their sum gives the isotropic total profile.

References

Calisti, A. et al., Phys. Rev. A 42, 5433 (1990). — FFM formulation. Ferri, S., Peyrusse, O. & Calisti, A., Matter Radiat. Extremes 7, 015901 (2022).