//! Van der Waals broadening parameter evaluation. //! //! Translated from SYNSPEC54.FOR function GVDW(IL,ILIST,ID) at line 19468. //! //! Supports two modes: //! - Standard expression (`ivdwli == 0`) //! - EXOMOL form with H2 and He broadening (`ivdwli > 0`) /// Parameters for Van der Waals broadening calculation. pub struct GvdwParams<'a> { /// Line index pub il: usize, /// Line list index pub ilist: usize, /// Depth index pub id: usize, /// Van der Waals damping parameter (standard mode) pub gwm: f64, /// Van der Waals coefficient at depth pub vdwc: &'a [f64], /// Mode of evaluation per line list (0 = standard, >0 = EXOMOL) pub ivdwli: &'a [i32], /// Temperature at each depth pub temp: &'a [f64], /// He number density at each depth (from rrr array) pub anhe: f64, /// H2 number density at each depth pub anh2: &'a [f64], /// EXOMOL H2 broadening exponent pub gexph2: f64, /// EXOMOL H2 broadening width pub gvdwh2: f64, /// EXOMOL He broadening exponent pub gexphe: f64, /// EXOMOL He broadening width pub gvdwhe: f64, } /// Van der Waals broadening parameter. /// /// Computes the Van der Waals broadening parameter for spectral line profiles. /// Supports both the standard classical expression and the EXOMOL form /// (broadening by H2 and He). /// /// # Arguments /// * `params` - Calculation parameters /// /// # Returns /// Van der Waals broadening parameter pub fn gvdw(params: &GvdwParams) -> f64 { // Standard classical expression if params.ivdwli[params.ilist] == 0 { return params.gwm * params.vdwc[params.id]; } // EXOMOL form - broadening by H2 and He // con = 1e-6 * c * k (cgs) let con = 4.1388e-12; let t = params.temp[params.id]; con * t * ((296.0 / t).powf(params.gexph2) * params.gvdwh2 * params.anh2[params.id] + (296.0 / t).powf(params.gexphe) * params.gvdwhe * params.anhe) } #[cfg(test)] mod tests { use super::*; #[test] fn test_gvdw_standard_mode() { let vdwc = vec![1.0, 2.0, 3.0]; let ivdwli = vec![0]; let temp = vec![5000.0, 6000.0, 7000.0]; let anh2 = vec![1e10, 1e10, 1e10]; let params = GvdwParams { il: 0, ilist: 0, id: 1, gwm: 0.5, vdwc: &vdwc, ivdwli: &ivdwli, temp: &temp, anhe: 1e10, anh2: &anh2, gexph2: 0.0, gvdwh2: 0.0, gexphe: 0.0, gvdwhe: 0.0, }; // Standard: gwm * vdwc[id] = 0.5 * 2.0 = 1.0 let result = gvdw(¶ms); assert!((result - 1.0).abs() < 1e-15); } #[test] fn test_gvdw_exomol_mode() { let vdwc = vec![1.0; 3]; let ivdwli = vec![1]; let temp = vec![5000.0; 3]; let anh2 = vec![1e12; 3]; let params = GvdwParams { il: 0, ilist: 0, id: 0, gwm: 1.0, vdwc: &vdwc, ivdwli: &ivdwli, temp: &temp, anhe: 1e11, anh2: &anh2, gexph2: 0.5, gvdwh2: 1e-9, gexphe: 0.3, gvdwhe: 5e-10, }; let result = gvdw(¶ms); assert!(result > 0.0); assert!(result.is_finite()); } #[test] fn test_gvdw_exomol_temperature_dependence() { let vdwc = vec![1.0; 2]; let ivdwli = vec![1]; let anh2 = vec![1e12; 2]; let params_low = GvdwParams { il: 0, ilist: 0, id: 0, gwm: 1.0, vdwc: &vdwc, ivdwli: &ivdwli, temp: &[3000.0, 10000.0], anhe: 1e11, anh2: &anh2, gexph2: 0.5, gvdwh2: 1e-9, gexphe: 0.3, gvdwhe: 5e-10, }; let params_high = GvdwParams { id: 1, ..params_low }; let r_low = gvdw(¶ms_low); let r_high = gvdw(¶ms_high); // Both should be positive assert!(r_low > 0.0); assert!(r_high > 0.0); } }