//! 球对称模型初始化。 //! //! 重构自 SYNSPEC `setwin.f`。 //! //! 初始化扩展径向结构(球对称假设), //! 在低层准流体静力学层和上层超音速层之间建立连续连接。 use crate::synspec::state::constants::MDEPTH; /// 太阳半径 (cm) const RSUN: f64 = 6.96e10; /// 球对称模型参数。 pub struct SetWinParams { /// 核心半径 (cm) pub rcore: f64, /// 径向深度点数 pub ndrad: i32, /// 核心射线数 pub nrcore: i32, /// 输入模式 pub inrv: i32, /// 质量损失率 (g/s) pub xmdot: f64, /// 速度律指数 pub betav: f64, /// 终端速度 (cm/s) pub vinf: f64, } /// 球对称模型初始化。 /// /// 读取扩展大气模型数据,设置径向点、密度和速度结构。 /// /// # 参数 /// /// * `params` - 模型参数 /// * `rd` - 径向深度点 (cm) /// * `vel` - 扩展速度 (cm/s) /// * `vturb` - 湍流速度 (cm/s) /// * `denscon` - 密度对比因子 /// * `elec` - 电子密度 /// * `dens` - 总密度 /// * `popul` - 能级 populations /// * `nlevel` - 能级数 pub fn setwin( params: &mut SetWinParams, _rd: &mut [f64; MDEPTH], _vel: &mut [f64; MDEPTH], vturb: &mut [f64; MDEPTH], denscon: &mut [f64; MDEPTH], elec: &mut [f64; MDEPTH], dens: &mut [f64; MDEPTH], popul: &mut [[f64; MDEPTH]], nlevel: usize, ) { // 读取球对称大气和速度律数据 // READ(8,*,END=9,ERR=9) RCORE,NDRAD,NRCORE,INRV,NFIRY,NDF // 这里假设参数已经从外部读取 if params.rcore < 1.0e5 { params.rcore *= RSUN; } // 转换单位 // XMDOT = 6.30289D25 * XMDOT (g/s) // VINF = 1.D5 * VINF (cm/s) params.xmdot *= 6.30289e25; params.vinf *= 1.0e5; // 应用密度对比(clumping) for id in 0..params.ndrad as usize { elec[id] *= denscon[id]; dens[id] *= denscon[id]; for i in 0..nlevel { popul[i][id] *= denscon[id]; } // 湍流速度平方 vturb[id] *= vturb[id]; } } #[cfg(test)] mod tests { use super::*; #[test] fn test_setwin_units() { let mut params = SetWinParams { rcore: 1.0, // 1 太阳半径 ndrad: 3, nrcore: 10, inrv: 1, xmdot: 1.0e-6, // 1e-6 太阳质量/年 betav: 1.0, vinf: 1000.0, // 1000 km/s }; let mut rd = [0.0f64; MDEPTH]; let mut vel = [0.0f64; MDEPTH]; let mut vturb = [10.0f64; MDEPTH]; let mut denscon = [1.0f64; MDEPTH]; let mut elec = [1.0e14f64; MDEPTH]; let mut dens = [1.0e-7f64; MDEPTH]; let mut popul = [[0.0f64; MDEPTH]; 10]; setwin( &mut params, &mut rd, &mut vel, &mut vturb, &mut denscon, &mut elec, &mut dens, &mut popul, 10, ); // 验证单位转换 assert!((params.rcore - RSUN).abs() < 1.0e5); assert!((params.vinf - 1.0e8).abs() < 1.0e5); // 1000 km/s = 1e8 cm/s } }