203 lines
6.4 KiB
Rust
203 lines
6.4 KiB
Rust
//! 特殊吸收轮廓类型判断。
|
|
//!
|
|
//! 重构自 SYNSPEC `ispec.f`
|
|
//!
|
|
//! 用于判断给定谱线是否使用特殊的预计算吸收轮廓(仅氢和氦)。
|
|
|
|
/// 特殊轮廓类型常量
|
|
pub const PROFILE_VOIGT: i32 = 0; // 普通 Voigt 轮廓
|
|
pub const PROFILE_HYDROGEN: i32 = 1; // 氢线
|
|
// He I 特殊轮廓 (2-5)
|
|
pub const PROFILE_HEI_4471: i32 = 2; // He I 447.1 nm
|
|
pub const PROFILE_HEI_4388: i32 = 3; // He I 438.8 nm
|
|
pub const PROFILE_HEI_4026: i32 = 4; // He I 402.6 nm
|
|
pub const PROFILE_HEI_4922: i32 = 5; // He I 492.2 nm
|
|
// He II 特殊轮廓 (6-24)
|
|
pub const PROFILE_HEII_1640: i32 = 6;
|
|
pub const PROFILE_HEII_3203: i32 = 7;
|
|
pub const PROFILE_HEII_2733: i32 = 8;
|
|
pub const PROFILE_HEII_2511: i32 = 9;
|
|
pub const PROFILE_HEII_2385: i32 = 10;
|
|
pub const PROFILE_HEII_2306: i32 = 11;
|
|
pub const PROFILE_HEII_2253: i32 = 12;
|
|
pub const PROFILE_HEII_4686: i32 = 13;
|
|
pub const PROFILE_HEII_4859: i32 = 14;
|
|
pub const PROFILE_HEII_4542: i32 = 15;
|
|
pub const PROFILE_HEII_4339: i32 = 16;
|
|
pub const PROFILE_HEII_4200: i32 = 17;
|
|
pub const PROFILE_HEII_4100: i32 = 18;
|
|
pub const PROFILE_HEII_4026: i32 = 19;
|
|
pub const PROFILE_HEII_3968: i32 = 20;
|
|
pub const PROFILE_HEII_3923: i32 = 21;
|
|
pub const PROFILE_HEII_10124: i32 = 22;
|
|
pub const PROFILE_HEII_6560: i32 = 23;
|
|
pub const PROFILE_HEII_5412: i32 = 24;
|
|
|
|
/// 判断谱线是否使用特殊吸收轮廓。
|
|
///
|
|
/// # 参数
|
|
///
|
|
/// * `iat` - 原子序数 (1=H, 2=He, ...)
|
|
/// * `ion` - 电离态 (1=中性, 2=一次电离, ...)
|
|
/// * `alam` - 波长 (nm)
|
|
/// * `ihe1pr` - He I 特殊轮廓标志 (>0 表示启用)
|
|
/// * `ihe2pr` - He II 特殊轮廓标志 (>0 表示启用)
|
|
///
|
|
/// # 返回值
|
|
///
|
|
/// * `0` - 普通 Voigt 轮廓
|
|
/// * `>0` - 特殊轮廓类型(见常量定义)
|
|
pub fn ispec(iat: i32, ion: i32, alam: f64, ihe1pr: i32, ihe2pr: i32) -> i32 {
|
|
// 非氢氦元素返回 0
|
|
if iat > 2 {
|
|
return PROFILE_VOIGT;
|
|
}
|
|
|
|
if iat == 1 {
|
|
// 氢线
|
|
return PROFILE_HYDROGEN;
|
|
}
|
|
|
|
// 氦线
|
|
if ion == 1 {
|
|
// He I
|
|
if (alam - 447.1).abs() < 0.5 && ihe1pr > 0 {
|
|
return PROFILE_HEI_4471;
|
|
}
|
|
if (alam - 438.8).abs() < 0.2 && ihe1pr > 0 {
|
|
return PROFILE_HEI_4388;
|
|
}
|
|
if (alam - 402.6).abs() < 0.2 && ihe1pr > 0 {
|
|
return PROFILE_HEI_4026;
|
|
}
|
|
if (alam - 492.2).abs() < 0.2 && ihe1pr > 0 {
|
|
return PROFILE_HEI_4922;
|
|
}
|
|
} else {
|
|
// He II
|
|
// 波长范围检查
|
|
if alam < 163.0 || alam > 1012.7 {
|
|
return PROFILE_VOIGT;
|
|
}
|
|
|
|
if alam < 321.0 {
|
|
if (alam - 164.0).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_1640;
|
|
}
|
|
if (alam - 320.3).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_3203;
|
|
}
|
|
if (alam - 273.3).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_2733;
|
|
}
|
|
if (alam - 251.1).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_2511;
|
|
}
|
|
if (alam - 238.5).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_2385;
|
|
}
|
|
if (alam - 230.6).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_2306;
|
|
}
|
|
if (alam - 225.3).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_2253;
|
|
}
|
|
} else if alam < 541.0 {
|
|
if alam < 392.3 {
|
|
return PROFILE_VOIGT;
|
|
}
|
|
if (alam - 468.6).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_4686;
|
|
}
|
|
if (alam - 485.9).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_4859;
|
|
}
|
|
if (alam - 454.2).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_4542;
|
|
}
|
|
if (alam - 433.9).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_4339;
|
|
}
|
|
if (alam - 420.0).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_4200;
|
|
}
|
|
if (alam - 410.0).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_4100;
|
|
}
|
|
if (alam - 402.6).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_4026;
|
|
}
|
|
if (alam - 396.8).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_3968;
|
|
}
|
|
if (alam - 392.3).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_3923;
|
|
}
|
|
} else {
|
|
if (alam - 1012.4).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_10124;
|
|
}
|
|
if (alam - 656.0).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_6560;
|
|
}
|
|
if (alam - 541.2).abs() < 0.2 && ihe2pr > 0 {
|
|
return PROFILE_HEII_5412;
|
|
}
|
|
}
|
|
}
|
|
|
|
PROFILE_VOIGT
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_hydrogen() {
|
|
// 氢线总是返回 1
|
|
assert_eq!(ispec(1, 1, 656.3, 0, 0), PROFILE_HYDROGEN);
|
|
assert_eq!(ispec(1, 1, 486.1, 0, 0), PROFILE_HYDROGEN);
|
|
}
|
|
|
|
#[test]
|
|
fn test_other_elements() {
|
|
// 非氢氦元素返回 0
|
|
assert_eq!(ispec(3, 1, 670.8, 1, 1), PROFILE_VOIGT); // Li
|
|
assert_eq!(ispec(26, 1, 500.0, 1, 1), PROFILE_VOIGT); // Fe
|
|
}
|
|
|
|
#[test]
|
|
fn test_he_i_lines() {
|
|
// He I 线,启用特殊轮廓
|
|
assert_eq!(ispec(2, 1, 447.1, 1, 0), PROFILE_HEI_4471);
|
|
assert_eq!(ispec(2, 1, 438.8, 1, 0), PROFILE_HEI_4388);
|
|
assert_eq!(ispec(2, 1, 402.6, 1, 0), PROFILE_HEI_4026);
|
|
assert_eq!(ispec(2, 1, 492.2, 1, 0), PROFILE_HEI_4922);
|
|
|
|
// 禁用特殊轮廓
|
|
assert_eq!(ispec(2, 1, 447.1, 0, 0), PROFILE_VOIGT);
|
|
}
|
|
|
|
#[test]
|
|
fn test_he_ii_lines() {
|
|
// He II 线,启用特殊轮廓
|
|
assert_eq!(ispec(2, 2, 164.0, 0, 1), PROFILE_HEII_1640);
|
|
assert_eq!(ispec(2, 2, 468.6, 0, 1), PROFILE_HEII_4686);
|
|
assert_eq!(ispec(2, 2, 541.2, 0, 1), PROFILE_HEII_5412);
|
|
|
|
// 禁用特殊轮廓
|
|
assert_eq!(ispec(2, 2, 468.6, 0, 0), PROFILE_VOIGT);
|
|
}
|
|
|
|
#[test]
|
|
fn test_he_ii_wavelength_ranges() {
|
|
// 超出波长范围
|
|
assert_eq!(ispec(2, 2, 150.0, 0, 1), PROFILE_VOIGT); // < 163
|
|
assert_eq!(ispec(2, 2, 1100.0, 0, 1), PROFILE_VOIGT); // > 1012.7
|
|
|
|
// 321-392.3 范围内没有特殊轮廓
|
|
assert_eq!(ispec(2, 2, 350.0, 0, 1), PROFILE_VOIGT);
|
|
}
|
|
}
|