//! 特殊吸收轮廓类型判断。 //! //! 重构自 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); } }