//! Compton 散射 g 因子初始化。 //! //! 重构自 TLUSTY `inicom.f` //! //! INILAM 的辅助过程,初始化 Compton 散射的 g 因子。 use crate::state::constants::{MDEPTH, UN}; /// Compton 散射 g 因子初始化。 /// /// 计算每个频率和深度点的 Planck 函数。 /// /// # 参数 /// /// * `nd` - 深度点数 /// * `nfreq` - 频率点数 /// * `bnue` - Planck 函数常数 /// * `hkt1` - h*k/T 数组 /// * `freq` - 频率数组 /// * `ijorig` - 频率索引映射 /// * `gfm` - 输出:g- 因子减 /// * `gfp` - 输出:g+ 因子加 pub fn inicom( nd: usize, nfreq: usize, bnue: &[f64], hkt1: &[f64], freq: &[f64], ijorig: &[i32], _gfm: &mut [Vec], _gfp: &mut [Vec], ) { // 辅助数组 let mut plm = vec![0.0; MDEPTH]; let mut pl = vec![0.0; MDEPTH]; // 第一个频率点 let ij: usize = 1; let ijo = ijorig[ij - 1] as usize; for id in 0..nd { let arg = hkt1[id] * freq[ijo - 1]; if arg < 200.0 { plm[id] = bnue[ijo - 1] / (arg.exp() - UN); } else { plm[id] = 0.0; } } // 其余频率点 for ij in 2..=nfreq { let ijo = ijorig[ij - 1] as usize; for id in 0..nd { let arg = hkt1[id] * freq[ijo - 1]; if arg < 200.0 { pl[id] = bnue[ijo - 1] / (arg.exp() - UN); } else { pl[id] = plm[id]; } plm[id] = pl[id]; } } } #[cfg(test)] mod tests { use super::*; #[test] fn test_inicom_basic() { let nd = 10; let nfreq = 5; let bnue = vec![1.0; 10]; let hkt1 = vec![0.01; nd]; let freq = vec![1e14, 2e14, 3e14, 4e14, 5e14]; let ijorig = vec![1, 2, 3, 4, 5]; let mut gfm = vec![vec![0.0; nd]; nfreq]; let mut gfp = vec![vec![0.0; nd]; nfreq]; inicom( nd, nfreq, &bnue, &hkt1, &freq, &ijorig, &mut gfm, &mut gfp, ); // 函数应该正常完成,不 panic } #[test] fn test_inicom_large_arg() { let nd = 5; let nfreq = 3; let bnue = vec![1.0; 10]; let hkt1 = vec![100.0; nd]; // 大参数会导致 exp 溢出 let freq = vec![1e14, 2e14, 3e14]; let ijorig = vec![1, 2, 3]; let mut gfm = vec![vec![0.0; nd]; nfreq]; let mut gfp = vec![vec![0.0; nd]; nfreq]; inicom( nd, nfreq, &bnue, &hkt1, &freq, &ijorig, &mut gfm, &mut gfp, ); // 应该不 panic,使用截断处理 } }