static_profile
Core quasi-static Stark-Zeeman solver. For each electric microfield magnitude \(F\) and orientation \(\mu=\cos\theta\), the solver diagonalizes the full field-dependent Hamiltonian and accumulates the three polarization profiles.
The static profile is the microfield and angle average
- starkzee.static_profile.build_stark_matrix(n, Z, Fz, Fx)[source]
Build the (2n²) × (2n²) Stark electric-field perturbation matrix in eV.
The linear Stark interaction for an electron in an external electric field F = Fz ẑ + Fx x̂ is:
V_E = −e (z Fz + x Fx)
In the hydrogenic basis the matrix elements reduce to products of a radial element and an angular element. The within-shell (Δn = 0) radial element ⟨n, l | r | n, l±1⟩ is given analytically:
⟨n, l | r | n, l−1⟩ = (3n/2Z) √(n² − l²) [a₀]
The angular elements ⟨l, m_l | cos θ | l±1, m_l⟩ (for Fz) and the combinations for Fx are provided by
angular_dipole_element().The x-component is constructed as:
x/r = (T_{−1} + T_{+1}) / √2
where T_q are the spherical tensor components of r̂.
- Parameters:
- Returns:
Hermitian Stark perturbation matrix in eV.
- Return type:
ndarray,shape (2n²,2n²),dtype complex
Notes
This matrix operates within a single n-shell; the quadratic Stark effect (coupling to n ± 1, ±2 shells) is neglected, which is valid when the Stark shift ≪ the shell spacing Z² Ry (1/n² − 1/(n+1)²).
- starkzee.static_profile.solve_starkzee(n, Z, B, Fz, Fx, quadratic_zeeman=True, fine_structure=True, A=1, use_empirical_data=False, atom='H')[source]
Diagonalize the combined Stark + Zeeman Hamiltonian for shell n.
Adds the Stark perturbation
build_stark_matrix()to the atomic/magnetic Hamiltonianbuild_hamiltonian()and diagonalizes the sum withnumpy.linalg.eigh:H = H_atom(B) + V_E(Fz, Fx)
This is the inner-loop solver called for every (microfield magnitude, microfield angle) quadrature point during profile integration.
- Parameters:
n (
int) – Principal quantum number.Z (
int) – Nuclear charge.B (
float) – Magnetic field [T].Fz (
float) – Electric field component along B [V m⁻¹].Fx (
float) – Electric field component perpendicular to B [V m⁻¹].quadratic_zeeman (
bool, optional) – Include the diamagnetic quadratic Zeeman term (default True).fine_structure (
bool, optional) – Include MV + Darwin corrections (default True).use_empirical_data (
bool, optional) – Use NIST empirical level energies for the field-free Hamiltonian instead of the analytic Rydberg formula (default False). The internal Hamiltonian is assembled in cm⁻¹; eigenvalues are converted back to eV before returning so callers see no unit change.atom (
str, optional) – Atom identifier passed toload_levels()whenuse_empirical_data=True(default"H").
- Returns:
eigenvalues (
ndarray,shape (2n²,)) – Energy eigenvalues in ascending order [eV].eigenvectors (
ndarray,shape (2n²,2n²)) – Orthonormal eigenstates as columns, in the canonical|n, l, m_l, m_s⟩basis.
- starkzee.static_profile.calculate_static_profile(n_u, n_l, Z, B, Ne_m3, Te_ev, energies_ev, num_f=20, num_mu=6, max_beta=10.0, use_screening=True, quadratic_zeeman=True, fine_structure=True, frequency_dependent_width=True, A=1, Ti_ev=None, species='H', electron_model='pppb', electron_operator=False, use_empirical_data=False, atom='H')[source]
Compute the static-ion Stark-Zeeman line profile for n_u → n_l.
Integrates the Stark-Zeeman Hamiltonian over the plasma microfield distribution using Gauss-Legendre quadrature for both the field magnitude and the angle μ = cos θ between the microfield and B. For each quadrature point the combined Hamiltonian H = H_atom(B) + V_E(Fz, Fx) is diagonalized and the transition intensities accumulated into three polarization components.
- Parameters:
n_u (
int) – Upper and lower principal quantum numbers.n_l (
int) – Upper and lower principal quantum numbers.Z (
int) – Nuclear charge (1 for hydrogen).B (
float) – Magnetic field [T].B=0is fully supported; at zero field the π/σ decomposition is physically meaningless (no preferred axis) and all three returned components are equal by spherical symmetry.Ne_m3 (
float) – Electron density [m⁻³].Te_ev (
float) – Electron temperature [eV].energies_ev (
array-like) – Photon energies at which to evaluate the profile [eV].num_f (
int, optional) – Number of microfield quadrature points (default 20). Ferri et al. (2022) recommend ~50; 20 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 angle points (default 6). Ferri et al. (2022) recommend ~30; 6 is sufficient for hydrogen but should be increased for multi-electron atoms (future: set dynamically by atom type).max_beta (
float, optional) – Upper limit of the reduced-microfield grid β = F/F₀ (default 10). The Holtsmark tail beyond β = 10 carries ~3 % of the probability, which the quadrature truncates and renormalizes away; increase this (together withnum_f) when the quasi-static far wings matter. Forwarded tomicrofield_quadrature().use_screening (
bool, optional) – Use Hooper screened microfield distribution (default True).quadratic_zeeman (
bool, optional) – Include diamagnetic (quadratic) Zeeman term (default True).fine_structure (
bool, optional) – Include mass-velocity and Darwin corrections (Dirac fine structure) so that 2s_{1/2} = 2p_{1/2} (default True).frequency_dependent_width (
bool, optional) – When True (default), evaluate the GBK electron-impact width pointwise at the observation detuning from the gross-structure line center,w(E − E0), as in the PPPB operator Φ(Δω) of Ferri et al. (2022) Eq. (19), where Δω is “the frequency detuning from the line center”. Every component then shares the same frequency-dependent width function: a far-shifted σ± component receives a reduced width at its own position, and the far wings of all components relax toward the strong-collision floor C_n as G(Δω) → 0 (breakdown of the impact approximation), making the components non-Lorentzian. When False, use the single on-resonance valuew(0)everywhere (faster; valid when the profile extent ≪ ω_c). Note the pointwise profile is not exactly area-normalized per component (the physical GBK non-Lorentzian shape isn’t either).Ti_ev (
float, optional) – Ion temperature [eV]. When supplied, Doppler broadening is folded into the Lorentzian accumulation as a Voigt profile, eliminating the need for a separate post-processing convolution. Default isNone(bare Lorentzian, no Doppler).species (
str, optional) – Emitting species ('H','D', or'T'); used to determine the ion mass for the Doppler width. Only relevant when Ti_ev is set. Default is'H'.electron_model (
str, optional) – Electron-impact width prescription, forwarded toelectron_impact_width_model().'pppb'(default) is the PPPB model (B-dependent ω_c cutoff);'zest','zest-lee','zest-dufty'select the ZEST model with the GBK, Lee, or Dufty RPA G-function.electron_operator (
bool, optional) – WhenTrue, use the electron-impact operator diagonal: each Stark-Zeeman dressed state gets a width scaled by its own ⟨k|r²|k⟩ (electron_impact_r2_scaling()) instead of the shell-averaged scalar (defaultFalse). This is the ZEST operator treatment with the off-diagonal /c_kset to zero. The full PPPB operator (off-diagonal → complex intensitya_k + i c_k) and the lower-manifoldd†·dcontribution are not yet implemented — see the REVIEW note inelectron_impact_r2_scaling(). Currently applied in the in-loop Lorentzian path; with Doppler-dominant grids (the post-FFT Lorentzian) the scalar resonance width is used.use_empirical_data (
bool, optional) – Use NIST empirical level energies for the field-free Hamiltonian instead of the analytic Dirac (spin-orbit + MV + Darwin) formula (default False); forwarded tobuild_hamiltonian(). The empirical levels include the Lamb shift, so the resulting profile centroid matches the measured NIST wavelength more closely than the pure-Dirac default, which is Lamb-shift-free.atomic_levels.jsontabulates H (n ≤ 8), D (n ≤ 6), and T (n ≤ 3) levels — pass the matchingatomfor the emitting species: the defaultatom="H"combined withspecies='D'/'T'reproduces the plain-hydrogen line center, not the isotope-shifted one (~0.1-0.2 nm for Balmer-α).atom (
str, optional) – Atom identifier passed toload_levels()whenuse_empirical_data=True(default"H").approximations (Notes on)
-----------------------
**sigma_D** (
the Doppler width is computed as)mean(energies_ev). (σ_D = E_mean × sqrt(Ti / mc²) where E_mean =)
Strictly
σ_D(dE_i) (each transition at energy dE_i should use)
but
H-alpha (the fractional error is ΔE/E ≈ Δ_Zeeman/E0 — about 0.03 % for)
practice. (at 10 T — and is negligible in)
step** (**Lorentzian FFT)
path) (Gaussian-loop)
uses (the post-loop Lorentzian convolution)
both (w_resonance (the on-resonance GBK width) for)
a (frequency_dependent_width settings — an FFT convolution cannot carry)
few (frequency-dependent width. The variation of w across the line is a)
σ_D. (% there and is negligible relative to)
resolution** (**Grid)
2Δx) (σ_D ≤)
and (components narrower than the grid spacing are undersampled)
is (part of the integrated intensity is silently lost; a UserWarning)
grid. (emitted when w(0) < 2Δx. Supply Ti_ev or refine the)
- Returns:
profile_pi (
ndarray) – π (Δm = m_u − m_l = 0) polarization component.profile_sig_plus (
ndarray) – σ+ (Δm = +1, blue-shifted at B > 0; dipole channel q = m_l − m_u = −1) polarization component.profile_sig_minus (
ndarray) – σ− (Δm = −1, red-shifted; channel q = +1) polarization component.
Notes
Observable intensity at angle θ to B:
I(θ) = I_π sin²θ + ½(I_σ+ + I_σ−)(1 + cos²θ)
Transverse (θ = 90°): I_π + ½(I_σ+ + I_σ−). Along B (θ = 0°): I_σ+ + I_σ−. Angle-averaged: ⅔ (I_π + I_σ+ + I_σ−) (both sin²θ and ½(1+cos²θ) average to ⅔ over the sphere; for the isotropic case I_π = I_σ± = I this gives I(θ) = 2I at every angle, as it must).
- starkzee.static_profile.discrete_transitions(n_u, n_l, Z, B, Fz=0.0, Fx=0.0, quadratic_zeeman=True, fine_structure=True, min_strength=0.0, A=1, radial_method=None, use_empirical_data=False, atom='H')[source]
Return all discrete Stark-Zeeman dipole transitions at a single field configuration.
Diagonalizes the Stark-Zeeman Hamiltonian for both shells and enumerates every (upper eigenstate i, lower eigenstate j, polarization q) triplet with non-zero dipole matrix element squared.
- 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].Fz (
float, optional) – Electric field component along B [V m⁻¹] (default 0).Fx (
float, optional) – Electric field component perpendicular to B [V m⁻¹] (default 0).quadratic_zeeman (
bool, optional) – Include diamagnetic Zeeman term (default True).fine_structure (
bool, optional) – Include mass-velocity + Darwin corrections (default True).min_strength (
float, optional) – Discard transitions with dipole strength abs(d_q)² < min_strength [a₀²] (default 0).A (
int, optional) – Atomic mass number of the emitter (1 = H, 2 = D, 3 = T). Sets the reduced-mass Rydberg used for the absolute level energies (default 1).radial_method (
{"gordon", "quad", None}, optional) – Backend for the radial dipole elements.None(default) uses the module-levelRADIAL_DIPOLE_METHOD("gordon"exact closed form by default;"quad"is the numerical fallback). The two agree to ~1e-15.use_empirical_data (
bool, optional) – Use NIST empirical level energies (default False); forwarded tosolve_starkzee().atom (
str, optional) – Atom identifier for empirical data (default"H"); forwarded tosolve_starkzee().
- Returns:
dict with five equal-length arrays sorted by transition energyenergy_ev– Transition energy E_upper_i − E_lower_j [eV].q– Polarization integer q = m_l − m_u: 0 = π; q = −1 is σ+ (Δm = m_u − m_l = +1, blue-shifted at B > 0); q = +1 is σ− (red-shifted).strength– abs(d_q(i→j))² [a₀²]. Summed over all transitions equalsline_strength()(unitary invariance).upper_idx– Upper eigenstate index (0 … 2n_u²−1).lower_idx– Lower eigenstate index (0 … 2n_l²−1).