1577 lines
41 KiB
Rust
1577 lines
41 KiB
Rust
//! 非标准参数输入模块。
|
||
//!
|
||
//! 重构自 TLUSTY `nstpar.f`
|
||
//!
|
||
//! 设置各种输入标志的默认值,并从文件读取非标准值。
|
||
//! 共有 236 个可配置参数。
|
||
|
||
use super::{FortranReader, FortranWriter, Result};
|
||
use crate::tlusty::math::getwrd;
|
||
|
||
// f2r_depends: GETWRD
|
||
// NOTE: Fortran NSTPAR conditionally calls GETLAL (if iquasi>0);
|
||
// in Rust, GETLAL is called by the main program based on iquasi value.
|
||
|
||
// ============================================================================
|
||
// 参数常量
|
||
// ============================================================================
|
||
|
||
/// 可配置变量数量
|
||
pub const MVAR: usize = 236;
|
||
|
||
/// 非标准参数输入文件单元号
|
||
pub const INPFI: u8 = 4;
|
||
|
||
// ============================================================================
|
||
// 变量名表
|
||
// ============================================================================
|
||
|
||
/// 所有可配置参数的名称
|
||
pub const VARNAM: [&str; MVAR] = [
|
||
"ISPLIN", "IRTE ", "IBC ", "ILMCOR", "ILPSCT",
|
||
"ILASCT", "DJMAX ", "NTRALI", "IPSLTE", "IOPTAB",
|
||
"IFMOL ", "IFENTR", "NFRECL", "IFRYB ", "IFRAYL",
|
||
"HCMASS", "RADSTR", "BERGFC", "IHYDPR", "IIRWIN",
|
||
"ICOMPT", "IZSCAL", "IBCHE ", "IVISC ", "ALPHAV",
|
||
"ZETA0 ", "ZETA1 ", "FRACTV", "DMVISC", "REYNUM",
|
||
"IFZ0 ", "IHESO6", "ICOLHN",
|
||
"IFALI ", "IFPOPR", "JALI ", "IFRALI", "IFALIH",
|
||
"IFPREC", "IELCOR", "ICHC ", "IRSPLT", "IATREF",
|
||
"MODREF", "IACPP ", "IACDP ", "IFLEV ", "IDLTE ",
|
||
"POPZER", "POPZR2", "POPZCH", "NITZER", "RADZER",
|
||
"IFDIEL", "IFCHTR", "SHFAC ",
|
||
"QTLAS ", "ITLUCY", "IACLT ", "IACLDT", "IFMOFF",
|
||
"IOVER ", "ITLAS ", "NITER ", "NLAMBD", "IFRSET",
|
||
"ND ", "JIDS ", "IDMFIX", "ITNDRE",
|
||
"NMU ", "IOSCOR",
|
||
"NELSC ", "IHECOR", "IBFINT", "IRDER ",
|
||
"CHMAX ", "ILDER ", "IBPOPE", "CHMAXT", "NLAMT ",
|
||
"INTRPL", "ICHANG", "IFIXMO", "IFIXDE",
|
||
"INHE ", "INRE ", "INPC ", "INZD ", "INSE ",
|
||
"INMP ", "INDL ", "NDRE ", "TAUDIV", "IDLST ",
|
||
"NRETC ", "ICONV ", "IPRESS", "ITEMP ",
|
||
"ITMCOR", "ICONRE", "IDEEPC", "NDCGAP", "CRFLIM",
|
||
"IOPHMI", "IOPH2P", "IOPHEM", "IOPCH ", "IOPOH ",
|
||
"IOPH2M", "IOH2H2", "IOH2HE", "IOH2H ", "IOHHE ",
|
||
"IOPLYM",
|
||
"IOPOLD", "IRWTAB", "MOLTAB",
|
||
"IRSCT ", "IRSCH2", "IRSCHE", "KEEPOP",
|
||
"IQUASI", "NUNALP", "NUNBET", "TQMPRF",
|
||
"IACC ", "IACD ", "KSNG ", "ITEK ", "ORELAX",
|
||
"IWINBL", "ICOMGR",
|
||
"ICRSW ", "SWPFAC", "SWPLIM", "SWPINC",
|
||
"TAUFIR", "TAULAS", "ABROS0", "TSURF ", "ALBAVE",
|
||
"DION0 ", "NDGREY", "IDGREY", "NCONIT", "IPRING",
|
||
"DM1 ", "ABPLA0", "ABPMIN", "ITGMAX", "NNEWD ",
|
||
"IHM ", "IH2 ", "IH2P ", "IFTENE",
|
||
"TRAD ", "WDIL ",
|
||
"TDISK ", "TFLOOR", "TMOLIM",
|
||
"HMIX0 ", "MLTYPE", "VTB ", "IPTURB", "ILGDER",
|
||
"XGRAD ", "STRL1 ", "STRL2 ", "STRLX ",
|
||
"FRCMAX", "FRCMIN", "FRLMAX", "FRLMIN", "CFRMAX",
|
||
"DFTAIL", "NFTAIL", "TSNU ", "VTNU ", "DDNU ",
|
||
"IELNU ", "CNU1 ", "CNU2 ", "ISPODF",
|
||
"DPSILG", "DPSILT", "DPSILN", "DPSILD",
|
||
"ICOMST", "ICOMDE", "ICOMBC", "ICOMVE", "ICOMRT",
|
||
"ICMDRA", "KNISH ", "FRLCOM", "ICHCOO",
|
||
"NCFOR1", "NCFOR2", "NCCOUP", "NCITOT", "NCFULL",
|
||
"IFPRD ", "XPDIV ", "IFPZEV",
|
||
"IPRINI", "IDCONZ", "INTENS",
|
||
"ICOOLP", "IPRIND", "IPRINP", "ICHCKP", "IPOPAC",
|
||
"ILBC ", "IUBC ", "DERT ", "ICONRS", "IMUCON",
|
||
"IFPRAD", "ICHANM", "CUTLYM", "CUTBAL", "IHXENB",
|
||
"IHGOM ", "HGLIM ", "IPRCRS", "NPRCRS", "FRTLIM",
|
||
"DIFT ", "DIFP ", "GRDAD0", "ITGRAD",
|
||
"IPRYBH", "IPELCH", "IPELDO", "IPCONF"
|
||
];
|
||
|
||
// ============================================================================
|
||
// 默认值表
|
||
// ============================================================================
|
||
|
||
/// 所有参数的默认值(字符串格式,与 Fortran DATA 语句一致)
|
||
pub const PVALUE_DEFAULT: [&str; MVAR] = [
|
||
" 0", " 0", " 3", " 3", " 1",
|
||
" 0", " 1.D-3", " 3", " 0", " 0",
|
||
" 0", " 1", " 0", " 0", " 1",
|
||
" 0.", " 0.", " 1.", " 0", " 1",
|
||
" 0", " 0", " 1", " 0", " 0.1",
|
||
" 0.0", " 0.0", " -1", " 0.01", " 0.",
|
||
" 9", " 0", " 0",
|
||
" 5", " 4", " 1", " 0", " 0",
|
||
" 1", " -1", " 1", " 1", " 1",
|
||
" 1", " 7", " 4", " 0", " 1000",
|
||
"1.D-20", "1.D-20", "1.D-15", " 1", "1.D-20",
|
||
" 0", " 0", " 0.",
|
||
" 1.D30", " 0", " 7", " 4", " 0",
|
||
" 1", " 100", " 30", " 2", " 0",
|
||
" 70", " 0", " 1", " 1",
|
||
" 3", " 0",
|
||
" 0", " 0", " 1", " 3",
|
||
" 1.D-3", " 0", " 1", " 0.01", " 1",
|
||
" 0", " 0", " 0", " 0",
|
||
" 1", " 2", " 3", " 0", " 4",
|
||
" 0", " 0", " 0", " 0.5", " 5",
|
||
" 0", " 0", " 0", " 0",
|
||
" 0", " 1", " 2", " 2", " 0.7",
|
||
" 1", " 1", " 1", " 1", " 1",
|
||
" 1", " 1", " 1", " 1", " 1",
|
||
" 0",
|
||
" 0", " 1", " 1",
|
||
" 1", " 1", " 1", " 0",
|
||
" 0", " 3", " 0", " 0.",
|
||
" 7", " 4", " 0", " 4", " 1.D0",
|
||
" -1", " 0",
|
||
" 0", " 1.D-1", " 1.D-3", " 3.D0",
|
||
" 1.D-7", "316.0", " 0.4", " 0.", " 0.",
|
||
" 1.", " 0", " 0", " 0", " 0",
|
||
" 1.D-3", "3.D-1", "1.D-5", " 10", " 0",
|
||
" 0", " 0", " 0", " 0",
|
||
" 0.", " 0.",
|
||
" 0.", " 8000.", " 9000.",
|
||
" -1.", " 1", " 0.", " 1", " 0",
|
||
" 0.", "0.001", " 0.02", "1.D-10",
|
||
" 0.", "1.D12", " 0.", "1.D13", " 0.",
|
||
" 0.25", " 21", " 0.", " 0.", " 0.75",
|
||
" 0", " 4.5", " 3.", " 0",
|
||
" 10.", " 1.25", " 10.", " 1.25",
|
||
" 1", " 1", " 1", " 0", " 0",
|
||
" 0", " 0", "8.2D14", " 1",
|
||
" 0", " 1", " 0", " 1", " 1",
|
||
" 0", " 3.D0", " 0",
|
||
" 0", " 31", " 10",
|
||
" 0", " 0", " 1", " 0", " 0",
|
||
" 0", " 0", " 0.01", " 10", " 10",
|
||
" 1", " 1", " 0.", " 0.", " 0",
|
||
" 0", "1.D18", " 0", " 0", "3.2880",
|
||
" 0.01", " 0.01", " 0.", " 0",
|
||
" 0", " 0", " 0", " 0"
|
||
];
|
||
|
||
// ============================================================================
|
||
// NstparParams - 非标准参数结构
|
||
// ============================================================================
|
||
|
||
/// 非标准参数配置。
|
||
///
|
||
/// 包含 TLUSTY 运行的所有可配置参数。
|
||
/// 参数按功能分组,便于理解。
|
||
#[derive(Debug, Clone)]
|
||
pub struct NstparParams {
|
||
// === 基本控制参数 ===
|
||
pub isplin: i32,
|
||
pub irte: i32,
|
||
pub ibc: i32,
|
||
pub ilmcor: i32,
|
||
pub ilpsct: i32,
|
||
pub ilasct: i32,
|
||
pub djmax: f64,
|
||
pub ntrali: i32,
|
||
pub ipslte: i32,
|
||
pub ioptab: i32,
|
||
|
||
// === 分子和能量参数 ===
|
||
pub ifmol: i32,
|
||
pub ifentr: i32,
|
||
pub nfrecl: i32,
|
||
pub ifryb: i32,
|
||
pub ifrayl: i32,
|
||
|
||
// === 恒星风/He参数 ===
|
||
pub hcmass: f64,
|
||
pub radstr: f64,
|
||
pub bergfc: f64,
|
||
pub ihydpr: i32,
|
||
pub iirwin: i32,
|
||
|
||
// === Compton/标度参数 ===
|
||
pub icompt: i32,
|
||
pub izscal: i32,
|
||
pub ibche: i32,
|
||
pub ivisc: i32,
|
||
pub alphav: f64,
|
||
|
||
// === 粘性参数 ===
|
||
pub zeta0: f64,
|
||
pub zeta1: f64,
|
||
pub fractv: i32,
|
||
pub dmvisc: f64,
|
||
pub reynum: f64,
|
||
|
||
// === 其他控制 ===
|
||
pub ifz0: i32,
|
||
pub iheso6: i32,
|
||
pub icolhn: i32,
|
||
|
||
// === ALI (加速Lambda迭代) 参数 ===
|
||
pub ifali: i32,
|
||
pub ifpopr: i32,
|
||
pub jali: i32,
|
||
pub ifrali: i32,
|
||
pub ifalih: i32,
|
||
pub ifprec: i32,
|
||
pub ielcor: i32,
|
||
pub ichc: i32,
|
||
pub irsplt: i32,
|
||
pub iatref: i32,
|
||
pub modref: i32,
|
||
pub iacpp: i32,
|
||
pub iacdp: i32,
|
||
pub iflev: i32,
|
||
pub idlte: i32,
|
||
|
||
// === 种群零点参数 ===
|
||
pub popzer: f64,
|
||
pub popzr2: f64,
|
||
pub popzch: f64,
|
||
pub nitzer: i32,
|
||
pub radzer: f64,
|
||
|
||
// === 介电/电荷转移 ===
|
||
pub ifdiel: i32,
|
||
pub ifchtr: i32,
|
||
pub shfac: f64,
|
||
|
||
// === 温度加速 ===
|
||
pub qtlas: f64,
|
||
pub itlucy: i32,
|
||
pub iaclt: i32,
|
||
pub iacldt: i32,
|
||
pub ifmoff: i32,
|
||
|
||
// === 迭代控制 ===
|
||
pub iover: i32,
|
||
pub itlas: i32,
|
||
pub niter: i32,
|
||
pub nlambd: i32,
|
||
pub ifrset: i32,
|
||
|
||
// === 深度/几何 ===
|
||
pub nd: i32,
|
||
pub jids: i32,
|
||
pub idmfix: i32,
|
||
pub itndre: i32,
|
||
pub nmu: i32,
|
||
pub ioscor: i32,
|
||
|
||
// === He/相关性 ===
|
||
pub nelsc: i32,
|
||
pub ihecor: i32,
|
||
pub ibfint: i32,
|
||
pub irder: i32,
|
||
|
||
// === 变化控制 ===
|
||
pub chmax: f64,
|
||
pub ilder: i32,
|
||
pub ibpope: i32,
|
||
pub chmaxt: f64,
|
||
pub nlamt: i32,
|
||
pub intrpl: i32,
|
||
pub ichang: i32,
|
||
pub ifixmo: i32,
|
||
pub ifixde: i32,
|
||
|
||
// === 材料变化索引 ===
|
||
pub inhe: i32,
|
||
pub inre: i32,
|
||
pub inpc: i32,
|
||
pub inzd: i32,
|
||
pub inse: i32,
|
||
pub inmp: i32,
|
||
pub indl: i32,
|
||
pub ndre: i32,
|
||
pub taudiv: f64,
|
||
pub idlst: i32,
|
||
|
||
// === 收敛控制 ===
|
||
pub nretc: i32,
|
||
pub iconv: i32,
|
||
pub ipress: i32,
|
||
pub itemp: i32,
|
||
pub itmcor: i32,
|
||
pub iconre: i32,
|
||
pub ideepc: i32,
|
||
pub ndcgap: i32,
|
||
pub crflim: f64,
|
||
|
||
// === 不透明度开关 ===
|
||
pub iophmi: i32,
|
||
pub ioph2p: i32,
|
||
pub iophem: i32,
|
||
pub iopch: i32,
|
||
pub iopoh: i32,
|
||
pub ioph2m: i32,
|
||
pub ioh2h2: i32,
|
||
pub ioh2he: i32,
|
||
pub ioh2h: i32,
|
||
pub iohhe: i32,
|
||
pub ioplym: i32,
|
||
|
||
// === 不透明度/分子表 ===
|
||
pub iopold: i32,
|
||
pub irwtab: i32,
|
||
pub moltab: i32,
|
||
|
||
// === 散射 ===
|
||
pub irsct: i32,
|
||
pub irsch2: i32,
|
||
pub irsche: i32,
|
||
pub keepop: i32,
|
||
|
||
// === 准静态 ===
|
||
pub iquasi: i32,
|
||
pub nunalp: i32,
|
||
pub nunbet: i32,
|
||
pub tqmprf: f64,
|
||
|
||
// === 加速控制 ===
|
||
pub iacc: i32,
|
||
pub iacd: i32,
|
||
pub ksng: i32,
|
||
pub itek: i32,
|
||
pub orelax: f64,
|
||
pub iwinbl: i32,
|
||
pub icomgr: i32,
|
||
|
||
// === 交换参数 ===
|
||
pub icrsw: i32,
|
||
pub swpfac: f64,
|
||
pub swplim: f64,
|
||
pub swpinc: f64,
|
||
|
||
// === 大气边界 ===
|
||
pub taufir: f64,
|
||
pub taulas: f64,
|
||
pub abros0: f64,
|
||
pub tsurf: f64,
|
||
pub albave: f64,
|
||
pub dion0: f64,
|
||
pub ndgrey: i32,
|
||
pub idgrey: i32,
|
||
pub nconit: i32,
|
||
pub ipring: i32,
|
||
|
||
// === 密度/丰度 ===
|
||
pub dm1: f64,
|
||
pub abpla0: f64,
|
||
pub abpmin: f64,
|
||
pub itgmax: i32,
|
||
pub nnewd: i32,
|
||
|
||
// === H/He 物种 ===
|
||
pub ihm: i32,
|
||
pub ih2: i32,
|
||
pub ih2p: i32,
|
||
pub iftene: i32,
|
||
|
||
// === 辐射稀释 ===
|
||
pub trad: f64,
|
||
pub wdil: f64,
|
||
|
||
// === 盘模型 ===
|
||
pub tdisk: f64,
|
||
pub tfloor: f64,
|
||
pub tmolim: f64,
|
||
|
||
// === 对流 ===
|
||
pub hmix0: f64,
|
||
pub mltype: i32,
|
||
pub vtb: f64,
|
||
pub ipturb: i32,
|
||
pub ilgder: i32,
|
||
|
||
// === 梯度 ===
|
||
pub xgrad: f64,
|
||
pub strl1: f64,
|
||
pub strl2: f64,
|
||
pub strlx: f64,
|
||
|
||
// === 频率范围 ===
|
||
pub frcmax: f64,
|
||
pub frcmin: f64,
|
||
pub frlmax: f64,
|
||
pub frlmin: f64,
|
||
pub cfrmax: f64,
|
||
|
||
// === 线尾参数 ===
|
||
pub dftail: f64,
|
||
pub nftail: i32,
|
||
pub tsnu: f64,
|
||
pub vtnu: f64,
|
||
pub ddnu: f64,
|
||
pub ielnu: i32,
|
||
pub cnu1: f64,
|
||
pub cnu2: f64,
|
||
pub ispodf: i32,
|
||
|
||
// === Psi 限制 ===
|
||
pub dpsilg: f64,
|
||
pub dpsilt: f64,
|
||
pub dpsiln: f64,
|
||
pub dpsild: f64,
|
||
|
||
// === Compton 控制 ===
|
||
pub icomst: i32,
|
||
pub icomde: i32,
|
||
pub icombc: i32,
|
||
pub icomve: i32,
|
||
pub icomrt: i32,
|
||
pub icmdra: i32,
|
||
pub knish: i32,
|
||
pub frlcom: f64,
|
||
pub ichcoo: i32,
|
||
|
||
// === 耦合迭代 ===
|
||
pub ncfor1: i32,
|
||
pub ncfor2: i32,
|
||
pub nccoup: i32,
|
||
pub ncitot: i32,
|
||
pub ncfull: i32,
|
||
|
||
// === 其他 ===
|
||
pub ifprd: i32,
|
||
pub xpdiv: f64,
|
||
pub ifpzev: i32,
|
||
|
||
// === 打印控制 ===
|
||
pub iprini: i32,
|
||
pub idconz: i32,
|
||
pub intens: i32,
|
||
pub icoolp: i32,
|
||
pub iprind: i32,
|
||
pub iprinp: i32,
|
||
pub ichckp: i32,
|
||
pub ipopac: i32,
|
||
|
||
// === 边界条件 ===
|
||
pub ilbc: i32,
|
||
pub iubc: i32,
|
||
pub dert: f64,
|
||
pub iconrs: i32,
|
||
pub imucon: i32,
|
||
pub ifprad: i32,
|
||
pub ichanm: i32,
|
||
pub cutlym: f64,
|
||
pub cutbal: f64,
|
||
pub ihxenb: i32,
|
||
|
||
// === He/H 梯度 ===
|
||
pub ihgom: i32,
|
||
pub hglim: f64,
|
||
pub iprcrs: i32,
|
||
pub nprcrs: i32,
|
||
pub frtlim: f64,
|
||
|
||
// === 扩散 ===
|
||
pub dift: f64,
|
||
pub difp: f64,
|
||
pub grdad0: f64,
|
||
pub itgrad: i32,
|
||
|
||
// === 打印键 ===
|
||
pub iprybh: i32,
|
||
pub ipelch: i32,
|
||
pub ipeldo: i32,
|
||
pub ipconf: i32,
|
||
}
|
||
|
||
impl Default for NstparParams {
|
||
fn default() -> Self {
|
||
Self {
|
||
// 基本控制
|
||
isplin: 0,
|
||
irte: 0,
|
||
ibc: 3,
|
||
ilmcor: 3,
|
||
ilpsct: 1,
|
||
ilasct: 0,
|
||
djmax: 1e-3,
|
||
ntrali: 3,
|
||
ipslte: 0,
|
||
ioptab: 0,
|
||
// 分子/能量
|
||
ifmol: 0,
|
||
ifentr: 1,
|
||
nfrecl: 0,
|
||
ifryb: 0,
|
||
ifrayl: 1,
|
||
// 恒星风/He
|
||
hcmass: 0.0,
|
||
radstr: 0.0,
|
||
bergfc: 1.0,
|
||
ihydpr: 0,
|
||
iirwin: 1,
|
||
// Compton/标度
|
||
icompt: 0,
|
||
izscal: 0,
|
||
ibche: 1,
|
||
ivisc: 0,
|
||
alphav: 0.1,
|
||
// 粘性
|
||
zeta0: 0.0,
|
||
zeta1: 0.0,
|
||
fractv: -1,
|
||
dmvisc: 0.01,
|
||
reynum: 0.0,
|
||
// 其他控制
|
||
ifz0: 9,
|
||
iheso6: 0,
|
||
icolhn: 0,
|
||
// ALI
|
||
ifali: 5,
|
||
ifpopr: 4,
|
||
jali: 1,
|
||
ifrali: 0,
|
||
ifalih: 0,
|
||
ifprec: 1,
|
||
ielcor: -1,
|
||
ichc: 1,
|
||
irsplt: 1,
|
||
iatref: 1,
|
||
modref: 1,
|
||
iacpp: 7,
|
||
iacdp: 4,
|
||
iflev: 0,
|
||
idlte: 1000,
|
||
// 种群零点
|
||
popzer: 1e-20,
|
||
popzr2: 1e-20,
|
||
popzch: 1e-15,
|
||
nitzer: 1,
|
||
radzer: 1e-20,
|
||
// 介电/电荷转移
|
||
ifdiel: 0,
|
||
ifchtr: 0,
|
||
shfac: 0.0,
|
||
// 温度加速
|
||
qtlas: 1e30,
|
||
itlucy: 0,
|
||
iaclt: 7,
|
||
iacldt: 4,
|
||
ifmoff: 0,
|
||
// 迭代控制
|
||
iover: 1,
|
||
itlas: 100,
|
||
niter: 30,
|
||
nlambd: 2,
|
||
ifrset: 0,
|
||
// 深度/几何
|
||
nd: 70,
|
||
jids: 0,
|
||
idmfix: 1,
|
||
itndre: 1,
|
||
nmu: 3,
|
||
ioscor: 0,
|
||
// He/相关性
|
||
nelsc: 0,
|
||
ihecor: 0,
|
||
ibfint: 1,
|
||
irder: 3,
|
||
// 变化控制
|
||
chmax: 1e-3,
|
||
ilder: 0,
|
||
ibpope: 1,
|
||
chmaxt: 0.01,
|
||
nlamt: 1,
|
||
intrpl: 0,
|
||
ichang: 0,
|
||
ifixmo: 0,
|
||
ifixde: 0,
|
||
// 材料变化
|
||
inhe: 1,
|
||
inre: 2,
|
||
inpc: 3,
|
||
inzd: 0,
|
||
inse: 4,
|
||
inmp: 0,
|
||
indl: 0,
|
||
ndre: 0,
|
||
taudiv: 0.5,
|
||
idlst: 5,
|
||
// 收敛
|
||
nretc: 0,
|
||
iconv: 0,
|
||
ipress: 0,
|
||
itemp: 0,
|
||
itmcor: 0,
|
||
iconre: 1,
|
||
ideepc: 2,
|
||
ndcgap: 2,
|
||
crflim: 0.7,
|
||
// 不透明度
|
||
iophmi: 1,
|
||
ioph2p: 1,
|
||
iophem: 1,
|
||
iopch: 1,
|
||
iopoh: 1,
|
||
ioph2m: 1,
|
||
ioh2h2: 1,
|
||
ioh2he: 1,
|
||
ioh2h: 1,
|
||
iohhe: 1,
|
||
ioplym: 0,
|
||
// 不透明度/分子表
|
||
iopold: 0,
|
||
irwtab: 1,
|
||
moltab: 1,
|
||
// 散射
|
||
irsct: 1,
|
||
irsch2: 1,
|
||
irsche: 1,
|
||
keepop: 0,
|
||
// 准静态
|
||
iquasi: 0,
|
||
nunalp: 3,
|
||
nunbet: 0,
|
||
tqmprf: 0.0,
|
||
// 加速
|
||
iacc: 7,
|
||
iacd: 4,
|
||
ksng: 0,
|
||
itek: 4,
|
||
orelax: 1.0,
|
||
iwinbl: -1,
|
||
icomgr: 0,
|
||
// 交换
|
||
icrsw: 0,
|
||
swpfac: 0.1,
|
||
swplim: 1e-3,
|
||
swpinc: 3.0,
|
||
// 大气边界
|
||
taufir: 1e-7,
|
||
taulas: 316.0,
|
||
abros0: 0.4,
|
||
tsurf: 0.0,
|
||
albave: 0.0,
|
||
dion0: 1.0,
|
||
ndgrey: 0,
|
||
idgrey: 0,
|
||
nconit: 0,
|
||
ipring: 0,
|
||
// 密度/丰度
|
||
dm1: 0.0,
|
||
abpla0: 1e-3,
|
||
abpmin: 0.3,
|
||
itgmax: 10,
|
||
nnewd: 0,
|
||
// H/He
|
||
ihm: 0,
|
||
ih2: 0,
|
||
ih2p: 0,
|
||
iftene: 0,
|
||
// 辐射稀释
|
||
trad: 0.0,
|
||
wdil: 0.0,
|
||
// 盘模型
|
||
tdisk: 0.0,
|
||
tfloor: 8000.0,
|
||
tmolim: 9000.0,
|
||
// 对流
|
||
hmix0: -1.0,
|
||
mltype: 1,
|
||
vtb: 0.0,
|
||
ipturb: 1,
|
||
ilgder: 0,
|
||
// 梯度
|
||
xgrad: 0.0,
|
||
strl1: 0.001,
|
||
strl2: 0.02,
|
||
strlx: 1e-10,
|
||
// 频率范围
|
||
frcmax: 0.0,
|
||
frcmin: 1e12,
|
||
frlmax: 0.0,
|
||
frlmin: 1e13,
|
||
cfrmax: 0.0,
|
||
// 线尾
|
||
dftail: 0.25,
|
||
nftail: 21,
|
||
tsnu: 0.0,
|
||
vtnu: 0.0,
|
||
ddnu: 0.75,
|
||
ielnu: 0,
|
||
cnu1: 4.5,
|
||
cnu2: 3.0,
|
||
ispodf: 0,
|
||
// Psi 限制
|
||
dpsilg: 10.0,
|
||
dpsilt: 1.25,
|
||
dpsiln: 10.0,
|
||
dpsild: 1.25,
|
||
// Compton 控制
|
||
icomst: 1,
|
||
icomde: 1,
|
||
icombc: 1,
|
||
icomve: 0,
|
||
icomrt: 0,
|
||
icmdra: 0,
|
||
knish: 0,
|
||
frlcom: 8.2e14,
|
||
ichcoo: 1,
|
||
// 耦合迭代
|
||
ncfor1: 0,
|
||
ncfor2: 1,
|
||
nccoup: 0,
|
||
ncitot: 1,
|
||
ncfull: 1,
|
||
// 其他
|
||
ifprd: 0,
|
||
xpdiv: 3.0,
|
||
ifpzev: 0,
|
||
// 打印控制
|
||
iprini: 0,
|
||
idconz: 31,
|
||
intens: 10,
|
||
icoolp: 0,
|
||
iprind: 0,
|
||
iprinp: 1,
|
||
ichckp: 0,
|
||
ipopac: 0,
|
||
// 边界条件
|
||
ilbc: 0,
|
||
iubc: 0,
|
||
dert: 0.01,
|
||
iconrs: 10,
|
||
imucon: 10,
|
||
ifprad: 1,
|
||
ichanm: 1,
|
||
cutlym: 0.0,
|
||
cutbal: 0.0,
|
||
ihxenb: 0,
|
||
// He/H 梯度
|
||
ihgom: 0,
|
||
hglim: 1e18,
|
||
iprcrs: 0,
|
||
nprcrs: 0,
|
||
frtlim: 3.2880,
|
||
// 扩散
|
||
dift: 0.01,
|
||
difp: 0.01,
|
||
grdad0: 0.0,
|
||
itgrad: 0,
|
||
// 打印键
|
||
iprybh: 0,
|
||
ipelch: 0,
|
||
ipeldo: 0,
|
||
ipconf: 0,
|
||
}
|
||
}
|
||
}
|
||
|
||
impl NstparParams {
|
||
/// 从字符串数组解析参数值
|
||
pub fn from_values(values: &[String; MVAR]) -> Self {
|
||
let parse_i32 = |s: &str| -> i32 {
|
||
s.trim()
|
||
.replace('D', "E")
|
||
.replace('d', "e")
|
||
.parse()
|
||
.unwrap_or(0)
|
||
};
|
||
|
||
let parse_f64 = |s: &str| -> f64 {
|
||
s.trim()
|
||
.replace('D', "E")
|
||
.replace('d', "e")
|
||
.parse()
|
||
.unwrap_or(0.0)
|
||
};
|
||
|
||
let mut idx = 0;
|
||
macro_rules! next_i32 {
|
||
() => {{
|
||
let v = parse_i32(&values[idx]);
|
||
idx += 1;
|
||
v
|
||
}};
|
||
}
|
||
macro_rules! next_f64 {
|
||
() => {{
|
||
let v = parse_f64(&values[idx]);
|
||
idx += 1;
|
||
v
|
||
}};
|
||
}
|
||
|
||
Self {
|
||
isplin: next_i32!(),
|
||
irte: next_i32!(),
|
||
ibc: next_i32!(),
|
||
ilmcor: next_i32!(),
|
||
ilpsct: next_i32!(),
|
||
ilasct: next_i32!(),
|
||
djmax: next_f64!(),
|
||
ntrali: next_i32!(),
|
||
ipslte: next_i32!(),
|
||
ioptab: next_i32!(),
|
||
ifmol: next_i32!(),
|
||
ifentr: next_i32!(),
|
||
nfrecl: next_i32!(),
|
||
ifryb: next_i32!(),
|
||
ifrayl: next_i32!(),
|
||
hcmass: next_f64!(),
|
||
radstr: next_f64!(),
|
||
bergfc: next_f64!(),
|
||
ihydpr: next_i32!(),
|
||
iirwin: next_i32!(),
|
||
icompt: next_i32!(),
|
||
izscal: next_i32!(),
|
||
ibche: next_i32!(),
|
||
ivisc: next_i32!(),
|
||
alphav: next_f64!(),
|
||
zeta0: next_f64!(),
|
||
zeta1: next_f64!(),
|
||
fractv: next_i32!(),
|
||
dmvisc: next_f64!(),
|
||
reynum: next_f64!(),
|
||
ifz0: next_i32!(),
|
||
iheso6: next_i32!(),
|
||
icolhn: next_i32!(),
|
||
ifali: next_i32!(),
|
||
ifpopr: next_i32!(),
|
||
jali: next_i32!(),
|
||
ifrali: next_i32!(),
|
||
ifalih: next_i32!(),
|
||
ifprec: next_i32!(),
|
||
ielcor: next_i32!(),
|
||
ichc: next_i32!(),
|
||
irsplt: next_i32!(),
|
||
iatref: next_i32!(),
|
||
modref: next_i32!(),
|
||
iacpp: next_i32!(),
|
||
iacdp: next_i32!(),
|
||
iflev: next_i32!(),
|
||
idlte: next_i32!(),
|
||
popzer: next_f64!(),
|
||
popzr2: next_f64!(),
|
||
popzch: next_f64!(),
|
||
nitzer: next_i32!(),
|
||
radzer: next_f64!(),
|
||
ifdiel: next_i32!(),
|
||
ifchtr: next_i32!(),
|
||
shfac: next_f64!(),
|
||
qtlas: next_f64!(),
|
||
itlucy: next_i32!(),
|
||
iaclt: next_i32!(),
|
||
iacldt: next_i32!(),
|
||
ifmoff: next_i32!(),
|
||
iover: next_i32!(),
|
||
itlas: next_i32!(),
|
||
niter: next_i32!(),
|
||
nlambd: next_i32!(),
|
||
ifrset: next_i32!(),
|
||
nd: next_i32!(),
|
||
jids: next_i32!(),
|
||
idmfix: next_i32!(),
|
||
itndre: next_i32!(),
|
||
nmu: next_i32!(),
|
||
ioscor: next_i32!(),
|
||
nelsc: next_i32!(),
|
||
ihecor: next_i32!(),
|
||
ibfint: next_i32!(),
|
||
irder: next_i32!(),
|
||
chmax: next_f64!(),
|
||
ilder: next_i32!(),
|
||
ibpope: next_i32!(),
|
||
chmaxt: next_f64!(),
|
||
nlamt: next_i32!(),
|
||
intrpl: next_i32!(),
|
||
ichang: next_i32!(),
|
||
ifixmo: next_i32!(),
|
||
ifixde: next_i32!(),
|
||
inhe: next_i32!(),
|
||
inre: next_i32!(),
|
||
inpc: next_i32!(),
|
||
inzd: next_i32!(),
|
||
inse: next_i32!(),
|
||
inmp: next_i32!(),
|
||
indl: next_i32!(),
|
||
ndre: next_i32!(),
|
||
taudiv: next_f64!(),
|
||
idlst: next_i32!(),
|
||
nretc: next_i32!(),
|
||
iconv: next_i32!(),
|
||
ipress: next_i32!(),
|
||
itemp: next_i32!(),
|
||
itmcor: next_i32!(),
|
||
iconre: next_i32!(),
|
||
ideepc: next_i32!(),
|
||
ndcgap: next_i32!(),
|
||
crflim: next_f64!(),
|
||
iophmi: next_i32!(),
|
||
ioph2p: next_i32!(),
|
||
iophem: next_i32!(),
|
||
iopch: next_i32!(),
|
||
iopoh: next_i32!(),
|
||
ioph2m: next_i32!(),
|
||
ioh2h2: next_i32!(),
|
||
ioh2he: next_i32!(),
|
||
ioh2h: next_i32!(),
|
||
iohhe: next_i32!(),
|
||
ioplym: next_i32!(),
|
||
iopold: next_i32!(),
|
||
irwtab: next_i32!(),
|
||
moltab: next_i32!(),
|
||
irsct: next_i32!(),
|
||
irsch2: next_i32!(),
|
||
irsche: next_i32!(),
|
||
keepop: next_i32!(),
|
||
iquasi: next_i32!(),
|
||
nunalp: next_i32!(),
|
||
nunbet: next_i32!(),
|
||
tqmprf: next_f64!(),
|
||
iacc: next_i32!(),
|
||
iacd: next_i32!(),
|
||
ksng: next_i32!(),
|
||
itek: next_i32!(),
|
||
orelax: next_f64!(),
|
||
iwinbl: next_i32!(),
|
||
icomgr: next_i32!(),
|
||
icrsw: next_i32!(),
|
||
swpfac: next_f64!(),
|
||
swplim: next_f64!(),
|
||
swpinc: next_f64!(),
|
||
taufir: next_f64!(),
|
||
taulas: next_f64!(),
|
||
abros0: next_f64!(),
|
||
tsurf: next_f64!(),
|
||
albave: next_f64!(),
|
||
dion0: next_f64!(),
|
||
ndgrey: next_i32!(),
|
||
idgrey: next_i32!(),
|
||
nconit: next_i32!(),
|
||
ipring: next_i32!(),
|
||
dm1: next_f64!(),
|
||
abpla0: next_f64!(),
|
||
abpmin: next_f64!(),
|
||
itgmax: next_i32!(),
|
||
nnewd: next_i32!(),
|
||
ihm: next_i32!(),
|
||
ih2: next_i32!(),
|
||
ih2p: next_i32!(),
|
||
iftene: next_i32!(),
|
||
trad: next_f64!(),
|
||
wdil: next_f64!(),
|
||
tdisk: next_f64!(),
|
||
tfloor: next_f64!(),
|
||
tmolim: next_f64!(),
|
||
hmix0: next_f64!(),
|
||
mltype: next_i32!(),
|
||
vtb: next_f64!(),
|
||
ipturb: next_i32!(),
|
||
ilgder: next_i32!(),
|
||
xgrad: next_f64!(),
|
||
strl1: next_f64!(),
|
||
strl2: next_f64!(),
|
||
strlx: next_f64!(),
|
||
frcmax: next_f64!(),
|
||
frcmin: next_f64!(),
|
||
frlmax: next_f64!(),
|
||
frlmin: next_f64!(),
|
||
cfrmax: next_f64!(),
|
||
dftail: next_f64!(),
|
||
nftail: next_i32!(),
|
||
tsnu: next_f64!(),
|
||
vtnu: next_f64!(),
|
||
ddnu: next_f64!(),
|
||
ielnu: next_i32!(),
|
||
cnu1: next_f64!(),
|
||
cnu2: next_f64!(),
|
||
ispodf: next_i32!(),
|
||
dpsilg: next_f64!(),
|
||
dpsilt: next_f64!(),
|
||
dpsiln: next_f64!(),
|
||
dpsild: next_f64!(),
|
||
icomst: next_i32!(),
|
||
icomde: next_i32!(),
|
||
icombc: next_i32!(),
|
||
icomve: next_i32!(),
|
||
icomrt: next_i32!(),
|
||
icmdra: next_i32!(),
|
||
knish: next_i32!(),
|
||
frlcom: next_f64!(),
|
||
ichcoo: next_i32!(),
|
||
ncfor1: next_i32!(),
|
||
ncfor2: next_i32!(),
|
||
nccoup: next_i32!(),
|
||
ncitot: next_i32!(),
|
||
ncfull: next_i32!(),
|
||
ifprd: next_i32!(),
|
||
xpdiv: next_f64!(),
|
||
ifpzev: next_i32!(),
|
||
iprini: next_i32!(),
|
||
idconz: next_i32!(),
|
||
intens: next_i32!(),
|
||
icoolp: next_i32!(),
|
||
iprind: next_i32!(),
|
||
iprinp: next_i32!(),
|
||
ichckp: next_i32!(),
|
||
ipopac: next_i32!(),
|
||
ilbc: next_i32!(),
|
||
iubc: next_i32!(),
|
||
dert: next_f64!(),
|
||
iconrs: next_i32!(),
|
||
imucon: next_i32!(),
|
||
ifprad: next_i32!(),
|
||
ichanm: next_i32!(),
|
||
cutlym: next_f64!(),
|
||
cutbal: next_f64!(),
|
||
ihxenb: next_i32!(),
|
||
ihgom: next_i32!(),
|
||
hglim: next_f64!(),
|
||
iprcrs: next_i32!(),
|
||
nprcrs: next_i32!(),
|
||
frtlim: next_f64!(),
|
||
dift: next_f64!(),
|
||
difp: next_f64!(),
|
||
grdad0: next_f64!(),
|
||
itgrad: next_i32!(),
|
||
iprybh: next_i32!(),
|
||
ipelch: next_i32!(),
|
||
ipeldo: next_i32!(),
|
||
ipconf: next_i32!(),
|
||
}
|
||
}
|
||
}
|
||
|
||
// ============================================================================
|
||
// NstparOutput - 输出状态
|
||
// ============================================================================
|
||
|
||
/// NSTPAR 输出状态。
|
||
///
|
||
/// 包含解析后的参数和需要更新的状态变量。
|
||
#[derive(Debug, Clone)]
|
||
pub struct NstparOutput {
|
||
pub params: NstparParams,
|
||
/// CRSW 数组(初始为 1.0)
|
||
pub crsw: Vec<f64>,
|
||
/// 是否启用 LCHC
|
||
pub lchc: bool,
|
||
/// 固定频率数
|
||
pub nffix: i32,
|
||
/// 总不透明度开关
|
||
pub iopadd: i32,
|
||
/// RRDIL 值
|
||
pub rrdil: f64,
|
||
/// ITGMX0 值
|
||
pub itgmx0: i32,
|
||
/// Lambda 迭代计数数组
|
||
pub nitlam: Vec<i32>,
|
||
/// 对流参数
|
||
pub aconml: f64,
|
||
pub bconml: f64,
|
||
pub cconml: f64,
|
||
}
|
||
|
||
// ============================================================================
|
||
// 纯解析函数
|
||
// ============================================================================
|
||
|
||
/// 纯解析函数:从文本行解析关键字-值对。
|
||
///
|
||
/// # 参数
|
||
/// * `lines` - 输入文件的文本行
|
||
///
|
||
/// # 返回
|
||
/// 包含所有参数值的数组
|
||
pub fn parse_keyword_values(lines: &[String]) -> [String; MVAR] {
|
||
let mut pvalue: [String; MVAR] = std::array::from_fn(|i| PVALUE_DEFAULT[i].to_string());
|
||
|
||
let mut ivar: isize = -1;
|
||
let mut indv: isize = -1;
|
||
|
||
for text in lines {
|
||
let mut k0: usize = 0;
|
||
|
||
loop {
|
||
let (k1, k2) = match getwrd(text, k0) {
|
||
Some((k1, k2)) => (k1, k2),
|
||
None => break,
|
||
};
|
||
k0 = k2 + 2;
|
||
|
||
// 跳过等号
|
||
if k2 >= k1 && k2 < text.len() {
|
||
let word = &text[k1..=k2];
|
||
if word == "=" {
|
||
continue;
|
||
}
|
||
|
||
indv = -indv;
|
||
|
||
if indv == 1 {
|
||
// 查找变量名
|
||
let mut found = false;
|
||
for i in 0..MVAR {
|
||
let varnam_trimmed = VARNAM[i].trim();
|
||
if word.len() <= varnam_trimmed.len()
|
||
&& word == &varnam_trimmed[..word.len()]
|
||
{
|
||
ivar = i as isize;
|
||
found = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if !found {
|
||
// 跳过未知变量的值
|
||
let result = getwrd(text, k0);
|
||
if result.is_none() {
|
||
// 需要读取下一行
|
||
break;
|
||
}
|
||
let (k1_next, k2_next) = result.unwrap();
|
||
k0 = k2_next + 2;
|
||
indv = -indv;
|
||
}
|
||
} else {
|
||
// 设置变量值
|
||
if ivar >= 0 && (ivar as usize) < MVAR {
|
||
// 右对齐到6字符
|
||
let padded = format!("{:>6}", word);
|
||
pvalue[ivar as usize] = padded;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
pvalue
|
||
}
|
||
|
||
// ============================================================================
|
||
// 后处理函数
|
||
// ============================================================================
|
||
|
||
/// 应用参数后处理逻辑。
|
||
///
|
||
/// 根据 TLUSTY 的规则调整参数值。
|
||
pub fn apply_nstpar_postprocessing(
|
||
params: &mut NstparParams,
|
||
teff: f64,
|
||
idisk: i32,
|
||
lte: bool,
|
||
ltgrey: bool,
|
||
ielhm: i32,
|
||
mdepth: usize,
|
||
mlambd: usize,
|
||
mmu: usize,
|
||
) -> NstparOutput {
|
||
// 初始化 CRSW 数组
|
||
let crsw = vec![1.0; mdepth];
|
||
|
||
// LTGREY 和 LTE 修正
|
||
if ltgrey {
|
||
params.ispodf = 0;
|
||
}
|
||
if lte {
|
||
params.iflev = 1;
|
||
}
|
||
if params.ifryb >= 1 {
|
||
params.idlst = 0;
|
||
}
|
||
|
||
// LCHC 标志
|
||
let lchc = params.ichc == 1;
|
||
|
||
// 固定频率数
|
||
let nffix = params.ifrali;
|
||
|
||
// IACC 修正
|
||
if params.iacc <= 4 {
|
||
params.iacc = 7;
|
||
}
|
||
|
||
// 频率范围修正(转换为 Hz)
|
||
if params.frtlim < 1e6 {
|
||
params.frtlim *= 1e15;
|
||
}
|
||
if params.frcmax < 1e6 {
|
||
params.frcmax *= 1e15;
|
||
}
|
||
if params.frlmax < 1e6 {
|
||
params.frlmax *= 1e15;
|
||
}
|
||
if params.frcmin < 1e6 {
|
||
params.frcmin *= 1e13;
|
||
}
|
||
if params.frlmin < 1e6 {
|
||
params.frlmin *= 1e13;
|
||
}
|
||
|
||
// FRLMAX 默认值
|
||
if params.frlmax == 0.0 {
|
||
params.frlmax = (1e11 * params.cnu1 * teff).max(3.288e15);
|
||
}
|
||
|
||
// CFRMAX 默认值
|
||
if idisk == 0 && params.cfrmax == 0.0 {
|
||
params.cfrmax = 2.0;
|
||
}
|
||
|
||
// TRAD 检查
|
||
if params.trad != 0.0 {
|
||
params.iwinbl = -1;
|
||
}
|
||
|
||
// NITZER 限制
|
||
if params.nitzer > params.itek {
|
||
params.nitzer = params.itek;
|
||
}
|
||
if params.nitzer > params.iacc - params.iacd {
|
||
params.nitzer = params.iacc - params.iacd;
|
||
}
|
||
|
||
// 高温修正
|
||
if teff > 15000.0 {
|
||
params.ioph2p = 0;
|
||
params.iopch = 0;
|
||
params.iopoh = 0;
|
||
params.irsch2 = 0;
|
||
params.ioph2m = 0;
|
||
params.ioh2h2 = 0;
|
||
params.ioh2he = 0;
|
||
params.ioh2h = 0;
|
||
params.iohhe = 0;
|
||
}
|
||
|
||
// 计算总不透明度开关
|
||
let iopadd = params.iophmi
|
||
+ params.ioph2p
|
||
+ params.iophem
|
||
+ params.iopch
|
||
+ params.iopoh
|
||
+ params.ioph2m
|
||
+ params.ioh2h2
|
||
+ params.ioh2he
|
||
+ params.ioh2h
|
||
+ params.iohhe
|
||
+ params.irsct
|
||
+ params.irsch2
|
||
+ params.irsche;
|
||
|
||
// IELCOR 修正
|
||
if params.ioptab < 0 || params.ifmol > 0 {
|
||
params.ielcor = -1;
|
||
}
|
||
|
||
// RRDIL
|
||
let rrdil = 1.0;
|
||
|
||
// IFZ0 修正
|
||
if idisk == 0 {
|
||
params.ifz0 = -1;
|
||
}
|
||
|
||
// ITGMX0
|
||
let itgmx0 = params.itgmax;
|
||
|
||
// Lambda 迭代计数
|
||
let mut nitlam = vec![0; params.niter as usize + 2];
|
||
if params.nlambd < 0 {
|
||
params.nlambd = -params.nlambd;
|
||
if lte {
|
||
params.nlambd = 1;
|
||
}
|
||
for itl in 0..12.min(nitlam.len()) {
|
||
nitlam[itl] = params.nlambd;
|
||
}
|
||
for itl in 12..nitlam.len() {
|
||
nitlam[itl] = 2;
|
||
}
|
||
} else if params.nlambd > 0 {
|
||
if lte {
|
||
params.nlambd = 1;
|
||
}
|
||
for itl in 0..nitlam.len() {
|
||
nitlam[itl] = params.nlambd;
|
||
}
|
||
}
|
||
|
||
// ILMCOR 修正
|
||
if params.ilmcor >= 3 {
|
||
params.ilpsct = 1;
|
||
}
|
||
|
||
// INZD/INSE 默认值
|
||
if idisk == 1
|
||
&& params.inzd == 0
|
||
&& params.izscal == 0
|
||
&& params.ivisc <= 1
|
||
&& params.ifryb == 0
|
||
{
|
||
params.inzd = 4;
|
||
params.inse = 5;
|
||
}
|
||
|
||
// IFIXMO 修正
|
||
if params.ifixmo > 0 {
|
||
params.inhe = 0;
|
||
params.inre = 0;
|
||
params.inpc = 0;
|
||
params.inzd = 0;
|
||
params.inse = 1;
|
||
}
|
||
|
||
// IFIXDE 修正
|
||
if params.ifixde > 0 {
|
||
params.inhe = 1;
|
||
params.inre = 0;
|
||
params.inpc = 2;
|
||
params.inzd = 0;
|
||
params.inse = 3;
|
||
}
|
||
|
||
// IPRCRS 修正
|
||
if params.iprcrs > 0 {
|
||
params.niter = 0;
|
||
params.nlambd = 1;
|
||
}
|
||
|
||
// 对流参数
|
||
let (aconml, bconml, cconml) = if params.mltype == 2 {
|
||
(1.0, 2.0, 16.0)
|
||
} else {
|
||
(1.0 / 8.0, 0.5, 16.0)
|
||
};
|
||
|
||
// IELHM 修正
|
||
if ielhm > 0 {
|
||
params.iophmi = 0;
|
||
}
|
||
|
||
NstparOutput {
|
||
params: params.clone(),
|
||
crsw,
|
||
lchc,
|
||
nffix,
|
||
iopadd,
|
||
rrdil,
|
||
itgmx0,
|
||
nitlam,
|
||
aconml,
|
||
bconml,
|
||
cconml,
|
||
}
|
||
}
|
||
|
||
// ============================================================================
|
||
// I/O 函数
|
||
// ============================================================================
|
||
|
||
/// 读取非标准参数文件。
|
||
///
|
||
/// # 参数
|
||
/// * `reader` - FortranReader 实例
|
||
/// * `teff` - 有效温度
|
||
/// * `idisk` - 盘模型标志
|
||
/// * `lte` - LTE 标志
|
||
/// * `ltgrey` - LTGREY 标志
|
||
/// * `ielhm` - IELHM 参数
|
||
/// * `mdepth` - 最大深度点数
|
||
/// * `mlambd` - 最大 Lambda 点数
|
||
/// * `mmu` - 最大角度点数
|
||
///
|
||
/// # 返回
|
||
/// 解析后的输出状态
|
||
pub fn nstpar<R: std::io::BufRead>(
|
||
reader: &mut FortranReader<R>,
|
||
teff: f64,
|
||
idisk: i32,
|
||
lte: bool,
|
||
ltgrey: bool,
|
||
ielhm: i32,
|
||
mdepth: usize,
|
||
mlambd: usize,
|
||
mmu: usize,
|
||
) -> Result<NstparOutput> {
|
||
// 读取所有行
|
||
let mut lines: Vec<String> = Vec::new();
|
||
loop {
|
||
match reader.read_line() {
|
||
Ok(line) => {
|
||
// 跳过空行
|
||
if !line.trim().is_empty() {
|
||
lines.push(line.to_string());
|
||
}
|
||
}
|
||
Err(_) => break, // EOF
|
||
}
|
||
}
|
||
|
||
// 解析关键字-值对
|
||
let pvalue = parse_keyword_values(&lines);
|
||
|
||
// 创建参数结构
|
||
let mut params = NstparParams::from_values(&pvalue);
|
||
|
||
// 验证边界
|
||
if params.nd > mdepth as i32 {
|
||
return Err(super::IoError::FormatError(format!(
|
||
"nd ({}) > mdepth ({})",
|
||
params.nd, mdepth
|
||
)));
|
||
}
|
||
if params.ndgrey > mdepth as i32 {
|
||
return Err(super::IoError::FormatError(format!(
|
||
"ndgrey ({}) > mdepth ({})",
|
||
params.ndgrey, mdepth
|
||
)));
|
||
}
|
||
if params.nlambd > mlambd as i32 {
|
||
return Err(super::IoError::FormatError(format!(
|
||
"nlambd ({}) > mlambd ({})",
|
||
params.nlambd, mlambd
|
||
)));
|
||
}
|
||
if params.iacc <= 2 {
|
||
return Err(super::IoError::FormatError(format!(
|
||
"Ng too early: iacc = {}",
|
||
params.iacc
|
||
)));
|
||
}
|
||
if params.nmu > mmu as i32 {
|
||
return Err(super::IoError::FormatError(format!(
|
||
"nmu ({}) > mmu ({})",
|
||
params.nmu, mmu
|
||
)));
|
||
}
|
||
|
||
// 后处理
|
||
Ok(apply_nstpar_postprocessing(
|
||
&mut params,
|
||
teff,
|
||
idisk,
|
||
lte,
|
||
ltgrey,
|
||
ielhm,
|
||
mdepth,
|
||
mlambd,
|
||
mmu,
|
||
))
|
||
}
|
||
|
||
// ============================================================================
|
||
// 测试
|
||
// ============================================================================
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
#[test]
|
||
fn test_default_params() {
|
||
let params = NstparParams::default();
|
||
assert_eq!(params.ibc, 3);
|
||
assert_eq!(params.ilmcor, 3);
|
||
assert!((params.djmax - 1e-3).abs() < 1e-10);
|
||
assert_eq!(params.iacc, 7);
|
||
assert_eq!(params.niter, 30);
|
||
}
|
||
|
||
#[test]
|
||
fn test_parse_empty_input() {
|
||
let lines: Vec<String> = vec![];
|
||
let pvalue = parse_keyword_values(&lines);
|
||
|
||
// 应该全部是默认值
|
||
assert_eq!(pvalue[0].trim(), "0"); // ISPLIN
|
||
assert_eq!(pvalue[2].trim(), "3"); // IBC
|
||
}
|
||
|
||
#[test]
|
||
fn test_parse_simple_keyword() {
|
||
let lines: Vec<String> = vec!["IBC = 5".to_string()];
|
||
let pvalue = parse_keyword_values(&lines);
|
||
|
||
// IBC 是第3个变量(索引2)
|
||
assert_eq!(pvalue[2].trim(), "5");
|
||
}
|
||
|
||
#[test]
|
||
fn test_parse_multiple_keywords() {
|
||
let lines: Vec<String> = vec![
|
||
"ISPLIN = 1".to_string(),
|
||
"IBC = 7".to_string(),
|
||
"NITER = 50".to_string(),
|
||
];
|
||
let pvalue = parse_keyword_values(&lines);
|
||
|
||
assert_eq!(pvalue[0].trim(), "1"); // ISPLIN
|
||
assert_eq!(pvalue[2].trim(), "7"); // IBC
|
||
assert_eq!(pvalue[63].trim(), "50"); // NITER (index 63)
|
||
}
|
||
|
||
#[test]
|
||
fn test_from_values() {
|
||
let mut values: [String; MVAR] = std::array::from_fn(|i| PVALUE_DEFAULT[i].to_string());
|
||
values[2] = " 7".to_string(); // IBC
|
||
values[63] = " 50".to_string(); // NITER (index 63)
|
||
|
||
let params = NstparParams::from_values(&values);
|
||
assert_eq!(params.ibc, 7);
|
||
assert_eq!(params.niter, 50);
|
||
}
|
||
|
||
#[test]
|
||
fn test_postprocessing_high_temp() {
|
||
let mut params = NstparParams::default();
|
||
let output = apply_nstpar_postprocessing(
|
||
&mut params,
|
||
20000.0, // teff > 15000
|
||
0, // idisk
|
||
false, // lte
|
||
false, // ltgrey
|
||
0, // ielhm
|
||
100, // mdepth
|
||
100, // mlambd
|
||
8, // mmu
|
||
);
|
||
|
||
// 高温时应关闭分子不透明度
|
||
assert_eq!(output.params.ioph2p, 0);
|
||
assert_eq!(output.params.iopch, 0);
|
||
assert_eq!(output.params.ioh2h2, 0);
|
||
}
|
||
|
||
#[test]
|
||
fn test_postprocessing_lte() {
|
||
let mut params = NstparParams::default();
|
||
params.nlambd = -5; // 负值表示均匀分布
|
||
let output = apply_nstpar_postprocessing(
|
||
&mut params,
|
||
10000.0,
|
||
0,
|
||
true, // lte
|
||
false,
|
||
0,
|
||
100,
|
||
100,
|
||
8,
|
||
);
|
||
|
||
// LTE 时 nlambd = 1
|
||
assert_eq!(output.params.nlambd, 1);
|
||
// IFLEV = 1
|
||
assert_eq!(output.params.iflev, 1);
|
||
}
|
||
|
||
#[test]
|
||
fn test_convection_params() {
|
||
let mut params = NstparParams::default();
|
||
params.mltype = 2;
|
||
let output = apply_nstpar_postprocessing(&mut params, 10000.0, 0, false, false, 0, 100, 100, 8);
|
||
|
||
assert!((output.aconml - 1.0).abs() < 1e-10);
|
||
assert!((output.bconml - 2.0).abs() < 1e-10);
|
||
}
|
||
|
||
#[test]
|
||
fn test_varnam_count() {
|
||
// 确保 VARNAM 和 PVALUE_DEFAULT 长度正确
|
||
assert_eq!(VARNAM.len(), MVAR);
|
||
assert_eq!(PVALUE_DEFAULT.len(), MVAR);
|
||
}
|
||
}
|