重构1
This commit is contained in:
@@ -0,0 +1,250 @@
|
||||
//! ALI (加速 Lambda 迭代) 相关数组。
|
||||
//!
|
||||
//! 重构自 TLUSTY `ALIPAR.FOR`
|
||||
|
||||
use super::constants::*;
|
||||
|
||||
// ============================================================================
|
||||
// FIXALP - 固定 ALI 参数
|
||||
// ============================================================================
|
||||
|
||||
/// ALI 固定参数和数组。
|
||||
/// 对应 COMMON /FIXALP/
|
||||
///
|
||||
/// 包含大量辐射转移计算中间变量:
|
||||
/// - ABSO, EMIS, SCAT: 吸收/发射/散射系数
|
||||
/// - REIT, REIN, REIM, REIP: 辐射等效项
|
||||
/// - AREIT, AREIN, AREIM, AREIP: A 相关
|
||||
/// - HEIT, HEIN, HEIM, HEIP: He 相关
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FixAlp {
|
||||
// 频率相关 (MFREQ)
|
||||
/// 吸收系数
|
||||
pub abso: Vec<f64>,
|
||||
/// 发射系数
|
||||
pub emis: Vec<f64>,
|
||||
/// 散射系数
|
||||
pub scat: Vec<f64>,
|
||||
|
||||
// 深度相关 (MDEPTH)
|
||||
/// 辐射等效 - T 导数
|
||||
pub reit: Vec<f64>,
|
||||
/// 辐射等效 - N 导数
|
||||
pub rein: Vec<f64>,
|
||||
/// 辐射等效 - M 导数
|
||||
pub reim: Vec<f64>,
|
||||
|
||||
// 能级导数 (MLVEXP × MDEPTH)
|
||||
pub reip: Vec<Vec<f64>>,
|
||||
|
||||
// A 矩阵相关
|
||||
pub areit: Vec<f64>,
|
||||
pub arein: Vec<f64>,
|
||||
pub areim: Vec<f64>,
|
||||
pub areip: Vec<Vec<f64>>,
|
||||
|
||||
// C 矩阵相关
|
||||
pub creit: Vec<f64>,
|
||||
pub crein: Vec<f64>,
|
||||
pub creim: Vec<f64>,
|
||||
pub creip: Vec<Vec<f64>>,
|
||||
|
||||
// 辐射等效 X
|
||||
pub reix: Vec<f64>,
|
||||
pub creix: Vec<f64>,
|
||||
|
||||
// Red 相关 - T
|
||||
pub redx: Vec<f64>,
|
||||
pub redt: Vec<f64>,
|
||||
pub redn: Vec<f64>,
|
||||
pub redm: Vec<f64>,
|
||||
pub redp: Vec<Vec<f64>>,
|
||||
|
||||
// Red 相关 - M
|
||||
pub redxm: Vec<f64>,
|
||||
pub redtm: Vec<f64>,
|
||||
pub rednm: Vec<f64>,
|
||||
pub redmm: Vec<f64>,
|
||||
pub redpm: Vec<Vec<f64>>,
|
||||
|
||||
// Red 相关 - P
|
||||
pub redtp: Vec<f64>,
|
||||
pub rednp: Vec<f64>,
|
||||
pub redxp: Vec<f64>,
|
||||
pub redmp: Vec<f64>,
|
||||
pub redpp: Vec<Vec<f64>>,
|
||||
|
||||
// He 相关 - T
|
||||
pub heit: Vec<f64>,
|
||||
pub hein: Vec<f64>,
|
||||
pub heim: Vec<f64>,
|
||||
pub heip: Vec<Vec<f64>>,
|
||||
|
||||
// He 相关 - M
|
||||
pub heitm: Vec<f64>,
|
||||
pub heinm: Vec<f64>,
|
||||
pub heimm: Vec<f64>,
|
||||
pub heipm: Vec<Vec<f64>>,
|
||||
|
||||
// He 相关 - P
|
||||
pub heitp: Vec<f64>,
|
||||
pub heinp: Vec<f64>,
|
||||
pub heimp: Vec<f64>,
|
||||
pub heipp: Vec<Vec<f64>>,
|
||||
|
||||
// Ehe/Ere 相关
|
||||
pub ehet: Vec<f64>,
|
||||
pub ehen: Vec<f64>,
|
||||
pub eret: Vec<f64>,
|
||||
pub eren: Vec<f64>,
|
||||
pub ehep: Vec<Vec<f64>>,
|
||||
pub erep: Vec<Vec<f64>>,
|
||||
|
||||
// AP 相关
|
||||
pub apt: Vec<Vec<f64>>,
|
||||
pub apn: Vec<Vec<f64>>,
|
||||
pub aapt: Vec<Vec<f64>>,
|
||||
pub aapn: Vec<Vec<f64>>,
|
||||
pub capt: Vec<Vec<f64>>,
|
||||
pub capn: Vec<Vec<f64>>,
|
||||
|
||||
// APP 矩阵 (MLVEXP × MLVEXP × MDEPTH)
|
||||
pub app: Vec<Vec<Vec<f64>>>,
|
||||
pub aapp: Vec<Vec<Vec<f64>>>,
|
||||
pub capp: Vec<Vec<Vec<f64>>>,
|
||||
|
||||
// 控制参数
|
||||
pub qtlas: f64,
|
||||
pub ifali: i32,
|
||||
pub ifpopr: i32,
|
||||
pub irprec: i32,
|
||||
pub ifprec: i32,
|
||||
pub itold1: i32,
|
||||
pub itold2: i32,
|
||||
pub itlas: i32,
|
||||
}
|
||||
|
||||
impl Default for FixAlp {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
abso: vec![0.0; MFREQ],
|
||||
emis: vec![0.0; MFREQ],
|
||||
scat: vec![0.0; MFREQ],
|
||||
|
||||
reit: vec![0.0; MDEPTH],
|
||||
rein: vec![0.0; MDEPTH],
|
||||
reim: vec![0.0; MDEPTH],
|
||||
reip: vec![vec![0.0; MDEPTH]; MLVEXP],
|
||||
|
||||
areit: vec![0.0; MDEPTH],
|
||||
arein: vec![0.0; MDEPTH],
|
||||
areim: vec![0.0; MDEPTH],
|
||||
areip: vec![vec![0.0; MDEPTH]; MLVEXP],
|
||||
|
||||
creit: vec![0.0; MDEPTH],
|
||||
crein: vec![0.0; MDEPTH],
|
||||
creim: vec![0.0; MDEPTH],
|
||||
creip: vec![vec![0.0; MDEPTH]; MLVEXP],
|
||||
|
||||
reix: vec![0.0; MDEPTH],
|
||||
creix: vec![0.0; MDEPTH],
|
||||
|
||||
redx: vec![0.0; MDEPTH],
|
||||
redt: vec![0.0; MDEPTH],
|
||||
redn: vec![0.0; MDEPTH],
|
||||
redm: vec![0.0; MDEPTH],
|
||||
redp: vec![vec![0.0; MDEPTH]; MLVEXP],
|
||||
|
||||
redxm: vec![0.0; MDEPTH],
|
||||
redtm: vec![0.0; MDEPTH],
|
||||
rednm: vec![0.0; MDEPTH],
|
||||
redmm: vec![0.0; MDEPTH],
|
||||
redpm: vec![vec![0.0; MDEPTH]; MLVEXP],
|
||||
|
||||
redtp: vec![0.0; MDEPTH],
|
||||
rednp: vec![0.0; MDEPTH],
|
||||
redxp: vec![0.0; MDEPTH],
|
||||
redmp: vec![0.0; MDEPTH],
|
||||
redpp: vec![vec![0.0; MDEPTH]; MLVEXP],
|
||||
|
||||
heit: vec![0.0; MDEPTH],
|
||||
hein: vec![0.0; MDEPTH],
|
||||
heim: vec![0.0; MDEPTH],
|
||||
heip: vec![vec![0.0; MDEPTH]; MLVEXP],
|
||||
|
||||
heitm: vec![0.0; MDEPTH],
|
||||
heinm: vec![0.0; MDEPTH],
|
||||
heimm: vec![0.0; MDEPTH],
|
||||
heipm: vec![vec![0.0; MDEPTH]; MLVEXP],
|
||||
|
||||
heitp: vec![0.0; MDEPTH],
|
||||
heinp: vec![0.0; MDEPTH],
|
||||
heimp: vec![0.0; MDEPTH],
|
||||
heipp: vec![vec![0.0; MDEPTH]; MLVEXP],
|
||||
|
||||
ehet: vec![0.0; MDEPTH],
|
||||
ehen: vec![0.0; MDEPTH],
|
||||
eret: vec![0.0; MDEPTH],
|
||||
eren: vec![0.0; MDEPTH],
|
||||
ehep: vec![vec![0.0; MDEPTH]; MLVEX3],
|
||||
erep: vec![vec![0.0; MDEPTH]; MLVEX3],
|
||||
|
||||
apt: vec![vec![0.0; MDEPTH]; MLVEXP],
|
||||
apn: vec![vec![0.0; MDEPTH]; MLVEXP],
|
||||
aapt: vec![vec![0.0; MDEPTH]; MLVEX3],
|
||||
aapn: vec![vec![0.0; MDEPTH]; MLVEX3],
|
||||
capt: vec![vec![0.0; MDEPTH]; MLVEX3],
|
||||
capn: vec![vec![0.0; MDEPTH]; MLVEX3],
|
||||
|
||||
app: vec![vec![vec![0.0; MDEPTH]; MLVEXP]; MLVEXP],
|
||||
aapp: vec![vec![vec![0.0; MDEPTH]; MLVEX3]; MLVEX3],
|
||||
capp: vec![vec![vec![0.0; MDEPTH]; MLVEX3]; MLVEX3],
|
||||
|
||||
qtlas: 0.0,
|
||||
ifali: 0,
|
||||
ifpopr: 0,
|
||||
irprec: 0,
|
||||
ifprec: 0,
|
||||
itold1: 0,
|
||||
itold2: 0,
|
||||
itlas: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FixAlp {
|
||||
/// 估算内存使用 (MB)
|
||||
pub fn memory_usage_mb(&self) -> f64 {
|
||||
// 主要数组大小估算
|
||||
let freq_size = 3 * MFREQ * std::mem::size_of::<f64>();
|
||||
let depth_1d = 22 * MDEPTH * std::mem::size_of::<f64>();
|
||||
let depth_2d_lvexp = 17 * MLVEXP * MDEPTH * std::mem::size_of::<f64>();
|
||||
let depth_2d_lvex3 = 10 * MLVEX3 * MDEPTH * std::mem::size_of::<f64>();
|
||||
let depth_3d_lvexp = 3 * MLVEXP * MLVEXP * MDEPTH * std::mem::size_of::<f64>();
|
||||
let depth_3d_lvex3 = 3 * MLVEX3 * MLVEX3 * MDEPTH * std::mem::size_of::<f64>();
|
||||
|
||||
(freq_size + depth_1d + depth_2d_lvexp + depth_2d_lvex3 + depth_3d_lvexp + depth_3d_lvex3) as f64
|
||||
/ (1024.0 * 1024.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_fixalp_creation() {
|
||||
let fixalp = FixAlp::default();
|
||||
assert_eq!(fixalp.abso.len(), MFREQ);
|
||||
assert_eq!(fixalp.reit.len(), MDEPTH);
|
||||
assert_eq!(fixalp.reip.len(), MLVEXP);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fixalp_memory() {
|
||||
let fixalp = FixAlp::default();
|
||||
let mem = fixalp.memory_usage_mb();
|
||||
println!("FixAlp memory usage: {:.2} MB", mem);
|
||||
assert!(mem > 0.0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
//! 大型计算数组。
|
||||
//!
|
||||
//! 重构自 TLUSTY `ARRAY1.FOR` 中的 COMMON 块。
|
||||
//! 包含辐射转移方程求解所需的大型矩阵和向量。
|
||||
|
||||
use super::constants::*;
|
||||
|
||||
// ============================================================================
|
||||
// 主矩阵数组 (无标签 COMMON)
|
||||
// ============================================================================
|
||||
|
||||
/// 主计算数组。
|
||||
/// 对应 ARRAY1.FOR 中的无标签 COMMON 块
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MainArrays {
|
||||
// 矩阵 (MTOT × MTOT)
|
||||
/// A 矩阵
|
||||
pub a: Vec<Vec<f64>>,
|
||||
/// B 矩阵
|
||||
pub b: Vec<Vec<f64>>,
|
||||
/// C 矩阵
|
||||
pub c: Vec<Vec<f64>>,
|
||||
/// E 矩阵
|
||||
pub e: Vec<Vec<f64>>,
|
||||
|
||||
// 向量 (MTOT)
|
||||
/// 左向量
|
||||
pub vecl: Vec<f64>,
|
||||
/// Y1 向量
|
||||
pub y1: Vec<f64>,
|
||||
/// Y2 向量
|
||||
pub y2: Vec<f64>,
|
||||
|
||||
// Ψ 相关向量 (MTOT)
|
||||
/// Ψ 在前深度
|
||||
pub psi0: Vec<f64>,
|
||||
/// Ψ 在当前深度
|
||||
pub psim: Vec<f64>,
|
||||
/// Ψ 在后深度
|
||||
pub psip: Vec<f64>,
|
||||
|
||||
// 辐射相关向量 (MTOT)
|
||||
pub rad0: Vec<f64>,
|
||||
pub radm: Vec<f64>,
|
||||
pub radp: Vec<f64>,
|
||||
|
||||
// 频率相关数组 (MFREX)
|
||||
/// FK 在前深度
|
||||
pub fkm: Vec<f64>,
|
||||
/// FK 在当前深度
|
||||
pub fk0: Vec<f64>,
|
||||
/// FK 在后深度
|
||||
pub fkp: Vec<f64>,
|
||||
|
||||
// 吸收系数 (MFREX)
|
||||
pub absom: Vec<f64>,
|
||||
pub abso0: Vec<f64>,
|
||||
pub absop: Vec<f64>,
|
||||
|
||||
// 发射系数 (MFREX)
|
||||
pub emism: Vec<f64>,
|
||||
pub emis0: Vec<f64>,
|
||||
pub emisp: Vec<f64>,
|
||||
|
||||
// 散射系数 (MFREX)
|
||||
pub scatm: Vec<f64>,
|
||||
pub scat0: Vec<f64>,
|
||||
pub scatp: Vec<f64>,
|
||||
|
||||
// 温度导数 (MFREX)
|
||||
pub dabtm: Vec<f64>,
|
||||
pub dabt0: Vec<f64>,
|
||||
pub dabtp: Vec<f64>,
|
||||
pub demtm: Vec<f64>,
|
||||
pub demt0: Vec<f64>,
|
||||
pub demtp: Vec<f64>,
|
||||
|
||||
// 密度导数 (MFREX)
|
||||
pub dabnm: Vec<f64>,
|
||||
pub dabn0: Vec<f64>,
|
||||
pub dabnp: Vec<f64>,
|
||||
pub demnm: Vec<f64>,
|
||||
pub demn0: Vec<f64>,
|
||||
pub demnp: Vec<f64>,
|
||||
|
||||
// 质量导数 (MFREX)
|
||||
pub dabmm: Vec<f64>,
|
||||
pub dabm0: Vec<f64>,
|
||||
pub dabmp: Vec<f64>,
|
||||
pub demmm: Vec<f64>,
|
||||
pub demm0: Vec<f64>,
|
||||
pub demmp: Vec<f64>,
|
||||
|
||||
// 深度权重 (MFREX)
|
||||
pub wdepm: Vec<f64>,
|
||||
pub wdep0: Vec<f64>,
|
||||
pub wdepp: Vec<f64>,
|
||||
|
||||
// 能级相关 (MLEVEL)
|
||||
/// 束缚-自由源函数 (前)
|
||||
pub sbfm: Vec<f64>,
|
||||
/// 束缚-自由源函数 (当前)
|
||||
pub sbf0: Vec<f64>,
|
||||
/// 束缚-自由源函数 (后)
|
||||
pub sbfp: Vec<f64>,
|
||||
|
||||
/// 氦激发速率
|
||||
pub hex: Vec<f64>,
|
||||
/// 复合激发速率
|
||||
pub rex: Vec<f64>,
|
||||
pub rexa: Vec<f64>,
|
||||
|
||||
/// 束缚-自由导数
|
||||
pub dsbfm: Vec<f64>,
|
||||
pub dsbf0: Vec<f64>,
|
||||
pub dsbfp: Vec<f64>,
|
||||
|
||||
/// 电荷求和
|
||||
pub sumdch: Vec<f64>,
|
||||
|
||||
// 二维导数数组 (MLEVEL × MFREX)
|
||||
pub drchm: Vec<Vec<f64>>,
|
||||
pub dretm: Vec<Vec<f64>>,
|
||||
pub drch0: Vec<Vec<f64>>,
|
||||
pub dret0: Vec<Vec<f64>>,
|
||||
pub drchp: Vec<Vec<f64>>,
|
||||
pub dretp: Vec<Vec<f64>>,
|
||||
}
|
||||
|
||||
impl Default for MainArrays {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
a: vec![vec![0.0; MTOT]; MTOT],
|
||||
b: vec![vec![0.0; MTOT]; MTOT],
|
||||
c: vec![vec![0.0; MTOT]; MTOT],
|
||||
e: vec![vec![0.0; MTOT]; MTOT],
|
||||
vecl: vec![0.0; MTOT],
|
||||
y1: vec![0.0; MTOT],
|
||||
y2: vec![0.0; MTOT],
|
||||
psi0: vec![0.0; MTOT],
|
||||
psim: vec![0.0; MTOT],
|
||||
psip: vec![0.0; MTOT],
|
||||
rad0: vec![0.0; MTOT],
|
||||
radm: vec![0.0; MTOT],
|
||||
radp: vec![0.0; MTOT],
|
||||
fkm: vec![0.0; MFREX],
|
||||
fk0: vec![0.0; MFREX],
|
||||
fkp: vec![0.0; MFREX],
|
||||
absom: vec![0.0; MFREX],
|
||||
abso0: vec![0.0; MFREX],
|
||||
absop: vec![0.0; MFREX],
|
||||
emism: vec![0.0; MFREX],
|
||||
emis0: vec![0.0; MFREX],
|
||||
emisp: vec![0.0; MFREX],
|
||||
scatm: vec![0.0; MFREX],
|
||||
scat0: vec![0.0; MFREX],
|
||||
scatp: vec![0.0; MFREX],
|
||||
dabtm: vec![0.0; MFREX],
|
||||
dabt0: vec![0.0; MFREX],
|
||||
dabtp: vec![0.0; MFREX],
|
||||
demtm: vec![0.0; MFREX],
|
||||
demt0: vec![0.0; MFREX],
|
||||
demtp: vec![0.0; MFREX],
|
||||
dabnm: vec![0.0; MFREX],
|
||||
dabn0: vec![0.0; MFREX],
|
||||
dabnp: vec![0.0; MFREX],
|
||||
demnm: vec![0.0; MFREX],
|
||||
demn0: vec![0.0; MFREX],
|
||||
demnp: vec![0.0; MFREX],
|
||||
dabmm: vec![0.0; MFREX],
|
||||
dabm0: vec![0.0; MFREX],
|
||||
dabmp: vec![0.0; MFREX],
|
||||
demmm: vec![0.0; MFREX],
|
||||
demm0: vec![0.0; MFREX],
|
||||
demmp: vec![0.0; MFREX],
|
||||
wdepm: vec![0.0; MFREX],
|
||||
wdep0: vec![0.0; MFREX],
|
||||
wdepp: vec![0.0; MFREX],
|
||||
sbfm: vec![0.0; MLEVEL],
|
||||
sbf0: vec![0.0; MLEVEL],
|
||||
sbfp: vec![0.0; MLEVEL],
|
||||
hex: vec![0.0; MLEVEL],
|
||||
rex: vec![0.0; MLEVEL],
|
||||
rexa: vec![0.0; MLEVEL],
|
||||
dsbfm: vec![0.0; MLEVEL],
|
||||
dsbf0: vec![0.0; MLEVEL],
|
||||
dsbfp: vec![0.0; MLEVEL],
|
||||
sumdch: vec![0.0; MLEVEL],
|
||||
drchm: vec![vec![0.0; MFREX]; MLEVEL],
|
||||
dretm: vec![vec![0.0; MFREX]; MLEVEL],
|
||||
drch0: vec![vec![0.0; MFREX]; MLEVEL],
|
||||
dret0: vec![vec![0.0; MFREX]; MLEVEL],
|
||||
drchp: vec![vec![0.0; MFREX]; MLEVEL],
|
||||
dretp: vec![vec![0.0; MFREX]; MLEVEL],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// EXPRAD - 扩展辐射数组
|
||||
// ============================================================================
|
||||
|
||||
/// 扩展辐射数组。
|
||||
/// 对应 COMMON /EXPRAD/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ExpRad {
|
||||
/// 吸收系数扩展 (频率 × 深度)
|
||||
pub absoex: Vec<Vec<f64>>,
|
||||
/// 发射系数扩展
|
||||
pub emisex: Vec<Vec<f64>>,
|
||||
/// 散射系数扩展
|
||||
pub scatex: Vec<Vec<f64>>,
|
||||
|
||||
// 导数扩展
|
||||
pub dabtex: Vec<Vec<f64>>,
|
||||
pub demtex: Vec<Vec<f64>>,
|
||||
pub dabcex: Vec<Vec<f64>>,
|
||||
pub demnex: Vec<Vec<f64>>,
|
||||
pub dabmex: Vec<Vec<f64>>,
|
||||
pub demmex: Vec<Vec<f64>>,
|
||||
|
||||
// 能级导数扩展 (线性化能级 × 频率 × 深度)
|
||||
pub drchex: Vec<Vec<Vec<f64>>>,
|
||||
pub dretex: Vec<Vec<Vec<f64>>>,
|
||||
}
|
||||
|
||||
impl Default for ExpRad {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
absoex: vec![vec![0.0; MDEPTH]; MFREX],
|
||||
emisex: vec![vec![0.0; MDEPTH]; MFREX],
|
||||
scatex: vec![vec![0.0; MDEPTH]; MFREX],
|
||||
dabtex: vec![vec![0.0; MDEPTH]; MFREX],
|
||||
demtex: vec![vec![0.0; MDEPTH]; MFREX],
|
||||
dabcex: vec![vec![0.0; MDEPTH]; MFREX],
|
||||
demnex: vec![vec![0.0; MDEPTH]; MFREX],
|
||||
dabmex: vec![vec![0.0; MDEPTH]; MFREX],
|
||||
demmex: vec![vec![0.0; MDEPTH]; MFREX],
|
||||
drchex: vec![vec![vec![0.0; MDEPTH]; MFREX]; MLVEXP],
|
||||
dretex: vec![vec![vec![0.0; MDEPTH]; MFREX]; MLVEXP],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// BPOCOM - 束缚-占据矩阵
|
||||
// ============================================================================
|
||||
|
||||
/// 束缚-占据矩阵。
|
||||
/// 对应 COMMON /BPOCOM/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct BpoCom {
|
||||
/// 电子散射矩阵
|
||||
pub esemat: Vec<Vec<f64>>,
|
||||
/// 束缚-电子散射
|
||||
pub bese: Vec<f64>,
|
||||
/// 衰减
|
||||
pub att: Vec<f64>,
|
||||
/// Ann 矩阵对角
|
||||
pub ann: Vec<f64>,
|
||||
}
|
||||
|
||||
impl BpoCom {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
esemat: vec![vec![0.0; MLEVEL]; MLEVEL],
|
||||
bese: vec![0.0; MLEVEL],
|
||||
att: vec![0.0; MLEVEL],
|
||||
ann: vec![0.0; MLEVEL],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 综合数组结构
|
||||
// ============================================================================
|
||||
|
||||
/// TLUSTY 计算数组。
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ComputeArrays {
|
||||
pub main: MainArrays,
|
||||
pub exprad: ExpRad,
|
||||
pub bpocom: BpoCom,
|
||||
}
|
||||
|
||||
impl ComputeArrays {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
bpocom: BpoCom::new(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// 估算内存使用量 (MB)
|
||||
pub fn memory_usage_mb(&self) -> f64 {
|
||||
let main_size = std::mem::size_of::<MainArrays>();
|
||||
let exprad_size = std::mem::size_of::<ExpRad>();
|
||||
let bpocom_size = std::mem::size_of::<BpoCom>();
|
||||
(main_size + exprad_size + bpocom_size) as f64 / (1024.0 * 1024.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_main_arrays_creation() {
|
||||
let arrays = MainArrays::default();
|
||||
assert_eq!(arrays.a.len(), MTOT);
|
||||
assert_eq!(arrays.a[0].len(), MTOT);
|
||||
assert_eq!(arrays.vecl.len(), MTOT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exprad_creation() {
|
||||
let exprad = ExpRad::default();
|
||||
assert_eq!(exprad.absoex.len(), MFREX);
|
||||
assert_eq!(exprad.absoex[0].len(), MDEPTH);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_compute_arrays() {
|
||||
let arrays = ComputeArrays::new();
|
||||
let mem = arrays.memory_usage_mb();
|
||||
println!("ComputeArrays memory usage: {:.2} MB", mem);
|
||||
assert!(mem > 0.0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
//! 原子、离子、能级数据。
|
||||
//!
|
||||
//! 重构自 TLUSTY `ATOMIC.FOR` 中的 COMMON 块。
|
||||
|
||||
use super::constants::*;
|
||||
|
||||
// ============================================================================
|
||||
// ATOPAR - 原子参数
|
||||
// ============================================================================
|
||||
|
||||
/// 原子参数。
|
||||
/// 对应 COMMON /ATOPAR/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AtoPar {
|
||||
/// 原子质量
|
||||
pub amass: Vec<f64>,
|
||||
/// 丰度 (原子/深度点)
|
||||
pub abund: Vec<Vec<f64>>,
|
||||
/// 原子序数
|
||||
pub numat: Vec<i32>,
|
||||
/// 原子起始能级索引
|
||||
pub n0a: Vec<i32>,
|
||||
/// 原子终止能级索引
|
||||
pub nka: Vec<i32>,
|
||||
/// 参考原子
|
||||
pub nref: Vec<i32>,
|
||||
/// 原子提取标志
|
||||
pub iatex: Vec<i32>,
|
||||
/// 参考丰度 (深度点)
|
||||
pub nrefs: Vec<Vec<i32>>,
|
||||
/// 采用的原子
|
||||
pub iadop: Vec<i32>,
|
||||
/// 固定丰度标志
|
||||
pub iifix: Vec<i32>,
|
||||
/// 参考原子索引
|
||||
pub iatref: i32,
|
||||
/// 参考模型
|
||||
pub modref: i32,
|
||||
}
|
||||
|
||||
impl Default for AtoPar {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
amass: vec![0.0; MATOM],
|
||||
abund: vec![vec![0.0; MDEPTH]; MATOM],
|
||||
numat: vec![0; MATOM],
|
||||
n0a: vec![0; MATOM],
|
||||
nka: vec![0; MATOM],
|
||||
nref: vec![0; MATOM],
|
||||
iatex: vec![0; MATOM],
|
||||
nrefs: vec![vec![0; MDEPTH]; MATOM],
|
||||
iadop: vec![0; MATOM],
|
||||
iifix: vec![0; MATOM],
|
||||
iatref: 0,
|
||||
modref: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// IONPAR - 离子参数
|
||||
// ============================================================================
|
||||
|
||||
/// 离子参数。
|
||||
/// 对应 COMMON /IONPAR/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct IonPar {
|
||||
/// 电离势 (Ry)
|
||||
pub ff: Vec<f64>,
|
||||
/// 电荷²
|
||||
pub charg2: Vec<f64>,
|
||||
/// 离子起始能级索引
|
||||
pub nfirst: Vec<i32>,
|
||||
/// 离子终止能级索引
|
||||
pub nlast: Vec<i32>,
|
||||
/// 下一个能级索引
|
||||
pub nnext: Vec<i32>,
|
||||
/// 原子序数 Z
|
||||
pub iz: Vec<i32>,
|
||||
/// 上能级求和索引
|
||||
pub iupsum: Vec<i32>,
|
||||
/// 碰撞耦合索引
|
||||
pub icup: Vec<i32>,
|
||||
/// LTE 标志
|
||||
pub ilte: Vec<i32>,
|
||||
/// LTE 离子标志
|
||||
pub iltion: Vec<i32>,
|
||||
}
|
||||
|
||||
impl Default for IonPar {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
ff: vec![0.0; MION],
|
||||
charg2: vec![0.0; MION],
|
||||
nfirst: vec![0; MION],
|
||||
nlast: vec![0; MION],
|
||||
nnext: vec![0; MION],
|
||||
iz: vec![0; MION],
|
||||
iupsum: vec![0; MION],
|
||||
icup: vec![0; MION],
|
||||
ilte: vec![0; MION],
|
||||
iltion: vec![0; MION],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// LEVPAR - 能级参数
|
||||
// ============================================================================
|
||||
|
||||
/// 能级参数。
|
||||
/// 对应 COMMON /LEVPAR/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LevPar {
|
||||
/// 电离能 (cm⁻¹)
|
||||
pub enion: Vec<f64>,
|
||||
/// 统计权重 g
|
||||
pub g: Vec<f64>,
|
||||
/// 主量子数
|
||||
pub nquant: Vec<i32>,
|
||||
/// 所属原子索引
|
||||
pub iatm: Vec<i32>,
|
||||
/// 所属离子索引
|
||||
pub iel: Vec<i32>,
|
||||
/// 能级类型
|
||||
pub ilk: Vec<i32>,
|
||||
/// 线性化标志
|
||||
pub ilin: Vec<i32>,
|
||||
/// LTE 能级标志
|
||||
pub iltlev: Vec<i32>,
|
||||
/// 能级索引
|
||||
pub indlev: Vec<i32>,
|
||||
/// 模型能级
|
||||
pub imodl: Vec<i32>,
|
||||
/// 显式能级标志
|
||||
pub iiexp: Vec<i32>,
|
||||
/// Fortran 能级标志
|
||||
pub iifor: Vec<i32>,
|
||||
/// 零占据概率标志
|
||||
pub ipzert: Vec<i32>,
|
||||
/// 零 g 标志
|
||||
pub igzert: Vec<i32>,
|
||||
/// 零 g 能级索引
|
||||
pub indlgz: Vec<i32>,
|
||||
/// 非零能级标志
|
||||
pub iinonz: Vec<i32>,
|
||||
/// 显式能级数
|
||||
pub nlvexp: i32,
|
||||
/// Fortran 能级数
|
||||
pub nlvfor: i32,
|
||||
/// 零能级数
|
||||
pub nlvexz: i32,
|
||||
/// 束缚-自由 X 标志
|
||||
pub lbpfx: i32,
|
||||
}
|
||||
|
||||
impl Default for LevPar {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enion: vec![0.0; MLEVEL],
|
||||
g: vec![0.0; MLEVEL],
|
||||
nquant: vec![0; MLEVEL],
|
||||
iatm: vec![0; MLEVEL],
|
||||
iel: vec![0; MLEVEL],
|
||||
ilk: vec![0; MLEVEL],
|
||||
ilin: vec![0; MLEVEL],
|
||||
iltlev: vec![0; MLEVEL],
|
||||
indlev: vec![0; MLEVEL],
|
||||
imodl: vec![0; MLEVEL],
|
||||
iiexp: vec![0; MLEVEL],
|
||||
iifor: vec![0; MLEVEL],
|
||||
ipzert: vec![0; MLEVEL],
|
||||
igzert: vec![0; MLEVEL],
|
||||
indlgz: vec![0; MLEVEL],
|
||||
iinonz: vec![0; MLEVEL],
|
||||
nlvexp: 0, nlvfor: 0, nlvexz: 0, lbpfx: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TRAPAR - 跃迁参数
|
||||
// ============================================================================
|
||||
|
||||
/// 跃迁参数。
|
||||
/// 对应 COMMON /TRAPAR/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TraPar {
|
||||
/// 跃迁频率 (Hz)
|
||||
pub fr0: Vec<f64>,
|
||||
/// 振子强度
|
||||
pub osc0: Vec<f64>,
|
||||
/// 线宽参数
|
||||
pub cpar: Vec<f64>,
|
||||
/// 最大频率
|
||||
pub frqmx: Vec<f64>,
|
||||
/// 跃迁频率 (cm⁻¹)
|
||||
pub fr0pc: Vec<f64>,
|
||||
/// 碰撞 Ω 矩阵
|
||||
pub omecol: Vec<Vec<f64>>,
|
||||
|
||||
// 梯度参数
|
||||
pub xgrad: f64,
|
||||
pub strl1: f64,
|
||||
pub strl2: f64,
|
||||
pub strlx: f64,
|
||||
|
||||
// 索引数组
|
||||
/// 下能级索引
|
||||
pub ilow: Vec<i32>,
|
||||
/// 上能级索引
|
||||
pub iup: Vec<i32>,
|
||||
/// 指数索引
|
||||
pub indexp: Vec<i32>,
|
||||
/// 频率索引
|
||||
pub kfr0: Vec<i32>,
|
||||
pub kfr1: Vec<i32>,
|
||||
/// Luck 跃迁标志
|
||||
pub iluctr: Vec<i32>,
|
||||
/// 频率计数
|
||||
pub ifc0: Vec<i32>,
|
||||
pub ifc1: Vec<i32>,
|
||||
pub ifr0: Vec<i32>,
|
||||
pub ifr1: Vec<i32>,
|
||||
/// 跃迁矩阵
|
||||
pub itra: Vec<Vec<i32>>,
|
||||
/// 轮廓类型
|
||||
pub iprof: Vec<i32>,
|
||||
/// 碰撞标志
|
||||
pub icol: Vec<i32>,
|
||||
/// 积分模式
|
||||
pub intmod: Vec<i32>,
|
||||
/// 连续跃迁标志
|
||||
pub itrcon: Vec<i32>,
|
||||
/// 双电子标志
|
||||
pub idiel: Vec<i32>,
|
||||
/// 跃迁 J-T 因子
|
||||
pub ijtf: Vec<i32>,
|
||||
/// 复合线标志
|
||||
pub lcomp: Vec<i32>,
|
||||
/// 谱线索引
|
||||
pub line: Vec<i32>,
|
||||
}
|
||||
|
||||
impl Default for TraPar {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
fr0: vec![0.0; MTRANS],
|
||||
osc0: vec![0.0; MTRANS],
|
||||
cpar: vec![0.0; MTRANS],
|
||||
frqmx: vec![0.0; MTRANS],
|
||||
fr0pc: vec![0.0; MTRANS],
|
||||
omecol: vec![vec![0.0; MLEVEL]; MLEVEL],
|
||||
xgrad: 0.0, strl1: 0.0, strl2: 0.0, strlx: 0.0,
|
||||
ilow: vec![0; MTRANS],
|
||||
iup: vec![0; MTRANS],
|
||||
indexp: vec![0; MTRANS],
|
||||
kfr0: vec![0; MTRANS],
|
||||
kfr1: vec![0; MTRANS],
|
||||
iluctr: vec![0; MTRANS],
|
||||
ifc0: vec![0; MTRANS],
|
||||
ifc1: vec![0; MTRANS],
|
||||
ifr0: vec![0; MTRANS],
|
||||
ifr1: vec![0; MTRANS],
|
||||
itra: vec![vec![0; MLEVEL]; MLEVEL],
|
||||
iprof: vec![0; MTRANS],
|
||||
icol: vec![0; MTRANS],
|
||||
intmod: vec![0; MTRANS],
|
||||
itrcon: vec![0; MTRANS],
|
||||
idiel: vec![0; MTRANS],
|
||||
ijtf: vec![0; MTRANS],
|
||||
lcomp: vec![0; MTRANS],
|
||||
line: vec![0; MTRANS],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PHOSET - 光电离设置
|
||||
// ============================================================================
|
||||
|
||||
/// 光电离设置。
|
||||
/// 对应 COMMON /PHOSET/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct PhoSet {
|
||||
/// 截面参数 S₀
|
||||
pub s0cs: Vec<f64>,
|
||||
/// 截面参数 α
|
||||
pub alfcs: Vec<f64>,
|
||||
/// 截面参数 β
|
||||
pub betcs: Vec<f64>,
|
||||
/// 截面参数 γ
|
||||
pub gamcs: Vec<f64>,
|
||||
/// 束缚-自由索引
|
||||
pub ibf: Vec<i32>,
|
||||
}
|
||||
|
||||
impl PhoSet {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
s0cs: vec![0.0; MLEVEL],
|
||||
alfcs: vec![0.0; MLEVEL],
|
||||
betcs: vec![0.0; MLEVEL],
|
||||
gamcs: vec![0.0; MLEVEL],
|
||||
ibf: vec![0; MLEVEL],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// VOIPAR - Voigt 参数
|
||||
// ============================================================================
|
||||
|
||||
/// Voigt 轮廓参数。
|
||||
/// 对应 COMMON /VOIPAR/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct VoiPar {
|
||||
/// 辐射宽度 γ
|
||||
pub gamar: Vec<f64>,
|
||||
/// Stark 展宽参数 1
|
||||
pub stark1: Vec<f64>,
|
||||
/// Stark 展宽参数 2
|
||||
pub stark2: Vec<f64>,
|
||||
/// Stark 展宽参数 3
|
||||
pub stark3: Vec<f64>,
|
||||
/// van der Waals 宽度
|
||||
pub vdwh: Vec<f64>,
|
||||
}
|
||||
|
||||
impl VoiPar {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
gamar: vec![0.0; MVOIGT],
|
||||
stark1: vec![0.0; MVOIGT],
|
||||
stark2: vec![0.0; MVOIGT],
|
||||
stark3: vec![0.0; MVOIGT],
|
||||
vdwh: vec![0.0; MVOIGT],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// HECRAT - 氦碰撞速率
|
||||
// ============================================================================
|
||||
|
||||
/// 氦碰撞速率系数。
|
||||
/// 对应 COMMON /HECRAT/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct HeCrat {
|
||||
/// 氦碰撞速率矩阵 (19×19)
|
||||
pub colhe1: [[f64; 19]; 19],
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 综合原子数据结构
|
||||
// ============================================================================
|
||||
|
||||
/// TLUSTY 原子数据。
|
||||
/// 包含所有原子、离子、能级、跃迁信息。
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct AtomicData {
|
||||
pub atopar: AtoPar,
|
||||
pub ionpar: IonPar,
|
||||
pub levpar: LevPar,
|
||||
pub trapar: TraPar,
|
||||
pub phoset: PhoSet,
|
||||
pub voipar: VoiPar,
|
||||
pub hecrat: HeCrat,
|
||||
}
|
||||
|
||||
impl AtomicData {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
phoset: PhoSet::new(),
|
||||
voipar: VoiPar::new(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取指定能级的原子序数 Z
|
||||
pub fn get_z(&self, level: usize) -> i32 {
|
||||
if level < MLEVEL {
|
||||
let ion_idx = self.levpar.iel[level] as usize;
|
||||
if ion_idx < MION {
|
||||
return self.ionpar.iz[ion_idx];
|
||||
}
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
/// 获取指定能级的电离电荷
|
||||
pub fn get_charge(&self, level: usize) -> f64 {
|
||||
if level < MLEVEL {
|
||||
let ion_idx = self.levpar.iel[level] as usize;
|
||||
if ion_idx < MION {
|
||||
return self.ionpar.charg2[ion_idx].sqrt();
|
||||
}
|
||||
}
|
||||
0.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_atomic_data_creation() {
|
||||
let data = AtomicData::new();
|
||||
assert_eq!(data.atopar.amass.len(), MATOM);
|
||||
assert_eq!(data.ionpar.ff.len(), MION);
|
||||
assert_eq!(data.levpar.g.len(), MLEVEL);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_z() {
|
||||
let mut data = AtomicData::new();
|
||||
data.levpar.iel[0] = 1;
|
||||
data.ionpar.iz[1] = 2; // He
|
||||
assert_eq!(data.get_z(0), 2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,428 @@
|
||||
//! 运行时配置参数。
|
||||
//!
|
||||
//! 重构自 TLUSTY `BASICS.FOR` 中的控制 COMMON 块。
|
||||
|
||||
use super::constants::*;
|
||||
|
||||
// ============================================================================
|
||||
// BASNUM - 基本数值计数器
|
||||
// ============================================================================
|
||||
|
||||
/// 基本数值计数器。
|
||||
/// 对应 COMMON /BASNUM/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BasNum {
|
||||
/// 显式原子数
|
||||
pub natom: i32,
|
||||
/// 显式离子数
|
||||
pub nion: i32,
|
||||
/// 显式能级数
|
||||
pub nlevel: i32,
|
||||
/// 跃迁数
|
||||
pub ntrans: i32,
|
||||
/// 深度点数
|
||||
pub nd: i32,
|
||||
/// 频率点数
|
||||
pub nfreq: i32,
|
||||
/// 连续谱频率数
|
||||
pub nfreqc: i32,
|
||||
/// 线性化频率数
|
||||
pub nfreqe: i32,
|
||||
|
||||
// 各种选项标志
|
||||
pub ioptab: i32,
|
||||
pub idisk: i32,
|
||||
pub izscal: i32,
|
||||
pub idmfix: i32,
|
||||
pub iheso6: i32,
|
||||
pub ifmol: i32,
|
||||
pub ifentr: i32,
|
||||
pub nfreql: i32,
|
||||
pub nlev0: i32,
|
||||
pub icolhn: i32,
|
||||
pub ioscor: i32,
|
||||
pub ilgder: i32,
|
||||
pub ifryb: i32,
|
||||
pub ifrset: i32,
|
||||
pub nfread: i32,
|
||||
pub nelsc: i32,
|
||||
pub ntranc: i32,
|
||||
pub iover: i32,
|
||||
pub jali: i32,
|
||||
pub ibc: i32,
|
||||
pub iubc: i32,
|
||||
pub intens: i32,
|
||||
pub irder: i32,
|
||||
pub ilmcor: i32,
|
||||
pub ifdiel: i32,
|
||||
pub ifalih: i32,
|
||||
pub iftene: i32,
|
||||
pub itndre: i32,
|
||||
pub ilpsct: i32,
|
||||
pub ilasct: i32,
|
||||
pub irte: i32,
|
||||
pub idlte: i32,
|
||||
pub ibfint: i32,
|
||||
pub intrpl: i32,
|
||||
pub ichang: i32,
|
||||
pub natoms: i32,
|
||||
pub ipslte: i32,
|
||||
pub ispodf: i32,
|
||||
pub itlucy: i32,
|
||||
pub nretc: i32,
|
||||
pub ifrayl: i32,
|
||||
pub ifprad: i32,
|
||||
}
|
||||
|
||||
impl Default for BasNum {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
natom: 0, nion: 0, nlevel: 0, ntrans: 0,
|
||||
nd: 0, nfreq: 0, nfreqc: 0, nfreqe: 0,
|
||||
ioptab: 0, idisk: 0, izscal: 0, idmfix: 0,
|
||||
iheso6: 0, ifmol: 0, ifentr: 0, nfreql: 0,
|
||||
nlev0: 0, icolhn: 0, ioscor: 0, ilgder: 0,
|
||||
ifryb: 0, ifrset: 0, nfread: 0, nelsc: 0,
|
||||
ntranc: 0, iover: 0, jali: 0, ibc: 0,
|
||||
iubc: 0, intens: 0, irder: 0, ilmcor: 0,
|
||||
ifdiel: 0, ifalih: 0, iftene: 0, itndre: 0,
|
||||
ilpsct: 0, ilasct: 0, irte: 0, idlte: 0,
|
||||
ibfint: 0, intrpl: 0, ichang: 0, natoms: 0,
|
||||
ipslte: 0, ispodf: 0, itlucy: 0, nretc: 0,
|
||||
ifrayl: 0, ifprad: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// INPPAR - 输入参数
|
||||
// ============================================================================
|
||||
|
||||
/// 输入参数。
|
||||
/// 对应 COMMON /INPPAR/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InpPar {
|
||||
/// 有效温度 (K)
|
||||
pub teff: f64,
|
||||
/// 表面重力 (cm/s²)
|
||||
pub grav: f64,
|
||||
|
||||
/// 总 He 丰度 (质量分数)
|
||||
pub ytot: Vec<f64>,
|
||||
/// 平均分子量
|
||||
pub wmm: Vec<f64>,
|
||||
/// He 质量分数
|
||||
pub wmy: Vec<f64>,
|
||||
/// 分子温度极限
|
||||
pub tmolim: f64,
|
||||
|
||||
// 恒星风参数
|
||||
pub xmstar: f64,
|
||||
pub xmdot: f64,
|
||||
pub rstar: f64,
|
||||
pub alpha0: f64,
|
||||
pub reynum: f64,
|
||||
|
||||
// 引力相关
|
||||
pub qgrav: f64,
|
||||
pub edisc: f64,
|
||||
pub dzeta: f64,
|
||||
pub reldst: f64,
|
||||
|
||||
// 粘性参数
|
||||
pub visc: f64,
|
||||
pub zeta0: f64,
|
||||
pub zeta1: f64,
|
||||
pub dmvisc: f64,
|
||||
pub fractv: f64,
|
||||
|
||||
// 自转参数
|
||||
pub omeg32: f64,
|
||||
pub wbarm: f64,
|
||||
pub wbar: f64,
|
||||
pub alphav: f64,
|
||||
pub pgas0: f64,
|
||||
|
||||
// 控制参数
|
||||
pub bergfc: f64, // β 引力因子 (wn.f 使用)
|
||||
pub cutlym: f64,
|
||||
pub cutbal: f64,
|
||||
|
||||
// 选项标志
|
||||
pub isplin: i32,
|
||||
pub irsplt: i32,
|
||||
pub ivisc: i32,
|
||||
pub ibche: i32,
|
||||
pub lte: bool,
|
||||
pub ltgrey: bool,
|
||||
pub lchc: bool,
|
||||
pub lresc: bool,
|
||||
}
|
||||
|
||||
impl InpPar {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
teff: 10000.0,
|
||||
grav: 4.44, // log g = 4.44 (太阳)
|
||||
ytot: vec![0.0; MDEPTH],
|
||||
wmm: vec![0.0; MDEPTH],
|
||||
wmy: vec![0.0; MDEPTH],
|
||||
tmolim: 0.0,
|
||||
xmstar: 0.0, xmdot: 0.0, rstar: 0.0, alpha0: 0.0, reynum: 0.0,
|
||||
qgrav: 0.0, edisc: 0.0, dzeta: 0.0, reldst: 0.0,
|
||||
visc: 0.0, zeta0: 0.0, zeta1: 0.0, dmvisc: 0.0, fractv: 0.0,
|
||||
omeg32: 0.0, wbarm: 0.0, wbar: 0.0, alphav: 0.0, pgas0: 0.0,
|
||||
bergfc: 1.0, // 默认值
|
||||
cutlym: 0.0, cutbal: 0.0,
|
||||
isplin: 0, irsplt: 0, ivisc: 0, ibche: 0,
|
||||
lte: false, ltgrey: false, lchc: false, lresc: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for InpPar {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// MATKEY - 材料键
|
||||
// ============================================================================
|
||||
|
||||
/// 材料键。
|
||||
/// 对应 COMMON /MATKEY/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct MatKey {
|
||||
pub nn: i32,
|
||||
pub nn0: i32,
|
||||
pub inhe: i32,
|
||||
pub inre: i32,
|
||||
pub inpc: i32,
|
||||
pub inse: i32,
|
||||
pub inzd: i32,
|
||||
pub inmp: i32,
|
||||
pub ndre: i32,
|
||||
pub insel: i32,
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// RUNKEY - 运行控制
|
||||
// ============================================================================
|
||||
|
||||
/// 运行控制键。
|
||||
/// 对应 COMMON /RUNKEY/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct RunKey {
|
||||
pub chmax: f64,
|
||||
pub iter: i32,
|
||||
pub niter: i32,
|
||||
pub nitzer: i32,
|
||||
pub init: i32,
|
||||
pub lac2: i32,
|
||||
pub lfin: i32,
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// CONKEY - 收敛控制
|
||||
// ============================================================================
|
||||
|
||||
/// 收敛控制键。
|
||||
/// 对应 COMMON /CONKEY/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ConKey {
|
||||
pub hmix0: f64,
|
||||
pub crflim: f64,
|
||||
pub nconit: i32,
|
||||
pub iconv: i32,
|
||||
pub indl: i32,
|
||||
pub ipress: i32,
|
||||
pub itemp: i32,
|
||||
pub icbeg: i32,
|
||||
pub itmcor: i32,
|
||||
pub iconre: i32,
|
||||
pub ideepc: i32,
|
||||
pub ndcgap: i32,
|
||||
pub idconz: i32,
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// OPCPAR - 额外不透明度控制
|
||||
// ============================================================================
|
||||
|
||||
/// 额外不透明度控制。
|
||||
/// 对应 COMMON /OPCPAR/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct OpcPar {
|
||||
pub iophmi: i32, // H⁻
|
||||
pub ioph2p: i32, // H₂⁺
|
||||
pub iophem: i32, // He⁻
|
||||
pub iopch: i32, // CH
|
||||
pub iopoh: i32, // OH
|
||||
pub ioph2m: i32, // H₂⁻
|
||||
pub ioh2h2: i32, // H₂-H₂ CIA
|
||||
pub ioh2he: i32, // H₂-He CIA
|
||||
pub ioh2h: i32, // H₂-H CIA
|
||||
pub iohhe: i32, // H-He CIA
|
||||
pub iophli: i32, // H⁻ 自由-自由
|
||||
pub irsct: i32, // 汤姆逊散射
|
||||
pub irsche: i32, // He 散射
|
||||
pub irsch2: i32, // H₂ 散射
|
||||
pub keepop: i32,
|
||||
pub iopold: i32,
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PRINTS - 打印控制
|
||||
// ============================================================================
|
||||
|
||||
/// 打印控制。
|
||||
/// 对应 COMMON /PRINTS/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Prints {
|
||||
pub iprint: i32,
|
||||
pub ipring: i32,
|
||||
pub iprind: i32,
|
||||
pub iprinp: i32,
|
||||
pub icoolp: i32,
|
||||
pub ichckp: i32,
|
||||
pub ipopac: i32,
|
||||
pub iprini: i32,
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ANGLES - 角度设置
|
||||
// ============================================================================
|
||||
|
||||
/// 角度设置。
|
||||
/// 对应 COMMON /ANGLES/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Angles {
|
||||
/// 角度余弦值
|
||||
pub amu: Vec<f64>,
|
||||
/// 角度权重
|
||||
pub wtmu: Vec<f64>,
|
||||
/// 角度函数
|
||||
pub fmu: Vec<f64>,
|
||||
/// 角度点数
|
||||
pub nmu: i32,
|
||||
}
|
||||
|
||||
impl Default for Angles {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
amu: vec![0.0; MMU],
|
||||
wtmu: vec![0.0; MMU],
|
||||
fmu: vec![0.0; MMU],
|
||||
nmu: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// COMPTN - Compton 散射角度参数
|
||||
// ============================================================================
|
||||
|
||||
/// Compton 散射角度参数。
|
||||
/// 对应 COMMON /COMPTN/ 和 /ANGNUM/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Comptn {
|
||||
/// 角度余弦值
|
||||
pub amuc: Vec<f64>,
|
||||
/// 角度权重
|
||||
pub wtmuc: Vec<f64>,
|
||||
/// amuc * wtmuc
|
||||
pub amuc1: Vec<f64>,
|
||||
/// amuc² * wtmuc
|
||||
pub amuc2: Vec<f64>,
|
||||
/// amuc³ * wtmuc
|
||||
pub amuc3: Vec<f64>,
|
||||
/// 角度相关量
|
||||
pub amuj: Vec<f64>,
|
||||
pub amuk: Vec<f64>,
|
||||
pub amuh: Vec<f64>,
|
||||
pub amun: Vec<f64>,
|
||||
/// Compton 散射 α 系数
|
||||
pub calph: Vec<Vec<f64>>,
|
||||
/// Compton 散射 β 系数
|
||||
pub cbeta: Vec<Vec<f64>>,
|
||||
/// Compton 散射 γ 系数
|
||||
pub cgamm: Vec<Vec<f64>>,
|
||||
/// 辐射零点
|
||||
pub radzer: f64,
|
||||
/// Compton 频率
|
||||
pub frlcom: f64,
|
||||
/// Compton 截面
|
||||
pub sigec: Vec<f64>,
|
||||
/// 原始频率索引
|
||||
pub ijorig: Vec<i32>,
|
||||
/// Compton 角度点数
|
||||
pub nmuc: i32,
|
||||
}
|
||||
|
||||
impl Default for Comptn {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
amuc: vec![0.0; MMUC],
|
||||
wtmuc: vec![0.0; MMUC],
|
||||
amuc1: vec![0.0; MMUC],
|
||||
amuc2: vec![0.0; MMUC],
|
||||
amuc3: vec![0.0; MMUC],
|
||||
amuj: vec![0.0; MMUC],
|
||||
amuk: vec![0.0; MMUC],
|
||||
amuh: vec![0.0; MMUC],
|
||||
amun: vec![0.0; MMUC],
|
||||
calph: vec![vec![0.0; MMUC]; MMUC],
|
||||
cbeta: vec![vec![0.0; MMUC]; MMUC],
|
||||
cgamm: vec![vec![0.0; MMUC]; MMUC],
|
||||
radzer: 0.0,
|
||||
frlcom: 0.0,
|
||||
sigec: vec![0.0; MFREQ],
|
||||
ijorig: vec![0; MFREQ],
|
||||
nmuc: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 综合配置结构
|
||||
// ============================================================================
|
||||
|
||||
/// TLUSTY 综合配置。
|
||||
/// 包含所有控制参数。
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct TlustyConfig {
|
||||
pub basnum: BasNum,
|
||||
pub inppar: InpPar,
|
||||
pub matkey: MatKey,
|
||||
pub runkey: RunKey,
|
||||
pub conkey: ConKey,
|
||||
pub opcpar: OpcPar,
|
||||
pub prints: Prints,
|
||||
pub angles: Angles,
|
||||
pub comptn: Comptn,
|
||||
}
|
||||
|
||||
impl TlustyConfig {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_config_creation() {
|
||||
let config = TlustyConfig::new();
|
||||
assert_eq!(config.basnum.natom, 0);
|
||||
assert_eq!(config.inppar.teff, 10000.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inppar_arrays() {
|
||||
let inppar = InpPar::new();
|
||||
assert_eq!(inppar.ytot.len(), MDEPTH);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
//! 物理常数和维度参数。
|
||||
//!
|
||||
//! 重构自 TLUSTY `BASICS.FOR` 中的 PARAMETER 定义。
|
||||
|
||||
// ============================================================================
|
||||
// 维度参数 (数组大小)
|
||||
// ============================================================================
|
||||
|
||||
/// 最大原子数
|
||||
pub const MATOM: usize = 99;
|
||||
/// 最大离子数
|
||||
pub const MION: usize = 170;
|
||||
/// 最大能级数
|
||||
pub const MLEVEL: usize = 1134;
|
||||
/// 最大线性化能级数
|
||||
pub const MLVEXP: usize = 233;
|
||||
/// 最大跃迁数
|
||||
pub const MTRANS: usize = 21000;
|
||||
/// 最大深度点数
|
||||
pub const MDEPTH: usize = 100;
|
||||
/// 最大频率点数
|
||||
pub const MFREQ: usize = 135000;
|
||||
/// 工作频率数组大小
|
||||
pub const MFREQP: usize = 220000;
|
||||
/// 连续谱频率点数
|
||||
pub const MFREQC: usize = 125000;
|
||||
/// 线性化频率数
|
||||
pub const MFREX: usize = 54;
|
||||
/// 每条谱线频率数
|
||||
pub const MFREQL: usize = 25798;
|
||||
/// 最大线性化参数数
|
||||
pub const MTOT: usize = 280;
|
||||
/// 最大角度点数
|
||||
pub const MMU: usize = 6;
|
||||
/// Compton 散射最大角度点数
|
||||
pub const MMUC: usize = 2;
|
||||
/// 光电离截面拟合点数
|
||||
pub const MFIT: usize = 357;
|
||||
/// 重叠跃迁数
|
||||
pub const MITJ: usize = 380;
|
||||
/// 伪连续能级数
|
||||
pub const MMCDW: usize = 26;
|
||||
/// 合并能级数
|
||||
pub const MMER: usize = 12;
|
||||
/// Voigt 轮廓谱线数
|
||||
pub const MVOIGT: usize = 8080;
|
||||
/// 占据概率离子最大电荷
|
||||
pub const MZZ: usize = 10;
|
||||
/// 最高氢能级
|
||||
pub const NLMX: usize = 80;
|
||||
/// 对角预处理能级数
|
||||
pub const MLEVE3: usize = 1;
|
||||
/// 对角/三对角操作能级数
|
||||
pub const MLVEX3: usize = 1;
|
||||
/// 对角/三对角操作跃迁数
|
||||
pub const MTRAN3: usize = 1;
|
||||
/// 光电离截面数
|
||||
pub const MCROSS: usize = MLEVEL + 5;
|
||||
/// 束缚-自由跃迁数
|
||||
pub const MBF: usize = MLEVEL;
|
||||
|
||||
// ============================================================================
|
||||
// 物理常数 (CGS 单位)
|
||||
// ============================================================================
|
||||
|
||||
/// 普朗克常数 h (erg·s)
|
||||
pub const H: f64 = 6.6256e-27;
|
||||
/// 玻尔兹曼常数 k (erg/K)
|
||||
pub const BOLK: f64 = 1.38054e-16;
|
||||
/// h/k (s·K)
|
||||
pub const HK: f64 = 4.79928144e-11;
|
||||
/// 光速 c (Å/s)
|
||||
pub const CAS: f64 = 2.997925e18;
|
||||
/// 氢电离能 (erg)
|
||||
pub const EH: f64 = 2.17853041e-11;
|
||||
/// 2*h/c³
|
||||
pub const BN: f64 = 1.4743e-2;
|
||||
/// 汤姆逊散射截面 (cm²)
|
||||
pub const SIGE: f64 = 6.6516e-25;
|
||||
/// 斯特藩-玻尔兹曼常数/4π
|
||||
pub const SIG4P: f64 = 4.5114062e-6;
|
||||
/// 4π/h
|
||||
pub const PI4H: f64 = 1.8966e27;
|
||||
/// 4π/c
|
||||
pub const PCK: f64 = 4.19168946e-10;
|
||||
/// 氢原子质量 (g)
|
||||
pub const HMASS: f64 = 1.67333e-24;
|
||||
|
||||
// ============================================================================
|
||||
// 数学常数
|
||||
// ============================================================================
|
||||
|
||||
/// 单位 1
|
||||
pub const UN: f64 = 1.0;
|
||||
/// 二分之一
|
||||
pub const HALF: f64 = 0.5;
|
||||
/// 二
|
||||
pub const TWO: f64 = 2.0;
|
||||
/// π
|
||||
pub const PI: f64 = std::f64::consts::PI;
|
||||
/// 2π
|
||||
pub const TWOPI: f64 = 2.0 * std::f64::consts::PI;
|
||||
/// 4π
|
||||
pub const FOURPI: f64 = 4.0 * std::f64::consts::PI;
|
||||
/// ln(10)
|
||||
pub const LN10: f64 = std::f64::consts::LN_10;
|
||||
|
||||
// ============================================================================
|
||||
// 辅助函数
|
||||
// ============================================================================
|
||||
|
||||
/// 安全指数函数,避免溢出。
|
||||
/// 重构自 TLUSTY `expo.f`
|
||||
#[inline]
|
||||
pub fn expo(x: f64) -> f64 {
|
||||
const MAX_EXP: f64 = 700.0;
|
||||
if x > MAX_EXP {
|
||||
(MAX_EXP).exp()
|
||||
} else if x < -MAX_EXP {
|
||||
0.0
|
||||
} else {
|
||||
x.exp()
|
||||
}
|
||||
}
|
||||
|
||||
/// 安全对数函数,避免 log(0)。
|
||||
#[inline]
|
||||
pub fn safe_log(x: f64) -> f64 {
|
||||
if x <= 0.0 {
|
||||
f64::NEG_INFINITY
|
||||
} else {
|
||||
x.ln()
|
||||
}
|
||||
}
|
||||
|
||||
/// 安全对数10函数。
|
||||
#[inline]
|
||||
pub fn safe_log10(x: f64) -> f64 {
|
||||
if x <= 0.0 {
|
||||
f64::NEG_INFINITY
|
||||
} else {
|
||||
x.log10()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_expo() {
|
||||
assert!((expo(0.0) - 1.0).abs() < 1e-15);
|
||||
assert!((expo(1.0) - std::f64::consts::E).abs() < 1e-15);
|
||||
assert_eq!(expo(-1000.0), 0.0);
|
||||
assert!(expo(1000.0).is_finite());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_constants() {
|
||||
assert!(H > 0.0);
|
||||
assert!(BOLK > 0.0);
|
||||
assert!(CAS > 0.0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
//! 迭代控制参数。
|
||||
//!
|
||||
//! 重构自 TLUSTY `ITERAT.FOR`
|
||||
|
||||
use super::constants::*;
|
||||
|
||||
// ============================================================================
|
||||
// 迭代参数维度
|
||||
// ============================================================================
|
||||
|
||||
/// 最大迭代次数
|
||||
pub const MITER: usize = 200;
|
||||
/// 最大 Lambda 点数
|
||||
pub const MLAMBD: usize = 100;
|
||||
|
||||
// ============================================================================
|
||||
// LAMBDA - Lambda 迭代参数
|
||||
// ============================================================================
|
||||
|
||||
/// Lambda 迭代控制。
|
||||
/// 对应 COMMON /LAMBDA/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Lambda {
|
||||
/// Lambda 点数
|
||||
pub nlambd: i32,
|
||||
/// 固定频率标志
|
||||
pub iffix: Vec<i32>,
|
||||
/// 显式净跃迁
|
||||
pub netexp: Vec<i32>,
|
||||
/// 固定净跃迁
|
||||
pub netfix: Vec<i32>,
|
||||
/// 显式能级跃迁
|
||||
pub ietexp: Vec<Vec<i32>>,
|
||||
/// 固定能级跃迁
|
||||
pub ietfix: Vec<Vec<i32>>,
|
||||
/// Lambda 索引
|
||||
pub nitlam: Vec<i32>,
|
||||
/// 能级修正标志
|
||||
pub ielcor: i32,
|
||||
}
|
||||
|
||||
impl Lambda {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
nlambd: 0,
|
||||
iffix: vec![0; MITER],
|
||||
netexp: vec![0; MITER],
|
||||
netfix: vec![0; MITER],
|
||||
ietexp: vec![vec![0; MLAMBD]; MITER],
|
||||
ietfix: vec![vec![0; MLAMBD]; MITER],
|
||||
nitlam: vec![0; MITER + 1],
|
||||
ielcor: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// CHNMAT - 材料变化控制
|
||||
// ============================================================================
|
||||
|
||||
/// 材料变化控制。
|
||||
/// 对应 COMMON /CHNMAT/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ChnMat {
|
||||
/// He 变化索引
|
||||
pub inhe0: Vec<i32>,
|
||||
/// 辐射变化索引
|
||||
pub inre0: Vec<i32>,
|
||||
/// PC 变化索引
|
||||
pub inpc0: Vec<i32>,
|
||||
/// 深度变化索引
|
||||
pub indl0: Vec<i32>,
|
||||
/// SE 变化索引
|
||||
pub inse0: Vec<i32>,
|
||||
/// MP 变化索引
|
||||
pub inmp0: Vec<i32>,
|
||||
/// NN 变化
|
||||
pub nn00: Vec<i32>,
|
||||
/// 深度修正
|
||||
pub ndre0: Vec<i32>,
|
||||
/// 材料变化标志
|
||||
pub lchmat: i32,
|
||||
/// 辐射存储
|
||||
pub lirost: i32,
|
||||
}
|
||||
|
||||
impl ChnMat {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
inhe0: vec![0; MITER],
|
||||
inre0: vec![0; MITER],
|
||||
inpc0: vec![0; MITER],
|
||||
indl0: vec![0; MITER],
|
||||
inse0: vec![0; MITER],
|
||||
inmp0: vec![0; MITER],
|
||||
nn00: vec![0; MITER],
|
||||
ndre0: vec![0; MITER],
|
||||
lchmat: 0,
|
||||
lirost: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ACCEL - 加速参数
|
||||
// ============================================================================
|
||||
|
||||
/// 加速收敛参数。
|
||||
/// 对应 COMMON /ACCEL/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Accel {
|
||||
/// 过松弛因子
|
||||
pub orelax: f64,
|
||||
/// 迭代计数
|
||||
pub itek: i32,
|
||||
/// 加速标志
|
||||
pub iacc: i32,
|
||||
/// 初始加速
|
||||
pub iacc0: i32,
|
||||
/// 加速方向
|
||||
pub iacd: i32,
|
||||
/// Kantorovich 向量
|
||||
pub kant: Vec<i32>,
|
||||
/// 奇异点计数
|
||||
pub ksng: i32,
|
||||
/// 奇异点位置
|
||||
pub lsng: Vec<i32>,
|
||||
/// Aitken 步
|
||||
pub laso: i32,
|
||||
/// 重启动标志
|
||||
pub lres2: i32,
|
||||
}
|
||||
|
||||
impl Accel {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
orelax: 1.0,
|
||||
itek: 0,
|
||||
iacc: 0,
|
||||
iacc0: 0,
|
||||
iacd: 0,
|
||||
kant: vec![0; MITER],
|
||||
ksng: 0,
|
||||
lsng: vec![0; MTOT],
|
||||
laso: 0,
|
||||
lres2: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ACCLP - 加速 Lambda 参数
|
||||
// ============================================================================
|
||||
|
||||
/// 加速 Lambda 迭代参数。
|
||||
/// 对应 COMMON /ACCLP/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Acclp {
|
||||
pub ilam: i32,
|
||||
pub iacpp: i32,
|
||||
pub iacc0p: i32,
|
||||
pub iacdp: i32,
|
||||
pub lac2p: i32,
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ACCLT - 温度加速
|
||||
// ============================================================================
|
||||
|
||||
/// 温度加速参数。
|
||||
/// 对应 COMMON /ACCLT/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Acclt {
|
||||
pub iaclt: i32,
|
||||
pub iacldt: i32,
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// CHNAD - 变化附加
|
||||
// ============================================================================
|
||||
|
||||
/// 变化附加参数。
|
||||
/// 对应 COMMON /CHNAD/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ChnAd {
|
||||
/// 最大变化
|
||||
pub chmaxt: f64,
|
||||
/// Lambda 计数
|
||||
pub nlamt: i32,
|
||||
/// 导数标志
|
||||
pubilder: i32,
|
||||
/// BPOP 标志
|
||||
pub ibpope: i32,
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 综合迭代控制
|
||||
// ============================================================================
|
||||
|
||||
/// TLUSTY 迭代控制。
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct IterControl {
|
||||
pub lambda: Lambda,
|
||||
pub chnmat: ChnMat,
|
||||
pub accel: Accel,
|
||||
pub acclp: Acclp,
|
||||
pub acclt: Acclt,
|
||||
pub chnad: ChnAd,
|
||||
}
|
||||
|
||||
impl IterControl {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
lambda: Lambda::new(),
|
||||
chnmat: ChnMat::new(),
|
||||
accel: Accel::new(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_lambda_creation() {
|
||||
let lambda = Lambda::new();
|
||||
assert_eq!(lambda.iffix.len(), MITER);
|
||||
assert_eq!(lambda.ietexp.len(), MITER);
|
||||
assert_eq!(lambda.nitlam.len(), MITER + 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_accel_creation() {
|
||||
let accel = Accel::new();
|
||||
assert_eq!(accel.kant.len(), MITER);
|
||||
assert_eq!(accel.lsng.len(), MTOT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iter_control() {
|
||||
let ctrl = IterControl::new();
|
||||
assert_eq!(ctrl.lambda.nlambd, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
//! TLUSTY 状态管理模块。
|
||||
//!
|
||||
//! 将 Fortran COMMON 块转换为 Rust struct。
|
||||
//!
|
||||
//! # 模块结构
|
||||
//!
|
||||
//! - `constants`: 物理和数学常数 (compile-time)
|
||||
//! - `config`: 运行时配置参数
|
||||
//! - `atomic`: 原子/离子/能级数据
|
||||
//! - `model`: 大气模型状态
|
||||
//! - `arrays`: 大型计算数组
|
||||
//! - `iterat`: 迭代控制参数
|
||||
//! - `alipar`: ALI (加速 Lambda 迭代) 数组
|
||||
//! - `odfpar`: ODF (不透明度分布函数) 数据
|
||||
|
||||
pub mod constants;
|
||||
pub mod config;
|
||||
pub mod atomic;
|
||||
pub mod model;
|
||||
pub mod arrays;
|
||||
pub mod iterat;
|
||||
pub mod alipar;
|
||||
pub mod odfpar;
|
||||
|
||||
pub use constants::*;
|
||||
pub use config::*;
|
||||
pub use atomic::*;
|
||||
pub use model::*;
|
||||
pub use arrays::*;
|
||||
pub use iterat::*;
|
||||
pub use alipar::*;
|
||||
pub use odfpar::*;
|
||||
@@ -0,0 +1,524 @@
|
||||
//! 大气模型状态。
|
||||
//!
|
||||
//! 重构自 TLUSTY `MODELQ.FOR` 中的 COMMON 块。
|
||||
//! 包含温度、密度、电子密度、占据数等物理状态。
|
||||
|
||||
use super::constants::*;
|
||||
|
||||
// ============================================================================
|
||||
// MODPAR - 模型参数
|
||||
// ============================================================================
|
||||
|
||||
/// 模型基本参数。
|
||||
/// 对应 COMMON /MODPAR/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ModPar {
|
||||
/// 深度 (柱质量密度, g/cm²)
|
||||
pub dm: Vec<f64>,
|
||||
/// 温度 (K)
|
||||
pub temp: Vec<f64>,
|
||||
/// 电子密度 (cm⁻³)
|
||||
pub elec: Vec<f64>,
|
||||
/// 总粒子密度 (cm⁻³)
|
||||
pub dens: Vec<f64>,
|
||||
/// 总粒子数
|
||||
pub totn: Vec<f64>,
|
||||
|
||||
/// 总原子密度
|
||||
pub anto: Vec<f64>,
|
||||
/// 金属原子密度
|
||||
pub anma: Vec<f64>,
|
||||
/// 中性氢密度
|
||||
pub anh1: Vec<f64>,
|
||||
/// 深度变量
|
||||
pub zd: Vec<f64>,
|
||||
|
||||
// 辅助温度量
|
||||
/// h/kT
|
||||
pub hkt1: Vec<f64>,
|
||||
/// 1/T
|
||||
pub tk1: Vec<f64>,
|
||||
/// h/(kT)²
|
||||
pub hkt21: Vec<f64>,
|
||||
/// sqrt(T)
|
||||
pub sqt1: Vec<f64>,
|
||||
|
||||
// 迭代中间量
|
||||
pub temp1: Vec<f64>,
|
||||
pub elec1: Vec<f64>,
|
||||
pub dens1: Vec<f64>,
|
||||
pub densi: Vec<f64>,
|
||||
pub densim: Vec<f64>,
|
||||
|
||||
// 散射相关
|
||||
/// 电子散射不透明度
|
||||
pub elscat: Vec<f64>,
|
||||
/// 线性化辐射参数
|
||||
pub alab: Vec<f64>,
|
||||
|
||||
// 深度差分
|
||||
pub deldm: Vec<f64>,
|
||||
pub dedm1: f64,
|
||||
pub deldmz: Vec<f64>,
|
||||
|
||||
// 速度场
|
||||
pub thetav: Vec<f64>,
|
||||
pub viscd: Vec<f64>,
|
||||
pub dalpmx: f64,
|
||||
pub xhyd: f64,
|
||||
|
||||
// 全局量
|
||||
pub dmtot: f64,
|
||||
pub rrdil: f64,
|
||||
pub tempbd: f64,
|
||||
pub alptav: f64,
|
||||
pub alpgav: f64,
|
||||
pub nalp: i32,
|
||||
pub ibeta: i32,
|
||||
}
|
||||
|
||||
impl Default for ModPar {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
dm: vec![0.0; MDEPTH],
|
||||
temp: vec![0.0; MDEPTH],
|
||||
elec: vec![0.0; MDEPTH],
|
||||
dens: vec![0.0; MDEPTH],
|
||||
totn: vec![0.0; MDEPTH],
|
||||
anto: vec![0.0; MDEPTH],
|
||||
anma: vec![0.0; MDEPTH],
|
||||
anh1: vec![0.0; MDEPTH],
|
||||
zd: vec![0.0; MDEPTH],
|
||||
hkt1: vec![0.0; MDEPTH],
|
||||
tk1: vec![0.0; MDEPTH],
|
||||
hkt21: vec![0.0; MDEPTH],
|
||||
sqt1: vec![0.0; MDEPTH],
|
||||
temp1: vec![0.0; MDEPTH],
|
||||
elec1: vec![0.0; MDEPTH],
|
||||
dens1: vec![0.0; MDEPTH],
|
||||
densi: vec![0.0; MDEPTH],
|
||||
densim: vec![0.0; MDEPTH],
|
||||
elscat: vec![0.0; MDEPTH],
|
||||
alab: vec![0.0; MDEPTH],
|
||||
deldm: vec![0.0; MDEPTH],
|
||||
dedm1: 0.0,
|
||||
deldmz: vec![0.0; MDEPTH],
|
||||
thetav: vec![0.0; MDEPTH],
|
||||
viscd: vec![0.0; MDEPTH],
|
||||
dalpmx: 0.0,
|
||||
xhyd: 0.0,
|
||||
dmtot: 0.0,
|
||||
rrdil: 0.0,
|
||||
tempbd: 0.0,
|
||||
alptav: 0.0,
|
||||
alpgav: 0.0,
|
||||
nalp: 0,
|
||||
ibeta: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// LEVPOP - 能级占据数
|
||||
// ============================================================================
|
||||
|
||||
/// 能级占据数。
|
||||
/// 对应 COMMON /LEVPOP/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LevPop {
|
||||
/// 占据数 (能级 × 深度)
|
||||
pub popul: Vec<Vec<f64>>,
|
||||
/// Boltzmann 因子
|
||||
pub bfac: Vec<Vec<f64>>,
|
||||
/// 逆占据数
|
||||
pub popinv: Vec<Vec<f64>>,
|
||||
|
||||
/// 当前深度占据数
|
||||
pub popgrp: Vec<f64>,
|
||||
pub pop: Vec<f64>,
|
||||
/// 束缚-自由源函数
|
||||
pub sbf: Vec<f64>,
|
||||
pub dsbf: Vec<f64>,
|
||||
/// 离子配分函数
|
||||
pub usum: Vec<f64>,
|
||||
}
|
||||
|
||||
impl Default for LevPop {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
popul: vec![vec![0.0; MDEPTH]; MLEVEL],
|
||||
bfac: vec![vec![0.0; MDEPTH]; MLEVEL],
|
||||
popinv: vec![vec![0.0; MDEPTH]; MLEVEL],
|
||||
popgrp: vec![0.0; MLEVEL],
|
||||
pop: vec![0.0; MLEVEL],
|
||||
sbf: vec![0.0; MLEVEL],
|
||||
dsbf: vec![0.0; MLEVEL],
|
||||
usum: vec![0.0; MION],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// GFFPAR - 自由-自由 Gaunt 因子
|
||||
// ============================================================================
|
||||
|
||||
/// 自由-自由 Gaunt 因子参数。
|
||||
/// 对应 COMMON /GFFPAR/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct GffPar {
|
||||
/// Gaunt 因子 (深度)
|
||||
pub gf0: Vec<f64>,
|
||||
pub gf1: Vec<f64>,
|
||||
pub gf2: Vec<f64>,
|
||||
pub gf3: Vec<f64>,
|
||||
pub gf4: Vec<f64>,
|
||||
pub gf5: Vec<f64>,
|
||||
pub gf6: Vec<f64>,
|
||||
|
||||
/// Gaunt 因子导数
|
||||
pub gf0d: Vec<f64>,
|
||||
pub gf1d: Vec<f64>,
|
||||
pub gf2d: Vec<f64>,
|
||||
pub gf3d: Vec<f64>,
|
||||
pub gf4d: Vec<f64>,
|
||||
pub gf5d: Vec<f64>,
|
||||
pub gf6d: Vec<f64>,
|
||||
|
||||
/// 温度步长
|
||||
pub deltt: Vec<f64>,
|
||||
}
|
||||
|
||||
impl GffPar {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
gf0: vec![0.0; MDEPTH],
|
||||
gf1: vec![0.0; MDEPTH],
|
||||
gf2: vec![0.0; MDEPTH],
|
||||
gf3: vec![0.0; MDEPTH],
|
||||
gf4: vec![0.0; MDEPTH],
|
||||
gf5: vec![0.0; MDEPTH],
|
||||
gf6: vec![0.0; MDEPTH],
|
||||
gf0d: vec![0.0; MDEPTH],
|
||||
gf1d: vec![0.0; MDEPTH],
|
||||
gf2d: vec![0.0; MDEPTH],
|
||||
gf3d: vec![0.0; MDEPTH],
|
||||
gf4d: vec![0.0; MDEPTH],
|
||||
gf5d: vec![0.0; MDEPTH],
|
||||
gf6d: vec![0.0; MDEPTH],
|
||||
deltt: vec![0.0; MDEPTH],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TOTRAD - 总辐射场
|
||||
// ============================================================================
|
||||
|
||||
/// 总辐射场。
|
||||
/// 对应 COMMON /TOTRAD/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TotRad {
|
||||
/// 辐射强度 (频率 × 深度)
|
||||
pub rad: Vec<Vec<f64>>,
|
||||
/// 频率相关深度
|
||||
pub fhd: Vec<f64>,
|
||||
/// 吸收系数 × 辐射
|
||||
pub fak: Vec<Vec<f64>>,
|
||||
pub radk: Vec<Vec<f64>>,
|
||||
|
||||
/// 外辐射
|
||||
pub extrad: Vec<f64>,
|
||||
/// 外辐射强度 (频率 × 角度)
|
||||
pub extint: Vec<Vec<f64>>,
|
||||
/// 氦外辐射
|
||||
pub hextrd: Vec<f64>,
|
||||
|
||||
// 全局量
|
||||
pub trad: f64,
|
||||
pub wdil: f64,
|
||||
pub extot: f64,
|
||||
pub tstar: f64,
|
||||
}
|
||||
|
||||
impl Default for TotRad {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
rad: vec![vec![0.0; MDEPTH]; MFREQ],
|
||||
fhd: vec![0.0; MFREQ],
|
||||
fak: vec![vec![0.0; MDEPTH]; MFREQ],
|
||||
radk: vec![vec![0.0; MDEPTH]; MFREQ],
|
||||
extrad: vec![0.0; MFREQ],
|
||||
extint: vec![vec![0.0; MMU]; MFREQ],
|
||||
hextrd: vec![0.0; MFREQ],
|
||||
trad: 0.0,
|
||||
wdil: 0.0,
|
||||
extot: 0.0,
|
||||
tstar: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// CURRAD - 当前深度辐射
|
||||
// ============================================================================
|
||||
|
||||
/// 当前深度辐射。
|
||||
/// 对应 COMMON /CURRAD/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct CurRad {
|
||||
pub rad1: Vec<f64>,
|
||||
pub ali1: Vec<f64>,
|
||||
pub fak1: Vec<f64>,
|
||||
pub radcm: Vec<Vec<f64>>,
|
||||
pub radl: Vec<Vec<f64>>,
|
||||
pub absali: Vec<Vec<f64>>,
|
||||
pub alih1: Vec<f64>,
|
||||
}
|
||||
|
||||
impl CurRad {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
rad1: vec![0.0; MDEPTH],
|
||||
ali1: vec![0.0; MDEPTH],
|
||||
fak1: vec![0.0; MDEPTH],
|
||||
radcm: vec![vec![0.0; MDEPTH]; MFREQ],
|
||||
radl: vec![vec![0.0; MDEPTH]; MFREQL],
|
||||
absali: vec![vec![0.0; MDEPTH]; MFREQL],
|
||||
alih1: vec![0.0; MDEPTH],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// FRQALL - 频率相关数组
|
||||
// ============================================================================
|
||||
|
||||
/// 频率相关数组。
|
||||
/// 对应 COMMON /FRQALL/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FrqAll {
|
||||
/// 频率网格 (Hz)
|
||||
pub freq: Vec<f64>,
|
||||
/// 频率权重
|
||||
pub w: Vec<f64>,
|
||||
/// 谱线轮廓
|
||||
pub prof: Vec<f64>,
|
||||
/// 谱线权重
|
||||
pub wch: Vec<f64>,
|
||||
|
||||
// 索引数组
|
||||
pub jik: Vec<i32>,
|
||||
pub ijx: Vec<i32>,
|
||||
pub ijbf: Vec<i32>,
|
||||
pub ifs0: i32,
|
||||
pub kij: Vec<i32>,
|
||||
pub lskip: Vec<Vec<i32>>,
|
||||
}
|
||||
|
||||
impl Default for FrqAll {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
freq: vec![0.0; MFREQ],
|
||||
w: vec![0.0; MFREQ],
|
||||
prof: vec![0.0; MFREQP],
|
||||
wch: vec![0.0; MFREQ],
|
||||
jik: vec![0; MFREQ],
|
||||
ijx: vec![0; MFREQ],
|
||||
ijbf: vec![0; MFREQ],
|
||||
ifs0: 0,
|
||||
kij: vec![0; MFREQ],
|
||||
lskip: vec![vec![0; MFREQ]; MDEPTH],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TOTPRF - 总谱线轮廓
|
||||
// ============================================================================
|
||||
|
||||
/// 谱线轮廓数组。
|
||||
/// 对应 COMMON /TOTPRF/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct TotPrf {
|
||||
/// 谱线轮廓 (深度 × 频率)
|
||||
pub prflin: Vec<Vec<f32>>,
|
||||
}
|
||||
|
||||
impl TotPrf {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
prflin: vec![vec![0.0; MFREQP]; MDEPTH],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PHOEXP - 光电离截面展开
|
||||
// ============================================================================
|
||||
|
||||
/// 光电离截面展开参数。
|
||||
/// 对应 COMMON /PHOEXP/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct PhoExp {
|
||||
/// 频率插值系数
|
||||
pub aijbf: Vec<f64>,
|
||||
/// 束缚-自由截面 (MCROSS × MFREQC)
|
||||
pub bfcs: Vec<Vec<f32>>,
|
||||
/// 频率索引
|
||||
pub ifreqb: Vec<i32>,
|
||||
}
|
||||
|
||||
impl PhoExp {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
aijbf: vec![0.0; MFREQ],
|
||||
bfcs: vec![vec![0.0; MFREQC]; MCROSS],
|
||||
ifreqb: vec![0; MFREQC],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// OBFPAR - 束缚-自由跃迁参数
|
||||
// ============================================================================
|
||||
|
||||
/// 束缚-自由跃迁参数。
|
||||
/// 对应 COMMON /OBFPAR/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ObfPar {
|
||||
/// 束缚-自由跃迁对应的跃迁索引
|
||||
pub itrbf: Vec<i32>,
|
||||
}
|
||||
|
||||
impl ObfPar {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
itrbf: vec![0; MBF],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// LEVADD - 能级附加数组
|
||||
// ============================================================================
|
||||
|
||||
/// 能级附加数组。
|
||||
/// 对应 COMMON /LEVADD/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct LevAdd {
|
||||
/// 离子配分函数和 (离子 × 深度)
|
||||
pub usums: Vec<Vec<f64>>,
|
||||
/// 配分函数温度导数
|
||||
pub dusmt: Vec<Vec<f64>>,
|
||||
/// 配分函数密度导数
|
||||
pub dusmn: Vec<Vec<f64>>,
|
||||
/// 双电子复合截面 (离子 × 深度)
|
||||
pub diesig: Vec<Vec<f64>>,
|
||||
}
|
||||
|
||||
impl LevAdd {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
usums: vec![vec![0.0; MDEPTH]; MION],
|
||||
dusmt: vec![vec![0.0; MDEPTH]; MION],
|
||||
dusmn: vec![vec![0.0; MDEPTH]; MION],
|
||||
diesig: vec![vec![0.0; MDEPTH]; MION],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 综合模型状态
|
||||
// ============================================================================
|
||||
|
||||
/// TLUSTY 大气模型状态。
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ModelState {
|
||||
pub modpar: ModPar,
|
||||
pub levpop: LevPop,
|
||||
pub gffpar: GffPar,
|
||||
pub totrad: TotRad,
|
||||
pub currad: CurRad,
|
||||
pub frqall: FrqAll,
|
||||
pub totprf: TotPrf,
|
||||
pub phoexp: PhoExp,
|
||||
pub obfpar: ObfPar,
|
||||
pub levadd: LevAdd,
|
||||
}
|
||||
|
||||
impl ModelState {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
gffpar: GffPar::new(),
|
||||
currad: CurRad::new(),
|
||||
totprf: TotPrf::new(),
|
||||
phoexp: PhoExp::new(),
|
||||
obfpar: ObfPar::new(),
|
||||
levadd: LevAdd::new(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取指定深度的温度
|
||||
pub fn temperature(&self, depth: usize) -> f64 {
|
||||
if depth < MDEPTH {
|
||||
self.modpar.temp[depth]
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取指定深度的电子密度
|
||||
pub fn electron_density(&self, depth: usize) -> f64 {
|
||||
if depth < MDEPTH {
|
||||
self.modpar.elec[depth]
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取指定深度的总粒子密度
|
||||
pub fn total_density(&self, depth: usize) -> f64 {
|
||||
if depth < MDEPTH {
|
||||
self.modpar.dens[depth]
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取指定能级在指定深度的占据数
|
||||
pub fn population(&self, level: usize, depth: usize) -> f64 {
|
||||
if level < MLEVEL && depth < MDEPTH {
|
||||
self.levpop.popul[level][depth]
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_model_state_creation() {
|
||||
let state = ModelState::new();
|
||||
assert_eq!(state.modpar.temp.len(), MDEPTH);
|
||||
assert_eq!(state.levpop.popul.len(), MLEVEL);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_temperature_accessor() {
|
||||
let mut state = ModelState::new();
|
||||
state.modpar.temp[0] = 10000.0;
|
||||
assert!((state.temperature(0) - 10000.0).abs() < 1e-10);
|
||||
assert_eq!(state.temperature(MDEPTH), 0.0); // 越界
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_population_accessor() {
|
||||
let mut state = ModelState::new();
|
||||
state.levpop.popul[0][0] = 1e10;
|
||||
assert!((state.population(0, 0) - 1e10).abs() < 1e-5);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,466 @@
|
||||
//! ODF (不透明度分布函数) 相关参数。
|
||||
//!
|
||||
//! 重构自 TLUSTY `ODFPAR.FOR`
|
||||
|
||||
use super::constants::*;
|
||||
|
||||
// ============================================================================
|
||||
// ODF 维度参数
|
||||
// ============================================================================
|
||||
|
||||
/// ODF 频率点数
|
||||
pub const MFODF: usize = 180;
|
||||
/// ODF 热点数
|
||||
pub const MHOD: usize = 3;
|
||||
/// ODF 频率范围
|
||||
pub const MFRO: usize = MFREQL;
|
||||
/// ODF 深度维度
|
||||
pub const MDODF: usize = 3;
|
||||
/// Kurucz 能级数
|
||||
pub const MKULEV: usize = 7000;
|
||||
/// 谱线数
|
||||
pub const MLINE: usize = 1140000;
|
||||
/// Fe 系数数
|
||||
pub const MCFE: usize = 7824000;
|
||||
|
||||
// ============================================================================
|
||||
// ODFION - ODF 离子控制
|
||||
// ============================================================================
|
||||
|
||||
/// ODF 离子控制。
|
||||
/// 对应 COMMON /ODFION/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct OdfIon {
|
||||
/// ODF 起始索引 1
|
||||
pub inodf1: Vec<i32>,
|
||||
/// ODF 起始索引 2
|
||||
pub inodf2: Vec<i32>,
|
||||
/// 束缚-自由截面索引
|
||||
pub inbfcs: Vec<i32>,
|
||||
/// Kurucz 观测标志
|
||||
pub ikobs: Vec<i32>,
|
||||
}
|
||||
|
||||
impl OdfIon {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
inodf1: vec![0; MION],
|
||||
inodf2: vec![0; MION],
|
||||
inbfcs: vec![0; MION],
|
||||
ikobs: vec![0; MION],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ODFCTR - ODF 控制
|
||||
// ============================================================================
|
||||
|
||||
/// ODF 控制参数。
|
||||
/// 对应 COMMON /ODFCTR/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct OdfCtr {
|
||||
/// ODF 频率
|
||||
pub frodf: Vec<f64>,
|
||||
/// ODF 频率计数
|
||||
pub nfrodf: Vec<i32>,
|
||||
/// 能级 ODF 索引
|
||||
pub indodf: Vec<i32>,
|
||||
/// 跃迁 ODF 索引
|
||||
pub jndodf: Vec<i32>,
|
||||
}
|
||||
|
||||
impl OdfCtr {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
frodf: vec![0.0; MLEVEL],
|
||||
nfrodf: vec![0; MHOD],
|
||||
indodf: vec![0; MLEVEL],
|
||||
jndodf: vec![0; MTRANS],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ODFFRQ - ODF 频率数据
|
||||
// ============================================================================
|
||||
|
||||
/// ODF 频率数据。
|
||||
/// 对应 COMMON /ODFFRQ/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct OdfFrq {
|
||||
/// ODF 频率 (起点)
|
||||
pub fros: Vec<Vec<f64>>,
|
||||
/// 波数
|
||||
pub wnus: Vec<Vec<f64>>,
|
||||
/// XDO
|
||||
pub xdo: Vec<Vec<f64>>,
|
||||
/// KDO
|
||||
pub kdo: Vec<Vec<i32>>,
|
||||
}
|
||||
|
||||
impl OdfFrq {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
fros: vec![vec![0.0; MHOD]; MFRO],
|
||||
wnus: vec![vec![0.0; MHOD]; MFRO],
|
||||
xdo: vec![vec![0.0; 3]; MHOD],
|
||||
kdo: vec![vec![0; 4]; MHOD],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ODFMOD - ODF 模型数据
|
||||
// ============================================================================
|
||||
|
||||
/// ODF 模型数据。
|
||||
/// 对应 COMMON /ODFMOD/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct OdfMod {
|
||||
pub i1odf: Vec<i32>,
|
||||
pub i2odf: Vec<i32>,
|
||||
pub nqlodf: Vec<i32>,
|
||||
}
|
||||
|
||||
impl OdfMod {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
i1odf: vec![0; MLEVEL],
|
||||
i2odf: vec![0; MLEVEL],
|
||||
nqlodf: vec![0; MLEVEL],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ODFSTK - ODF Stark 数据
|
||||
// ============================================================================
|
||||
|
||||
/// ODF Stark 展宽数据。
|
||||
/// 对应 COMMON /ODFSTK/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct OdfStk {
|
||||
/// XKIJ
|
||||
pub xkij: Vec<Vec<f64>>,
|
||||
/// 波长
|
||||
pub wl0: Vec<Vec<f64>>,
|
||||
/// FIJ
|
||||
pub fij: Vec<Vec<f64>>,
|
||||
}
|
||||
|
||||
impl OdfStk {
|
||||
pub fn new(nlmx: usize) -> Self {
|
||||
Self {
|
||||
xkij: vec![vec![0.0; nlmx]; MHOD],
|
||||
wl0: vec![vec![0.0; nlmx]; MHOD],
|
||||
fij: vec![vec![0.0; nlmx]; MHOD],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// SPLCOM - 样条/Fe 线数据
|
||||
// ============================================================================
|
||||
|
||||
/// Fe 线样条数据。
|
||||
/// 对应 COMMON /SPLCOM/
|
||||
///
|
||||
/// 注意:SIGFE 是非常大的数组 (3 × 7,824,000 = 23,472,000 个 f32)
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SplCom {
|
||||
/// Fe 截面 (f32 节省内存)
|
||||
pub sigfe: Vec<Vec<Vec<f32>>>,
|
||||
/// 频率起点 1
|
||||
pub frs1: f64,
|
||||
/// 频率终点 2
|
||||
pub frs2: f64,
|
||||
/// 频率间隔
|
||||
pub dxnu: f64,
|
||||
/// J 积分
|
||||
pub xjid: Vec<f64>,
|
||||
/// J ID
|
||||
pub jidi: Vec<i32>,
|
||||
/// J ID 半径
|
||||
pub jidr: Vec<i32>,
|
||||
/// J ID 起始
|
||||
pub jids: i32,
|
||||
/// J ID 数量
|
||||
pub jidn: i32,
|
||||
/// 频率起始索引
|
||||
pub nfrs1: i32,
|
||||
/// 频率表总数
|
||||
pub nftt: i32,
|
||||
}
|
||||
|
||||
impl Default for SplCom {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
// 使用较小的测试大小,实际运行时需要调整
|
||||
sigfe: vec![vec![vec![0.0; 100]; MDODF]; 100],
|
||||
frs1: 0.0,
|
||||
frs2: 0.0,
|
||||
dxnu: 0.0,
|
||||
xjid: vec![0.0; MDEPTH],
|
||||
jidi: vec![0; MDEPTH],
|
||||
jidr: vec![0; MDODF],
|
||||
jids: 0,
|
||||
jidn: 0,
|
||||
nfrs1: 0,
|
||||
nftt: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SplCom {
|
||||
/// 创建完整大小的数组 (需要大量内存)
|
||||
pub fn new_full() -> Self {
|
||||
Self {
|
||||
sigfe: vec![vec![vec![0.0; MCFE]; MDODF]; 1],
|
||||
frs1: 0.0,
|
||||
frs2: 0.0,
|
||||
dxnu: 0.0,
|
||||
xjid: vec![0.0; MDEPTH],
|
||||
jidi: vec![0; MDEPTH],
|
||||
jidr: vec![0; MDODF],
|
||||
jids: 0,
|
||||
jidn: 0,
|
||||
nfrs1: 0,
|
||||
nftt: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// 估算完整内存使用 (MB)
|
||||
pub fn full_memory_mb() -> f64 {
|
||||
// SIGFE: MDODF × MCFE × sizeof(f32)
|
||||
(MDODF * MCFE * std::mem::size_of::<f32>()) as f64 / (1024.0 * 1024.0)
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// OPALIM - 不透明度限制
|
||||
// ============================================================================
|
||||
|
||||
/// 不透明度限制参数。
|
||||
/// 对应 COMMON /OPALIM/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct OpaLim {
|
||||
pub m1file: Vec<Vec<i32>>,
|
||||
pub m2file: Vec<Vec<i32>>,
|
||||
pub imerg: i32,
|
||||
}
|
||||
|
||||
impl OpaLim {
|
||||
pub fn new(nlmx: usize) -> Self {
|
||||
Self {
|
||||
m1file: vec![vec![0; MHOD]; nlmx],
|
||||
m2file: vec![vec![0; MHOD]; nlmx],
|
||||
imerg: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// OPLIMT - 不透明度限制 T
|
||||
// ============================================================================
|
||||
|
||||
/// 不透明度限制温度相关。
|
||||
/// 对应 COMMON /OPLIMT/
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct OpLimT {
|
||||
pub allim1: f64,
|
||||
pub ablim1: f64,
|
||||
pub ablim2: f64,
|
||||
pub ablim3: f64,
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// LEVCOM - 能级 ODF 数据
|
||||
// ============================================================================
|
||||
|
||||
/// 能级 ODF 综合数据。
|
||||
/// 对应 COMMON /LEVCOM/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LevCom {
|
||||
/// EMKU
|
||||
pub emku: Vec<Vec<f64>>,
|
||||
/// YMKU
|
||||
pub ymku: Vec<Vec<f64>>,
|
||||
/// XEV
|
||||
pub xev: Vec<Vec<f64>>,
|
||||
/// XOD
|
||||
pub xod: Vec<Vec<f64>>,
|
||||
/// EU
|
||||
pub eu: Vec<f64>,
|
||||
/// JEN
|
||||
pub jen: Vec<i32>,
|
||||
|
||||
// Kurucz 能级数据
|
||||
/// EEV
|
||||
pub eev: Vec<f64>,
|
||||
/// AEV
|
||||
pub aev: Vec<f64>,
|
||||
/// SEV
|
||||
pub sev: Vec<f64>,
|
||||
/// WEV
|
||||
pub wev: Vec<f64>,
|
||||
/// EOD
|
||||
pub eod: Vec<f64>,
|
||||
/// AOD
|
||||
pub aod: Vec<f64>,
|
||||
/// SOD
|
||||
pub sod: Vec<f64>,
|
||||
/// WOD
|
||||
pub wod: Vec<f64>,
|
||||
/// KSEV
|
||||
pub ksev: Vec<i32>,
|
||||
/// KSOD
|
||||
pub ksod: Vec<i32>,
|
||||
/// NEVKU
|
||||
pub nevku: Vec<i32>,
|
||||
/// NODKU
|
||||
pub nodku: Vec<i32>,
|
||||
|
||||
// 计数器
|
||||
pub nlevku: i32,
|
||||
pub nlinku: i32,
|
||||
pub keve: i32,
|
||||
pub kodd: i32,
|
||||
}
|
||||
|
||||
impl Default for LevCom {
|
||||
fn default() -> Self {
|
||||
// 使用较小的测试大小
|
||||
Self {
|
||||
emku: vec![vec![0.0; 2]; MLEVEL],
|
||||
ymku: vec![vec![0.0; 2]; MLEVEL],
|
||||
xev: vec![vec![0.0; MION]; MLEVEL],
|
||||
xod: vec![vec![0.0; MION]; MLEVEL],
|
||||
eu: vec![0.0; 2 * MLEVEL],
|
||||
jen: vec![0; 2 * MLEVEL],
|
||||
|
||||
// Kurucz 数据使用较小的默认大小
|
||||
eev: vec![0.0; 1000],
|
||||
aev: vec![0.0; 1000],
|
||||
sev: vec![0.0; 1000],
|
||||
wev: vec![0.0; 1000],
|
||||
eod: vec![0.0; 1000],
|
||||
aod: vec![0.0; 1000],
|
||||
sod: vec![0.0; 1000],
|
||||
wod: vec![0.0; 1000],
|
||||
ksev: vec![0; 1000],
|
||||
ksod: vec![0; 1000],
|
||||
nevku: vec![0; MION],
|
||||
nodku: vec![0; MION],
|
||||
|
||||
nlevku: 0,
|
||||
nlinku: 0,
|
||||
keve: 0,
|
||||
kodd: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LevCom {
|
||||
/// 创建完整大小的数组
|
||||
pub fn new_full() -> Self {
|
||||
Self {
|
||||
emku: vec![vec![0.0; 2]; MLEVEL],
|
||||
ymku: vec![vec![0.0; 2]; MLEVEL],
|
||||
xev: vec![vec![0.0; MION]; MLEVEL],
|
||||
xod: vec![vec![0.0; MION]; MLEVEL],
|
||||
eu: vec![0.0; 2 * MLEVEL],
|
||||
jen: vec![0; 2 * MLEVEL],
|
||||
|
||||
eev: vec![0.0; MKULEV],
|
||||
aev: vec![0.0; MKULEV],
|
||||
sev: vec![0.0; MKULEV],
|
||||
wev: vec![0.0; MKULEV],
|
||||
eod: vec![0.0; MKULEV],
|
||||
aod: vec![0.0; MKULEV],
|
||||
sod: vec![0.0; MKULEV],
|
||||
wod: vec![0.0; MKULEV],
|
||||
ksev: vec![0; MKULEV],
|
||||
ksod: vec![0; MKULEV],
|
||||
nevku: vec![0; MION],
|
||||
nodku: vec![0; MION],
|
||||
|
||||
nlevku: 0,
|
||||
nlinku: 0,
|
||||
keve: 0,
|
||||
kodd: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// 估算完整内存使用 (MB)
|
||||
pub fn full_memory_mb() -> f64 {
|
||||
let main_size = (4 * MLEVEL * MION + 4 * MLEVEL + 2 * 2 * MLEVEL) * std::mem::size_of::<f64>();
|
||||
let kurucz_size = 8 * MKULEV * std::mem::size_of::<f64>();
|
||||
(main_size + kurucz_size) as f64 / (1024.0 * 1024.0)
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 综合 ODF 数据结构
|
||||
// ============================================================================
|
||||
|
||||
/// TLUSTY ODF 综合数据。
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct OdfData {
|
||||
pub odfion: OdfIon,
|
||||
pub odfctr: OdfCtr,
|
||||
pub odffrq: OdfFrq,
|
||||
pub odfmod: OdfMod,
|
||||
pub splcom: SplCom,
|
||||
pub opalim: OpaLim,
|
||||
pub oplimt: OpLimT,
|
||||
pub levcom: LevCom,
|
||||
}
|
||||
|
||||
impl OdfData {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
odfion: OdfIon::new(),
|
||||
odfctr: OdfCtr::new(),
|
||||
odffrq: OdfFrq::new(),
|
||||
odfmod: OdfMod::new(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// 估算完整内存使用 (MB)
|
||||
pub fn full_memory_mb() -> f64 {
|
||||
SplCom::full_memory_mb() + LevCom::full_memory_mb()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_odfion_creation() {
|
||||
let odfion = OdfIon::new();
|
||||
assert_eq!(odfion.inodf1.len(), MION);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_odfctr_creation() {
|
||||
let odfctr = OdfCtr::new();
|
||||
assert_eq!(odfctr.frodf.len(), MLEVEL);
|
||||
assert_eq!(odfctr.nfrodf.len(), MHOD);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_memory_estimates() {
|
||||
println!("SplCom full memory: {:.2} MB", SplCom::full_memory_mb());
|
||||
println!("LevCom full memory: {:.2} MB", LevCom::full_memory_mb());
|
||||
println!("Total ODF memory: {:.2} MB", OdfData::full_memory_mb());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_odf_data_creation() {
|
||||
let odf = OdfData::new();
|
||||
assert_eq!(odf.odfion.inodf1.len(), MION);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user