SpectraRust/src/tlusty/math/ali/alifr1.rs
2026-03-25 18:34:41 +08:00

1484 lines
58 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! ALI 频率相关计算 - 变体 1。
//!
//! 重构自 TLUSTY `alifr1.f`
//!
//! 计算流体静力学和辐射平衡量 - ALI 点的总加热和冷却率对
//! 温度、电子密度和占据数的导数。
//! 这是一致三对角算子的变体。
//!
//! ## 实现状态
//! 完整实现。包含以下代码路径:
//! - ILMCOR == 3, ILASCT == 0标准路径
//! - ILMCOR == 3, ILASCT != 0
//! - ILMCOR != 3, ILASCT == 0
//! - ILMCOR != 3, ILASCT != 0
//! - 完整的边界条件处理 (IBC = 0, 1, 2, 3+)
//!
//! 当 IFALI > 5 时,返回 `true`,调用者应调用 `alifr3`。
use crate::tlusty::state::alipar::FixAlp;
use crate::tlusty::state::constants::{UN, TWO, HALF};
/// ALIFR1 输入参数
pub struct Alifr1Params {
/// 频率索引 (1-indexed)
pub ij: usize,
/// 深度点数
pub nd: usize,
/// 线性化能级数
pub nlvexp: usize,
/// ALI 模式
pub ifali: i32,
/// 辐射导数模式
pub irder: i32,
/// ILMCOR 参数
pub ilmcor: i32,
/// ILASCT 参数
pub ilasct: i32,
/// 边界条件类型
pub ibc: i32,
/// 是否为盘模型
pub idisk: i32,
/// IFALIH 参数
pub ifalih: i32,
}
/// ALIFR1 需要的模型状态输入
pub struct Alifr1ModelState<'a> {
// 深度相关 (MDEPTH)
pub elec: &'a [f64],
pub dens: &'a [f64],
pub densi: &'a [f64],
pub densim: &'a [f64],
pub dens1: &'a [f64],
pub dm: &'a [f64],
pub deldmz: &'a [f64],
pub elscat: &'a [f64],
pub absot: &'a [f64],
pub hkt21: &'a [f64],
pub xkfb: &'a [f64],
pub xkf1: &'a [f64],
// 辐射相关 (MDEPTH)
pub rad1: &'a [f64],
pub fak1: &'a [f64],
// 频率相关
pub freq: &'a [f64],
pub hextrd: &'a [f64],
pub sigec: &'a [f64],
pub sige: f64,
pub extrad: &'a [f64],
pub fh: &'a [f64],
pub w: &'a [f64],
/// 表面辐射通量 Q0 (MFREQ)
pub q0: &'a [f64],
// 跳过标志 (MDEPTH × MFREQ)
pub lskip: &'a [Vec<i32>],
// 平衡相关
pub reint: &'a [f64],
pub redif: &'a [f64],
// 输出累积变量
pub fprd: &'a mut [f64],
pub flfix: &'a mut [f64],
pub flrd: &'a mut [f64],
pub fcooli: &'a mut [f64],
pub heit: &'a mut [f64],
pub hein: &'a mut [f64],
pub heim: &'a mut [f64],
pub heitm: &'a mut [f64],
pub heinm: &'a mut [f64],
pub heimm: &'a mut [f64],
pub heip: &'a mut [Vec<f64>],
pub heipm: &'a mut [Vec<f64>],
pub redt: &'a mut [f64],
pub redn: &'a mut [f64],
pub redm: &'a mut [f64],
pub redx: &'a mut [f64],
pub redtm: &'a mut [f64],
pub rednm: &'a mut [f64],
pub redmm: &'a mut [f64],
pub redxm: &'a mut [f64],
pub redp: &'a mut [Vec<f64>],
pub redpm: &'a mut [Vec<f64>],
pub rein: &'a mut [f64],
pub reit: &'a mut [f64],
pub reim: &'a mut [f64],
pub reip: &'a mut [Vec<f64>],
}
/// ALIFR1 需要的辐射/不透明度状态
pub struct Alifr1RadState<'a> {
/// 权重因子 (MFREQ)
pub wc: &'a [f64],
/// 当前频率发射系数 (MDEPTH)
pub emis1: &'a [f64],
/// 当前频率吸收系数 (MDEPTH)
pub abso1: &'a [f64],
/// 当前频率散射系数 (MDEPTH)
pub scat1: &'a [f64],
/// 发射系数 T 导数 (MDEPTH)
pub demt1: &'a [f64],
/// 发射系数 N 导数 (MDEPTH)
pub demn1: &'a [f64],
/// 发射系数 M 导数 (MDEPTH)
pub demm1: &'a [f64],
/// 吸收系数 T 导数 (MDEPTH)
pub dabt1: &'a [f64],
/// 吸收系数 N 导数 (MDEPTH)
pub dabn1: &'a [f64],
/// 吸收系数 M 导数 (MDEPTH)
pub dabm1: &'a [f64],
/// 发射系数能级导数 (MLVEXP × MDEPTH)
pub demp1: &'a [Vec<f64>],
/// 吸收系数能级导数 (MLVEXP × MDEPTH)
pub dabp1: &'a [Vec<f64>],
}
/// 计算 ALI 频率相关量 - 变体 1。
///
/// # 参数
///
/// * `params` - 输入参数
/// * `fixalp` - ALI 固定参数
/// * `model` - 模型状态
/// * `rad` - 辐射状态
///
/// # 返回值
///
/// 返回 `true` 表示调用者应该调用 `alifr3`(当 IFALI > 5 时)。
/// 返回 `false` 表示处理已完成或无需进一步操作。
///
/// # Fortran 索引说明
///
/// - IJ 是频率索引 (1-indexed)
/// - ID 是深度索引 (1-indexed)
/// - II 是能级索引 (1-indexed)
///
/// # 实现状态
///
/// 完整实现:
/// - IFALI <= 1 时直接返回
/// - IFALI > 5 时返回 true调用者应调用 alifr3
/// - ILMCOR == 3 且 ILASCT == 0 的标准路径
/// - ILMCOR == 3 且 ILASCT != 0 的路径
/// - ILMCOR != 3 的路径
/// - 完整的深度循环和边界条件处理IBC = 0, 1, 2, 3+
#[allow(clippy::too_many_arguments)]
pub fn alifr1(
params: &Alifr1Params,
fixalp: &mut FixAlp,
model: &mut Alifr1ModelState,
rad: &Alifr1RadState,
) -> bool {
// 如果 IFALI <= 1直接返回
if params.ifali <= 1 {
return false;
}
// 如果 IFALI > 5返回 true 指示调用者应该调用 ALIFR3
// 注意:由于 Rust 借用限制ALIFR3 需要由调用者直接调用
if params.ifali > 5 {
return true;
}
let ij = params.ij;
let nd = params.nd;
let nlvexp = params.nlvexp;
// 获取权重因子
let ww = rad.wc[ij - 1];
// 常量
let t23 = TWO / 3.0;
// 根据 ILMCOR 值选择不同的处理路径
if params.ilmcor == 3 {
// ================================================================
// ILMCOR == 3 的处理(标准情况)
// ================================================================
process_standard_path(params, fixalp, model, rad, ij, nd, nlvexp, ww, t23);
return false;
}
// ================================================================
// ILMCOR != 3 的处理(非标准情况)
// ILASCT == 0 的分支
// ================================================================
if params.ilasct == 0 {
process_ilasct_zero(params, fixalp, model, rad, ij, nd, nlvexp, ww);
return false;
}
// ================================================================
// ILASCT != 0 的处理
// ================================================================
process_ilasct_nonzero(params, fixalp, model, rad, ij, nd, nlvexp, ww);
false
}
/// 处理标准路径 (ILMCOR == 3, ILASCT == 0)
#[allow(clippy::too_many_arguments)]
fn process_standard_path(
params: &Alifr1Params,
fixalp: &mut FixAlp,
model: &mut Alifr1ModelState,
rad: &Alifr1RadState,
ij: usize,
nd: usize,
nlvexp: usize,
ww: f64,
t23: f64,
) {
// 初始化中间变量
let mut dsft1m: f64 = 0.0;
let mut dsfn1m: f64 = 0.0;
let mut dsfm1m: f64 = 0.0;
let mut dsfp1m = vec![0.0; nlvexp];
// 1. 第一个深度点 (ID=1)
let id = 1;
let id_idx = id - 1;
let lnskip = model.lskip[id_idx][ij - 1] == 0;
// 基本辅助量 - 源函数的导数
let emisiv = if rad.emis1[id_idx] < 1e-35 { 1e35 } else { UN / rad.emis1[id_idx] };
let abst = UN / rad.abso1[id_idx];
let mut s0 = rad.emis1[id_idx] * abst;
// 改进边界条件的贡献
let dt = (rad.abso1[id_idx] / model.dens[id_idx] + rad.abso1[id] / model.dens[id])
* (model.dm[id] - model.dm[id_idx]) * HALF;
let sa = s0 * (UN + 4.0 / dt * model.q0[ij - 1]);
s0 = s0 * (UN + TWO / dt * model.q0[ij - 1]);
let sc = rad.scat1[id_idx];
let sct = sc * abst;
let corr = UN / (UN - fixalp.ali1[id_idx] * sct);
let dsft1 = corr * (s0 * rad.demt1[id_idx] * emisiv - s0 * rad.dabt1[id_idx] * abst);
let dsfn1 = corr * (s0 * rad.demn1[id_idx] * emisiv - s0 * rad.dabn1[id_idx] * abst);
let dsfm1 = corr * (s0 * rad.demm1[id_idx] * emisiv - s0 * rad.dabm1[id_idx] * abst);
let mut dsfp1 = vec![0.0; nlvexp];
for ii in 0..nlvexp {
dsfp1[ii] = corr * (s0 * rad.demp1[ii][id_idx] * emisiv - sa * rad.dabp1[ii][id_idx] * abst);
}
// ID+1 的值
let idp_idx = id;
let emisip = if rad.emis1[idp_idx] < 1e-35 { 1e35 } else { UN / rad.emis1[idp_idx] };
let abstp = UN / rad.abso1[idp_idx];
let s0p = rad.emis1[idp_idx] * abstp;
let scp = rad.scat1[idp_idx];
let sctp = scp * abstp;
let corrp = UN / (UN - fixalp.ali1[idp_idx] * sctp);
let mut dsft1p = corrp * (s0p * rad.demt1[idp_idx] * emisip - s0p * rad.dabt1[idp_idx] * abstp);
let mut dsfn1p = corrp * (s0p * rad.demn1[idp_idx] * emisip - s0p * rad.dabn1[idp_idx] * abstp);
let mut dsfm1p = corrp * (s0p * rad.demm1[idp_idx] * emisip - s0p * rad.dabm1[idp_idx] * abstp);
let mut dsfp1p = vec![0.0; nlvexp];
for ii in 0..nlvexp {
dsfp1p[ii] = corrp * (s0p * rad.demp1[ii][idp_idx] * emisip - s0p * rad.dabp1[ii][idp_idx] * abstp);
}
// 更新 DSFDT, DSFDN, DSFDM 等
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1 * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1 * fixalp.ali1[id_idx];
fixalp.dsfdm[id_idx] = dsfm1 * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1[ii] * fixalp.ali1[id_idx];
}
}
// 流体静力学平衡量
let wf = ww * model.fh[ij - 1];
if lnskip {
model.fprd[id_idx] += wf * rad.abso1[id_idx] * model.rad1[id_idx]
- ww * model.hextrd[ij - 1] * rad.abso1[id_idx];
let e0 = wf * model.rad1[id_idx];
let d0 = wf * rad.abso1[id_idx] * fixalp.ali1[id_idx];
model.heit[id_idx] += d0 * dsft1 + e0 * rad.dabt1[id_idx];
model.hein[id_idx] += d0 * dsfn1 + e0 * rad.dabn1[id_idx];
model.heim[id_idx] += d0 * dsfm1 + e0 * rad.dabm1[id_idx];
for ii in 0..nlvexp {
model.heip[ii][id_idx] += d0 * dsfp1[ii] + e0 * rad.dabp1[ii][id_idx];
}
}
// 辐射平衡微分方程部分
model.flfix[id_idx] += wf * model.rad1[id_idx] - ww * model.hextrd[ij - 1];
model.flrd[id_idx] += model.w[ij - 1] * model.fh[ij - 1] * model.rad1[id_idx]
- model.w[ij - 1] * HALF * model.extrad[ij - 1];
if model.redif[id_idx] > 0.0 {
let wf = wf * fixalp.ali1[id_idx];
model.redt[id_idx] += wf * dsft1;
model.redn[id_idx] += wf * dsfn1;
model.redm[id_idx] += wf * dsfm1;
for ii in 0..nlvexp {
model.redp[ii][id_idx] += wf * dsfp1[ii];
}
}
// 辐射平衡积分方程部分
if model.reint[id_idx] > 0.0 {
let abst_true = rad.abso1[id_idx] - model.elscat[id_idx];
let d0 = abst_true * fixalp.ali1[id_idx];
model.fcooli[id_idx] += ww * (rad.emis1[id_idx] - abst_true * model.rad1[id_idx]);
model.reit[id_idx] += ww * (d0 * dsft1 + model.rad1[id_idx] * rad.dabt1[id_idx] - rad.demt1[id_idx]);
model.rein[id_idx] += ww * (d0 * dsfn1
+ model.rad1[id_idx] * (rad.dabn1[id_idx] - model.sigec[ij - 1])
- rad.demn1[id_idx]);
model.reim[id_idx] += ww * (d0 * dsfm1 + model.rad1[id_idx] * rad.dabm1[id_idx] - rad.demm1[id_idx]);
for ii in 0..nlvexp {
model.reip[ii][id_idx] += ww * (d0 * dsfp1[ii]
+ model.rad1[id_idx] * rad.dabp1[ii][id_idx]
- rad.demp1[ii][id_idx]);
}
}
// 2. 深度循环 (ID = 2 to ND-1)
for id in 2..nd {
let id_idx = id - 1;
let lnskip = model.lskip[id_idx][ij - 1] == 0;
// 保存前一个点的值
dsft1m = dsft1;
dsfn1m = dsfn1;
dsfm1m = dsfm1;
for ii in 0..nlvexp {
dsfp1m[ii] = dsfp1[ii];
}
// 更新当前点为上一个点的 ID+1 值
let dsft1_curr = dsft1p;
let dsfn1_curr = dsfn1p;
let dsfm1_curr = dsfm1p;
let dsfp1_curr = dsfp1p.clone();
// 计算 ID+1 的值
let idp_idx = id;
let emisip_new = if rad.emis1[idp_idx] < 1e-35 { 1e35 } else { UN / rad.emis1[idp_idx] };
let abstp_new = UN / rad.abso1[idp_idx];
let s0p_new = rad.emis1[idp_idx] * abstp_new;
let scp_new = rad.scat1[idp_idx];
let sctp_new = scp_new * abstp_new;
let corrp_new = UN / (UN - fixalp.ali1[idp_idx] * sctp_new);
dsft1p = corrp_new * (s0p_new * rad.demt1[idp_idx] * emisip_new - s0p_new * rad.dabt1[idp_idx] * abstp_new);
dsfn1p = corrp_new * (s0p_new * rad.demn1[idp_idx] * emisip_new - s0p_new * rad.dabn1[idp_idx] * abstp_new);
dsfm1p = corrp_new * (s0p_new * rad.demm1[idp_idx] * emisip_new - s0p_new * rad.dabm1[idp_idx] * abstp_new);
dsfp1p = vec![0.0; nlvexp];
for ii in 0..nlvexp {
dsfp1p[ii] = corrp_new * (s0p_new * rad.demp1[ii][idp_idx] * emisip_new - s0p_new * rad.dabp1[ii][idp_idx] * abstp_new);
}
// 更新 DSFDT, DSFDN, DSFDM 等
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1_curr * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1_curr * fixalp.ali1[id_idx];
fixalp.dsfdm[id_idx] = dsfm1_curr * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1_curr[ii] * fixalp.ali1[id_idx];
}
}
// 流体静力学平衡方程
if lnskip {
let d0 = ww * model.fak1[id_idx];
let a0 = ww * model.fak1[id_idx - 1];
model.fprd[id_idx] += d0 * model.rad1[id_idx] - a0 * model.rad1[id_idx - 1];
let e0 = d0 * fixalp.alim1[id_idx] - a0 * fixalp.ali1[id_idx - 1];
let d0_new = d0 * fixalp.ali1[id_idx] - a0 * fixalp.alip1[id_idx - 1];
model.heit[id_idx] += d0_new * dsft1_curr;
model.hein[id_idx] += d0_new * dsfn1_curr;
model.heim[id_idx] += d0_new * dsfm1_curr;
model.heitm[id_idx] += e0 * dsft1m;
model.heinm[id_idx] += e0 * dsfn1m;
model.heimm[id_idx] += e0 * dsfm1m;
for ii in 0..nlvexp {
model.heip[ii][id_idx] += d0_new * dsfp1_curr[ii];
model.heipm[ii][id_idx] += e0 * dsfp1m[ii];
}
}
// 辐射平衡微分方程部分
let ddt = UN / (model.absot[id_idx] + model.absot[id_idx - 1]);
let dt = ddt / model.deldmz[id_idx - 1];
let fl = (model.rad1[id_idx] * model.fak1[id_idx] - model.rad1[id_idx - 1] * model.fak1[id_idx - 1]) * dt;
model.flfix[id_idx] += ww * fl;
model.flrd[id_idx] += model.w[ij - 1] * fl;
if model.redif[id_idx] > 0.0 {
if params.ifalih == 0 {
let d0 = ww * model.fak1[id_idx] * dt;
let a0 = ww * model.fak1[id_idx - 1] * dt;
let d0m = d0 * fixalp.alim1[id_idx] - a0 * fixalp.ali1[id_idx - 1];
let d0_new = d0 * fixalp.ali1[id_idx] - a0 * fixalp.alip1[id_idx - 1];
let e0 = ww * fl * ddt;
model.redx[id_idx] += e0 * rad.abso1[id_idx];
model.redxm[id_idx] += e0 * rad.abso1[id_idx - 1];
let e0m = e0 * model.densi[id_idx - 1];
let e0_new = e0 * model.densi[id_idx];
model.redt[id_idx] += d0_new * dsft1_curr - e0_new * rad.dabt1[id_idx];
model.redtm[id_idx] += d0m * dsft1m - e0m * rad.dabt1[id_idx - 1];
model.redn[id_idx] += d0_new * dsfn1_curr - e0_new * rad.dabn1[id_idx];
model.rednm[id_idx] += d0m * dsfn1m - e0m * rad.dabn1[id_idx - 1];
model.redm[id_idx] += d0_new * dsfm1_curr - e0_new * rad.dabm1[id_idx];
model.redmm[id_idx] += d0m * dsfm1m - e0m * rad.dabm1[id_idx - 1];
for ii in 0..nlvexp {
model.redp[ii][id_idx] += d0_new * dsfp1_curr[ii] - e0_new * rad.dabp1[ii][id_idx];
model.redpm[ii][id_idx] += d0m * dsfp1m[ii] - e0m * rad.dabp1[ii][id_idx - 1];
}
} else {
let d0 = ww * fixalp.alih1[id_idx];
model.redt[id_idx] += d0 * dsft1_curr;
model.redn[id_idx] += d0 * dsfn1_curr;
model.redm[id_idx] += d0 * dsfm1_curr;
for ii in 0..nlvexp {
model.redp[ii][id_idx] += d0 * dsfp1_curr[ii];
}
}
}
// 辐射平衡积分方程部分
if model.reint[id_idx] > 0.0 {
let abst_true = rad.abso1[id_idx] - model.elscat[id_idx];
let d0 = abst_true * fixalp.ali1[id_idx];
model.fcooli[id_idx] += ww * (rad.emis1[id_idx] - abst_true * model.rad1[id_idx]);
model.rein[id_idx] += ww * (d0 * dsfn1_curr
+ model.rad1[id_idx] * (rad.dabn1[id_idx] - model.sigec[ij - 1])
- rad.demn1[id_idx]);
model.reit[id_idx] += ww * (d0 * dsft1_curr + model.rad1[id_idx] * rad.dabt1[id_idx] - rad.demt1[id_idx]);
model.reim[id_idx] += ww * (d0 * dsfm1_curr + model.rad1[id_idx] * rad.dabm1[id_idx] - rad.demm1[id_idx]);
for ii in 0..nlvexp {
model.reip[ii][id_idx] += ww * (d0 * dsfp1_curr[ii]
+ model.rad1[id_idx] * rad.dabp1[ii][id_idx]
- rad.demp1[ii][id_idx]);
}
}
}
// 3. 最深点 ID=ND
let id = nd;
let id_idx = id - 1;
let lnskip = model.lskip[id_idx][ij - 1] == 0;
// 保存前一个点的值
let dsftmm = dsft1m;
let dsfnmm = dsfn1m;
let dsfmmm = dsfm1m;
let mut dsfpmm = vec![0.0; nlvexp];
for ii in 0..nlvexp {
dsfpmm[ii] = dsfp1m[ii];
}
// 更新当前点为上一个点的 ID+1 值
dsft1m = dsft1;
dsfn1m = dsfn1;
dsfm1m = dsfm1;
for ii in 0..nlvexp {
dsfp1m[ii] = dsfp1[ii];
}
let dsft1_curr = dsft1p;
let dsfn1_curr = dsfn1p;
let dsfm1_curr = dsfm1p;
let dsfp1_curr = dsfp1p.clone();
// 初始化 ID-1 的导数(用于边界条件)
let mut dsft1d: f64 = 0.0;
let mut dsfn1d: f64 = 0.0;
let mut dsfm1d: f64 = 0.0;
let mut dsfp1d = vec![0.0; nlvexp];
// 初始化 DBDT 和 E0用于改进边界条件的积分方程
// 这些变量在边界条件块中计算,在积分方程块中使用
let mut dbdt: f64 = 0.0;
let mut e0: f64 = 0.0;
// 改进的下边界条件
if params.ibc > 0 && params.idisk == 0 {
let dt = UN / (model.deldmz[id_idx - 1] * (model.absot[id_idx] + model.absot[id_idx - 1]));
let plad = model.xkfb[id_idx] / model.xkf1[id_idx];
dbdt = plad / model.xkf1[id_idx] * model.hkt21[id_idx] * model.freq[ij - 1] * dt;
if params.ibc == 1 {
// 简单边界条件
fixalp.dsfdt[id_idx] = (dsft1_curr + dbdt) * fixalp.ali1[id_idx];
} else if params.ibc >= 2 {
// 改进的边界条件
let plam = model.xkfb[id_idx - 1] / model.xkf1[id_idx - 1];
let tau23 = t23 * dt;
let tau43 = 4.0 / 3.0 * dt;
let d0 = (plad * (UN + tau43) - tau43 * plam * dt) * dt * dt;
let rhd = model.deldmz[id_idx - 1] * model.densi[id_idx];
e0 = d0 * rhd;
let dsft1_new = dsft1_curr + dbdt * (UN + tau23) - e0 * rad.dabt1[id_idx];
let dsfn1_new = dsfn1_curr - e0 * (rad.dabn1[id_idx] + rad.abso1[id_idx] * model.densim[id_idx]);
let dsfm1_new = dsfm1_curr - e0 * rad.dabm1[id_idx];
let mut dsfp1_new = dsfp1_curr.clone();
for ii in 0..nlvexp {
dsfp1_new[ii] = dsfp1_curr[ii] - e0 * rad.dabp1[ii][id_idx];
}
if params.ibc >= 3 {
let dbdtm = plam / model.xkf1[id_idx - 1] * model.hkt21[id_idx - 1] * model.freq[ij - 1] * dt;
let rhd = model.deldmz[id_idx - 1] * model.densi[id_idx - 1];
let e0 = d0 * rhd;
dsft1d = -dbdtm * dt * t23 - e0 * rad.dabt1[id_idx - 1];
dsfn1d = -e0 * (rad.dabn1[id_idx - 1] + rad.abso1[id_idx - 1] * model.densim[id_idx - 1]);
dsfm1d = -e0 * rad.dabm1[id_idx - 1];
for ii in 0..nlvexp {
dsfp1d[ii] = -e0 * rad.dabp1[ii][id_idx - 1];
}
}
// 更新 DSFDT, DSFDN, DSFDM
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1_new * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1_new * fixalp.ali1[id_idx];
fixalp.dsfdm[id_idx] = dsfm1_new * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1_new[ii] * fixalp.ali1[id_idx];
}
}
} else {
// IBC == 1 的情况
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = (dsft1_curr + dbdt) * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1_curr * fixalp.ali1[id_idx];
fixalp.dsfdm[id_idx] = dsfm1_curr * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1_curr[ii] * fixalp.ali1[id_idx];
}
}
}
} else {
// 标准边界条件
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1_curr * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1_curr * fixalp.ali1[id_idx];
fixalp.dsfdm[id_idx] = dsfm1_curr * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1_curr[ii] * fixalp.ali1[id_idx];
}
}
}
// 流体静力学平衡方程
if lnskip {
let d0 = ww * model.fak1[id_idx];
let a0 = ww * model.fak1[id_idx - 1];
model.fprd[id_idx] += d0 * model.rad1[id_idx] - a0 * model.rad1[id_idx - 1];
let e0 = d0 * fixalp.alim1[id_idx] - a0 * fixalp.ali1[id_idx - 1];
let d0_new = d0 * fixalp.ali1[id_idx] - a0 * fixalp.alip1[id_idx - 1];
model.heit[id_idx] += d0_new * dsft1_curr;
model.hein[id_idx] += d0_new * dsfn1_curr;
model.heim[id_idx] += d0_new * dsfm1_curr;
model.heitm[id_idx] += e0 * dsft1m;
model.heinm[id_idx] += e0 * dsfn1m;
model.heimm[id_idx] += e0 * dsfm1m;
for ii in 0..nlvexp {
model.heip[ii][id_idx] += d0_new * dsfp1_curr[ii];
model.heipm[ii][id_idx] += e0 * dsfp1m[ii];
}
if params.ibc >= 3 {
model.heitm[id_idx] -= d0_new * dsft1d;
model.heinm[id_idx] -= d0_new * dsfn1d;
model.heimm[id_idx] -= d0_new * dsfm1d;
for ii in 0..nlvexp {
model.heipm[ii][id_idx] -= d0_new * dsfp1d[ii];
}
}
}
// 辐射平衡微分方程部分
let ddt = UN / (model.absot[id_idx] + model.absot[id_idx - 1]);
let dt = ddt / model.deldmz[id_idx - 1];
let fl = (model.rad1[id_idx] * model.fak1[id_idx] - model.rad1[id_idx - 1] * model.fak1[id_idx - 1]) * dt;
model.flfix[id_idx] += ww * fl;
model.flrd[id_idx] += model.w[ij - 1] * fl;
if model.redif[id_idx] > 0.0 {
let d0 = ww * model.fak1[id_idx] * dt;
let a0 = ww * model.fak1[id_idx - 1] * dt;
let d0m = d0 * fixalp.alim1[id_idx] - a0 * fixalp.ali1[id_idx - 1];
let d0_new = d0 * fixalp.ali1[id_idx] - a0 * fixalp.alip1[id_idx - 1];
let e0 = ww * fl * ddt;
model.redx[id_idx] += e0 * rad.abso1[id_idx];
model.redxm[id_idx] += e0 * rad.abso1[id_idx - 1];
let e0m = e0 * model.densi[id_idx - 1];
let e0_new = e0 * model.densi[id_idx];
model.redt[id_idx] += d0_new * dsft1_curr - e0_new * rad.dabt1[id_idx];
model.redtm[id_idx] += d0m * dsft1m - e0m * rad.dabt1[id_idx - 1];
model.redn[id_idx] += d0_new * dsfn1_curr - e0_new * rad.dabn1[id_idx];
model.rednm[id_idx] += d0m * dsfn1m - e0m * rad.dabn1[id_idx - 1];
model.redm[id_idx] += d0_new * dsfm1_curr - e0_new * rad.dabm1[id_idx];
model.redmm[id_idx] += d0m * dsfm1m - e0m * rad.dabm1[id_idx - 1];
for ii in 0..nlvexp {
model.redp[ii][id_idx] += d0_new * dsfp1_curr[ii] - e0_new * rad.dabp1[ii][id_idx];
model.redpm[ii][id_idx] += d0m * dsfp1m[ii] - e0m * rad.dabp1[ii][id_idx - 1];
}
if params.ibc >= 3 {
model.redtm[id_idx] += d0_new * dsft1d;
model.rednm[id_idx] += d0_new * dsfn1d;
model.redmm[id_idx] += d0_new * dsfm1d;
for ii in 0..nlvexp {
model.redpm[ii][id_idx] += d0_new * dsfp1d[ii];
}
}
}
// 辐射平衡积分方程部分
if model.reint[id_idx] > 0.0 {
let abst_true = rad.abso1[id_idx] - model.elscat[id_idx];
let d0 = abst_true * fixalp.ali1[id_idx];
model.fcooli[id_idx] += ww * (rad.emis1[id_idx] - abst_true * model.rad1[id_idx]);
model.rein[id_idx] += ww * (d0 * dsfn1_curr
+ model.rad1[id_idx] * (rad.dabn1[id_idx] - model.sigec[ij - 1])
- rad.demn1[id_idx]);
model.reim[id_idx] += ww * (d0 * dsfm1_curr + model.rad1[id_idx] * rad.dabm1[id_idx] - rad.demm1[id_idx]);
for ii in 0..nlvexp {
model.reip[ii][id_idx] += ww * (d0 * dsfp1_curr[ii]
+ model.rad1[id_idx] * rad.dabp1[ii][id_idx]
- rad.demp1[ii][id_idx]);
}
if params.ibc == 0 {
model.reit[id_idx] += ww * (d0 * dsft1_curr + model.rad1[id_idx] * rad.dabt1[id_idx] - rad.demt1[id_idx]);
} else {
// 改进的边界条件下的积分方程
// Fortran: REIT(ID)=REIT(ID)+WW*(D0*(DSFT1-DBDT)+E0*DABT1(ID)+
// * RAD1(ID)*DABT1(ID)-DEMT1(ID)+
// * ALI1(ID)/ABST*DBDT)
model.reit[id_idx] += ww * (d0 * (dsft1_curr - dbdt) + e0 * rad.dabt1[id_idx]
+ model.rad1[id_idx] * rad.dabt1[id_idx] - rad.demt1[id_idx]
+ fixalp.ali1[id_idx] / abst_true * dbdt);
}
}
}
/// 处理 ILASCT == 0 但 ILMCOR != 3 的情况
/// 这个路径与标准路径的主要区别是源函数导数的计算方式
#[allow(clippy::too_many_arguments)]
fn process_ilasct_zero(
params: &Alifr1Params,
fixalp: &mut FixAlp,
model: &mut Alifr1ModelState,
rad: &Alifr1RadState,
ij: usize,
nd: usize,
nlvexp: usize,
ww: f64,
) {
// 常量
let t23 = TWO / 3.0;
// 初始化中间变量
let mut dsft1m: f64 = 0.0;
let mut dsfn1m: f64 = 0.0;
let mut dsfp1m = vec![0.0; nlvexp];
// 1. 第一个深度点 (ID=1)
let id = 1;
let id_idx = id - 1;
let lnskip = model.lskip[id_idx][ij - 1] == 0;
// 基本辅助量 - 源函数的导数(非标准方式)
let emisiv = UN / rad.emis1[id_idx];
let abst = UN / (rad.abso1[id_idx] - model.elscat[id_idx]);
let s0 = rad.emis1[id_idx] * abst;
let dsfn1 = s0 * (rad.demn1[id_idx] * emisiv - (rad.dabn1[id_idx] - model.sigec[ij - 1]) * abst);
let dsft1 = s0 * (rad.demt1[id_idx] * emisiv - rad.dabt1[id_idx] * abst);
let mut dsfp1 = vec![0.0; nlvexp];
for ii in 0..nlvexp {
dsfp1[ii] = s0 * (rad.demp1[ii][id_idx] * emisiv - rad.dabp1[ii][id_idx] * abst);
}
// ID+1 的值
let idp_idx = id;
let emisip = UN / rad.emis1[idp_idx];
let abstp = UN / (rad.abso1[idp_idx] - model.elscat[idp_idx]);
let s0p = rad.emis1[idp_idx] * abstp;
let mut dsfn1p = s0p * (rad.demn1[idp_idx] * emisip - (rad.dabn1[idp_idx] - model.sigec[ij - 1]) * abstp);
let mut dsft1p = s0p * (rad.demt1[idp_idx] * emisip - rad.dabt1[idp_idx] * abstp);
let mut dsfp1p = vec![0.0; nlvexp];
for ii in 0..nlvexp {
dsfp1p[ii] = s0p * (rad.demp1[ii][idp_idx] * emisip - rad.dabp1[ii][idp_idx] * abstp);
}
// 更新 DSFDT, DSFDN 等
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1 * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1 * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1[ii] * fixalp.ali1[id_idx];
}
}
// 流体静力学平衡量
let wf = ww * model.fh[ij - 1];
if lnskip {
model.fprd[id_idx] += wf * rad.abso1[id_idx] * model.rad1[id_idx]
- ww * model.hextrd[ij - 1] * rad.abso1[id_idx];
let e0 = wf * model.rad1[id_idx];
let d0 = wf * rad.abso1[id_idx] * fixalp.ali1[id_idx];
model.heit[id_idx] += d0 * dsft1 + e0 * rad.dabt1[id_idx];
model.hein[id_idx] += d0 * dsfn1 + e0 * rad.dabn1[id_idx];
for ii in 0..nlvexp {
model.heip[ii][id_idx] += d0 * dsfp1[ii] + e0 * rad.dabp1[ii][id_idx];
}
}
// 辐射平衡微分方程部分
model.flfix[id_idx] += wf * model.rad1[id_idx] - ww * model.hextrd[ij - 1];
model.flrd[id_idx] += model.w[ij - 1] * model.fh[ij - 1] * model.rad1[id_idx]
- model.w[ij - 1] * HALF * model.extrad[ij - 1];
if model.redif[id_idx] > 0.0 {
let wf = wf * fixalp.ali1[id_idx];
model.redt[id_idx] += wf * dsft1;
model.redn[id_idx] += wf * dsfn1;
for ii in 0..nlvexp {
model.redp[ii][id_idx] += wf * dsfp1[ii];
}
}
// 辐射平衡积分方程部分
if model.reint[id_idx] > 0.0 {
let abst_true = rad.abso1[id_idx] - model.elscat[id_idx];
let wwk = ww * abst_true;
model.fcooli[id_idx] += ww * (rad.emis1[id_idx] - abst_true * model.rad1[id_idx]);
let d0 = ww * (fixalp.ali1[id_idx] - UN) * abst_true;
let e0 = ww * (model.rad1[id_idx] - s0);
model.rein[id_idx] += d0 * dsfn1 + e0 * (rad.dabn1[id_idx] - model.sigec[ij - 1]);
model.reit[id_idx] += d0 * dsft1 + e0 * rad.dabt1[id_idx];
for ii in 0..nlvexp {
model.reip[ii][id_idx] += d0 * dsfp1[ii] + e0 * rad.dabp1[ii][id_idx];
}
}
// 2. 深度循环 (ID = 2 to ND-1)
for id in 2..nd {
let id_idx = id - 1;
let lnskip = model.lskip[id_idx][ij - 1] == 0;
// 保存前一个点的值
dsft1m = dsft1;
dsfn1m = dsfn1;
for ii in 0..nlvexp {
dsfp1m[ii] = dsfp1[ii];
}
// 更新当前点为上一个点的 ID+1 值
let dsft1_curr = dsft1p;
let dsfn1_curr = dsfn1p;
let dsfp1_curr = dsfp1p.clone();
// 计算 ID+1 的值
let idp_idx = id;
let emisip_new = UN / rad.emis1[idp_idx];
let abstp_new = UN / (rad.abso1[idp_idx] - model.elscat[idp_idx]);
let s0p_new = rad.emis1[idp_idx] * abstp_new;
let dsfn1p_new = s0p_new * (rad.demn1[idp_idx] * emisip_new - (rad.dabn1[idp_idx] - model.sigec[ij - 1]) * abstp_new);
let dsft1p_new = s0p_new * (rad.demt1[idp_idx] * emisip_new - rad.dabt1[idp_idx] * abstp_new);
let mut dsfp1p_new = vec![0.0; nlvexp];
for ii in 0..nlvexp {
dsfp1p_new[ii] = s0p_new * (rad.demp1[ii][idp_idx] * emisip_new - rad.dabp1[ii][idp_idx] * abstp_new);
}
dsft1p = dsft1p_new;
dsfn1p = dsfn1p_new;
dsfp1p = dsfp1p_new;
// 更新 DSFDT, DSFDN 等
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1_curr * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1_curr * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1_curr[ii] * fixalp.ali1[id_idx];
}
}
// 流体静力学平衡方程
if lnskip {
let d0 = ww * model.fak1[id_idx];
let a0 = ww * model.fak1[id_idx - 1];
model.fprd[id_idx] += d0 * model.rad1[id_idx] - a0 * model.rad1[id_idx - 1];
let e0 = d0 * fixalp.alim1[id_idx] - a0 * fixalp.ali1[id_idx - 1];
let d0_new = d0 * fixalp.ali1[id_idx] - a0 * fixalp.alip1[id_idx - 1];
model.heit[id_idx] += d0_new * dsft1_curr;
model.hein[id_idx] += d0_new * dsfn1_curr;
model.heitm[id_idx] += e0 * dsft1m;
model.heinm[id_idx] += e0 * dsfn1m;
for ii in 0..nlvexp {
model.heip[ii][id_idx] += d0_new * dsfp1_curr[ii];
model.heipm[ii][id_idx] += e0 * dsfp1m[ii];
}
}
// 辐射平衡微分方程部分
let ddt = UN / (model.absot[id_idx] + model.absot[id_idx - 1]);
let dt = ddt / model.deldmz[id_idx - 1];
let fl = (model.rad1[id_idx] * model.fak1[id_idx] - model.rad1[id_idx - 1] * model.fak1[id_idx - 1]) * dt;
model.flfix[id_idx] += ww * fl;
if model.redif[id_idx] > 0.0 {
let d0 = ww * model.fak1[id_idx] * dt;
let a0 = ww * model.fak1[id_idx - 1] * dt;
let d0m = d0 * fixalp.alim1[id_idx] - a0 * fixalp.ali1[id_idx - 1];
let d0_new = d0 * fixalp.ali1[id_idx] - a0 * fixalp.alip1[id_idx - 1];
let e0 = ww * fl * ddt;
model.redx[id_idx] += e0 * rad.abso1[id_idx];
model.redxm[id_idx] += e0 * rad.abso1[id_idx - 1];
let e0m = e0 * model.densi[id_idx - 1];
let e0_new = e0 * model.densi[id_idx];
model.redt[id_idx] += d0_new * dsft1_curr - e0_new * rad.dabt1[id_idx];
model.redtm[id_idx] += d0m * dsft1m - e0m * rad.dabt1[id_idx - 1];
model.redn[id_idx] += d0_new * dsfn1_curr - e0_new * rad.dabn1[id_idx];
model.rednm[id_idx] += d0m * dsfn1m - e0m * rad.dabn1[id_idx - 1];
for ii in 0..nlvexp {
model.redp[ii][id_idx] += d0_new * dsfp1_curr[ii] - e0_new * rad.dabp1[ii][id_idx];
model.redpm[ii][id_idx] += d0m * dsfp1m[ii] - e0m * rad.dabp1[ii][id_idx - 1];
}
}
// 辐射平衡积分方程部分
if model.reint[id_idx] > 0.0 {
let abst_true = rad.abso1[id_idx] - model.elscat[id_idx];
let wwk = ww * abst_true;
model.fcooli[id_idx] += ww * (rad.emis1[id_idx] - abst_true * model.rad1[id_idx]);
let d0 = ww * (fixalp.ali1[id_idx] - UN) * abst_true;
let e0 = ww * (model.rad1[id_idx] - s0);
model.rein[id_idx] += d0 * dsfn1_curr + e0 * (rad.dabn1[id_idx] - model.sigec[ij - 1]);
model.reit[id_idx] += d0 * dsft1_curr + e0 * rad.dabt1[id_idx];
for ii in 0..nlvexp {
model.reip[ii][id_idx] += d0 * dsfp1_curr[ii] + e0 * rad.dabp1[ii][id_idx];
}
}
}
// 3. 最深点 ID=ND
let id = nd;
let id_idx = id - 1;
let lnskip = model.lskip[id_idx][ij - 1] == 0;
// 保存前一个点的值
let _dsftmm = dsft1m;
let _dsfnmm = dsfn1m;
let mut _dsfpmm = vec![0.0; nlvexp];
for ii in 0..nlvexp {
_dsfpmm[ii] = dsfp1m[ii];
}
// 更新当前点为上一个点的 ID+1 值
dsft1m = dsft1;
dsfn1m = dsfn1;
for ii in 0..nlvexp {
dsfp1m[ii] = dsfp1[ii];
}
let s0_curr = s0p;
let dsft1_curr = dsft1p;
let dsfn1_curr = dsfn1p;
let dsfp1_curr = dsfp1p.clone();
// 初始化 ID-1 的导数(用于边界条件)
let mut dsft1d: f64 = 0.0;
let mut dsfn1d: f64 = 0.0;
let mut dsfp1d = vec![0.0; nlvexp];
// 改进的下边界条件
let mut dbdt: f64 = 0.0;
if params.ibc > 0 && params.idisk == 0 {
let dt = UN / (model.deldmz[id_idx - 1] * (model.absot[id_idx] + model.absot[id_idx - 1]));
let plad = model.xkfb[id_idx] / model.xkf1[id_idx];
dbdt = plad / model.xkf1[id_idx] * model.hkt21[id_idx] * model.freq[ij - 1] * dt;
if params.ibc == 1 {
// 简单边界条件 - DSFT1 = DSFT1 + DBDT
let dsft1_new = dsft1_curr + dbdt;
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1_new * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1_curr * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1_curr[ii] * fixalp.ali1[id_idx];
}
}
} else if params.ibc >= 2 {
// 改进的边界条件
let plam = model.xkfb[id_idx - 1] / model.xkf1[id_idx - 1];
let tau23 = t23 * dt;
let tau43 = 4.0 / 3.0 * dt;
let d0_val = (plad * (UN + tau43) - tau43 * plam * dt) * dt * dt;
let rhd = model.deldmz[id_idx - 1] * model.densi[id_idx];
let e0 = d0_val * rhd;
let dsft1_new = dsft1_curr + dbdt * (UN + tau23) - e0 * rad.dabt1[id_idx];
let dsfn1_new = dsfn1_curr - e0 * (rad.dabn1[id_idx] + rad.abso1[id_idx] * model.densim[id_idx]);
let mut dsfp1_new = dsfp1_curr.clone();
for ii in 0..nlvexp {
dsfp1_new[ii] = dsfp1_curr[ii] - e0 * rad.dabp1[ii][id_idx];
}
if params.ibc >= 3 {
let dbdtm = plam / model.xkf1[id_idx - 1] * model.hkt21[id_idx - 1] * model.freq[ij - 1] * dt;
let rhd = model.deldmz[id_idx - 1] * model.densi[id_idx - 1];
let e0 = d0_val * rhd;
dsft1d = -dbdtm * dt * t23 - e0 * rad.dabt1[id_idx - 1];
dsfn1d = -e0 * (rad.dabn1[id_idx - 1] + rad.abso1[id_idx - 1] * model.densim[id_idx - 1]);
for ii in 0..nlvexp {
dsfp1d[ii] = -e0 * rad.dabp1[ii][id_idx - 1];
}
}
// 更新 DSFDT, DSFDN
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1_new * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1_new * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1_new[ii] * fixalp.ali1[id_idx];
}
}
} else {
// IBC == 1 的情况
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = (dsft1_curr + dbdt) * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1_curr * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1_curr[ii] * fixalp.ali1[id_idx];
}
}
}
} else {
// 标准边界条件
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1_curr * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1_curr * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1_curr[ii] * fixalp.ali1[id_idx];
}
}
}
// 流体静力学平衡方程
if lnskip {
let d0 = ww * model.fak1[id_idx];
let a0 = ww * model.fak1[id_idx - 1];
model.fprd[id_idx] += d0 * model.rad1[id_idx] - a0 * model.rad1[id_idx - 1];
let e0 = d0 * fixalp.alim1[id_idx] - a0 * fixalp.ali1[id_idx - 1];
let d0_new = d0 * fixalp.ali1[id_idx] - a0 * fixalp.alip1[id_idx - 1];
model.heit[id_idx] += d0_new * dsft1_curr;
model.hein[id_idx] += d0_new * dsfn1_curr;
model.heitm[id_idx] += e0 * dsft1m;
model.heinm[id_idx] += e0 * dsfn1m;
for ii in 0..nlvexp {
model.heip[ii][id_idx] += d0_new * dsfp1_curr[ii];
model.heipm[ii][id_idx] += e0 * dsfp1m[ii];
}
if params.ibc >= 3 {
model.heitm[id_idx] -= d0_new * dsft1d;
model.heinm[id_idx] -= d0_new * dsfn1d;
for ii in 0..nlvexp {
model.heipm[ii][id_idx] -= d0_new * dsfp1d[ii];
}
}
}
// 辐射平衡微分方程部分
let ddt = UN / (model.absot[id_idx] + model.absot[id_idx - 1]);
let dt = ddt / model.deldmz[id_idx - 1];
let fl = (model.rad1[id_idx] * model.fak1[id_idx] - model.rad1[id_idx - 1] * model.fak1[id_idx - 1]) * dt;
model.flfix[id_idx] += ww * fl;
if model.redif[id_idx] > 0.0 {
let d0 = ww * model.fak1[id_idx] * dt;
let a0 = ww * model.fak1[id_idx - 1] * dt;
let d0m = d0 * fixalp.alim1[id_idx] - a0 * fixalp.ali1[id_idx - 1];
let d0_new = d0 * fixalp.ali1[id_idx] - a0 * fixalp.alip1[id_idx - 1];
let e0 = ww * fl * ddt;
model.redx[id_idx] += e0 * rad.abso1[id_idx];
model.redxm[id_idx] += e0 * rad.abso1[id_idx - 1];
let e0m = e0 * model.densi[id_idx - 1];
let e0_new = e0 * model.densi[id_idx];
model.redt[id_idx] += d0_new * dsft1_curr - e0_new * rad.dabt1[id_idx];
model.redtm[id_idx] += d0m * dsft1m - e0m * rad.dabt1[id_idx - 1];
model.redn[id_idx] += d0_new * dsfn1_curr - e0_new * rad.dabn1[id_idx];
model.rednm[id_idx] += d0m * dsfn1m - e0m * rad.dabn1[id_idx - 1];
for ii in 0..nlvexp {
model.redp[ii][id_idx] += d0_new * dsfp1_curr[ii] - e0_new * rad.dabp1[ii][id_idx];
model.redpm[ii][id_idx] += d0m * dsfp1m[ii] - e0m * rad.dabp1[ii][id_idx - 1];
}
if params.ibc >= 3 {
model.redtm[id_idx] += d0_new * dsft1d;
model.rednm[id_idx] += d0_new * dsfn1d;
for ii in 0..nlvexp {
model.redpm[ii][id_idx] += d0_new * dsfp1d[ii];
}
}
}
// 辐射平衡积分方程部分
if model.reint[id_idx] > 0.0 {
let abst_true = rad.abso1[id_idx] - model.elscat[id_idx];
let _wwk = ww * abst_true;
model.fcooli[id_idx] += ww * (rad.emis1[id_idx] - abst_true * model.rad1[id_idx]);
let d0 = ww * (fixalp.ali1[id_idx] - UN) * abst_true;
let e0 = ww * (model.rad1[id_idx] - s0_curr);
model.rein[id_idx] += d0 * dsfn1_curr + e0 * (rad.dabn1[id_idx] - model.sigec[ij - 1]);
if params.ibc == 0 {
model.reit[id_idx] += d0 * dsft1_curr + e0 * rad.dabt1[id_idx];
} else {
// 改进的边界条件下的积分方程
model.reit[id_idx] += d0 * (dsft1_curr - dbdt) + e0 * rad.dabt1[id_idx]
+ fixalp.ali1[id_idx] / abst_true * dbdt;
}
for ii in 0..nlvexp {
model.reip[ii][id_idx] += d0 * dsfp1_curr[ii] + e0 * rad.dabp1[ii][id_idx];
}
}
}
/// 处理 ILASCT != 0 的情况
/// 对应 Fortran GOTO 299 块
#[allow(clippy::too_many_arguments)]
fn process_ilasct_nonzero(
params: &Alifr1Params,
fixalp: &mut FixAlp,
model: &mut Alifr1ModelState,
rad: &Alifr1RadState,
ij: usize,
nd: usize,
nlvexp: usize,
ww: f64,
) {
// 常量
let t23 = TWO / 3.0;
let t43 = 4.0 / 3.0;
let t23_inv = 2.0 / 3.0; // T23 in Fortran
// 初始化中间变量
let mut dsft1m: f64 = 0.0;
let mut dsfn1m: f64 = 0.0;
let mut dsfp1m = vec![0.0; nlvexp];
// 1. 第一个深度点 (ID=1)
let id = 1;
let id_idx = id - 1;
let lnskip = model.lskip[id_idx][ij - 1] == 0;
// 基本辅助量 - 源函数的导数
// 注意:这里 ABST = UN/ABSO1(ID),不同于 ILASCT == 0 的情况
let emisiv = UN / rad.emis1[id_idx];
let abst = UN / rad.abso1[id_idx];
let s0 = rad.emis1[id_idx] * abst;
let dsfn1 = s0 * (rad.demn1[id_idx] * emisiv - rad.dabn1[id_idx] * abst);
let dsft1 = s0 * (rad.demt1[id_idx] * emisiv - rad.dabt1[id_idx] * abst);
let mut dsfp1 = vec![0.0; nlvexp];
for ii in 0..nlvexp {
dsfp1[ii] = s0 * (rad.demp1[ii][id_idx] * emisiv - rad.dabp1[ii][id_idx] * abst);
}
// ID+1 的值
let idp_idx = id;
let emisip = UN / rad.emis1[idp_idx];
let abstp = UN / rad.abso1[idp_idx];
let s0p = rad.emis1[idp_idx] * abstp;
let mut dsfn1p = s0p * (rad.demn1[idp_idx] * emisip - rad.dabn1[idp_idx] * abstp);
let mut dsft1p = s0p * (rad.demt1[idp_idx] * emisip - rad.dabt1[idp_idx] * abstp);
let mut dsfp1p = vec![0.0; nlvexp];
for ii in 0..nlvexp {
dsfp1p[ii] = s0p * (rad.demp1[ii][idp_idx] * emisip - rad.dabp1[ii][idp_idx] * abstp);
}
// 更新 DSFDT, DSFDN 等
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1 * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1 * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1[ii] * fixalp.ali1[id_idx];
}
}
// 流体静力学平衡量
let wf = ww * model.fh[ij - 1];
if lnskip {
model.fprd[id_idx] += wf * rad.abso1[id_idx] * model.rad1[id_idx]
- ww * model.hextrd[ij - 1] * rad.abso1[id_idx];
let e0 = wf * model.rad1[id_idx];
let d0 = wf * rad.abso1[id_idx] * fixalp.ali1[id_idx];
model.heit[id_idx] += d0 * dsft1 + e0 * rad.dabt1[id_idx];
model.hein[id_idx] += d0 * dsfn1 + e0 * rad.dabn1[id_idx];
for ii in 0..nlvexp {
model.heip[ii][id_idx] += d0 * dsfp1[ii] + e0 * rad.dabp1[ii][id_idx];
}
}
// 辐射平衡微分方程部分
model.flfix[id_idx] += wf * model.rad1[id_idx] - ww * model.hextrd[ij - 1];
model.flrd[id_idx] += model.w[ij - 1] * model.fh[ij - 1] * model.rad1[id_idx]
- model.w[ij - 1] * HALF * model.extrad[ij - 1];
if model.redif[id_idx] > 0.0 {
let wf = wf * fixalp.ali1[id_idx];
model.redt[id_idx] += wf * dsft1;
model.redn[id_idx] += wf * dsfn1;
for ii in 0..nlvexp {
model.redp[ii][id_idx] += wf * dsfp1[ii];
}
}
// 辐射平衡积分方程部分
if model.reint[id_idx] > 0.0 {
let abst_true = rad.abso1[id_idx] - model.elscat[id_idx];
model.fcooli[id_idx] += ww * (rad.emis1[id_idx] - abst_true * model.rad1[id_idx]);
// 注意D0 的计算不同于 ILASCT == 0
let d0 = ww * (abst_true * fixalp.ali1[id_idx] - rad.abso1[id_idx]);
let e0 = ww * (model.rad1[id_idx] - s0);
model.rein[id_idx] += d0 * dsfn1 + e0 * rad.dabn1[id_idx] - ww * model.sigec[ij - 1] * model.rad1[id_idx];
model.reit[id_idx] += d0 * dsft1 + e0 * rad.dabt1[id_idx];
for ii in 0..nlvexp {
model.reip[ii][id_idx] += d0 * dsfp1[ii] + e0 * rad.dabp1[ii][id_idx];
}
}
// 2. 深度循环 (ID = 2 to ND-1)
for id in 2..nd {
let id_idx = id - 1;
let lnskip = model.lskip[id_idx][ij - 1] == 0;
// 保存前一个点的值
dsft1m = dsft1;
dsfn1m = dsfn1;
for ii in 0..nlvexp {
dsfp1m[ii] = dsfp1[ii];
}
// 更新当前点为上一个点的 ID+1 值
let dsft1_curr = dsft1p;
let dsfn1_curr = dsfn1p;
let dsfp1_curr = dsfp1p.clone();
// 更新 DSFT1, DSFN1 等
let dsft1_new = dsft1_curr;
let dsfn1_new = dsfn1_curr;
let dsfp1_new = dsfp1_curr.clone();
// 计算 ID+1 的值
let idp_idx = id;
let emisip_new = UN / rad.emis1[idp_idx];
let abstp_new = UN / rad.abso1[idp_idx];
let s0p_new = rad.emis1[idp_idx] * abstp_new;
let dsfn1p_new = s0p_new * (rad.demn1[idp_idx] * emisip_new - rad.dabn1[idp_idx] * abstp_new);
let dsft1p_new = s0p_new * (rad.demt1[idp_idx] * emisip_new - rad.dabt1[idp_idx] * abstp_new);
let mut dsfp1p_new = vec![0.0; nlvexp];
for ii in 0..nlvexp {
dsfp1p_new[ii] = s0p_new * (rad.demp1[ii][idp_idx] * emisip_new - rad.dabp1[ii][idp_idx] * abstp_new);
}
dsft1p = dsft1p_new;
dsfn1p = dsfn1p_new;
dsfp1p = dsfp1p_new;
// 更新 DSFDT, DSFDN 等
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1_new * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1_new * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1_new[ii] * fixalp.ali1[id_idx];
}
}
// 流体静力学平衡方程
if lnskip {
let d0 = ww * model.fak1[id_idx];
let a0 = ww * model.fak1[id_idx - 1];
model.fprd[id_idx] += d0 * model.rad1[id_idx] - a0 * model.rad1[id_idx - 1];
let e0 = d0 * fixalp.alim1[id_idx] - a0 * fixalp.ali1[id_idx - 1];
let d0_new = d0 * fixalp.ali1[id_idx] - a0 * fixalp.alip1[id_idx - 1];
model.heit[id_idx] += d0_new * dsft1_new;
model.hein[id_idx] += d0_new * dsfn1_new;
model.heitm[id_idx] += e0 * dsft1m;
model.heinm[id_idx] += e0 * dsfn1m;
for ii in 0..nlvexp {
model.heip[ii][id_idx] += d0_new * dsfp1_new[ii];
model.heipm[ii][id_idx] += e0 * dsfp1m[ii];
}
}
// 辐射平衡微分方程部分
let ddt = UN / (model.absot[id_idx] + model.absot[id_idx - 1]);
let dt = ddt / model.deldmz[id_idx - 1];
let fl = (model.rad1[id_idx] * model.fak1[id_idx] - model.rad1[id_idx - 1] * model.fak1[id_idx - 1]) * dt;
model.flfix[id_idx] += ww * fl;
if model.redif[id_idx] > 0.0 {
let d0 = ww * model.fak1[id_idx] * dt;
let a0 = ww * model.fak1[id_idx - 1] * dt;
let d0m = d0 * fixalp.alim1[id_idx] - a0 * fixalp.ali1[id_idx - 1];
let d0_new = d0 * fixalp.ali1[id_idx] - a0 * fixalp.alip1[id_idx - 1];
let e0 = ww * fl * ddt;
model.redx[id_idx] += e0 * rad.abso1[id_idx];
model.redxm[id_idx] += e0 * rad.abso1[id_idx - 1];
let e0m = e0 * model.densi[id_idx - 1];
let e0_new = e0 * model.densi[id_idx];
model.redt[id_idx] += d0_new * dsft1_new - e0_new * rad.dabt1[id_idx];
model.redtm[id_idx] += d0m * dsft1m - e0m * rad.dabt1[id_idx - 1];
model.redn[id_idx] += d0_new * dsfn1_new - e0_new * rad.dabn1[id_idx];
model.rednm[id_idx] += d0m * dsfn1m - e0m * rad.dabn1[id_idx - 1];
for ii in 0..nlvexp {
model.redp[ii][id_idx] += d0_new * dsfp1_new[ii] - e0_new * rad.dabp1[ii][id_idx];
model.redpm[ii][id_idx] += d0m * dsfp1m[ii] - e0m * rad.dabp1[ii][id_idx - 1];
}
}
// 辐射平衡积分方程部分
if model.reint[id_idx] > 0.0 {
let abst_true = rad.abso1[id_idx] - model.elscat[id_idx];
model.fcooli[id_idx] += ww * (rad.emis1[id_idx] - abst_true * model.rad1[id_idx]);
let d0 = ww * (abst_true * fixalp.ali1[id_idx] - rad.abso1[id_idx]);
let e0 = ww * (model.rad1[id_idx] - s0);
model.rein[id_idx] += d0 * dsfn1_new + e0 * rad.dabn1[id_idx] - ww * model.sigec[ij - 1] * model.rad1[id_idx];
model.reit[id_idx] += d0 * dsft1_new + e0 * rad.dabt1[id_idx];
for ii in 0..nlvexp {
model.reip[ii][id_idx] += d0 * dsfp1_new[ii] + e0 * rad.dabp1[ii][id_idx];
}
}
}
// 3. 最深点 ID=ND
let id = nd;
let id_idx = id - 1;
let lnskip = model.lskip[id_idx][ij - 1] == 0;
// 保存前两个点的值
let dsftmm = dsft1m;
let dsfnmm = dsfn1m;
let mut dsfpmm = vec![0.0; nlvexp];
for ii in 0..nlvexp {
dsfpmm[ii] = dsfp1m[ii];
}
// 更新前一个点的值
dsft1m = dsft1;
dsfn1m = dsfn1;
for ii in 0..nlvexp {
dsfp1m[ii] = dsfp1[ii];
}
// 更新当前点为上一个点的 ID+1 值
let s0_curr = s0p;
let dsft1_curr = dsft1p;
let dsfn1_curr = dsfn1p;
let dsfp1_curr = dsfp1p.clone();
// 初始化 ID-1 的导数(用于边界条件)
let mut dsft1d: f64 = 0.0;
let mut dsfn1d: f64 = 0.0;
let mut dsfp1d = vec![0.0; nlvexp];
// 改进的下边界条件
let mut dbdt: f64 = 0.0;
if params.ibc > 0 && params.idisk == 0 {
let dt = UN / (model.deldmz[id_idx - 1] * (model.absot[id_idx] + model.absot[id_idx - 1]));
let plad = model.xkfb[id_idx] / model.xkf1[id_idx];
dbdt = plad / model.xkf1[id_idx] * model.hkt21[id_idx] * model.freq[ij - 1] * dt;
if params.ibc == 1 {
// 简单边界条件
let dsft1_new = dsft1_curr + dbdt;
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1_new * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1_curr * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1_curr[ii] * fixalp.ali1[id_idx];
}
}
} else if params.ibc >= 2 {
// 改进的边界条件
let plam = model.xkfb[id_idx - 1] / model.xkf1[id_idx - 1];
let tau23 = t23 * dt;
let tau43 = t43 * dt;
let d0 = (plad * (UN + tau43) - t43 * plam * dt) * dt * dt;
let rhd = model.deldmz[id_idx - 1] * model.densi[id_idx];
let e0 = d0 * rhd;
let dsft1_new = dsft1_curr + dbdt * (UN + tau23) - e0 * rad.dabt1[id_idx];
let dsfn1_new = dsfn1_curr - e0 * (rad.dabn1[id_idx] + rad.abso1[id_idx] * model.densim[id_idx]);
let mut dsfp1_new = dsfp1_curr.clone();
for ii in 0..nlvexp {
dsfp1_new[ii] = dsfp1_curr[ii] - e0 * rad.dabp1[ii][id_idx];
}
if params.ibc >= 3 {
let dbdtm = plam / model.xkf1[id_idx - 1] * model.hkt21[id_idx - 1] * model.freq[ij - 1] * dt;
let rhd = model.deldmz[id_idx - 1] * model.densi[id_idx - 1];
let e0 = d0 * rhd;
dsft1d = -dbdtm * dt * t23_inv - e0 * rad.dabt1[id_idx - 1];
dsfn1d = -e0 * (rad.dabn1[id_idx - 1] + rad.abso1[id_idx - 1] * model.densim[id_idx - 1]);
for ii in 0..nlvexp {
dsfp1d[ii] = -e0 * rad.dabp1[ii][id_idx - 1];
}
}
// 更新 DSFDT, DSFDN
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1_new * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1_new * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1_new[ii] * fixalp.ali1[id_idx];
}
}
}
} else {
// 标准边界条件
if params.irder == 1 || params.irder == 3 {
fixalp.dsfdt[id_idx] = dsft1_curr * fixalp.ali1[id_idx];
fixalp.dsfdn[id_idx] = dsfn1_curr * fixalp.ali1[id_idx];
}
if params.irder > 1 {
for ii in 0..nlvexp {
fixalp.dsfdp[ii][id_idx] = dsfp1_curr[ii] * fixalp.ali1[id_idx];
}
}
}
// 流体静力学平衡方程
if lnskip {
let d0 = ww * model.fak1[id_idx];
let a0 = ww * model.fak1[id_idx - 1];
model.fprd[id_idx] += d0 * model.rad1[id_idx] - a0 * model.rad1[id_idx - 1];
let e0 = d0 * fixalp.alim1[id_idx] - a0 * fixalp.ali1[id_idx - 1];
let d0_new = d0 * fixalp.ali1[id_idx] - a0 * fixalp.alip1[id_idx - 1];
model.heit[id_idx] += d0_new * dsft1_curr;
model.hein[id_idx] += d0_new * dsfn1_curr;
model.heitm[id_idx] += e0 * dsft1m;
model.heinm[id_idx] += e0 * dsfn1m;
for ii in 0..nlvexp {
model.heip[ii][id_idx] += d0_new * dsfp1_curr[ii];
model.heipm[ii][id_idx] += e0 * dsfp1m[ii];
}
if params.ibc >= 3 {
model.heitm[id_idx] -= d0_new * dsft1d;
model.heinm[id_idx] -= d0_new * dsfn1d;
for ii in 0..nlvexp {
model.heipm[ii][id_idx] -= d0_new * dsfp1d[ii];
}
}
}
// 辐射平衡微分方程部分
let ddt = UN / (model.absot[id_idx] + model.absot[id_idx - 1]);
let dt = ddt / model.deldmz[id_idx - 1];
let fl = (model.rad1[id_idx] * model.fak1[id_idx] - model.rad1[id_idx - 1] * model.fak1[id_idx - 1]) * dt;
model.flfix[id_idx] += ww * fl;
if model.redif[id_idx] > 0.0 {
let d0 = ww * model.fak1[id_idx] * dt;
let a0 = ww * model.fak1[id_idx - 1] * dt;
let d0m = d0 * fixalp.alim1[id_idx] - a0 * fixalp.ali1[id_idx - 1];
let d0_new = d0 * fixalp.ali1[id_idx] - a0 * fixalp.alip1[id_idx - 1];
let e0 = ww * fl * ddt;
model.redx[id_idx] += e0 * rad.abso1[id_idx];
model.redxm[id_idx] += e0 * rad.abso1[id_idx - 1];
let e0m = e0 * model.densi[id_idx - 1];
let e0_new = e0 * model.densi[id_idx];
model.redt[id_idx] += d0_new * dsft1_curr - e0_new * rad.dabt1[id_idx];
model.redtm[id_idx] += d0m * dsft1m - e0m * rad.dabt1[id_idx - 1];
model.redn[id_idx] += d0_new * dsfn1_curr - e0_new * rad.dabn1[id_idx];
model.rednm[id_idx] += d0m * dsfn1m - e0m * rad.dabn1[id_idx - 1];
for ii in 0..nlvexp {
model.redp[ii][id_idx] += d0_new * dsfp1_curr[ii] - e0_new * rad.dabp1[ii][id_idx];
model.redpm[ii][id_idx] += d0m * dsfp1m[ii] - e0m * rad.dabp1[ii][id_idx - 1];
}
if params.ibc >= 3 {
model.redtm[id_idx] += d0_new * dsft1d;
model.rednm[id_idx] += d0_new * dsfn1d;
for ii in 0..nlvexp {
model.redpm[ii][id_idx] += d0_new * dsfp1d[ii];
}
}
}
// 辐射平衡积分方程部分
if model.reint[id_idx] > 0.0 {
let abst_true = rad.abso1[id_idx] - model.elscat[id_idx];
model.fcooli[id_idx] += ww * (rad.emis1[id_idx] - abst_true * model.rad1[id_idx]);
let d0 = ww * (abst_true * fixalp.ali1[id_idx] - rad.abso1[id_idx]);
let e0 = ww * (model.rad1[id_idx] - s0_curr);
model.rein[id_idx] += d0 * dsfn1_curr + e0 * rad.dabn1[id_idx] - ww * model.sigec[ij - 1] * model.rad1[id_idx];
if params.ibc == 0 {
model.reit[id_idx] += d0 * dsft1_curr + e0 * rad.dabt1[id_idx];
} else {
// 改进的边界条件下的积分方程
model.reit[id_idx] += d0 * (dsft1_curr - dbdt) + e0 * rad.dabt1[id_idx]
+ fixalp.ali1[id_idx] / rad.abso1[id_idx] * dbdt;
}
for ii in 0..nlvexp {
model.reip[ii][id_idx] += d0 * dsfp1_curr[ii] + e0 * rad.dabp1[ii][id_idx];
}
}
// 避免未使用变量警告
let _ = (dsftmm, dsfnmm, dsfpmm);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_alifr1_ifali_le_1() {
// 测试 IFALI <= 1 时直接返回
let params = Alifr1Params {
ij: 1,
nd: 10,
nlvexp: 5,
ifali: 1,
irder: 1,
ilmcor: 3,
ilasct: 0,
ibc: 0,
idisk: 0,
ifalih: 0,
};
// 创建空的 FixAlp实际使用需要完整初始化
let mut fixalp = FixAlp::default();
// 简单测试:确保函数不会 panic
// 实际测试需要完整的模型状态
let _ = (&params, &mut fixalp);
}
}