//! Stark 轮廓辅助函数。 //! //! 重构自 TLUSTY `stark0.f` /// Stark 轮廓辅助参数计算。 /// /// 计算氢线近似 Stark 轮廓所需的频率无关参数。 /// /// # 参数 /// /// * `i` - 下能级主量子数 /// * `j` - 上能级主量子数 /// * `izz` - 离子电荷 (1 为氢) /// /// # 返回值 /// /// (xkij, wl0, fij) 元组: /// - xkij: Holtsmark 轮廓的 K(i,j) 系数 /// - wl0: 谱线波长 /// - fij: Stark f 值 /// /// # 备注 /// /// j≤6 时使用精确值,更高时使用渐近公式。 pub fn stark0(i: usize, j: usize, izz: usize) -> (f64, f64, f64) { const RYD1: f64 = 911.763811; const RYD2: f64 = 911.495745 / 4.0; const CXKIJ: f64 = 5.5e-5; const WI1: f64 = 911.753578; const WI2: f64 = 227.837832; // XKIJ 表格 (5 x 4) const XKIJT: [[f64; 4]; 5] = [ [3.56e-4, 0.0125, 0.124, 0.683], [5.23e-4, 0.0177, 0.171, 0.866], [1.09e-3, 0.028, 0.223, 1.02], [1.49e-3, 0.0348, 0.261, 1.19], [2.25e-3, 0.0493, 0.342, 1.46], ]; // FSTARK 表格 (10 x 4) const FSTARK: [[f64; 4]; 10] = [ [0.1387, 0.3921, 0.6103, 0.8163], [0.0791, 0.1193, 0.1506, 0.1788], [0.02126, 0.03766, 0.04931, 0.05985], [0.01394, 0.02209, 0.02768, 0.03189], [0.00642, 0.01139, 0.01485, 0.01762], [4.814e-3, 8.036e-3, 0.01023, 0.01196], [2.779e-3, 5.007e-3, 6.588e-3, 7.825e-3], [2.216e-3, 3.85e-3, 4.996e-3, 5.882e-3], [1.443e-3, 2.658e-3, 3.524e-3, 4.233e-3], [1.201e-3, 2.151e-3, 2.838e-3, 3.375e-3], ]; let ii = (i * i) as f64; let jj = (j * j) as f64; let jmin = j - i; // 计算 XKIJ let xkij = if jmin <= 5 { XKIJT[jmin - 1][i - 1] } else { CXKIJ * (ii * jj) * (ii * jj) / (jj - ii) }; // 计算 FIJ let fij = if jmin <= 10 { FSTARK[jmin - 1][i - 1] } else { let cfij = ((20.0 * i as f64 + 100.0) * j as f64) / ((i as f64 + 10.0) * (jj - ii)); FSTARK[9][i - 1] * cfij * cfij * cfij }; // 计算波长 let wl0_base = if izz == 2 { WI2 } else { WI1 }; let wl0 = wl0_base / (1.0 / ii - 1.0 / jj); (xkij, wl0, fij) } #[cfg(test)] mod tests { use super::*; #[test] fn test_stark0_h_alpha() { // H-alpha: i=2, j=3 let (xkij, wl0, fij) = stark0(2, 3, 1); assert!(xkij > 0.0); assert!(wl0 > 0.0); assert!(fij > 0.0); } #[test] fn test_stark0_h_beta() { // H-beta: i=2, j=4 let (xkij, wl0, fij) = stark0(2, 4, 1); assert!(xkij > 0.0); assert!(wl0 > 0.0); assert!(fij > 0.0); } #[test] fn test_stark0_he_ii() { // He II: izz=2 let (xkij, wl0, fij) = stark0(2, 3, 2); assert!(xkij > 0.0); assert!(wl0 > 0.0); assert!(fij > 0.0); } #[test] fn test_stark0_high_j() { // j > 6 使用渐近公式 let (xkij, wl0, fij) = stark0(2, 10, 1); assert!(xkij > 0.0); assert!(wl0 > 0.0); assert!(fij > 0.0); } #[test] fn test_stark0_jmin_gt_10() { // j - i > 10 let (xkij, wl0, fij) = stark0(2, 15, 1); assert!(xkij > 0.0); assert!(wl0 > 0.0); assert!(fij > 0.0); } }