120 lines
3.3 KiB
Rust
120 lines
3.3 KiB
Rust
//! 氢原子碰撞电离速率。
|
||
//!
|
||
//! 重构自 TLUSTY `irc.f`
|
||
//!
|
||
//! 基于 Johnson (1972)。
|
||
|
||
use crate::tlusty::math::{expinx, szirc};
|
||
|
||
// f2r_depends: EXPINX, SZIRC
|
||
|
||
/// 氢原子碰撞电离激发速率。
|
||
///
|
||
/// 计算从状态 N 由于电子碰撞导致的氢原子电离激发速率。
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `n` - 主量子数
|
||
/// * `t` - 温度 (K)
|
||
/// * `ic` - 电荷 (1 = H)
|
||
/// * `rno` - 连续谱起始能级
|
||
///
|
||
/// # 返回值
|
||
///
|
||
/// 激发速率 SE (cm³/s)。
|
||
///
|
||
/// # 备注
|
||
///
|
||
/// 基于 Johnson (1972)。
|
||
/// Tim Kallman 的 XSTAR 程序的修改版本。
|
||
pub fn irc(n: i32, t: f64, ic: i32, rno: f64) -> f64 {
|
||
// 非 H 原子调用 szirc
|
||
if ic != 1 {
|
||
return szirc(n as usize, t, ic, rno);
|
||
}
|
||
|
||
let nf = n as f64;
|
||
let xo = 1.0 - nf * nf / rno / rno;
|
||
let yn = xo * 157803.0 / (t * nf * nf);
|
||
|
||
let (an, bn, rn) = if n <= 1 {
|
||
let an = 1.9603 * nf
|
||
* (1.133 / 3.0 / xo.powi(3) - 0.4059 / 4.0 / xo.powi(4) + 0.07014 / 5.0 / xo.powi(5));
|
||
let bn = 2.0 / 3.0 * nf * nf / xo * (3.0 + 2.0 / xo - 0.603 / (xo * xo));
|
||
let rn = 0.45;
|
||
(an, bn, rn)
|
||
} else if n == 2 {
|
||
let an = 1.9603 * nf
|
||
* (1.0785 / 3.0 / xo.powi(3) - 0.2319 / 4.0 / xo.powi(4) + 0.02947 / 5.0 / xo.powi(5));
|
||
let bn = (4.0 - 18.63 / nf + 36.24 / (nf * nf) - 28.09 / (nf * nf * nf)) / nf;
|
||
let bn = 2.0 / 3.0 * nf * nf / xo * (3.0 + 2.0 / xo + bn / (xo * xo));
|
||
let rn = 0.653;
|
||
(an, bn, rn)
|
||
} else {
|
||
let g0 = (0.9935 + 0.2328 / nf - 0.1296 / (nf * nf)) / 3.0 / xo.powi(3);
|
||
let g1 = -(0.6282 - 0.5598 / nf + 0.5299 / (nf * nf)) / (nf * 4.0) / xo.powi(4);
|
||
let g2 = (0.3887 - 1.181 / nf + 1.470 / (nf * nf)) / (nf * nf * 5.0) / xo.powi(5);
|
||
let an = 1.9603 * nf * (g0 + g1 + g2);
|
||
let bn = (4.0 - 18.63 / nf + 36.24 / (nf * nf) - 28.09 / (nf * nf * nf)) / nf;
|
||
let bn = (3.0 + 2.0 / xo + bn / (xo * xo)) * 2.0 * nf * nf / 3.0 / xo;
|
||
let rn = 1.94 * nf.powf(-1.57);
|
||
(an, bn, rn)
|
||
};
|
||
|
||
let rn = rn * xo;
|
||
let zn = rn + yn;
|
||
|
||
let ey = expinx(yn);
|
||
let ez = expinx(zn);
|
||
|
||
let mut se = an * (ey / (yn * yn) - (-rn).exp() * ez / (zn * zn));
|
||
|
||
let ey = 1.0 + 1.0 / yn - ey * (2.0 / yn + 1.0);
|
||
let ez = (-rn).exp() * (1.0 + 1.0 / zn - ez * (2.0 / zn + 1.0));
|
||
|
||
se = se + (bn - an * (2.0 * nf * nf / xo).ln()) * (ey - ez);
|
||
se = se * t.sqrt() * yn * yn * nf * nf * 1.095e-10 / xo;
|
||
|
||
se
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
#[test]
|
||
fn test_irc_hydrogen_n1() {
|
||
// H I 从 n=1 电离,rno > n² = 1
|
||
let result = irc(1, 10000.0, 1, 2.0);
|
||
assert!(result.is_finite());
|
||
}
|
||
|
||
#[test]
|
||
fn test_irc_hydrogen_n2() {
|
||
// H I 从 n=2 电离,rno > n² = 4
|
||
let result = irc(2, 10000.0, 1, 5.0);
|
||
assert!(result.is_finite());
|
||
}
|
||
|
||
#[test]
|
||
fn test_irc_hydrogen_n3() {
|
||
// H I 从 n=3 电离,rno > n² = 9
|
||
let result = irc(3, 10000.0, 1, 10.0);
|
||
assert!(result.is_finite());
|
||
}
|
||
|
||
#[test]
|
||
fn test_irc_hydrogen_high_temp() {
|
||
// 高温
|
||
let result = irc(1, 50000.0, 1, 2.0);
|
||
assert!(result.is_finite());
|
||
}
|
||
|
||
#[test]
|
||
fn test_irc_non_hydrogen() {
|
||
// 非 H 原子 (调用 szirc)
|
||
let result = irc(1, 10000.0, 2, 2.0);
|
||
assert!(result.is_finite());
|
||
}
|
||
}
|