SpectraRust/src/tlusty/math/hydrogen/hephot.rs
2026-04-01 16:35:36 +08:00

88 lines
2.5 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! 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);
}
}