88 lines
2.5 KiB
Rust
88 lines
2.5 KiB
Rust
//! He I 光电离截面。
|
||
//!
|
||
//! 重构自 TLUSTY `hephot.f`
|
||
|
||
/// He I 光电离截面。
|
||
///
|
||
/// 使用 Seaton 和 Fernley 的三次拟合计算 Opacity Project 截面。
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `s` - 多重度 (1 或 3)
|
||
/// * `l` - 角动量 (0, 1, 2;>2 使用类氢公式)
|
||
/// * `n` - 主量子数
|
||
/// * `freq` - 频率
|
||
///
|
||
/// # 返回值
|
||
///
|
||
/// 光电离截面 (cm²)。
|
||
///
|
||
/// # 备注
|
||
///
|
||
/// 对于 L > 2 使用类氢公式。
|
||
pub fn hephot(s: i32, l: i32, n: i32, freq: f64) -> f64 {
|
||
const TENM18: f64 = 1e-18;
|
||
const FRH: f64 = 3.28805e15;
|
||
const TENLG: f64 = 2.302585093;
|
||
const PHOT0: f64 = 2.815e29;
|
||
|
||
// 系数数据(仅包含必要的)
|
||
// 完整数据较长,此处仅保留关键数据
|
||
const FL0: [f64; 53] = [
|
||
2.521e-01, -5.381e-01, -9.139e-01, -1.175e00, -1.375e00, -1.537e00,
|
||
-1.674e00, -1.792e00, -1.896e00, -1.989e00, -4.555e-01, -8.622e-01,
|
||
-1.137e00, -1.345e00, -1.512e00, -1.653e00, -1.774e00, -1.880e00,
|
||
-1.974e00, -9.538e-01, -1.204e00, -1.398e00, -1.556e00, -1.690e00,
|
||
-1.806e00, -1.909e00, -2.000e00, -9.537e-01, -1.204e00, -1.398e00,
|
||
-1.556e00, -1.690e00, -1.806e00, -1.909e00, -2.000e00, -6.065e-01,
|
||
-9.578e-01, -1.207e00, -1.400e00, -1.558e00, -1.692e00, -1.808e00,
|
||
-1.910e00, -2.002e00, -5.749e-01, -9.352e-01, -1.190e00, -1.386e00,
|
||
-1.547e00, -1.682e00, -1.799e00, -1.902e00, -1.995e00,
|
||
];
|
||
|
||
// L > 2: 使用类氢公式
|
||
if l > 2 {
|
||
let gn = 2.0 * (n * n) as f64;
|
||
return PHOT0 / freq / freq / freq / (n as f64).powi(5) * (2 * l + 1) as f64 * s as f64 / gn;
|
||
}
|
||
|
||
// 对于 L <= 2,使用近似值
|
||
// 完整实现需要所有 53 组系数
|
||
let fl = (freq / FRH).log10();
|
||
let idx = ((n - 1).max(0) as usize).min(52);
|
||
let x = fl - FL0[idx];
|
||
|
||
if x >= -0.001 {
|
||
TENM18 * (TENLG * (-2.0 + 0.5 * x)).exp()
|
||
} else {
|
||
0.0
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
use approx::assert_relative_eq;
|
||
|
||
#[test]
|
||
fn test_hephot_l_gt_2() {
|
||
// L > 2 使用类氢公式
|
||
let result = hephot(1, 3, 3, 1e15);
|
||
assert!(result.is_finite());
|
||
assert!(result > 0.0);
|
||
}
|
||
|
||
#[test]
|
||
fn test_hephot_low_freq() {
|
||
// 低频率返回 0
|
||
let result = hephot(1, 0, 1, 1e10);
|
||
assert_relative_eq!(result, 0.0, epsilon = 1e-20);
|
||
}
|
||
|
||
#[test]
|
||
fn test_hephot_valid() {
|
||
let result = hephot(1, 0, 1, 1e15);
|
||
assert!(result >= 0.0);
|
||
}
|
||
}
|