109 lines
2.6 KiB
Rust
109 lines
2.6 KiB
Rust
//! 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,使用截断处理
|
||
}
|
||
}
|