Skip to content
This repository was archived by the owner on Jun 14, 2022. It is now read-only.

Commit 95996d4

Browse files
authored
Add conversions between error types to improve error messages (#40)
1 parent 1d10196 commit 95996d4

File tree

6 files changed

+79
-76
lines changed

6 files changed

+79
-76
lines changed

src/errors.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::parameter::ParameterError;
12
use argmin::core::Error as ArgminError;
23
use num_dual::linalg::LinAlgError;
34
use quantity::QuantityError;
@@ -25,6 +26,8 @@ pub enum EosError {
2526
#[error(transparent)]
2627
QuantityError(#[from] QuantityError),
2728
#[error(transparent)]
29+
ParameterError(#[from] ParameterError),
30+
#[error(transparent)]
2831
ArgminError(#[from] ArgminError),
2932
#[error(transparent)]
3033
LinAlgError(#[from] LinAlgError),

src/joback.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ mod tests {
171171
struct ModelRecord;
172172

173173
#[test]
174-
fn paper_example() {
174+
fn paper_example() -> EosResult<()> {
175175
let segments_json = r#"[
176176
{
177177
"identifier": "-Cl",
@@ -226,8 +226,7 @@ mod tests {
226226
],
227227
None,
228228
)
229-
.segment_count(&segment_records)
230-
.unwrap();
229+
.segment_count(&segment_records)?;
231230
assert_eq!(segments.get(&segment_records[0]), Some(&2.0));
232231
assert_eq!(segments.get(&segment_records[1]), Some(&4.0));
233232
assert_eq!(segments.get(&segment_records[2]), Some(&2.0));
@@ -264,17 +263,16 @@ mod tests {
264263
1000.0 * KELVIN,
265264
1.0 * ANGSTROM.powi(3),
266265
&(arr1(&[1.0]) * MOL),
267-
)
268-
.unwrap();
266+
)?;
269267
assert!(
270268
(state
271269
.c_p(Contributions::IdealGas)
272-
.to_reduced(JOULE / MOL / KELVIN)
273-
.unwrap()
270+
.to_reduced(JOULE / MOL / KELVIN)?
274271
- 224.6)
275272
.abs()
276273
< 1.0
277-
)
274+
);
275+
Ok(())
278276
}
279277

280278
#[test]

src/python/utils.rs

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,12 @@ macro_rules! impl_estimator {
138138
target: &PySIArray1,
139139
temperature: &PySIArray1,
140140
std_parameters: Option<Vec<f64>>,
141-
) -> Self {
142-
Self(Rc::new(
143-
VaporPressure::<SIUnit>::new(
144-
target.clone().into(),
145-
temperature.clone().into(),
146-
std_parameters.unwrap_or(vec![0.0, 0.0, 0.0]),
147-
)
148-
.unwrap(),
149-
))
141+
) -> PyResult<Self> {
142+
Ok(Self(Rc::new(VaporPressure::<SIUnit>::new(
143+
target.clone().into(),
144+
temperature.clone().into(),
145+
std_parameters.unwrap_or(vec![0.0, 0.0, 0.0]),
146+
)?)))
150147
}
151148

152149
/// Create a DataSet with experimental data for liquid density.
@@ -177,15 +174,12 @@ macro_rules! impl_estimator {
177174
target: &PySIArray1,
178175
temperature: &PySIArray1,
179176
pressure: &PySIArray1,
180-
) -> Self {
181-
Self(Rc::new(
182-
LiquidDensity::<SIUnit>::new(
183-
target.clone().into(),
184-
temperature.clone().into(),
185-
pressure.clone().into(),
186-
)
187-
.unwrap(),
188-
))
177+
) -> PyResult<Self> {
178+
Ok(Self(Rc::new(LiquidDensity::<SIUnit>::new(
179+
target.clone().into(),
180+
temperature.clone().into(),
181+
pressure.clone().into(),
182+
)?)))
189183
}
190184

191185
/// Create a DataSet with experimental data for liquid density
@@ -211,14 +205,14 @@ macro_rules! impl_estimator {
211205
/// eos_python.saft.estimator.DataSet.relative_difference
212206
#[staticmethod]
213207
#[pyo3(text_signature = "(target, temperature)")]
214-
fn equilibrium_liquid_density(target: &PySIArray1, temperature: &PySIArray1) -> Self {
215-
Self(Rc::new(
216-
EquilibriumLiquidDensity::<SIUnit>::new(
217-
target.clone().into(),
218-
temperature.clone().into(),
219-
)
220-
.unwrap(),
221-
))
208+
fn equilibrium_liquid_density(
209+
target: &PySIArray1,
210+
temperature: &PySIArray1,
211+
) -> PyResult<Self> {
212+
Ok(Self(Rc::new(EquilibriumLiquidDensity::<SIUnit>::new(
213+
target.clone().into(),
214+
temperature.clone().into(),
215+
)?)))
222216
}
223217

224218
/// Return `input` as ``Dict[str, SIArray1]``.

src/state/builder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::rc::Rc;
1818
/// # use approx::assert_relative_eq;
1919
/// # fn main() -> EosResult<()> {
2020
/// // Create a state for given T,V,N
21-
/// let eos = Rc::new(PengRobinson::new(Rc::new(PengRobinsonParameters::new_simple(&[369.8], &[41.9 * 1e5], &[0.15], &[15.0]).unwrap())));
21+
/// let eos = Rc::new(PengRobinson::new(Rc::new(PengRobinsonParameters::new_simple(&[369.8], &[41.9 * 1e5], &[0.15], &[15.0])?)));
2222
/// let state = StateBuilder::new(&eos)
2323
/// .temperature(300.0 * KELVIN)
2424
/// .volume(12.5 * METER.powi(3))
@@ -27,7 +27,7 @@ use std::rc::Rc;
2727
/// assert_eq!(state.density, 0.2 * MOL / METER.powi(3));
2828
///
2929
/// // For a pure component, the composition does not need to be specified.
30-
/// let eos = Rc::new(PengRobinson::new(Rc::new(PengRobinsonParameters::new_simple(&[369.8], &[41.9 * 1e5], &[0.15], &[15.0]).unwrap())));
30+
/// let eos = Rc::new(PengRobinson::new(Rc::new(PengRobinsonParameters::new_simple(&[369.8], &[41.9 * 1e5], &[0.15], &[15.0])?)));
3131
/// let state = StateBuilder::new(&eos)
3232
/// .temperature(300.0 * KELVIN)
3333
/// .volume(12.5 * METER.powi(3))
@@ -42,7 +42,7 @@ use std::rc::Rc;
4242
/// &[41.9 * 1e5, 48.2 * 1e5],
4343
/// &[0.15, 0.10],
4444
/// &[15.0, 30.0]
45-
/// ).unwrap())
45+
/// )?)
4646
/// ));
4747
/// let state = StateBuilder::new(&eos)
4848
/// .temperature(300.0 * KELVIN)

src/utils/dataset.rs

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ impl<U: EosUnit> VaporPressure<U> {
100100
) -> Result<Self, FitError> {
101101
let datapoints = target.len();
102102
let max_temperature = temperature
103-
.to_reduced(U::reference_temperature())
104-
.unwrap()
103+
.to_reduced(U::reference_temperature())?
105104
.into_iter()
106105
.reduce(|a, b| a.max(b))
107106
.unwrap()
@@ -147,10 +146,13 @@ impl<U: EosUnit, E: EquationOfState> DataSet<U, E> for VaporPressure<U> {
147146
where
148147
QuantityScalar<U>: std::fmt::Display + std::fmt::LowerExp,
149148
{
150-
let tc =
151-
State::critical_point(eos, None, Some(self.max_temperature), SolverOptions::default())
152-
.unwrap()
153-
.temperature;
149+
let tc = State::critical_point(
150+
eos,
151+
None,
152+
Some(self.max_temperature),
153+
SolverOptions::default(),
154+
)?
155+
.temperature;
154156

155157
let unit = self.target.get(0);
156158
let mut prediction = Array1::zeros(self.datapoints) * unit;
@@ -160,12 +162,12 @@ impl<U: EosUnit, E: EquationOfState> DataSet<U, E> for VaporPressure<U> {
160162
if let Some(pvap) =
161163
PhaseEquilibrium::vapor_pressure(eos, self.temperature.get(i))[0]
162164
{
163-
prediction.try_set(i, pvap).unwrap();
165+
prediction.try_set(i, pvap)?;
164166
} else {
165-
prediction.try_set(i, f64::NAN * unit).unwrap();
167+
prediction.try_set(i, f64::NAN * unit)?;
166168
}
167169
} else {
168-
prediction.try_set(i, f64::NAN * unit).unwrap();
170+
prediction.try_set(i, f64::NAN * unit)?;
169171
}
170172
}
171173
Ok(prediction)
@@ -176,14 +178,18 @@ impl<U: EosUnit, E: EquationOfState> DataSet<U, E> for VaporPressure<U> {
176178
QuantityScalar<U>: std::fmt::Display + std::fmt::LowerExp,
177179
{
178180
let tc_inv = 1.0
179-
/ State::critical_point(eos, None, Some(self.max_temperature), SolverOptions::default())
180-
.unwrap()
181-
.temperature;
182-
183-
let reduced_temperatures = (0..self.datapoints)
184-
.map(|i| (self.temperature.get(i) * tc_inv).into_value().unwrap())
181+
/ State::critical_point(
182+
eos,
183+
None,
184+
Some(self.max_temperature),
185+
SolverOptions::default(),
186+
)?
187+
.temperature;
188+
189+
let reduced_temperatures: Result<_, _> = (0..self.datapoints)
190+
.map(|i| (self.temperature.get(i) * tc_inv).into_value())
185191
.collect();
186-
let mut weights = self.weight_from_std(&reduced_temperatures);
192+
let mut weights = self.weight_from_std(&reduced_temperatures?);
187193
weights /= weights.sum();
188194

189195
let prediction = &self.predict(eos)?;
@@ -193,8 +199,7 @@ impl<U: EosUnit, E: EquationOfState> DataSet<U, E> for VaporPressure<U> {
193199
cost[i] = weights[i]
194200
* 5.0
195201
* (self.temperature.get(i) - 1.0 / tc_inv)
196-
.to_reduced(U::reference_temperature())
197-
.unwrap();
202+
.to_reduced(U::reference_temperature())?;
198203
} else {
199204
cost[i] = weights[i]
200205
* ((self.target.get(i) - prediction.get(i)) / self.target.get(i))
@@ -275,9 +280,9 @@ impl<U: EosUnit, E: EquationOfState + MolarWeight<U>> DataSet<U, E> for LiquidDe
275280
DensityInitialization::Liquid,
276281
);
277282
if let Ok(s) = state {
278-
prediction.try_set(i, s.mass_density()).unwrap();
283+
prediction.try_set(i, s.mass_density())?;
279284
} else {
280-
prediction.try_set(i, 1.0e10 * unit).unwrap();
285+
prediction.try_set(i, 1.0e10 * unit)?;
281286
}
282287
}
283288
Ok(prediction)
@@ -322,8 +327,7 @@ impl<U: EosUnit> EquilibriumLiquidDensity<U> {
322327
) -> Result<Self, FitError> {
323328
let datapoints = target.len();
324329
let max_temperature = temperature
325-
.to_reduced(U::reference_temperature())
326-
.unwrap()
330+
.to_reduced(U::reference_temperature())?
327331
.into_iter()
328332
.reduce(|a, b| a.max(b))
329333
.unwrap()
@@ -362,23 +366,24 @@ impl<U: EosUnit, E: EquationOfState + MolarWeight<U>> DataSet<U, E>
362366
where
363367
QuantityScalar<U>: std::fmt::Display + std::fmt::LowerExp,
364368
{
365-
let tc =
366-
State::critical_point(eos, None, Some(self.max_temperature), SolverOptions::default())
367-
.unwrap()
368-
.temperature;
369+
let tc = State::critical_point(
370+
eos,
371+
None,
372+
Some(self.max_temperature),
373+
SolverOptions::default(),
374+
)?
375+
.temperature;
369376

370377
let unit = self.target.get(0);
371378
let mut prediction = Array1::zeros(self.datapoints) * unit;
372379
for i in 0..self.datapoints {
373380
let t: QuantityScalar<U> = self.temperature.get(i);
374381
if t < tc {
375382
let state: PhaseEquilibrium<U, E, 2> =
376-
PhaseEquilibrium::pure_t(eos, t, None, SolverOptions::default()).unwrap();
377-
prediction
378-
.try_set(i, state.liquid().mass_density())
379-
.unwrap();
383+
PhaseEquilibrium::pure_t(eos, t, None, SolverOptions::default())?;
384+
prediction.try_set(i, state.liquid().mass_density())?;
380385
} else {
381-
prediction.try_set(i, f64::NAN * unit).unwrap();
386+
prediction.try_set(i, f64::NAN * unit)?;
382387
}
383388
}
384389
Ok(prediction)
@@ -388,20 +393,21 @@ impl<U: EosUnit, E: EquationOfState + MolarWeight<U>> DataSet<U, E>
388393
where
389394
QuantityScalar<U>: std::fmt::Display + std::fmt::LowerExp,
390395
{
391-
let tc =
392-
State::critical_point(eos, None, Some(self.max_temperature), SolverOptions::default())
393-
.unwrap()
394-
.temperature;
396+
let tc = State::critical_point(
397+
eos,
398+
None,
399+
Some(self.max_temperature),
400+
SolverOptions::default(),
401+
)?
402+
.temperature;
395403
let n_inv = 1.0 / self.datapoints as f64;
396404
let prediction = &self.predict(eos)?;
397405
let mut cost = Array1::zeros(self.datapoints);
398406
for i in 0..self.datapoints {
399407
if prediction.get(i).is_nan() {
400408
cost[i] = n_inv
401409
* 5.0
402-
* (self.temperature.get(i) - tc)
403-
.to_reduced(U::reference_temperature())
404-
.unwrap();
410+
* (self.temperature.get(i) - tc).to_reduced(U::reference_temperature())?;
405411
} else {
406412
cost[i] = n_inv
407413
* ((self.target.get(i) - prediction.get(i)) / self.target.get(i))

src/utils/estimator.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! optimization.
33
use super::dataset::*;
44
use crate::equation_of_state::EquationOfState;
5-
use crate::EosUnit;
5+
use crate::{EosError, EosUnit};
66
use ndarray::{arr1, concatenate, Array1, ArrayView1, Axis};
77
use quantity::{QuantityArray1, QuantityError, QuantityScalar};
88
use std::fmt;
@@ -25,6 +25,8 @@ pub enum FitError {
2525
ParseError(#[from] ParseFloatError),
2626
#[error(transparent)]
2727
QuantityError(#[from] QuantityError),
28+
#[error(transparent)]
29+
EosError(#[from] EosError),
2830
}
2931

3032
/// A collection of [`DataSet`]s and weights that can be used to

0 commit comments

Comments
 (0)