diff --git a/src/core/heating_systems/common.rs b/src/core/heating_systems/common.rs index 5aade00..75885a1 100644 --- a/src/core/heating_systems/common.rs +++ b/src/core/heating_systems/common.rs @@ -95,6 +95,7 @@ impl HeatSourceWet { pub enum SpaceHeatSystem { Instant(InstantElecHeater), WarmAir(HeatPumpServiceSpaceWarmAir), + WetDistribution(Emitters), } impl SpaceHeatSystem { @@ -102,6 +103,9 @@ impl SpaceHeatSystem { match self { SpaceHeatSystem::Instant(instant) => instant.temp_setpnt(&simulation_time_iteration), SpaceHeatSystem::WarmAir(warm_air) => warm_air.temp_setpnt(&simulation_time_iteration), + SpaceHeatSystem::WetDistribution(wet_distribution) => { + wet_distribution.temp_setpnt(&simulation_time_iteration) + } } } @@ -109,6 +113,9 @@ impl SpaceHeatSystem { match self { SpaceHeatSystem::Instant(instant) => instant.frac_convective(), SpaceHeatSystem::WarmAir(warm_air) => warm_air.frac_convective(), + SpaceHeatSystem::WetDistribution(wet_distribution) => { + wet_distribution.frac_convective() + } } } @@ -125,6 +132,12 @@ impl SpaceHeatSystem { space_heat_running_time_cumulative, simulation_time_iteration, ), + SpaceHeatSystem::WetDistribution(wet_distribution) => wet_distribution + .running_time_throughput_factor( + energy_demand, + space_heat_running_time_cumulative, + simulation_time_iteration, + ), } } @@ -140,6 +153,9 @@ impl SpaceHeatSystem { SpaceHeatSystem::WarmAir(ref mut warm_air) => { warm_air.demand_energy(energy_demand, simulation_time_iteration)? } + SpaceHeatSystem::WetDistribution(ref mut wet_distribution) => { + wet_distribution.demand_energy(energy_demand, simulation_time_iteration)? + } }) } @@ -154,6 +170,9 @@ impl SpaceHeatSystem { SpaceHeatSystem::WarmAir(warm_air) => { warm_air.in_required_period(&simulation_time_iteration) } + SpaceHeatSystem::WetDistribution(emitters) => { + emitters.in_required_period(&simulation_time_iteration) + } } } } @@ -272,4 +291,5 @@ impl SpaceHeatingService { use anyhow::Error; +use super::emitters::Emitters; use super::heat_pump::{BufferTankEmittersData, BufferTankEmittersDataWithResult}; diff --git a/src/core/heating_systems/emitters.rs b/src/core/heating_systems/emitters.rs index b80c2f4..6691be6 100644 --- a/src/core/heating_systems/emitters.rs +++ b/src/core/heating_systems/emitters.rs @@ -30,11 +30,12 @@ pub fn convert_flow_to_return_temp(flow_temp_celsius: f64) -> f64 { (6.0 / 7.0) * flow_temp_celsius } +#[derive(Clone)] pub struct Emitters { pub thermal_mass: f64, pub c: f64, pub n: f64, - temp_diff_emit_dsgn: f64, + _temp_diff_emit_dsgn: f64, frac_convective: f64, heat_source: Arc>, temp_internal_air_fn: TempInternalAirFn, @@ -46,7 +47,6 @@ pub struct Emitters { max_outdoor_temp: Option, min_flow_temp: Option, max_flow_temp: Option, - simulation_timestep: f64, temp_emitter_prev: f64, target_flow_temp: Option, // In Python this is set from inside demand energy and does not exist before then } @@ -134,7 +134,6 @@ impl Emitters { external_conditions: Arc, ecodesign_controller: EcoDesignController, design_flow_temp: f64, - simulation_timestep: f64, with_buffer_tank: bool, ) -> Self { let ecodesign_controller_class = ecodesign_controller.ecodesign_control_class; @@ -158,7 +157,7 @@ impl Emitters { thermal_mass, c, n, - temp_diff_emit_dsgn, + _temp_diff_emit_dsgn: temp_diff_emit_dsgn, frac_convective, heat_source, temp_internal_air_fn, @@ -170,7 +169,6 @@ impl Emitters { max_outdoor_temp, min_flow_temp, max_flow_temp, - simulation_timestep, temp_emitter_prev: 20.0, target_flow_temp: None, } @@ -391,7 +389,7 @@ impl Emitters { let _ = stepper.integrate(); - let mut temp_emitter = 0.; + let temp_emitter; let mut time_temp_diff_max_reached: Option = None; let y_count = stepper.y_out().len(); @@ -571,7 +569,7 @@ impl Emitters { /// Demand energy from emitters and calculate how much energy can be provided /// Arguments: /// energy_demand -- in kWh - fn demand_energy( + pub(crate) fn demand_energy( &mut self, energy_demand: f64, simulation_time: SimulationTimeIteration, @@ -674,7 +672,7 @@ impl Emitters { /// energy_demand -- in kWh /// space_heat_running_time_cumulative /// -- running time spent on higher-priority space heating services - fn running_time_throughput_factor( + pub(crate) fn running_time_throughput_factor( &self, energy_demand: f64, space_heat_running_time_cumulative: f64, @@ -723,15 +721,10 @@ mod tests { use crate::core::controls::time_control::Control; use crate::core::controls::time_control::OnOffTimeControl; - use crate::core::energy_supply; use crate::core::energy_supply::energy_supply::EnergySupply; use crate::core::energy_supply::energy_supply::EnergySupplyConnection; use crate::core::heating_systems::boiler::Boiler; use crate::core::heating_systems::boiler::BoilerServiceSpace; - use crate::core::heating_systems::boiler::BoilerServiceWaterRegular; - use crate::core::heating_systems::common::HeatSourceWet; - use crate::core::space_heat_demand::zone::Zone; - use crate::corpus::HeatSource; use crate::external_conditions::DaylightSavingsConfig; use crate::external_conditions::ShadingSegment; use crate::input::EnergySupplyType; @@ -894,7 +887,6 @@ mod tests { pub(crate) fn emitters( heat_source: SpaceHeatingService, external_conditions: ExternalConditions, - simulation_time: SimulationTime, ) -> Emitters { let thermal_mass = 0.14; let c = 0.08; @@ -924,7 +916,6 @@ mod tests { external_conditions.into(), ecodesign_controller, design_flow_temp, - simulation_time.step, with_buffer_tank, ) } @@ -1009,7 +1000,6 @@ mod tests { external_conditions.clone().into(), ecodesign_controller, 55., - 1., false, ); @@ -1038,7 +1028,6 @@ mod tests { external_conditions.into(), ecodesign_controller, 55., - 1., false, ); @@ -1059,7 +1048,6 @@ mod tests { /// Test emitter output at given emitter and room temp #[rstest] fn test_power_output_emitter( - simulation_time_iterator: SimulationTimeIterator, heat_source: SpaceHeatingService, external_conditions: ExternalConditions, ) { @@ -1083,7 +1071,6 @@ mod tests { external_conditions.into(), ecodesign_controller, 55.0, - 1., false, ); diff --git a/src/corpus.rs b/src/corpus.rs index 05fff19..0fb8c70 100644 --- a/src/corpus.rs +++ b/src/corpus.rs @@ -12,6 +12,7 @@ use crate::core::energy_supply::energy_supply::{ use crate::core::energy_supply::pv::PhotovoltaicSystem; use crate::core::heating_systems::boiler::{Boiler, BoilerServiceWaterCombi}; use crate::core::heating_systems::common::{HeatSourceWet, SpaceHeatSystem, SpaceHeatingService}; +use crate::core::heating_systems::emitters::Emitters; use crate::core::heating_systems::heat_battery::HeatBattery; use crate::core::heating_systems::heat_network::{HeatNetwork, HeatNetworkServiceWaterDirect}; use crate::core::heating_systems::heat_pump::{ @@ -348,6 +349,11 @@ impl Corpus { &heat_system_name_for_zone, &zones, &heat_sources_wet_with_buffer_tank, + TempInternalAirAccessor { + zones: zones.clone(), + total_volume, + }, + external_conditions.clone(), )?) }) .transpose()? @@ -4210,6 +4216,8 @@ fn space_heat_systems_from_input( heat_system_name_for_zone: &IndexMap, zones: &Arc>, heat_sources_wet_with_buffer_tank: &Vec, + temp_internal_air_accessor: TempInternalAirAccessor, + external_conditions: Arc, ) -> anyhow::Result { let mut energy_conn_names_for_systems: IndexMap = Default::default(); let space_heat_systems = input @@ -4241,7 +4249,7 @@ fn space_heat_systems_from_input( )) }, SpaceHeatSystemDetails::ElectricStorageHeater { .. } => unimplemented!(), // requires implementation of ElecStorageHeater, make sure to add energy supply conn name to energy_conn_names_for_systems collection - SpaceHeatSystemDetails::WetDistribution { heat_source, temp_diff_emit_dsgn, control, .. } => { + SpaceHeatSystemDetails::WetDistribution { heat_source, temp_diff_emit_dsgn, control, thermal_mass, c, n, frac_convective, ecodesign_controller, design_flow_temp, .. } => { let heat_source_name = &heat_source.name; let temp_flow_limit_upper = &heat_source.temp_flow_limit_upper; @@ -4293,7 +4301,9 @@ fn space_heat_systems_from_input( unimplemented!() } }; - todo!("Currently working on Emitters") + let temp_internal_air_fn = temp_internal_air_fn(temp_internal_air_accessor.clone()); + let space_heater = Emitters::new(*thermal_mass, *c, *n, *temp_diff_emit_dsgn, *frac_convective, Arc::new(RwLock::new(heat_source_service)), temp_internal_air_fn, external_conditions.clone(), *ecodesign_controller, *design_flow_temp as f64, with_buffer_tank); + SpaceHeatSystem::WetDistribution(space_heater) } SpaceHeatSystemDetails::WarmAir { frac_convective, diff --git a/src/input.rs b/src/input.rs index 12e63f5..ab3a5c5 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1467,7 +1467,7 @@ pub struct SpaceHeatSystemHeatSource { } // it is unclear whether this struct should be used - see reference to the struct above -#[derive(Debug, Deserialize)] +#[derive(Clone, Copy, Debug, Deserialize)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[allow(dead_code)] @@ -1479,7 +1479,7 @@ pub(crate) struct EcoDesignController { pub(crate) min_flow_temp: Option, } -#[derive(Debug, Deserialize_repr, PartialEq)] +#[derive(Clone, Copy, Debug, Deserialize_repr, PartialEq)] #[repr(u8)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]