SpectraRust/src/math/inicom.rs
2026-03-21 09:12:18 +08:00

109 lines
2.6 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.

//! 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<f64>],
_gfp: &mut [Vec<f64>],
) {
// 辅助数组
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使用截断处理
}
}