//! 钙离子光电离截面 (Verner 1996)。 //! //! 重构自 TLUSTY `vern20.f` //! //! 参考: //! - Verner D.A. et al. 1996, ApJ 465 //! - Verner & Yakovlev 1995, A&AS 109, 125 use crate::state::constants::{HALF, UN}; // ============================================================================ // VERN20 - 钙离子光电离截面 // ============================================================================ const T18: f64 = 1e-18; const MVER: usize = 20; // 1996 参数 static S0: [f64; MVER] = [ 5.37e5, 1.064e7, 3.815e1, 7.736, 1.523e-1, 7.642e1, 4.76e-1, 6.641e-1, 2.076e2, 1.437e1, 9.384e-1, 1.227e1, 1.849e3, 1.116, 5.513e1, 1.293, 2.028e4, 1.105e1, 1.936e1, 1.369e2 ]; static E0: [f64; MVER] = [ 12.78, 15.53, 24.36, 4.255, 0.6882, 9.515, 0.808, 1.366, 0.0552, 16.05, 0.2288, 23.45, 10.08, 9.98, 130.9, 4.293, 26.18, 94.72, 629.7, 172.9 ]; static EMX: [f64; MVER] = [ 34.43, 40.9, 373.1, 394.4, 417.5, 442.3, 468.7, 496.7, 527., 556.9, 4265., 4362., 4453., 4555., 4659., 4767., 4880., 4982., 5e4, 5e4 ]; static Y0: [f64; MVER] = [ 1.012e-3, 2.161e-3, 1.802, 14.67, 121., 4.829, 148.7, 103.9, 2.826e-4, 0., 24.78, 24.17, 6.138e-3, 71.04, 1.833e-2, 0.9363, 2.402e-2, 0., 0., 0. ]; static Y1: [f64; MVER] = [ 1.851e-2, 6.706e-2, 1.233, 3.298e-2, 3.876, 5.824, 1.283, 3.329, 1.657, 0., 3.1, 0.5469, 69.31, 5.311, 0.9359, 4.589e-2, 9.323e-3, 0., 0., 0. ]; static YW: [f64; MVER] = [ 0.4477, 0.6453, 0.3126, 1.369, 8.277, 2.471, 0.572, 0.2806, 1.843e-3, 0., 1.39, 6.842e-4, 241., 3.879, 9.084e-2, 3.461e-5, 28.03, 0., 0., 0. ]; static YA: [f64; MVER] = [ 0.3162, 0.779, 293.1, 13.55, 150.2, 89.73, 368.2, 318.8, 1.79e4, 698.9, 254.9, 13.12, 1.792e4, 59.18, 382.8, 16.91, 1.456, 38.18, 39.21, 32.88 ]; static PV: [f64; MVER] = [ 12.42, 21.3, 3.944, 12.36, 10.61, 5.141, 8.634, 8.138, 5.893, 3.857, 11.03, 9.771, 2.868, 9.005, 2.023, 14.38, 25.6, 4.192, 1.862, 2.963 ]; // 1995 参数 (高能) static S95: [f64; MVER] = [ 9.017e1, 7.314e1, 1.945e2, 1.542e2, 1.622e2, 1.855e2, 2.181e2, 2.788e2, 1.934e2, 6.616e2, 1.547e1, 1.324e1, 1.57e1, 1.384e1, 1.417e1, 1.665e1, 1.486e1, 1.82e1, 1.936e1, 1.369e2 ]; static E95: [f64; MVER] = [ 44.87, 44.98, 126., 141.3, 138.4, 130.3, 120.8, 107., 129.3, 65.11, 701., 750.3, 698.9, 739.6, 734.2, 686.2, 723.5, 664., 629.7, 172.9 ]; static Y95: [f64; MVER] = [ 14.65, 18.98, 68.19, 99.06, 88.11, 69.93, 58.16, 47.68, 70., 43.71, 31.97, 50., 32.18, 50., 50., 34.43, 50., 39.79, 39.21, 32.88 ]; static YW95: [f64; MVER] = [ 0.2754, 0.2735, 4.791e-4, 1.107e-3, 4.384e-4, 1.4e-5, 4.346e-6, 4.591e-6, 0.1, 7.881e-6, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. ]; static P95: [f64; MVER] = [ 7.498, 7.152, 3.77, 3.446, 3.521, 3.707, 3.907, 4.2, 3.7, 4.937, 1.858, 1.65, 1.851, 1.65, 1.65, 1.823, 1.65, 1.777, 1.862, 2.963 ]; /// 计算钙离子基态光电离截面。 /// /// # 参数 /// /// - `e` - 光子能量 (Rydberg) /// - `izz` - 离子电荷 (1-20, 对应 Ca I - Ca XX) /// /// # 返回 /// /// 光电离截面 (cm²) pub fn vern20(e: f64, izz: usize) -> f64 { if izz == 0 || izz > MVER { return 0.0; } let iver = izz - 1; if e < EMX[iver] { let xx = e / E0[iver] - Y0[iver]; let yy = (xx * xx + Y1[iver] * Y1[iver]).sqrt(); let aa = (xx - UN) * (xx - UN) + YW[iver] * YW[iver]; let bb = yy.powf(HALF * PV[iver] - 5.5); let cc = (UN + (yy / YA[iver]).sqrt()).powf(PV[iver]); let fy = aa * bb / cc; S0[iver] * T18 * fy } else { let yy = e / E95[iver]; let xl = if izz <= 10 { UN } else { 0.0 }; let q = HALF * P95[iver] - 5.5 - xl; let aa = (yy - UN) * (yy - UN) + YW95[iver] * YW95[iver]; let bb = yy.powf(q); let cc = (UN + (yy / Y95[iver]).sqrt()).powf(P95[iver]); let fy = aa * bb / cc; S95[iver] * T18 * fy } } #[cfg(test)] mod tests { use super::*; #[test] fn test_vern20_ca_ii() { let izz = 2; let e = E0[izz - 1]; let sigma = vern20(e, izz); assert!(sigma > 0.0); } #[test] fn test_vern20_ca_i_low_energy() { let izz = 1; let e = 10.0; let sigma = vern20(e, izz); assert!(sigma > 0.0); } #[test] fn test_vern20_ca_i_high_energy() { let izz = 1; let e = 50.0; // 高于 EMX[0] = 34.43 let sigma = vern20(e, izz); assert!(sigma > 0.0); } #[test] fn test_vern20_invalid_izz() { assert_eq!(vern20(10.0, 0), 0.0); assert_eq!(vern20(10.0, 21), 0.0); } #[test] fn test_vern20_decreasing_with_energy() { let izz = 3; let sigma_low = vern20(50.0, izz); let sigma_high = vern20(200.0, izz); assert!(sigma_low > sigma_high); } }