From 063ec157956ff01f25825d91e4c160a8906ba932 Mon Sep 17 00:00:00 2001 From: Alex Selimov Date: Sun, 29 Mar 2026 22:31:09 -0400 Subject: [PATCH] Prevent polynomial_at from panicking --- src/properties/thermo_db.rs | 76 +++++++++++++++++++++++++++--------- src/properties/thermo_fit.rs | 30 +++++++++----- 2 files changed, 78 insertions(+), 28 deletions(-) diff --git a/src/properties/thermo_db.rs b/src/properties/thermo_db.rs index 5eecb2d..7db0c05 100644 --- a/src/properties/thermo_db.rs +++ b/src/properties/thermo_db.rs @@ -295,9 +295,17 @@ mod test { -1.742171366e+01, ]; - assert_vec_delta!(species.polynomial_at(650.0).a, real_coeff_1, 1e-9); - assert_delta!(species.polynomial_at(650.0).temp_range.0, 300.000, 1e-3); - assert_delta!(species.polynomial_at(650.0).temp_range.1, 1000.000, 1e-3); + assert_vec_delta!(species.polynomial_at(650.0).unwrap().a, real_coeff_1, 1e-9); + assert_delta!( + species.polynomial_at(650.0).unwrap().temp_range.0, + 300.000, + 1e-3 + ); + assert_delta!( + species.polynomial_at(650.0).unwrap().temp_range.1, + 1000.000, + 1e-3 + ); let real_coeff_2 = [ -3.523782900e+05, @@ -311,9 +319,17 @@ mod test { -2.695610360e+00, ]; - assert_vec_delta!(species.polynomial_at(3500.0).a, real_coeff_2, 1e-9); - assert_delta!(species.polynomial_at(3500.0).temp_range.0, 1000.000, 1e-3); - assert_delta!(species.polynomial_at(3500.0).temp_range.1, 6000.000, 1e-3); + assert_vec_delta!(species.polynomial_at(3500.0).unwrap().a, real_coeff_2, 1e-9); + assert_delta!( + species.polynomial_at(3500.0).unwrap().temp_range.0, + 1000.000, + 1e-3 + ); + assert_delta!( + species.polynomial_at(3500.0).unwrap().temp_range.1, + 6000.000, + 1e-3 + ); } #[test] @@ -366,7 +382,7 @@ END REACTANTS assert_eq!(alcl3.num_polynomials(), 2); assert_vec_delta!( - alcl3.polynomial_at(650.0).a, + alcl3.polynomial_at(650.0).unwrap().a, [ 7.750600970e+04, -1.440779717e+03, @@ -380,11 +396,19 @@ END REACTANTS ], 1e-9 ); - assert_delta!(alcl3.polynomial_at(650.0).temp_range.0, 300.0, 1e-3); - assert_delta!(alcl3.polynomial_at(650.0).temp_range.1, 1000.0, 1e-3); + assert_delta!( + alcl3.polynomial_at(650.0).unwrap().temp_range.0, + 300.0, + 1e-3 + ); + assert_delta!( + alcl3.polynomial_at(650.0).unwrap().temp_range.1, + 1000.0, + 1e-3 + ); assert_vec_delta!( - alcl3.polynomial_at(3500.0).a, + alcl3.polynomial_at(3500.0).unwrap().a, [ -1.378630916e+05, -5.579207290e+01, @@ -398,8 +422,16 @@ END REACTANTS ], 1e-9 ); - assert_delta!(alcl3.polynomial_at(3500.0).temp_range.0, 1000.0, 1e-3); - assert_delta!(alcl3.polynomial_at(3500.0).temp_range.1, 6000.0, 1e-3); + assert_delta!( + alcl3.polynomial_at(3500.0).unwrap().temp_range.0, + 1000.0, + 1e-3 + ); + assert_delta!( + alcl3.polynomial_at(3500.0).unwrap().temp_range.1, + 6000.0, + 1e-3 + ); // --- Air (reactant 0) --- let air = &thermo_db.reactants[0]; @@ -419,7 +451,7 @@ END REACTANTS assert_eq!(air.num_polynomials(), 2); assert_vec_delta!( - air.polynomial_at(650.0).a, + air.polynomial_at(650.0).unwrap().a, [ 1.009950160e+04, -1.968275610e+02, @@ -433,11 +465,11 @@ END REACTANTS ], 1e-9 ); - assert_delta!(air.polynomial_at(650.0).temp_range.0, 300.0, 1e-3); - assert_delta!(air.polynomial_at(650.0).temp_range.1, 1000.0, 1e-3); + assert_delta!(air.polynomial_at(650.0).unwrap().temp_range.0, 300.0, 1e-3); + assert_delta!(air.polynomial_at(650.0).unwrap().temp_range.1, 1000.0, 1e-3); assert_vec_delta!( - air.polynomial_at(3500.0).a, + air.polynomial_at(3500.0).unwrap().a, [ 2.415214430e+05, -1.257874600e+03, @@ -451,8 +483,16 @@ END REACTANTS ], 1e-9 ); - assert_delta!(air.polynomial_at(3500.0).temp_range.0, 1000.0, 1e-3); - assert_delta!(air.polynomial_at(3500.0).temp_range.1, 6000.0, 1e-3); + assert_delta!( + air.polynomial_at(3500.0).unwrap().temp_range.0, + 1000.0, + 1e-3 + ); + assert_delta!( + air.polynomial_at(3500.0).unwrap().temp_range.1, + 6000.0, + 1e-3 + ); // --- n-Butanol (reactant 1) --- let butanol = &thermo_db.reactants[1]; diff --git a/src/properties/thermo_fit.rs b/src/properties/thermo_fit.rs index 2d5bdf0..893bbcf 100644 --- a/src/properties/thermo_fit.rs +++ b/src/properties/thermo_fit.rs @@ -44,18 +44,22 @@ impl SpeciesThermoData { self.polynomials.len() } - pub fn polynomial_at(&self, temp: f64) -> &ThermoPolynomial { + pub fn polynomial_at(&self, temp: f64) -> Option<&ThermoPolynomial> { //TODO: Not the most efficient. Can refactor to pre-compute tables //and do 1-d linear interpolation if needed // //TODO: I Think condensed species need to be treated differently. Verify how that works in //the paper. + if self.polynomials.is_empty() { + return None; + } + let i_polynomial = self .polynomials .iter() .rposition(|polynomial| temp > polynomial.temp_range.0) .unwrap_or(0); - &self.polynomials[i_polynomial] + Some(&self.polynomials[i_polynomial]) } } @@ -113,8 +117,8 @@ mod test { a: vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0], temp_range: (0.0, 0.0), } - .cp_over_r(1.0); - assert_delta!(result, 28.0, 1e-10); + .cp_over_r(100.0); + assert_delta!(result, 706050403.0201, 1e-4); let result = ThermoPolynomial { a: vec![4.0, 2.0, 1.0, 2.0, 1.0, 1.0, 1.0], @@ -180,22 +184,28 @@ mod test { h_formation: 1.0, }; - assert!(std::ptr::eq(data.polynomial_at(0.5), &data.polynomials[0])); - assert!(std::ptr::eq(data.polynomial_at(50.0), &data.polynomials[0])); assert!(std::ptr::eq( - data.polynomial_at(100.0), + data.polynomial_at(0.5).unwrap(), &data.polynomials[0] )); assert!(std::ptr::eq( - data.polynomial_at(100.0 + 1e-12), + data.polynomial_at(50.0).unwrap(), + &data.polynomials[0] + )); + assert!(std::ptr::eq( + data.polynomial_at(100.0).unwrap(), + &data.polynomials[0] + )); + assert!(std::ptr::eq( + data.polynomial_at(100.0 + 1e-12).unwrap(), &data.polynomials[1] )); assert!(std::ptr::eq( - data.polynomial_at(150.0 + 1e-12), + data.polynomial_at(150.0 + 1e-12).unwrap(), &data.polynomials[1] )); assert!(std::ptr::eq( - data.polynomial_at(500.0 + 1e-12), + data.polynomial_at(500.0 + 1e-12).unwrap(), &data.polynomials[1] )); }