130 lines
3.2 KiB
Rust
130 lines
3.2 KiB
Rust
//! Stark 轮廓辅助函数。
|
|
//!
|
|
//! 重构自 TLUSTY `stark0.f`
|
|
|
|
/// Stark 轮廓辅助参数计算。
|
|
///
|
|
/// 计算氢线近似 Stark 轮廓所需的频率无关参数。
|
|
///
|
|
/// # 参数
|
|
///
|
|
/// * `i` - 下能级主量子数
|
|
/// * `j` - 上能级主量子数
|
|
/// * `izz` - 离子电荷 (1 为氢)
|
|
///
|
|
/// # 返回值
|
|
///
|
|
/// (xkij, wl0, fij) 元组:
|
|
/// - xkij: Holtsmark 轮廓的 K(i,j) 系数
|
|
/// - wl0: 谱线波长
|
|
/// - fij: Stark f 值
|
|
///
|
|
/// # 备注
|
|
///
|
|
/// j≤6 时使用精确值,更高时使用渐近公式。
|
|
pub fn stark0(i: usize, j: usize, izz: usize) -> (f64, f64, f64) {
|
|
const RYD1: f64 = 911.763811;
|
|
const RYD2: f64 = 911.495745 / 4.0;
|
|
const CXKIJ: f64 = 5.5e-5;
|
|
const WI1: f64 = 911.753578;
|
|
const WI2: f64 = 227.837832;
|
|
|
|
// XKIJ 表格 (5 x 4)
|
|
const XKIJT: [[f64; 4]; 5] = [
|
|
[3.56e-4, 0.0125, 0.124, 0.683],
|
|
[5.23e-4, 0.0177, 0.171, 0.866],
|
|
[1.09e-3, 0.028, 0.223, 1.02],
|
|
[1.49e-3, 0.0348, 0.261, 1.19],
|
|
[2.25e-3, 0.0493, 0.342, 1.46],
|
|
];
|
|
|
|
// FSTARK 表格 (10 x 4)
|
|
const FSTARK: [[f64; 4]; 10] = [
|
|
[0.1387, 0.3921, 0.6103, 0.8163],
|
|
[0.0791, 0.1193, 0.1506, 0.1788],
|
|
[0.02126, 0.03766, 0.04931, 0.05985],
|
|
[0.01394, 0.02209, 0.02768, 0.03189],
|
|
[0.00642, 0.01139, 0.01485, 0.01762],
|
|
[4.814e-3, 8.036e-3, 0.01023, 0.01196],
|
|
[2.779e-3, 5.007e-3, 6.588e-3, 7.825e-3],
|
|
[2.216e-3, 3.85e-3, 4.996e-3, 5.882e-3],
|
|
[1.443e-3, 2.658e-3, 3.524e-3, 4.233e-3],
|
|
[1.201e-3, 2.151e-3, 2.838e-3, 3.375e-3],
|
|
];
|
|
|
|
let ii = (i * i) as f64;
|
|
let jj = (j * j) as f64;
|
|
let jmin = j - i;
|
|
|
|
// 计算 XKIJ
|
|
let xkij = if jmin <= 5 {
|
|
XKIJT[jmin - 1][i - 1]
|
|
} else {
|
|
CXKIJ * (ii * jj) * (ii * jj) / (jj - ii)
|
|
};
|
|
|
|
// 计算 FIJ
|
|
let fij = if jmin <= 10 {
|
|
FSTARK[jmin - 1][i - 1]
|
|
} else {
|
|
let cfij = ((20.0 * i as f64 + 100.0) * j as f64) / ((i as f64 + 10.0) * (jj - ii));
|
|
FSTARK[9][i - 1] * cfij * cfij * cfij
|
|
};
|
|
|
|
// 计算波长
|
|
let wl0_base = if izz == 2 { WI2 } else { WI1 };
|
|
let wl0 = wl0_base / (1.0 / ii - 1.0 / jj);
|
|
|
|
(xkij, wl0, fij)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_stark0_h_alpha() {
|
|
// H-alpha: i=2, j=3
|
|
let (xkij, wl0, fij) = stark0(2, 3, 1);
|
|
assert!(xkij > 0.0);
|
|
assert!(wl0 > 0.0);
|
|
assert!(fij > 0.0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_stark0_h_beta() {
|
|
// H-beta: i=2, j=4
|
|
let (xkij, wl0, fij) = stark0(2, 4, 1);
|
|
assert!(xkij > 0.0);
|
|
assert!(wl0 > 0.0);
|
|
assert!(fij > 0.0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_stark0_he_ii() {
|
|
// He II: izz=2
|
|
let (xkij, wl0, fij) = stark0(2, 3, 2);
|
|
assert!(xkij > 0.0);
|
|
assert!(wl0 > 0.0);
|
|
assert!(fij > 0.0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_stark0_high_j() {
|
|
// j > 6 使用渐近公式
|
|
let (xkij, wl0, fij) = stark0(2, 10, 1);
|
|
assert!(xkij > 0.0);
|
|
assert!(wl0 > 0.0);
|
|
assert!(fij > 0.0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_stark0_jmin_gt_10() {
|
|
// j - i > 10
|
|
let (xkij, wl0, fij) = stark0(2, 15, 1);
|
|
assert!(xkij > 0.0);
|
|
assert!(wl0 > 0.0);
|
|
assert!(fij > 0.0);
|
|
}
|
|
}
|