//! 光致电离截面插值(Hidalgo 1968)。 //! //! 重构自 SYNSPEC `hidalg.f` //! //! 使用 Hidalgo (1968, Ap. J., 153, 981) 的波长和光致电离截面数据表, //! 对给定频率进行线性插值。 /// 波长网格 1 (Å),用于 INDEX < 13 的物种 const WL1: [f64; 20] = [ 39.1, 80.9, 97.6, 100.1, 104.3, 107.2, 108.7, 111.9, 113.6, 115.4, 117.1, 119.0, 124.8, 126.9, 129.1, 131.3, 133.6, 136.0, 138.5, 141.1, ]; /// 波长网格 2 (Å),用于 INDEX >= 13 的物种 const WL2: [f64; 20] = [ 68.5, 80.9, 100.1, 120.9, 158.8, 165.7, 177.3, 190.6, 200.7, 206.2, 211.9, 218.0, 224.5, 231.3, 246.3, 0.0, 0.0, 0.0, 0.0, 0.0, ]; /// 光致电离截面数据 (Mbarn),20×24 矩阵(列优先存储) const SIG0: [[f64; 20]; 24] = [ [0.0; 20], // col 1 [ 0.0460, 0.2400, 0.3500, 0.3700, 0.4000, 0.4300, 0.4400, 0.4600, 0.4700, 0.4900, 0.5000, 0.5200, 0.5700, 0.6200, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ], // col 2 [0.0; 20], // col 3 [ 0.0092, 0.1000, 0.1900, 0.2100, 0.2300, 0.2500, 0.2600, 0.2900, 0.3000, 0.3200, 0.3400, 0.3500, 0.4100, 0.4300, 0.4500, 0.4800, 0.5000, 0.5300, 0.5600, 0.5900, ], // col 4 [ 0.3400, 0.4600, 0.6300, 0.7700, 0.9100, 1.080, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ], // col 5 [0.0; 20], // col 6 [ 0.0064, 0.1100, 0.2200, 0.4100, 0.9400, 1.000, 1.300, 1.600, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ], // col 7 [0.0; 20], // col 8 [ 0.0370, 0.0650, 0.1300, 0.2400, 0.5500, 0.6300, 0.7700, 0.9500, 1.100, 1.250, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ], // col 9 [0.0; 20], // col 10 [ 0.0220, 0.0390, 0.0800, 0.1500, 0.3500, 0.4000, 0.4900, 0.6200, 0.7200, 0.7800, 0.8500, 0.9300, 1.020, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ], // col 11 [0.0; 20], // col 12 [0.0; 20], // col 13 [0.0; 20], // col 14 [0.0; 20], // col 15 [0.0; 20], // col 16 [0.0; 20], // col 17 [0.0; 20], // col 18 [0.0; 20], // col 19 [0.0; 20], // col 20 [0.0; 20], // col 21 [0.0; 20], // col 22 [0.0; 20], // col 23 [0.0; 20], // col 24 ]; /// 光速 (cm/s) const C_LIGHT: f64 = 2.997925e18; /// 截面单位转换因子 (cm^2) const SIG_FACTOR: f64 = 1.0e-18; /// Hidalgo (1968) 光致电离截面插值。 /// /// 根据 Hidalgo 数据表,对给定频率进行线性插值。 /// /// # 参数 /// /// * `ib` - 物种标识(负值,`INDEX = -IB - 100`) /// * `fr` - 频率 (Hz) /// /// # 返回值 /// /// 光致电离截面 (cm^2) pub fn hidalg(ib: i32, fr: f64) -> f64 { let index = (-ib - 101) as usize; // 转为 0-indexed if index >= 24 { return 0.0; } // 根据 INDEX 选择波长网格和数据 let num = if index < 12 { 20 } else { 15 }; let wli = if index < 12 { &WL1 } else { &WL2 }; let sigs = &SIG0[index]; // 将频率转换为波长 (Å) let wlam = C_LIGHT / fr; // 查找插值区间 let mut il = 0; let mut ir = num - 1; for i in 0..num - 1 { if wlam >= wli[i] && wlam <= wli[i + 1] { il = i; ir = i + 1; break; } } // 线性插值 let mut sigm = if wli[ir] - wli[il] > 0.0 { (sigs[ir] - sigs[il]) * (wlam - wli[il]) / (wli[ir] - wli[il]) + sigs[il] } else { sigs[il] }; // 边界处理 if wlam <= wli[0] { sigm = sigs[0]; } if wlam >= wli[num - 1] { sigm = sigs[num - 1]; } sigm * SIG_FACTOR } #[cfg(test)] mod tests { use super::*; #[test] fn test_hidalg_in_range() { // 测试 H I (IB=-101, INDEX=0) 在有效波长范围内 // 100 Å 对应频率 let fr = C_LIGHT / 100.0; let result = hidalg(-101, fr); // H I 数据全为 0,所以结果应为 0 assert!(result >= 0.0); } #[test] fn test_hidalg_species_2() { // 测试物种 2 (IB=-102, INDEX=1) let fr = C_LIGHT / 50.0; // 50 Å let result = hidalg(-102, fr); assert!(result >= 0.0); assert!(result.is_finite()); } #[test] fn test_hidalg_invalid_index() { let result = hidalg(-125, C_LIGHT / 100.0); assert_eq!(result, 0.0); } #[test] fn test_hidalg_above_range() { // 高于波长范围时返回末值 let fr = C_LIGHT / 200.0; let result = hidalg(-102, fr); assert!(result >= 0.0); } }