From 3ce4d1cbe60ce9f10edf2185c8c3dbc76cbfc588 Mon Sep 17 00:00:00 2001 From: Kyle Carow Date: Tue, 4 Feb 2025 15:33:50 -0700 Subject: [PATCH] implement save intervals for most things --- fastsim-core/src/vehicle/bev.rs | 6 +-- fastsim-core/src/vehicle/cabin.rs | 30 +++++++++++- fastsim-core/src/vehicle/conv.rs | 5 +- fastsim-core/src/vehicle/hev.rs | 6 ++- fastsim-core/src/vehicle/hvac.rs | 20 ++++++++ .../vehicle/hvac/hvac_sys_for_lumped_cabin.rs | 13 ++++- .../hvac/hvac_sys_for_lumped_cabin_and_res.rs | 13 ++++- .../vehicle/powertrain/electric_machine.rs | 9 ++++ .../src/vehicle/powertrain/fuel_converter.rs | 47 ++++++++++++++----- .../powertrain/reversible_energy_storage.rs | 35 +++++++++++++- .../src/vehicle/powertrain/transmission.rs | 10 +++- fastsim-core/src/vehicle/vehicle_model.rs | 5 +- 12 files changed, 174 insertions(+), 25 deletions(-) diff --git a/fastsim-core/src/vehicle/bev.rs b/fastsim-core/src/vehicle/bev.rs index 7912db8a..c3b8315d 100644 --- a/fastsim-core/src/vehicle/bev.rs +++ b/fastsim-core/src/vehicle/bev.rs @@ -112,9 +112,9 @@ impl SaveInterval for BatteryElectricVehicle { bail!("`save_interval` is not implemented in BatteryElectricVehicle") } fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { - self.res.save_interval = save_interval; - self.em.save_interval = save_interval; - self.transmission.save_interval = save_interval; + self.res.set_save_interval(save_interval)?; + self.em.set_save_interval(save_interval)?; + self.transmission.set_save_interval(save_interval)?; Ok(()) } } diff --git a/fastsim-core/src/vehicle/cabin.rs b/fastsim-core/src/vehicle/cabin.rs index 6fe0b699..35f9924d 100644 --- a/fastsim-core/src/vehicle/cabin.rs +++ b/fastsim-core/src/vehicle/cabin.rs @@ -48,6 +48,22 @@ impl Init for CabinOption { } } impl SerdeAPI for CabinOption {} +impl SaveInterval for CabinOption { + fn save_interval(&self) -> anyhow::Result> { + match self { + CabinOption::LumpedCabin(lc) => lc.save_interval(), + CabinOption::LumpedCabinWithShell => todo!(), + CabinOption::None => Ok(None), + } + } + fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { + match self { + CabinOption::LumpedCabin(lc) => lc.set_save_interval(save_interval), + CabinOption::LumpedCabinWithShell => todo!(), + CabinOption::None => Ok(()), + } + } +} impl SetCumulative for CabinOption { fn set_cumulative(&mut self, dt: si::Time) { match self { @@ -85,7 +101,8 @@ pub struct LumpedCabin { pub state: LumpedCabinState, #[serde(default, skip_serializing_if = "LumpedCabinStateHistoryVec::is_empty")] pub history: LumpedCabinStateHistoryVec, - // TODO: add `save_interval` and associated method + /// Time step interval at which history is saved + pub save_interval: Option, } impl SetCumulative for LumpedCabin { fn set_cumulative(&mut self, dt: si::Time) { @@ -94,6 +111,15 @@ impl SetCumulative for LumpedCabin { } impl SerdeAPI for LumpedCabin {} impl Init for LumpedCabin {} +impl SaveInterval for LumpedCabin { + fn save_interval(&self) -> anyhow::Result> { + Ok(self.save_interval) + } + fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { + self.save_interval = save_interval; + Ok(()) + } +} impl LumpedCabin { /// Solve temperatures, HVAC powers, and cumulative energies of cabin and HVAC system @@ -177,7 +203,7 @@ impl LumpedCabin { #[serde(default)] pub struct LumpedCabinState { /// time step counter - pub i: u32, + pub i: usize, /// lumped cabin temperature pub temperature: si::Temperature, /// lumped cabin temperature at previous simulation time step diff --git a/fastsim-core/src/vehicle/conv.rs b/fastsim-core/src/vehicle/conv.rs index 5c02184d..3b6b9b1d 100644 --- a/fastsim-core/src/vehicle/conv.rs +++ b/fastsim-core/src/vehicle/conv.rs @@ -32,8 +32,9 @@ impl SaveInterval for ConventionalVehicle { bail!("`save_interval` is not implemented in ConventionalVehicle") } fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { - self.fc.save_interval = save_interval; - self.transmission.save_interval = save_interval; + // self.fs.set_save_interval(save_interval)?; + self.fc.set_save_interval(save_interval)?; + self.transmission.set_save_interval(save_interval)?; Ok(()) } } diff --git a/fastsim-core/src/vehicle/hev.rs b/fastsim-core/src/vehicle/hev.rs index 3cfedf86..80585432 100644 --- a/fastsim-core/src/vehicle/hev.rs +++ b/fastsim-core/src/vehicle/hev.rs @@ -42,8 +42,10 @@ impl SaveInterval for HybridElectricVehicle { bail!("`save_interval` is not implemented in HybridElectricVehicle") } fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { - self.res.save_interval = save_interval; - self.em.save_interval = save_interval; + self.res.set_save_interval(save_interval)?; + // self.fs.set_save_interval(save_interval)?; + self.fc.set_save_interval(save_interval)?; + self.em.set_save_interval(save_interval)?; Ok(()) } } diff --git a/fastsim-core/src/vehicle/hvac.rs b/fastsim-core/src/vehicle/hvac.rs index 1138b42c..776b5540 100644 --- a/fastsim-core/src/vehicle/hvac.rs +++ b/fastsim-core/src/vehicle/hvac.rs @@ -38,6 +38,26 @@ impl Init for HVACOption { } } impl SerdeAPI for HVACOption {} +impl SaveInterval for HVACOption { + fn save_interval(&self) -> anyhow::Result> { + match self { + HVACOption::LumpedCabin(lc) => lc.save_interval(), + HVACOption::LumpedCabinAndRES(lcr) => lcr.save_interval(), + HVACOption::LumpedCabinWithShell => todo!(), + HVACOption::ReversibleEnergyStorageOnly => todo!(), + HVACOption::None => Ok(None), + } + } + fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { + match self { + HVACOption::LumpedCabin(lc) => lc.set_save_interval(save_interval), + HVACOption::LumpedCabinAndRES(lcr) => lcr.set_save_interval(save_interval), + HVACOption::LumpedCabinWithShell => todo!(), + HVACOption::ReversibleEnergyStorageOnly => todo!(), + HVACOption::None => Ok(()), + } + } +} impl SaveState for HVACOption { fn save_state(&mut self) { match self { diff --git a/fastsim-core/src/vehicle/hvac/hvac_sys_for_lumped_cabin.rs b/fastsim-core/src/vehicle/hvac/hvac_sys_for_lumped_cabin.rs index 366bbd31..37cec54c 100644 --- a/fastsim-core/src/vehicle/hvac/hvac_sys_for_lumped_cabin.rs +++ b/fastsim-core/src/vehicle/hvac/hvac_sys_for_lumped_cabin.rs @@ -42,6 +42,7 @@ pub struct HVACSystemForLumpedCabin { skip_serializing_if = "HVACSystemForLumpedCabinStateHistoryVec::is_empty" )] pub history: HVACSystemForLumpedCabinStateHistoryVec, + pub save_interval: Option, } impl Default for HVACSystemForLumpedCabin { fn default() -> Self { @@ -58,6 +59,7 @@ impl Default for HVACSystemForLumpedCabin { pwr_aux_for_hvac_max: uc::KW * 5., state: Default::default(), history: Default::default(), + save_interval: Some(1), } } } @@ -68,6 +70,15 @@ impl SetCumulative for HVACSystemForLumpedCabin { } impl Init for HVACSystemForLumpedCabin {} impl SerdeAPI for HVACSystemForLumpedCabin {} +impl SaveInterval for HVACSystemForLumpedCabin { + fn save_interval(&self) -> anyhow::Result> { + Ok(self.save_interval) + } + fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { + self.save_interval = save_interval; + Ok(()) + } +} impl HVACSystemForLumpedCabin { /// # Arguments /// - `te_amb_air`: ambient air temperature @@ -345,7 +356,7 @@ impl SerdeAPI for CabinHeatSource {} #[serde(default)] pub struct HVACSystemForLumpedCabinState { /// time step counter - pub i: u32, + pub i: usize, /// portion of total HVAC cooling/heating (negative/positive) power due to proportional gain pub pwr_p: si::Power, /// portion of total HVAC cooling/heating (negative/positive) cumulative energy due to proportional gain diff --git a/fastsim-core/src/vehicle/hvac/hvac_sys_for_lumped_cabin_and_res.rs b/fastsim-core/src/vehicle/hvac/hvac_sys_for_lumped_cabin_and_res.rs index b3e843d1..056c0e60 100644 --- a/fastsim-core/src/vehicle/hvac/hvac_sys_for_lumped_cabin_and_res.rs +++ b/fastsim-core/src/vehicle/hvac/hvac_sys_for_lumped_cabin_and_res.rs @@ -58,6 +58,7 @@ pub struct HVACSystemForLumpedCabinAndRES { skip_serializing_if = "HVACSystemForLumpedCabinAndRESStateHistoryVec::is_empty" )] pub history: HVACSystemForLumpedCabinAndRESStateHistoryVec, + pub save_interval: Option, } impl Default for HVACSystemForLumpedCabinAndRES { fn default() -> Self { @@ -80,6 +81,7 @@ impl Default for HVACSystemForLumpedCabinAndRES { pwr_aux_for_hvac_max: uc::KW * 5., state: Default::default(), history: Default::default(), + save_interval: Some(1), } } } @@ -90,6 +92,15 @@ impl SetCumulative for HVACSystemForLumpedCabinAndRES { } impl Init for HVACSystemForLumpedCabinAndRES {} impl SerdeAPI for HVACSystemForLumpedCabinAndRES {} +impl SaveInterval for HVACSystemForLumpedCabinAndRES { + fn save_interval(&self) -> anyhow::Result> { + Ok(self.save_interval) + } + fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { + self.save_interval = save_interval; + Ok(()) + } +} impl HVACSystemForLumpedCabinAndRES { /// # Arguments /// - `te_amb_air`: ambient air temperature @@ -510,7 +521,7 @@ impl HVACSystemForLumpedCabinAndRES { #[serde(default)] pub struct HVACSystemForLumpedCabinAndRESState { /// time step counter - pub i: u32, + pub i: usize, /// portion of total HVAC cooling/heating (negative/positive) power due to proportional gain pub pwr_p_cab: si::Power, /// portion of total HVAC cooling/heating (negative/positive) cumulative energy due to proportional gain diff --git a/fastsim-core/src/vehicle/powertrain/electric_machine.rs b/fastsim-core/src/vehicle/powertrain/electric_machine.rs index 9782aca9..d1cf585c 100755 --- a/fastsim-core/src/vehicle/powertrain/electric_machine.rs +++ b/fastsim-core/src/vehicle/powertrain/electric_machine.rs @@ -334,6 +334,15 @@ impl Init for ElectricMachine { Ok(()) } } +impl SaveInterval for ElectricMachine { + fn save_interval(&self) -> anyhow::Result> { + Ok(self.save_interval) + } + fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { + self.save_interval = save_interval; + Ok(()) + } +} impl SetCumulative for ElectricMachine { fn set_cumulative(&mut self, dt: si::Time) { diff --git a/fastsim-core/src/vehicle/powertrain/fuel_converter.rs b/fastsim-core/src/vehicle/powertrain/fuel_converter.rs index 2f7576fd..f421a43e 100755 --- a/fastsim-core/src/vehicle/powertrain/fuel_converter.rs +++ b/fastsim-core/src/vehicle/powertrain/fuel_converter.rs @@ -122,6 +122,16 @@ impl Init for FuelConverter { Ok(()) } } +impl SaveInterval for FuelConverter { + fn save_interval(&self) -> anyhow::Result> { + Ok(self.save_interval) + } + fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { + self.save_interval = save_interval; + self.thrml.set_save_interval(save_interval)?; + Ok(()) + } +} impl Mass for FuelConverter { fn mass(&self) -> anyhow::Result> { @@ -186,16 +196,6 @@ impl Mass for FuelConverter { } } -impl SaveInterval for FuelConverter { - fn save_interval(&self) -> anyhow::Result> { - Ok(self.save_interval) - } - fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { - self.save_interval = save_interval; - Ok(()) - } -} - // non-py methods impl FuelConverter { /// Sets maximum possible total power [FuelConverter] @@ -544,6 +544,20 @@ impl SetCumulative for FuelConverterThermalOption { } } } +impl SaveInterval for FuelConverterThermalOption { + fn save_interval(&self) -> anyhow::Result> { + match self { + FuelConverterThermalOption::FuelConverterThermal(fct) => fct.save_interval(), + FuelConverterThermalOption::None => Ok(None), + } + } + fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { + match self { + FuelConverterThermalOption::FuelConverterThermal(fct) => fct.set_save_interval(save_interval), + FuelConverterThermalOption::None => Ok(()), + } + } +} impl FuelConverterThermalOption { /// Solve change in temperature and other thermal effects /// # Arguments @@ -633,7 +647,17 @@ pub struct FuelConverterThermal { skip_serializing_if = "FuelConverterThermalStateHistoryVec::is_empty" )] pub history: FuelConverterThermalStateHistoryVec, - // TODO: add `save_interval` and associated methods + pub save_interval: Option, +} + +impl SaveInterval for FuelConverterThermal { + fn save_interval(&self) -> anyhow::Result> { + Ok(self.save_interval) + } + fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { + self.save_interval = save_interval; + Ok(()) + } } /// Dummy interpolator that will be overridden in [FuelConverterThermal::init] @@ -822,6 +846,7 @@ impl Default for FuelConverterThermal { fc_eff_model: Default::default(), state: Default::default(), history: Default::default(), + save_interval: Some(1), }; fct.init().unwrap(); fct diff --git a/fastsim-core/src/vehicle/powertrain/reversible_energy_storage.rs b/fastsim-core/src/vehicle/powertrain/reversible_energy_storage.rs index 4167b31b..b4ee9447 100644 --- a/fastsim-core/src/vehicle/powertrain/reversible_energy_storage.rs +++ b/fastsim-core/src/vehicle/powertrain/reversible_energy_storage.rs @@ -630,6 +630,16 @@ impl Init for ReversibleEnergyStorage { Ok(()) } } +impl SaveInterval for ReversibleEnergyStorage { + fn save_interval(&self) -> anyhow::Result> { + Ok(self.save_interval) + } + fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { + self.save_interval = save_interval; + self.thrml.set_save_interval(save_interval)?; + Ok(()) + } +} #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, IsVariant, From, TryInto)] /// Controls which parameter to update when setting specific energy @@ -769,6 +779,20 @@ impl Init for RESThermalOption { } } impl SerdeAPI for RESThermalOption {} +impl SaveInterval for RESThermalOption { + fn save_interval(&self) -> anyhow::Result> { + match self { + RESThermalOption::RESLumpedThermal(rlt) => rlt.save_interval(), + RESThermalOption::None => Ok(None), + } + } + fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { + match self { + RESThermalOption::RESLumpedThermal(rlt) => rlt.set_save_interval(save_interval), + RESThermalOption::None => Ok(()), + } + } +} impl RESThermalOption { /// Solve change in temperature and other thermal effects /// # Arguments @@ -832,7 +856,7 @@ pub struct RESLumpedThermal { skip_serializing_if = "RESLumpedThermalStateHistoryVec::is_empty" )] pub history: RESLumpedThermalStateHistoryVec, - // TODO: add `save_interval` and associated methods + pub save_interval: Option } impl SetCumulative for RESLumpedThermal { fn set_cumulative(&mut self, dt: si::Time) { @@ -841,6 +865,15 @@ impl SetCumulative for RESLumpedThermal { } impl SerdeAPI for RESLumpedThermal {} impl Init for RESLumpedThermal {} +impl SaveInterval for RESLumpedThermal { + fn save_interval(&self) -> anyhow::Result> { + Ok(self.save_interval) + } + fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { + self.save_interval = save_interval; + Ok(()) + } +} impl RESLumpedThermal { fn solve( &mut self, diff --git a/fastsim-core/src/vehicle/powertrain/transmission.rs b/fastsim-core/src/vehicle/powertrain/transmission.rs index 4863c39c..9a8c70d1 100644 --- a/fastsim-core/src/vehicle/powertrain/transmission.rs +++ b/fastsim-core/src/vehicle/powertrain/transmission.rs @@ -50,7 +50,15 @@ impl Transmission { Ok(state.pwr_in) } } - +impl SaveInterval for Transmission { + fn save_interval(&self) -> anyhow::Result> { + Ok(self.save_interval) + } + fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { + self.save_interval = save_interval; + Ok(()) + } +} impl SerdeAPI for Transmission {} impl Init for Transmission {} diff --git a/fastsim-core/src/vehicle/vehicle_model.rs b/fastsim-core/src/vehicle/vehicle_model.rs index 768ac0de..b505e2b3 100644 --- a/fastsim-core/src/vehicle/vehicle_model.rs +++ b/fastsim-core/src/vehicle/vehicle_model.rs @@ -272,7 +272,10 @@ impl SaveInterval for Vehicle { } fn set_save_interval(&mut self, save_interval: Option) -> anyhow::Result<()> { self.save_interval = save_interval; - self.pt_type.set_save_interval(save_interval) + self.pt_type.set_save_interval(save_interval)?; + self.cabin.set_save_interval(save_interval)?; + self.hvac.set_save_interval(save_interval)?; + Ok(()) } }