Skip to content

Commit

Permalink
upgrade to ninterp 0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
kylecarow committed Jan 23, 2025
1 parent 74487fb commit 120999e
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 114 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion fastsim-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ toml = { version = "0.8.12", optional = true }
derive_more = { version = "1.0.0", features = ["from_str", "from", "is_variant", "try_into"] }
ureq = { version = "2.9.1", optional = true }
url = { version = "2.5.0", optional = true }
ninterp = { version = "0.1.0", features = ["serde"] }
ninterp = { version = "0.2.0", features = ["serde"] }

[dev-dependencies]
pretty_assertions = "1.4.1"
Expand Down
8 changes: 4 additions & 4 deletions fastsim-core/src/drive_cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,19 +100,19 @@ impl Init for Cycle {
)
.collect();
// println!("{:?}", self.dist);
self.grade_interp = Some(Interpolator::Interp1D(Interp1D::new(
self.grade_interp = Some(Interpolator::new_1d(
self.dist.iter().map(|x| x.get::<si::meter>()).collect(),
self.grade.iter().map(|y| y.get::<si::ratio>()).collect(),
Strategy::Linear,
Extrapolate::Error,
)?));
)?);

self.elev_interp = Some(Interpolator::Interp1D(Interp1D::new(
self.elev_interp = Some(Interpolator::new_1d(
self.dist.iter().map(|x| x.get::<si::meter>()).collect(),
self.elev.iter().map(|y| y.get::<si::meter>()).collect(),
Strategy::Linear,
Extrapolate::Error,
)?));
)?);

Ok(())
}
Expand Down
20 changes: 10 additions & 10 deletions fastsim-core/src/gas_properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,13 +273,13 @@ mod air_static_props {
.iter()
.map(|x| *x * uc::KELVIN + *uc::CELSIUS_TO_KELVIN)
.collect();
pub static ref TEMP_FROM_ENTHALPY: Interp1D = Interp1D::new(
pub static ref TEMP_FROM_ENTHALPY: Interpolator = Interpolator::new_1d(
ENTHALPY_VALUES.iter().map(|x| x.get::<si::joule_per_kilogram>()).collect::<Vec<f64>>(),
TEMPERATURE_VALUES.iter().map(|x| x.get::<si::kelvin>()).collect::<Vec<f64>>(),
Strategy::Linear,
Extrapolate::Error
).unwrap();
pub static ref TEMP_FROM_ENERGY: Interp1D = Interp1D::new(
pub static ref TEMP_FROM_ENERGY: Interpolator = Interpolator::new_1d(
ENERGY_VALUES.iter().map(|x| x.get::<si::joule_per_kilogram>()).collect::<Vec<f64>>(),
TEMPERATURE_VALUES.iter().map(|x| x.get::<si::kelvin>()).collect::<Vec<f64>>(),
Strategy::Linear,
Expand Down Expand Up @@ -316,7 +316,7 @@ mod air_static_props {
.iter()
.map(|x| *x * uc::WATT_PER_METER_KELVIN)
.collect();
pub static ref THERMAL_CONDUCTIVITY_INTERP: Interp1D = Interp1D::new(
pub static ref THERMAL_CONDUCTIVITY_INTERP: Interpolator = Interpolator::new_1d(
TEMPERATURE_VALUES.iter().map(|x| x.get::<si::kelvin>()).collect::<Vec<f64>>(),
THERMAL_CONDUCTIVITY_VALUES.iter().map(|x| x.get::<si::watt_per_meter_degree_celsius>()).collect::<Vec<f64>>(),
Strategy::Linear,
Expand Down Expand Up @@ -353,7 +353,7 @@ mod air_static_props {
.iter()
.map(|x| *x * uc::J_PER_KG_K)
.collect();
pub static ref C_P_INTERP: Interp1D = Interp1D::new(
pub static ref C_P_INTERP: Interpolator = Interpolator::new_1d(
TEMPERATURE_VALUES.iter().map(|x| x.get::<si::kelvin>()).collect::<Vec<f64>>(),
C_P_VALUES.iter().map(|x| x.get::<si::joule_per_kilogram_kelvin>()).collect::<Vec<f64>>(),
Strategy::Linear,
Expand Down Expand Up @@ -389,7 +389,7 @@ mod air_static_props {
.iter()
.map(|x| *x * uc::J_PER_KG)
.collect();
pub static ref ENTHALPY_INTERP: Interp1D = Interp1D::new(
pub static ref ENTHALPY_INTERP: Interpolator = Interpolator::new_1d(
TEMPERATURE_VALUES.iter().map(|x| x.get::<si::kelvin>()).collect::<Vec<f64>>(),
ENTHALPY_VALUES.iter().map(|x| x.get::<si::joule_per_kilogram>()).collect::<Vec<f64>>(),
Strategy::Linear,
Expand Down Expand Up @@ -425,7 +425,7 @@ mod air_static_props {
.iter()
.map(|x| *x * uc::J_PER_KG)
.collect();
pub static ref ENERGY_INTERP: Interp1D = Interp1D::new(
pub static ref ENERGY_INTERP: Interpolator = Interpolator::new_1d(
TEMPERATURE_VALUES.iter().map(|x| x.get::<si::kelvin>()).collect::<Vec<f64>>(),
ENERGY_VALUES.iter().map(|x| x.get::<si::joule_per_kilogram>()).collect::<Vec<f64>>(),
Strategy::Linear,
Expand Down Expand Up @@ -461,7 +461,7 @@ mod air_static_props {
.iter()
.map(|x| *x * uc::PASCAL_SECOND)
.collect();
pub static ref DYN_VISC_INTERP: Interp1D = Interp1D::new(
pub static ref DYN_VISC_INTERP: Interpolator = Interpolator::new_1d(
TEMPERATURE_VALUES.iter().map(|x| x.get::<si::kelvin>()).collect::<Vec<f64>>(),
DYN_VISCOSITY_VALUES.iter().map(|x| x.get::<si::pascal_second>()).collect::<Vec<f64>>(),
Strategy::Linear,
Expand All @@ -473,7 +473,7 @@ mod air_static_props {
.zip(THERMAL_CONDUCTIVITY_VALUES.iter())
.map(|((mu, c_p), k)| -> si::Ratio {*mu * *c_p / *k})
.collect::<Vec<si::Ratio>>();
pub static ref PRANDTL_INTERP: Interp1D = Interp1D::new(
pub static ref PRANDTL_INTERP: Interpolator = Interpolator::new_1d(
TEMPERATURE_VALUES.iter().map(|x| x.get::<si::kelvin>()).collect::<Vec<f64>>(),
PRANDTL_VALUES.iter().map(|x| x.get::<si::ratio>()).collect::<Vec<f64>>(),
Strategy::Linear,
Expand Down Expand Up @@ -551,7 +551,7 @@ mod octane_static_props {
.iter()
.map(|x| *x * uc::KELVIN + *uc::CELSIUS_TO_KELVIN)
.collect();
pub static ref TEMP_FROM_ENERGY: Interp1D = Interp1D::new(
pub static ref TEMP_FROM_ENERGY: Interpolator = Interpolator::new_1d(
ENERGY_VALUES.iter().map(|x| x.get::<si::joule_per_kilogram>()).collect::<Vec<f64>>(),
TEMPERATURE_VALUES.iter().map(|x| x.get::<si::kelvin>()).collect::<Vec<f64>>(),
Strategy::Linear,
Expand Down Expand Up @@ -587,7 +587,7 @@ mod octane_static_props {
.iter()
.map(|x| *x * uc::J_PER_KG)
.collect();
pub static ref ENERGY_INTERP: Interp1D = Interp1D::new(
pub static ref ENERGY_INTERP: Interpolator = Interpolator::new_1d(
TEMPERATURE_VALUES.iter().map(|x| x.get::<si::kelvin>()).collect::<Vec<f64>>(),
ENERGY_VALUES.iter().map(|x| x.get::<si::joule_per_kilogram>()).collect::<Vec<f64>>(),
Strategy::Linear,
Expand Down
20 changes: 10 additions & 10 deletions fastsim-core/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ impl Min for Interpolator {
fn min(&self) -> anyhow::Result<f64> {
match self {
Interpolator::Interp0D(value) => Ok(*value),
Interpolator::Interp1D(interp) => interp.f_x().min(),
Interpolator::Interp2D(interp) => interp.f_xy().min(),
Interpolator::Interp3D(interp) => interp.f_xyz().min(),
Interpolator::InterpND(interp) => Ok(interp
.values()
Interpolator::Interp1D(..) => self.f_x()?.min(),
Interpolator::Interp2D(..) => self.f_xy()?.min(),
Interpolator::Interp3D(..) => self.f_xyz()?.min(),
Interpolator::InterpND(..) => Ok(self
.values()?
.iter()
.fold(f64::INFINITY, |acc, x| acc.min(*x))),
}
Expand Down Expand Up @@ -138,11 +138,11 @@ impl Max for Interpolator {
fn max(&self) -> anyhow::Result<f64> {
match self {
Interpolator::Interp0D(value) => Ok(*value),
Interpolator::Interp1D(interp) => interp.f_x().max(),
Interpolator::Interp2D(interp) => interp.f_xy().max(),
Interpolator::Interp3D(interp) => interp.f_xyz().max(),
Interpolator::InterpND(interp) => Ok(interp
.values()
Interpolator::Interp1D(..) => self.f_x()?.max(),
Interpolator::Interp2D(..) => self.f_xy()?.max(),
Interpolator::Interp3D(..) => self.f_xyz()?.max(),
Interpolator::InterpND(..) => Ok(self
.values()?
.iter()
.fold(f64::NEG_INFINITY, |acc, x| acc.max(*x))),
}
Expand Down
48 changes: 21 additions & 27 deletions fastsim-core/src/utils/interp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ impl InterpolatorMethods for Interpolator {
*value = min;
Ok(())
}
Interpolator::Interp1D(interp) => {
Interpolator::Interp1D(..) => {
todo!()
}
Interpolator::Interp2D(interp) => {
Interpolator::Interp2D(..) => {
todo!()
}
Interpolator::Interp3D(interp) => {
Interpolator::Interp3D(..) => {
todo!()
}
Interpolator::InterpND(interp) => {
Interpolator::InterpND(..) => {
todo!()
}
}
Expand All @@ -38,19 +38,17 @@ impl InterpolatorMethods for Interpolator {
*value = max;
Ok(())
}
Interpolator::Interp1D(interp) => {
Ok(interp.set_f_x(interp.f_x().iter().map(|x| x * max / old_max).collect())?)
Interpolator::Interp1D(..) => {
Ok(self.set_f_x(self.f_x()?.iter().map(|x| x * max / old_max).collect())?)
}
Interpolator::Interp2D(interp) => Ok(interp.set_f_xy(
interp
.f_xy()
Interpolator::Interp2D(..) => Ok(self.set_f_xy(
self.f_xy()?
.iter()
.map(|v| v.iter().map(|x| x * max / old_max).collect())
.collect(),
)?),
Interpolator::Interp3D(interp) => Ok(interp.set_f_xyz(
interp
.f_xyz()
Interpolator::Interp3D(..) => Ok(self.set_f_xyz(
self.f_xyz()?
.iter()
.map(|v0| {
v0.iter()
Expand All @@ -59,8 +57,8 @@ impl InterpolatorMethods for Interpolator {
})
.collect(),
)?),
Interpolator::InterpND(interp) => {
Ok(interp.set_values(interp.values().map(|x| x * max / old_max))?)
Interpolator::InterpND(..) => {
Ok(self.set_values(self.values()?.map(|x| x * max / old_max))?)
}
}
}
Expand All @@ -70,17 +68,15 @@ impl InterpolatorMethods for Interpolator {
let old_range = old_max - self.min()?;
ensure!(old_range != 0., "Cannot modify range when min == max");
match self {
Interpolator::Interp0D(_value) => unreachable!("The above `ensure` should trigger"),
Interpolator::Interp1D(interp) => Ok(interp.set_f_x(
interp
.f_x()
Interpolator::Interp0D(..) => unreachable!("The above `ensure` should trigger"),
Interpolator::Interp1D(..) => Ok(self.set_f_x(
self.f_x()?
.iter()
.map(|x| old_max + (x - old_max) * range / old_range)
.collect(),
)?),
Interpolator::Interp2D(interp) => Ok(interp.set_f_xy(
interp
.f_xy()
Interpolator::Interp2D(..) => Ok(self.set_f_xy(
self.f_xy()?
.iter()
.map(|v| {
v.iter()
Expand All @@ -89,9 +85,8 @@ impl InterpolatorMethods for Interpolator {
})
.collect(),
)?),
Interpolator::Interp3D(interp) => Ok(interp.set_f_xyz(
interp
.f_xyz()
Interpolator::Interp3D(..) => Ok(self.set_f_xyz(
self.f_xyz()?
.iter()
.map(|v0| {
v0.iter()
Expand All @@ -104,9 +99,8 @@ impl InterpolatorMethods for Interpolator {
})
.collect(),
)?),
Interpolator::InterpND(interp) => Ok(interp.set_values(
interp
.values()
Interpolator::InterpND(..) => Ok(self.set_values(
self.values()?
.map(|x| old_max + (x - old_max) * range / old_range),
)?),
}
Expand Down
21 changes: 10 additions & 11 deletions fastsim-core/src/vehicle/powertrain/electric_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ impl Init for ElectricMachine {
if self.eff_interp_at_max_input.is_none() {
// sets eff_interp_bwd to eff_interp_fwd, but changes the x-value.
// TODO: what should the default strategy be for eff_interp_bwd?
let eff_interp_at_max_input = Interp1D::new(
let eff_interp_at_max_input = Interpolator::new_1d(
self.eff_interp_achieved
.x()?
.iter()
Expand All @@ -335,7 +335,7 @@ impl Init for ElectricMachine {
self.eff_interp_achieved.strategy()?.to_owned(),
self.eff_interp_achieved.extrapolate()?.to_owned(),
)?;
self.eff_interp_at_max_input = Some(Interpolator::Interp1D(eff_interp_at_max_input));
self.eff_interp_at_max_input = Some(eff_interp_at_max_input);
} else {
println!(
"`eff_interp_at_max_input` is being overwritten by {}",
Expand Down Expand Up @@ -445,9 +445,8 @@ impl ElectricMachine {
let old_max_bwd = self.get_eff_max_bwd()?;
let f_x_fwd = self.eff_interp_achieved.f_x()?.to_owned();
match &mut self.eff_interp_achieved {
Interpolator::Interp1D(interp1d) => {
interp1d
.set_f_x(f_x_fwd.iter().map(|x| x * eff_max / old_max_fwd).collect())?;
interp @ Interpolator::Interp1D(..) => {
interp.set_f_x(f_x_fwd.iter().map(|x| x * eff_max / old_max_fwd).collect())?;
}
_ => bail!("{}\n", "Only `Interpolator::Interp1D` is allowed."),
}
Expand All @@ -460,9 +459,9 @@ impl ElectricMachine {
.f_x()?
.to_owned();
match &mut self.eff_interp_at_max_input {
Some(Interpolator::Interp1D(interp1d)) => {
Some(interp @ Interpolator::Interp1D(..)) => {
// let old_interp = interp1d;
interp1d.set_f_x(
interp.set_f_x(
f_x_bwd
.iter()
.map(|x| x * eff_max / old_max_bwd)
Expand Down Expand Up @@ -556,8 +555,8 @@ impl ElectricMachine {
}
let f_x_fwd = self.eff_interp_achieved.f_x()?.to_owned();
match &mut self.eff_interp_achieved {
Interpolator::Interp1D(interp1d) => {
interp1d.set_f_x(
interp @ Interpolator::Interp1D(..) => {
interp.set_f_x(
f_x_fwd
.iter()
.map(|x| eff_max_fwd + (x - eff_max_fwd) * eff_range / old_range)
Expand All @@ -570,8 +569,8 @@ impl ElectricMachine {
let x_neg = self.get_eff_min_fwd()?;
let f_x_fwd = self.eff_interp_achieved.f_x()?.to_owned();
match &mut self.eff_interp_achieved {
Interpolator::Interp1D(interp1d) => {
interp1d.set_f_x(f_x_fwd.iter().map(|x| x - x_neg).collect())?;
interp @ Interpolator::Interp1D(..) => {
interp.set_f_x(f_x_fwd.iter().map(|x| x - x_neg).collect())?;
}
_ => bail!("{}\n", "Only `Interpolator::Interp1D` is allowed."),
}
Expand Down
6 changes: 3 additions & 3 deletions fastsim-core/src/vehicle/powertrain/fuel_converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,8 @@ pub struct FuelConverterThermal {
}

/// Dummy interpolator that will be overridden in [FuelConverterThermal::init]
fn tstat_interp_default() -> Interp1D {
Interp1D::new(
fn tstat_interp_default() -> Interpolator {
Interpolator::new_1d(
vec![85.0, 90.0],
vec![0.0, 1.0],
Strategy::Linear,
Expand Down Expand Up @@ -690,7 +690,7 @@ impl Init for FuelConverterThermal {
.tstat_te_sto
.or(Some(85. * uc::KELVIN + *uc::CELSIUS_TO_KELVIN));
self.tstat_te_delta = self.tstat_te_delta.or(Some(5. * uc::KELVIN));
self.tstat_interp = Interp1D::new(
self.tstat_interp = Interpolator::new_1d(
vec![
self.tstat_te_sto.unwrap().get::<si::kelvin>(),
self.tstat_te_sto.unwrap().get::<si::kelvin>()
Expand Down
35 changes: 15 additions & 20 deletions fastsim-core/src/vehicle/powertrain/reversible_energy_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,28 +203,23 @@ impl ReversibleEnergyStorage {
)
);
}
state.eff = match &self.eff_interp {
Interpolator::Interp0D(eff) => *eff * uc::R,
Interpolator::Interp1D(interp1d) => {
interp1d.interpolate(&[state.pwr_out_electrical.get::<si::watt>()])? * uc::R
}
Interpolator::Interp2D(interp2d) => {
interp2d.interpolate(&[
state.pwr_out_electrical.get::<si::watt>(),
state.soc.get::<si::ratio>(),
])? * uc::R
}
Interpolator::Interp3D(interp3d) => {
interp3d.interpolate(&[
state.pwr_out_electrical.get::<si::watt>(),
state.soc.get::<si::ratio>(),
te_res
.with_context(|| format_dbg!("Expected thermal model to be configured"))?
.get::<si::degree_celsius>(),
])? * uc::R
}
let interp_pt: &[f64] = match &self.eff_interp {
Interpolator::Interp0D(..) => &[],
Interpolator::Interp1D(..) => &[state.pwr_out_electrical.get::<si::watt>()],
Interpolator::Interp2D(..) => &[
state.pwr_out_electrical.get::<si::watt>(),
state.soc.get::<si::ratio>(),
],
Interpolator::Interp3D(..) => &[
state.pwr_out_electrical.get::<si::watt>(),
state.soc.get::<si::ratio>(),
te_res
.with_context(|| format_dbg!("Expected thermal model to be configured"))?
.get::<si::degree_celsius>(),
],
_ => bail!("Invalid interpolator. See docs for `ReversibleEnergyStorage::eff_interp`"),
};
state.eff = self.eff_interp.interpolate(interp_pt)? * uc::R;
ensure!(
state.eff >= 0.0 * uc::R && state.eff <= 1.0 * uc::R,
format!(
Expand Down
Loading

0 comments on commit 120999e

Please sign in to comment.