SpectraRust/src/synspec/math/hylsew.rs
fmq e2c1a4580a feat: F2R 重构全部完成 + 自动化脚本改进
Phase 1 翻译 (完成):
- TLUSTY 350 函数 100% 翻译
- SYNSPEC 168 函数 100% 翻译
- ~495 Rust 模块

Phase 2 集成 (完成):
- TLUSTY RESOLV 7 个 TODO 全部清除
- TLUSTY Runner IJALI 频率选择实现
- OPFRAC ioniz.dat 解析完整实现
- SYNSPEC Runner 编排流程连接完成
- SYNSPEC RESOLV OPAC→RTE→OUTPRI 调用链完整

Phase 3 验证 (完成, 修复 8 处 bug):
- INITIA: compute_hydrogen_level_bounds 索引混合修复
- INILIN: GAMR0/GS0/GW0 展宽公式修复, 经典 VdW 公式修复
- INIBL0: CNM 常数 2.997925e18→e17 修复
- OPAC: Lyman IJ=2 修正缺失修复
- RTE: minv3 矩阵求逆符号错误修复

自动化脚本改进:
- specf2r.sh: 添加 429 限流退避、完成检测、同步等待
- SKILL.md: 三阶段工作流 + 状态文件系统
- references/: Phase 1/2/3 独立参考文档

新增:
- src/bin/synspec.rs: SYNSPEC 可执行文件入口
- .f2r_phase/.f2r_tasks/.f2r_complete: 状态管理文件

编译: 0 错误 | Clippy: 0 错误 | 测试: voigt 28 + eldens 5 通过

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 14:54:53 +08:00

137 lines
3.1 KiB
Rust

//! SYNSPEC 氢线窗口初始化。
//!
//! 重构自 SYNSPEC 54 的 HYLSEW 子程序。
/// 氢线窗口参数
#[derive(Debug, Clone)]
pub struct HylsewOutput {
/// 是否包含氢线 (0=否, 1=是)
pub ihylw: i32,
/// 线数参数
pub m20w: i32,
/// 最低主量子数索引
pub ilowhw: i32,
/// 线翼参数
pub m10w: i32,
}
/// 初始化氢线处理窗口。
///
/// 根据频率和重力加速度判断是否包含氢线,并设置相关参数。
///
/// # Arguments
/// * `ij` - 频率索引
/// * `freq` - 频率值 (Hz)
/// * `grav` - 重力加速度 (log g)
///
/// # Returns
/// 氢线窗口参数
pub fn hylsew(_ij: usize, freq: f64, grav: f64) -> HylsewOutput {
let mut output = HylsewOutput {
ihylw: 0,
m20w: 0,
ilowhw: 0,
m10w: 0,
};
// 检查频率是否在氢线范围内
if freq >= 3.28805e15 {
return output;
}
let al0 = 2.997925e17 / freq;
let al1 = al0;
// 根据重力加速度检查波长范围
if grav < 6.0 {
if al0 > 160.0 && al1 < 364.6 {
return output;
}
if al0 > 506.0 && al1 < 630.0 {
return output;
}
if al0 > 680.0 && al1 < 820.3 {
return output;
}
} else {
if al0 > 540.0 && al1 < 600.0 {
return output;
}
if al0 > 720.0 && al1 < 820.3 {
return output;
}
}
// 包含氢线
output.ihylw = 1;
output.m20w = 40;
// 确定最低主量子数
let frion = if al1 < 364.6 {
output.ilowhw = 1;
3.28805e15
} else if al1 < 820.0 {
output.ilowhw = 2;
8.2225e14
} else if al1 < 1458.0 {
output.ilowhw = 3;
3.6544142e14
} else if al1 < 2278.0 {
output.ilowhw = 4;
2.0555837e14
} else if al1 < 3281.0 {
output.ilowhw = 5;
1.315589e14
} else if al1 < 4466.0 {
output.ilowhw = 6;
9.136394e13
} else {
output.ilowhw = 7;
6.7120228e13
};
// 计算线翼参数
if frion > freq {
output.m10w = (3.289017e15 / (frion - freq).abs()).sqrt() as i32;
}
output
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_hylsew_high_freq() {
// 频率太高,不包含氢线
let result = hylsew(1, 4.0e15, 4.0);
assert_eq!(result.ihylw, 0);
}
#[test]
fn test_hylsew_lyman_region() {
// Lyman 系区域
let result = hylsew(1, 3.0e15, 4.0);
assert_eq!(result.ihylw, 1);
assert_eq!(result.ilowhw, 1);
}
#[test]
fn test_hylsew_balmer_region() {
// Balmer 系区域 (500 Å,在 Lyman 极限和 Balmer 极限之间)
let freq = 2.997925e17 / 500.0;
let result = hylsew(1, freq, 4.0);
assert_eq!(result.ihylw, 1);
assert_eq!(result.ilowhw, 2);
}
#[test]
fn test_hylsew_high_gravity() {
// 高重力情况
let freq = 2.997925e17 / 550.0;
let result = hylsew(1, freq, 7.0);
assert_eq!(result.ihylw, 0);
}
}