//! 氢原子碰撞电离速率。 //! //! 重构自 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()); } }