1484 lines
58 KiB
Rust
1484 lines
58 KiB
Rust
//! 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 _ = (¶ms, &mut fixalp);
|
||
}
|
||
}
|