radiator
Atomic basis, Hamiltonian, and transition dipole construction. The radiator Hamiltonian assembled in the uncoupled hydrogenic basis is
The linear Zeeman term is diagonal,
while the diamagnetic term is
Transition dipole matrices obey
- class starkzee.radiator.AtomicState(index, n, l, ml, s=0.5, ms=0.5)[source]
Bases:
objectHydrogenic basis state
|n, l, m_l, s=½, m_s⟩.
- starkzee.radiator.build_basis(n)[source]
Return the ordered list of 2n² hydrogenic basis states for shell n.
Each state is an
AtomicStatelabeled by (n, l, m_l, s=½, m_s). The ordering is: outer loop over l ∈ {0, …, n−1}, then m_l ∈ {−l, …, +l}, then m_s ∈ {+½, −½}. This ordering is fixed throughout the package; all Hamiltonian and dipole matrices use the same index convention.- Parameters:
n (
int) – Principal quantum number.- Returns:
2n² basis states in the canonical ordering described above.
- Return type:
listofAtomicState
- starkzee.radiator.radial_wavefunction(r, n, l, Z)[source]
Return the hydrogenic radial wavefunction R_{nl}(r) [a₀^{−3/2}].
Evaluates the normalized hydrogenic radial wavefunction using the associated Laguerre polynomial representation:
R_{nl}(r) = N_{nl} × exp(−Z r / n) × (2Z r/n)^l × L_{n-l-1}^{2l+1}(2Z r/n)
where r is in units of a₀ and N_{nl} is chosen so that ∫₀^∞ |R_{nl}|² r² dr = 1.
- Parameters:
- Returns:
Radial wavefunction value [a₀^{−3/2}]. Returns 0 if l ≥ n.
- Return type:
floatorndarray
Notes
Uses
scipy.special.assoc_laguerrefor the polynomial, which handles the high-n case accurately.
- starkzee.radiator.radial_r2_element(n, l1, l2, Z, method=None)[source]
Return the within-shell radial matrix element ⟨n, l₁ | r² | n, l₂⟩ [a₀²].
Used for the off-diagonal (abs(Δl) = 2) elements arising from the angular decomposition of r² sin²θ in the quadratic Zeeman term.
- Parameters:
n (
int) – Principal quantum number (same for both bra and ket).l1 (
int) – Orbital quantum numbers (the quadratic-Zeeman term needs abs(l₁ − l₂) = 2).l2 (
int) – Orbital quantum numbers (the quadratic-Zeeman term needs abs(l₁ − l₂) = 2).Z (
int) – Nuclear charge.method (
{"gordon", "quad", None}, optional) – Backend.None(default) resolves to the module-levelRADIAL_DIPOLE_METHOD."gordon"uses the exact closed form (_closed_radial_r2_element());"quad"uses numerical integration. The two agree to ~1e-8.
- Returns:
Radial matrix element [a₀²]; numerical fallback is used for the (unused) abs(Δl) ∉ {0, 2} case when the closed form does not apply.
- Return type:
- starkzee.radiator.set_radial_dipole_method(method)[source]
Set the global radial-dipole backend:
"gordon"or"quad".
- starkzee.radiator.radial_dipole(n1, l1, n2, l2, Z, method=None)[source]
Return the radial transition matrix element ⟨n₁, l₁ | r | n₂, l₂⟩ [a₀].
- Parameters:
n1 (
int) – Quantum numbers and nuclear charge.l1 (
int) – Quantum numbers and nuclear charge.n2 (
int) – Quantum numbers and nuclear charge.l2 (
int) – Quantum numbers and nuclear charge.Z (
int) – Quantum numbers and nuclear charge.method (
{"gordon", "quad", None}, optional) – Backend to use.None(default) resolves to the module-levelRADIAL_DIPOLE_METHOD(settable viaset_radial_dipole_method())."gordon"uses the exact closed form;"quad"uses numerical integration. The two agree to ~1e-15 for n ≲ 10. The degenerate same-n element (n₁ = n₂) always uses"quad"since Gordon’s form is defined only for n₁ ≠ n₂.
- Returns:
Radial dipole matrix element [a₀];
0.0when abs(l₁ − l₂) ≠ 1.- Return type:
- starkzee.radiator.angular_dipole_element(l1, m1, l2, m2, q)[source]
Return the angular part of the dipole matrix element ⟨l₁, m₁ | T_q^(1) | l₂, m₂⟩.
The spherical tensor components T_q^(1) of the position unit vector r̂ are:
q = 0 (π): T₀ = cos θ
q = +1 (σ+): T₊₁ = sin θ e^{iφ} / √2
q = −1 (σ−): T₋₁ = sin θ e^{−iφ} / √2
The matrix elements are expressed via Clebsch-Gordan coefficients and are non-zero only when abs(l₁ − l₂) = 1 and m₁ − m₂ = q. Explicit formulas:
q = 0 (Δm = 0, both states share the same m):
⟨l, m | cos θ | l+1, m⟩ = √((l+1)² − m²) / √((2l+1)(2l+3))
evaluated with l = max(l₁, l₂) − 1.
q = +1 (m₁ = m₂ + 1):
⟨l−1, m | T₊₁ | l, m⟩ = +√((l−m)(l−m−1) / (2(2l−1)(2l+1))) ⟨l, m+1 | T₊₁ | l−1, m⟩ = −√((l+m)(l+m+1) / (2(2l−1)(2l+1)))
q = −1 (m₁ = m₂ − 1):
⟨l−1, m | T₋₁ | l, m⟩ = −√((l+m)(l+m−1) / (2(2l−1)(2l+1))) ⟨l, m−1 | T₋₁ | l−1, m⟩ = +√((l−m)(l−m+1) / (2(2l−1)(2l+1)))
- Parameters:
l1 (
int) – Orbital and magnetic quantum numbers of the bra state.m1 (
int) – Orbital and magnetic quantum numbers of the bra state.l2 (
int) – Orbital and magnetic quantum numbers of the ket state.m2 (
int) – Orbital and magnetic quantum numbers of the ket state.q (
int) – Polarization index: 0 (π), +1 (σ+), or −1 (σ−).
- Returns:
Angular matrix element (real). Returns 0 if abs(l₁ − l₂) ≠ 1 or m₁ − m₂ ≠ q.
- Return type:
Notes
The full dipole matrix element between two basis states is
−radial_dipole(n1,l1,n2,l2,Z) × angular_dipole_element(l1,m1,l2,m2,q)(the minus sign comes from d = −e r).
- starkzee.radiator.build_hamiltonian(n, Z, B, quadratic_zeeman=True, fine_structure=True, A=1, use_empirical_data=False, atom='H')[source]
Build the (2n²) × (2n²) atomic Hamiltonian matrix in eV.
Constructs the full magnetic Hamiltonian in the uncoupled
|n, l, m_l, m_s⟩basis returned bybuild_basis(). Four physical contributions are included:1. Unperturbed energy (diagonal, degenerate across the shell):
E_n = −Z² Ry / n²
2. Spin-orbit coupling L·S (off-diagonal in m_l, m_s):
H_SO = ξ_{nl} L·S, ξ_{nl} = Z⁴ α² Ry / (n³ l (l+½)(l+1))
Written with ladder operators: L·S = L_z S_z + ½(L₊ S₋ + L₋ S₊).
3. Mass-velocity and Darwin corrections (diagonal, only when
fine_structure=True):ΔE_{l=0} = −A (n − ¾) ΔE_{l>0} = −A (n/(l+½) − ¾), A = Z⁴ α² Ry / n⁴
Together with spin-orbit, these reproduce the Dirac fine-structure formula and restore the 2s_{1/2} = 2p_{1/2} degeneracy.
4. Linear Zeeman (diagonal):
H_LZ = μ_B B (m_l + g_s m_s), g_s = 2.0023192
5. Quadratic (diamagnetic) Zeeman (diagonal and off-diagonal in l, only when
quadratic_zeeman=Trueand B > 0):H_QZ = (e²B²/8m_e) r² sin²θ
Matrix elements in the
|n, l, m_l⟩basis involve⟨l, m_l | sin²θ | l', m_l⟩for abs(l − l’) ∈ {0, 2} and the radial elements⟨n, l | r² | n, l'⟩.- Parameters:
n (
int) – Principal quantum number.Z (
int) – Nuclear charge.B (
float) – Magnetic field [T]. B = 0 is fully supported (skips the QZ term).quadratic_zeeman (
bool, optional) – Include the diamagnetic quadratic Zeeman term H_QZ (default True). At B ≤ 10 T the QZ shift is typically < 0.1 meV for n ≤ 3 and can be omitted for speed.fine_structure (
bool, optional) – Include mass-velocity and Darwin corrections alongside spin-orbit (default True). When False, only H_SO is added, breaking the 2s_{1/2} = 2p_{1/2} degeneracy — useful for isolated unit tests.use_empirical_data (
bool, optional) – If True, injects precise empirical field-free energies from atomic_data.atom (
str, optional) – Element symbol used to fetch empirical data.
- Returns:
Hermitian Hamiltonian matrix in eV.
- Return type:
ndarray,shape (2n²,2n²),dtype complex
Notes
The Stark electric-field perturbation is not included here; it is added separately in
build_stark_matrix()and combined insolve_starkzee().At B = 0 the pi/σ decomposition of the resulting profile is physically meaningless (no preferred axis); only the total profile is physically observable.
- starkzee.radiator.diagonalize_hamiltonian(n, Z, B, quadratic_zeeman=True, fine_structure=True, A=1, use_empirical_data=False, atom='H')[source]
Diagonalize the field-free (F = 0) magnetic Hamiltonian for shell n.
Builds the (2n²) × (2n²) Hamiltonian via
build_hamiltonian()with no applied electric field and diagonalizes it usingnumpy.linalg.eigh(real symmetric solver, numerically stable).- Parameters:
n (
int) – Principal quantum number.Z (
int) – Nuclear charge.B (
float) – Magnetic field [T]. B = 0 is valid (returns hydrogenic/fine-structure eigenvalues).quadratic_zeeman (
bool, optional) – Include the diamagnetic (quadratic Zeeman) term (default True).fine_structure (
bool, optional) – Include mass-velocity and Darwin corrections alongside spin-orbit coupling (default True).use_empirical_data (
bool, optional) – If True, injects precise empirical field-free energies.atom (
str, optional) – Element symbol used to fetch empirical data.
- Returns:
eigenvalues (
ndarray,shape (2n²,)) – Energy eigenvalues in ascending order [eV].eigenvectors (
ndarray,shape (2n²,2n²)) – Columns are the corresponding orthonormal eigenstates expressed in the|n, l, m_l, m_s⟩basis ofbuild_basis().
- starkzee.radiator.dipole_matrix_elements(n_u, n_l, Z, B, quadratic_zeeman=True, fine_structure=True, A=1, use_empirical_data=False, atom='H')[source]
Return transition dipole matrices between the eigenstate bases of n_u and n_l.
Diagonalizes the Hamiltonian for both shells and rotates the uncoupled dipole matrices D_q into the eigenstate basis:
d_q[i, j] = ⟨ψ_l^j | T_q^(1) | ψ_u^i⟩
where ψ_u^i and ψ_l^j are the i-th upper and j-th lower eigenstates.
- 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].quadratic_zeeman (
bool, optional) – Include diamagnetic Zeeman term (default True).fine_structure (
bool, optional) – Include MV + Darwin corrections (default True).use_empirical_data (
bool, optional) – If True, injects precise empirical field-free energies.atom (
str, optional) – Element symbol used to fetch empirical data.
- Returns:
eigenvalues_u (
ndarray,shape (2n_u²,)) – Upper-shell energy eigenvalues [eV].eigenvalues_l (
ndarray,shape (2n_l²,)) – Lower-shell energy eigenvalues [eV].d_elements (
dict) – Keys are q ∈ {0, 1, −1}. Values are complex arrays of shape (2n_u², 2n_l²) whered_elements[q][i, j]is the dipole matrix element between upper eigenstate i and lower eigenstate j.
- starkzee.radiator.line_strength(n_u, n_l, Z)[source]
Compute the line strength S_ul = Σ_{q,i,j}
|⟨l_j|r_q|u_i⟩|²in a₀².Sums over all polarizations q ∈ {0,±1}, all uncoupled upper states i, and all lower states j, restricted to Δl = ±1 and Δms = 0 (dipole selection rules). Fine structure mixing is neglected (field-free, B = 0 limit with the states labeled by
|n, l, ml, ms⟩).The profile returned by calculate_static_profile integrates to approximately S_ul at B = 0 and Ne → 0. The Gauss-Legendre weights over the microfield angle [0, 1] sum to 1 and the microfield distribution is normalized to 1, so the total quadrature weight is unity.
- Returns:
S_ul (float): line strength in a₀²
- starkzee.radiator.oscillator_strength(n_u, n_l, Z)[source]
Compute the weighted absorption oscillator strength gf = g_l × f_lu.
Uses: gf = (2/3) × (ΔE / E_hartree) × S_ul
where E_hartree = 2 × RYDBERG_EV ≈ 27.211 eV, g_l = 2n_l² is the statistical weight of the lower shell, and S_ul is the total line strength (a₀²) summed over all allowed Δl = ±1 pairs.
The result is independent of Z for hydrogen-like ions (the Z-dependence of ΔE ∝ Z² and S_ul ∝ Z⁻² cancel exactly).
Convention matches NIST ASD for full shell-to-shell transitions (e.g. Hα, Hβ). For Lyman series (n_l = 1) only l_u = 1 upper states contribute, so gf is the weighted oscillator strength for the specific 2p/3p/… level.
- Returns:
gf (float): dimensionless weighted oscillator strength
- starkzee.radiator.einstein_a(n_u, n_l, Z)[source]
Compute the Einstein A coefficient for spontaneous emission, in s⁻¹.
Uses the atomic-unit formula:
A_ul = (4α³/3) × (ΔE/E_hartree)³ × S_ul / (2n_u²) / τ_au
where α is the fine-structure constant, τ_au = ħ/E_hartree ≈ 2.419 × 10⁻¹⁷ s is the atomic unit of time, and g_u = 2n_u² is the full upper-shell statistical weight (NIST convention: all 2n_u² substates, including any non-radiating ones).
This gives the shell-averaged spontaneous emission rate: the total Ly-α photon emission rate from a uniformly populated n=2 level equals n_{n=2} × einstein_a(2, 1, Z). For NIST’s level-specific A coefficient (e.g. A(2p→1s) using g_k = 6), multiply by 2n_u² / g_participating, where g_participating = Σ_{l_u that have an allowed lower state} 2(2l_u+1).
- Returns:
A_ul (float): spontaneous emission rate in s⁻¹