diff --git a/src/core/cooling_systems/air_conditioning.rs b/src/core/cooling_systems/air_conditioning.rs index ec5ccee..13bc8cc 100644 --- a/src/core/cooling_systems/air_conditioning.rs +++ b/src/core/cooling_systems/air_conditioning.rs @@ -86,7 +86,7 @@ mod tests { use super::*; use crate::core::controls::time_control::OnOffTimeControl; use crate::core::energy_supply::energy_supply::EnergySupply; - use crate::input::{EnergySupplyType, FuelType}; + use crate::input::FuelType; use crate::simulation_time::SimulationTime; use parking_lot::Mutex; use rstest::*; diff --git a/src/core/ductwork.rs b/src/core/ductwork.rs index abb13b8..1ee5bc7 100644 --- a/src/core/ductwork.rs +++ b/src/core/ductwork.rs @@ -16,12 +16,13 @@ pub struct Ductwork { length_in_in_m: f64, length_out_in_m: f64, mvhr_location: MVHRLocation, - diameter_including_insulation_in_m: f64, internal_surface_resistance: f64, // in K m / W insulation_resistance: f64, // in K m / W external_surface_resistance: f64, // K m / W + #[cfg(test)] + diameter_including_insulation_in_m: f64, } impl Ductwork { @@ -70,10 +71,11 @@ impl Ductwork { length_in_in_m, length_out_in_m, mvhr_location, - diameter_including_insulation_in_m, internal_surface_resistance, insulation_resistance, external_surface_resistance, + #[cfg(test)] + diameter_including_insulation_in_m, } } diff --git a/src/core/energy_supply/energy_supply.rs b/src/core/energy_supply/energy_supply.rs index 1610ae3..6537b6b 100644 --- a/src/core/energy_supply/energy_supply.rs +++ b/src/core/energy_supply/energy_supply.rs @@ -460,6 +460,8 @@ impl EnergySupply { enum BetaFactorFunction { Pv, + // variant currently commented out in upstream + #[allow(dead_code)] Wind, } diff --git a/src/core/energy_supply/pv.rs b/src/core/energy_supply/pv.rs index ced4ccc..cb9c74a 100644 --- a/src/core/energy_supply/pv.rs +++ b/src/core/energy_supply/pv.rs @@ -167,7 +167,7 @@ mod tests { use crate::external_conditions::{ DaylightSavingsConfig, ShadingObject, ShadingObjectType, ShadingSegment, }; - use crate::input::{EnergySupplyType, FuelType}; + use crate::input::FuelType; use crate::simulation_time::SimulationTime; use parking_lot::Mutex; use rstest::*; diff --git a/src/core/heating_systems/boiler.rs b/src/core/heating_systems/boiler.rs index d441466..75fb893 100644 --- a/src/core/heating_systems/boiler.rs +++ b/src/core/heating_systems/boiler.rs @@ -801,6 +801,7 @@ struct ServiceResult { mod tests { use super::*; use crate::core::controls::time_control::SetpointTimeControl; + use crate::core::water_heat_demand::cold_water_source::ColdWaterSource; use crate::external_conditions::{DaylightSavingsConfig, ShadingSegment}; use crate::input::{ColdWaterSourceType, FuelType, HeatSourceControlType, HeatSourceWetType}; use crate::simulation_time::SimulationTime; diff --git a/src/core/heating_systems/heat_battery.rs b/src/core/heating_systems/heat_battery.rs index 15ff6f1..0ac9485 100644 --- a/src/core/heating_systems/heat_battery.rs +++ b/src/core/heating_systems/heat_battery.rs @@ -1,9 +1,7 @@ use crate::compare_floats::min_of_2; use crate::core::controls::time_control::{per_control, Control, ControlBehaviour}; use crate::core::energy_supply::energy_supply::{EnergySupply, EnergySupplyConnection}; -use crate::core::water_heat_demand::cold_water_source::ColdWaterSource; -use crate::external_conditions::ExternalConditions; -use crate::input::{HeatSourceLocation, HeatSourceWetDetails}; +use crate::input::HeatSourceWetDetails; use crate::simulation_time::{SimulationTimeIteration, SimulationTimeIterator}; use anyhow::bail; use interp::interp; @@ -13,7 +11,7 @@ use std::sync::Arc; /// This module provides object(s) to model the behaviour of heat batteries. -enum ServiceType { +pub enum ServiceType { WaterRegular, Space, } @@ -28,7 +26,6 @@ pub struct HeatBatteryServiceWaterRegular { service_name: String, control: Option>, temp_hot_water: f64, - cold_feed: Arc, temp_return: f64, } @@ -37,7 +34,6 @@ impl HeatBatteryServiceWaterRegular { heat_battery: Arc>, service_name: String, temp_hot_water: f64, - cold_feed: Arc, temp_return: f64, control: Option>, ) -> Self { @@ -46,7 +42,6 @@ impl HeatBatteryServiceWaterRegular { service_name, control, temp_hot_water, - cold_feed, temp_return, } } @@ -150,7 +145,8 @@ impl HeatBatteryServiceSpace { } } -const LABS_TESTS_RATED_OUTPUT: [[f64; 2]; 21] = [ +// TODO - check upstream whether it's an error that these numbers are not used +const _LABS_TESTS_RATED_OUTPUT: [[f64; 2]; 21] = [ [0.0, 0.0], [0.08, 0.00], [0.16, 0.03], @@ -218,7 +214,9 @@ const LABS_TESTS_LOSSES: [[f64; 2]; 20] = [ const HEAT_BATTERY_TIME_UNIT: u32 = 3_600; +// nothing seems to read this - check upstream whether service_results field is necessary #[derive(Clone, Debug)] +#[allow(dead_code)] struct HeatBatteryResult { service_name: String, time_running: f64, @@ -228,11 +226,9 @@ struct HeatBatteryResult { #[derive(Clone, Debug)] pub struct HeatBattery { simulation_time: Arc, - external_conditions: Arc, energy_supply: Arc>, energy_supply_connection: EnergySupplyConnection, energy_supply_connections: HashMap, - heat_battery_location: HeatSourceLocation, pwr_in: f64, heat_storage_capacity: f64, max_rated_heat_output: f64, @@ -241,6 +237,7 @@ pub struct HeatBattery { power_standby: f64, n_units: usize, charge_control: Arc, // ToUChargeControl variant expected + // nothing external seems to read this - check upstream whether service_results field is necessary service_results: Vec, total_time_running_current_timestamp: f64, flag_first_call: bool, @@ -257,10 +254,8 @@ impl HeatBattery { energy_supply: Arc>, energy_supply_connection: EnergySupplyConnection, simulation_time: Arc, - external_conditions: Arc, ) -> Self { let ( - heat_battery_location, pwr_in, heat_storage_capacity, max_rated_heat_output, @@ -268,8 +263,8 @@ impl HeatBattery { power_circ_pump, power_standby, n_units, + .., ) = if let HeatSourceWetDetails::HeatBattery { - heat_battery_location, rated_charge_power: pwr_in, heat_storage_capacity, max_rated_heat_output, @@ -281,7 +276,6 @@ impl HeatBattery { } = heat_battery_details { ( - *heat_battery_location, *pwr_in, *heat_storage_capacity, *max_rated_heat_output, @@ -296,11 +290,9 @@ impl HeatBattery { Self { simulation_time, - external_conditions, energy_supply, energy_supply_connection, energy_supply_connections: Default::default(), - heat_battery_location, pwr_in, heat_storage_capacity, max_rated_heat_output, @@ -354,7 +346,6 @@ impl HeatBattery { heat_battery: Arc>, service_name: &str, temp_hot_water: f64, - cold_feed: Arc, temp_return: f64, control: Option>, ) -> HeatBatteryServiceWaterRegular { @@ -363,7 +354,6 @@ impl HeatBattery { heat_battery, service_name.to_string(), temp_hot_water, - cold_feed, temp_return, control, ) @@ -385,7 +375,7 @@ impl HeatBattery { /// * `timestep` - length of the timestep /// /// returns -- Energy in kWH - fn convert_to_energy(&self, power: f64, timestep: f64) -> f64 { + fn _convert_to_energy(&self, power: f64, timestep: f64) -> f64 { power * timestep * self.n_units as f64 } diff --git a/src/core/heating_systems/heat_network.rs b/src/core/heating_systems/heat_network.rs index 2580905..46ef39f 100644 --- a/src/core/heating_systems/heat_network.rs +++ b/src/core/heating_systems/heat_network.rs @@ -373,7 +373,7 @@ mod tests { use super::*; use crate::core::controls::time_control::SetpointTimeControl; use crate::core::water_heat_demand::cold_water_source::ColdWaterSource; - use crate::input::{EnergySupplyType, FuelType}; + use crate::input::FuelType; use crate::simulation_time::SimulationTime; use rstest::*; @@ -411,7 +411,7 @@ mod tests { #[rstest] pub fn should_calc_heat_network_energy_output_provider( - mut heat_network: (Arc>, Arc>), + heat_network: (Arc>, Arc>), two_len_simulation_time: SimulationTime, ) { let (heat_network, energy_supply) = heat_network; @@ -523,7 +523,7 @@ mod tests { #[rstest] pub fn should_calc_demand_hot_water_for_water_direct( mut heat_network_water_direct: HeatNetworkServiceWaterDirect, - mut heat_network_for_water_direct: Arc>, + heat_network_for_water_direct: Arc>, two_len_simulation_time: SimulationTime, ) { let volume_demanded = [50.0, 100.0]; diff --git a/src/core/heating_systems/heat_pump.rs b/src/core/heating_systems/heat_pump.rs index 764bd41..e7cc84a 100644 --- a/src/core/heating_systems/heat_pump.rs +++ b/src/core/heating_systems/heat_pump.rs @@ -2862,7 +2862,7 @@ pub enum ServiceResult { } #[derive(Debug)] -struct HeatPumpEnergyCalculation { +pub struct HeatPumpEnergyCalculation { service_name: ResultString, service_type: ServiceType, service_on: bool, @@ -2975,7 +2975,7 @@ impl Div for ResultParamValue { } #[derive(Debug)] -struct AuxiliaryParameters { +pub struct AuxiliaryParameters { _energy_standby: f64, _energy_crankcase_heater_mode: f64, _energy_off_mode: f64, diff --git a/src/core/heating_systems/instant_elec_heater.rs b/src/core/heating_systems/instant_elec_heater.rs index 8ad75a3..2f33636 100644 --- a/src/core/heating_systems/instant_elec_heater.rs +++ b/src/core/heating_systems/instant_elec_heater.rs @@ -85,7 +85,7 @@ mod tests { use super::*; use crate::core::controls::time_control::OnOffTimeControl; use crate::core::energy_supply::energy_supply::EnergySupply; - use crate::input::{EnergySupplyType, FuelType}; + use crate::input::FuelType; use crate::simulation_time::SimulationTime; use parking_lot::Mutex; use rstest::*; diff --git a/src/core/heating_systems/storage_tank.rs b/src/core/heating_systems/storage_tank.rs index 7518726..c4dd8a1 100644 --- a/src/core/heating_systems/storage_tank.rs +++ b/src/core/heating_systems/storage_tank.rs @@ -30,7 +30,7 @@ const STORAGE_TANK_F_RVD_AUX: f64 = 0.25; // part of the thermal losses transmitted to the room const STORAGE_TANK_F_STO_M: f64 = 0.75; -// ambient temperature - degress (sic - from Python code) +// ambient temperature - degrees const STORAGE_TANK_TEMP_AMB: f64 = 16.; #[derive(Clone, Debug)] @@ -54,7 +54,6 @@ pub struct StorageTank { temp_set_on: f64, // set point temperature cold_feed: WaterSourceWithTemperature, simulation_timestep: f64, - contents: MaterialProperties, energy_supply_connection_unmet_demand: Option, control_hold_at_setpoint: Option>, volume_total_in_litres: f64, @@ -138,7 +137,6 @@ impl StorageTank { temp_set_on, cold_feed, simulation_timestep, - contents, energy_supply_connection_unmet_demand, control_hold_at_setpoint, volume_total_in_litres, @@ -668,19 +666,17 @@ impl StorageTank { // TODO 6.4.3.11 Heat exchanger // demand adjusted energy from heat source (before was just using potential without taking it) - let mut input_energy_adj = q_in_h_w; + let input_energy_adj = q_in_h_w; #[cfg(test)] { self.energy_demand_test = input_energy_adj; } - // energy demand saved for unittest (not implemented in Rust until needed) - // self.__energy_demand_test = deepcopy(input_energy_adj) - - let heat_source_output = + let _heat_source_output = self.heat_source_output(heat_source, input_energy_adj, simulation_time_iteration); - input_energy_adj -= heat_source_output; + // variable is updated in upstream but then never read + // input_energy_adj -= _heat_source_output; ( temp_s8_n, q_x_in_n, q_s6, temp_s6_n, temp_s7_n, q_in_h_w, q_ls, q_ls_n, @@ -1038,9 +1034,8 @@ impl PVDiverter { supply_surplus: f64, simulation_time_iteration: SimulationTimeIteration, ) -> f64 { - let mut imm_heater_max_capacity_spare: f64 = Default::default(); // check how much spare capacity the immersion heater has - imm_heater_max_capacity_spare = self + let imm_heater_max_capacity_spare = self .immersion_heater .lock() .energy_output_max(simulation_time_iteration, true) @@ -1288,7 +1283,7 @@ mod tests { use crate::external_conditions::{ DaylightSavingsConfig, ShadingObject, ShadingObjectType, ShadingSegment, }; - use crate::input::{EnergySupplyType, FuelType}; + use crate::input::FuelType; use crate::simulation_time::SimulationTime; use rstest::*; @@ -1630,11 +1625,6 @@ mod tests { let cold_feed = WaterSourceWithTemperature::ColdWaterSource(Arc::new( ColdWaterSource::new(cold_water_temps.to_vec(), &simulation_time, 1.), )); - let control = OnOffTimeControl::new( - vec![true, false, false, false, true, true, true, true], - 0, - 1., - ); let energy_supply = Arc::new(Mutex::new(EnergySupply::new( FuelType::Electricity, simulation_time.total_steps(), diff --git a/src/core/space_heat_demand/internal_gains.rs b/src/core/space_heat_demand/internal_gains.rs index c99b252..5833bee 100644 --- a/src/core/space_heat_demand/internal_gains.rs +++ b/src/core/space_heat_demand/internal_gains.rs @@ -107,7 +107,7 @@ impl ApplianceGains { mod tests { use super::*; use crate::core::energy_supply::energy_supply::EnergySupply; - use crate::input::{EnergySupplyType, FuelType}; + use crate::input::FuelType; use crate::simulation_time::{SimulationTime, SimulationTimeIterator}; use parking_lot::Mutex; use rstest::*; diff --git a/src/core/space_heat_demand/ventilation_element.rs b/src/core/space_heat_demand/ventilation_element.rs index abd3e02..f59b0b5 100644 --- a/src/core/space_heat_demand/ventilation_element.rs +++ b/src/core/space_heat_demand/ventilation_element.rs @@ -1,4 +1,4 @@ -use crate::core::controls::time_control::SetpointTimeControl; +use crate::core::controls::time_control::{ControlBehaviour, SetpointTimeControl}; use crate::core::energy_supply::energy_supply::EnergySupplyConnection; use crate::core::space_heat_demand::building_element::{ area_for_building_element_input, cloned_element_from_named, element_from_named, mid_height_for, @@ -148,7 +148,6 @@ impl VentilationElement { #[derive(Clone)] pub struct VentilationElementInfiltration { - volume: f64, infiltration_rate_from_openings: f64, q50_divisor: f64, shelter_factor: f64, @@ -229,7 +228,6 @@ impl VentilationElementInfiltration { ); VentilationElementInfiltration { - volume, infiltration_rate_from_openings, q50_divisor, shelter_factor, @@ -693,8 +691,8 @@ const DC_P: f64 = 0.2 - (-0.25); // Difference in wind pressure coeff from CIBSE pub struct WindowOpeningForCooling { window_area_equivalent: f64, external_conditions: Arc, - openings: Option>, // actually only meaningfully contains BuildingElement::Transparent + openings: Option>, control: Option, natural_ventilation: Option, a_b: Option, @@ -932,6 +930,12 @@ impl WindowOpeningForCooling { } } + pub fn temp_setpnt(&self, simtime: SimulationTimeIteration) -> Option { + self.control + .as_ref() + .and_then(|control| control.setpnt(&simtime)) + } + pub fn h_ve_max( &self, zone_volume: f64, @@ -1028,7 +1032,7 @@ mod test { use super::*; use crate::core::energy_supply::energy_supply::EnergySupply; use crate::external_conditions::{DaylightSavingsConfig, ExternalConditions}; - use crate::input::{EnergySupplyType, FuelType}; + use crate::input::FuelType; use crate::simulation_time::{SimulationTime, SimulationTimeIterator}; use parking_lot::Mutex; use rstest::*; @@ -1361,10 +1365,7 @@ mod test { #[rstest] pub fn should_have_correct_fan_gains_for_whole_house( - mut whole_house_extract_ventilation: ( - WholeHouseExtractVentilation, - Arc>, - ), + whole_house_extract_ventilation: (WholeHouseExtractVentilation, Arc>), simulation_time_iterator: SimulationTimeIterator, ) { let (mut whole_house_extract_ventilation, energy_supply) = whole_house_extract_ventilation; diff --git a/src/core/space_heat_demand/zone.rs b/src/core/space_heat_demand/zone.rs index 1c75ad0..abc8320 100644 --- a/src/core/space_heat_demand/zone.rs +++ b/src/core/space_heat_demand/zone.rs @@ -36,7 +36,6 @@ pub struct Zone { useful_area: f64, volume: f64, building_elements: Vec, - thermal_bridging: ThermalBridging, vent_elements: Vec, vent_cool_extra: Option, tb_heat_trans_coeff: f64, @@ -156,7 +155,6 @@ impl Zone { useful_area: area, volume, building_elements: named_building_elements, - thermal_bridging, vent_elements, vent_cool_extra, tb_heat_trans_coeff, @@ -301,7 +299,7 @@ impl Zone { throughput_factor: Option, simulation_time_iteration: SimulationTimeIteration, external_conditions: &ExternalConditions, - ) -> Option<()> { + ) -> Option { let (temp_prev, heat_balance_map) = calc_temperatures( delta_t, &self.temp_prev.lock(), @@ -832,7 +830,7 @@ fn calc_temperatures( vent_elements: &[VentilationElement], vent_cool_extra: &Option, print_heat_balance: Option, -) -> (Vec, Option<()>) { +) -> (Vec, Option) { let print_heat_balance = print_heat_balance.unwrap_or(false); let throughput_factor = throughput_factor.unwrap_or(1.0); @@ -1318,46 +1316,46 @@ impl Hash for NamedBuildingElement { } } -struct HeatBalanceAirNode { - solar_gains: f64, - internal_gains: f64, - heating_or_cooling_system_gains: f64, - energy_to_change_internal_temperature: f64, - heat_loss_through_thermal_bridges: f64, - heat_loss_through_infiltration: f64, - heat_loss_through_ventilation: f64, - fabric_heat_loss: f64, +pub struct HeatBalanceAirNode { + pub solar_gains: f64, + pub internal_gains: f64, + pub heating_or_cooling_system_gains: f64, + pub energy_to_change_internal_temperature: f64, + pub heat_loss_through_thermal_bridges: f64, + pub heat_loss_through_infiltration: f64, + pub heat_loss_through_ventilation: f64, + pub fabric_heat_loss: f64, } -struct HeatBalanceInternalBoundary { - fabric_int_air_convective: f64, - fabric_int_sol: f64, - fabric_int_int_gains: f64, - fabric_int_heat_cool: f64, +pub struct HeatBalanceInternalBoundary { + pub fabric_int_air_convective: f64, + pub fabric_int_sol: f64, + pub fabric_int_int_gains: f64, + pub fabric_int_heat_cool: f64, } -struct HeatBalanceExternalBoundary { - solar_gains: f64, - internal_gains: f64, - heating_or_cooling_system_gains: f64, - thermal_bridges: f64, - ventilation: f64, - infiltration: f64, - fabric_ext_air_convective: f64, - fabric_ext_air_radiative: f64, - fabric_ext_sol: f64, - fabric_ext_sky: f64, - opaque_fabric_ext: f64, - transparent_fabric_ext: f64, - ground_fabric_ext: f64, - ztc_fabric_ext: f64, - ztu_fabric_ext: f64, +pub struct HeatBalanceExternalBoundary { + pub solar_gains: f64, + pub internal_gains: f64, + pub heating_or_cooling_system_gains: f64, + pub thermal_bridges: f64, + pub ventilation: f64, + pub infiltration: f64, + pub fabric_ext_air_convective: f64, + pub fabric_ext_air_radiative: f64, + pub fabric_ext_sol: f64, + pub fabric_ext_sky: f64, + pub opaque_fabric_ext: f64, + pub transparent_fabric_ext: f64, + pub ground_fabric_ext: f64, + pub ztc_fabric_ext: f64, + pub ztu_fabric_ext: f64, } -struct HeatBalance { - air_node: HeatBalanceAirNode, - internal_boundary: HeatBalanceInternalBoundary, - external_boundary: HeatBalanceExternalBoundary, +pub struct HeatBalance { + pub air_node: HeatBalanceAirNode, + pub internal_boundary: HeatBalanceInternalBoundary, + pub external_boundary: HeatBalanceExternalBoundary, } #[cfg(test)] diff --git a/src/core/water_heat_demand/shower.rs b/src/core/water_heat_demand/shower.rs index 8b21ed3..d9faffc 100644 --- a/src/core/water_heat_demand/shower.rs +++ b/src/core/water_heat_demand/shower.rs @@ -165,7 +165,7 @@ impl InstantElectricShower { mod tests { use super::*; use crate::core::energy_supply::energy_supply::EnergySupply; - use crate::input::{EnergySupplyType, FuelType}; + use crate::input::FuelType; use crate::simulation_time::SimulationTime; use parking_lot::Mutex; use rstest::*; @@ -188,6 +188,8 @@ mod tests { } } + #[rstest] + #[ignore = "test brought into suite but needs to pass"] pub fn should_calculate_correct_hot_water_demand_for_instant() { let simulation_time = SimulationTime::new(0f64, 3f64, 1f64); let cold_water_temps = [2.0, 3.0, 4.0]; diff --git a/src/corpus.rs b/src/corpus.rs index 3e98600..66a7895 100644 --- a/src/corpus.rs +++ b/src/corpus.rs @@ -35,7 +35,7 @@ use crate::core::space_heat_demand::ventilation_element::{ VentilationElement, VentilationElementInfiltration, WholeHouseExtractVentilation, WindowOpeningForCooling, }; -use crate::core::space_heat_demand::zone::{NamedBuildingElement, Zone}; +use crate::core::space_heat_demand::zone::{HeatBalance, NamedBuildingElement, Zone}; use crate::core::units::{ kelvin_to_celsius, LITRES_PER_CUBIC_METRE, MILLIMETRES_IN_METRE, SECONDS_PER_HOUR, WATTS_PER_KILOWATT, @@ -106,11 +106,16 @@ pub struct Corpus { impl Corpus { pub fn from_inputs( input: Input, - external_conditions: ExternalConditions, + external_conditions: Option, ) -> anyhow::Result { let simulation_time_iterator = Arc::new(input.simulation_time.iter()); - let external_conditions = Arc::new(external_conditions); + let external_conditions = Arc::new(match external_conditions { + Some(external_conditions) => external_conditions, + None => { + external_conditions_from_input(input.external_conditions, &simulation_time_iterator) + } + }); let diverter_types: DiverterTypes = (&input.energy_supply).into(); let mut diverters: Vec>> = Default::default(); @@ -762,7 +767,7 @@ impl Corpus { // update resultant temperatures in zones. let mut internal_air_temp: HashMap<&str, f64> = Default::default(); let mut operative_temp: HashMap<&str, f64> = Default::default(); - let mut heat_balance_map: HashMap<&str, Option<()>> = Default::default(); // using unit type here as placeholder + let mut heat_balance_map: HashMap<&str, Option> = Default::default(); // using unit type here as placeholder for (z_name, zone) in &self.zones { // Look up names of relevant heating and cooling systems for this zone let h_name = self.heat_system_name_for_zone[z_name.as_str()].as_ref(); @@ -1393,13 +1398,7 @@ impl Corpus { gains_solar_zone: &HashMap<&str, f64>, throughput_factor: Option, simulation_time_iteration: SimulationTimeIteration, - ) -> ( - HashMap, - HashMap, - HashMap, - HashMap, - HashMap, - ) { + ) -> (NumberMap, NumberMap, NumberMap, NumberMap, NumberMap) { let mut space_heat_demand_system: HashMap = Default::default(); for heat_system_name in self.space_heat_systems.keys() { space_heat_demand_system.insert((*heat_system_name).clone(), 0.0); @@ -1508,6 +1507,8 @@ pub enum NumberOrDivisionByZero { DivisionByZero, } +type NumberMap = HashMap; + fn has_unique_some_values(map: &HashMap>) -> bool { let some_values: Vec<&V> = map.values().flat_map(|v| v.iter()).collect(); let value_set: HashSet<&&V> = some_values.iter().collect(); @@ -2003,7 +2004,7 @@ type SpaceHeatingCalculation<'a> = ( HashMap<&'a str, f64>, HashMap<&'a str, f64>, f64, - HashMap<&'a str, Option<()>>, + HashMap<&'a str, Option>, ); fn get_cold_water_source_ref_for_type( @@ -2143,8 +2144,6 @@ fn ventilation_from_input<'a>( *sfp, *efficiency, energy_supply_conn, - // energy_supply_from_type_for_ventilation(energy_supply, energy_supplies), - // "Ventilation system".to_string(), simulation_time.step_in_hours(), )) } @@ -2155,21 +2154,6 @@ fn ventilation_from_input<'a>( }) } -fn energy_supply_from_type_for_ventilation( - energy_supply_type: &EnergySupplyType, - energy_supplies: EnergySupplies, -) -> Arc> { - match energy_supply_type { - EnergySupplyType::Electricity => energy_supplies.mains_electricity.unwrap().clone(), - EnergySupplyType::MainsGas => energy_supplies.mains_gas.unwrap().clone(), - EnergySupplyType::UnmetDemand => energy_supplies.unmet_demand.clone(), - EnergySupplyType::LpgBulk => energy_supplies.bulk_lpg.unwrap().clone(), - // commenting out for now as this is a different type and might not be used in this context - // EnergySupplyType::HeatNetwork => energy_supplies.heat_network.unwrap(), - _ => panic!("Unexpected energy supply type listed for ventilation."), - } -} - fn opening_area_total_from_zones(zones: &ZoneDictionary) -> f64 { zones .iter() @@ -2619,7 +2603,6 @@ fn heat_source_wet_from_input( energy_supply, energy_supply_conn, simulation_time, - external_conditions.clone(), )); Ok(heat_source) } @@ -2772,7 +2755,6 @@ fn heat_source_from_input( Arc::new(Mutex::new(battery)), &energy_supply_conn_name, temp_setpoint, - Arc::new(cold_water_source), 55., source_control, ), @@ -2813,7 +2795,7 @@ fn heat_source_from_input( } } -enum HotWaterSource { +pub enum HotWaterSource { StorageTank(Arc>), CombiBoiler(BoilerServiceWaterCombi), PointOfUse(PointOfUse), @@ -3097,10 +3079,7 @@ fn space_heat_systems_from_input( heat_sources_wet: &HashMap>, heat_system_names_requiring_overvent: &mut Vec, heat_system_names_for_zone: Vec<&str>, -) -> anyhow::Result<( - HashMap>>, - HashMap, -)> { +) -> anyhow::Result { let mut energy_conn_names_for_systems: HashMap = Default::default(); let space_heat_systems = input .iter() @@ -3161,6 +3140,11 @@ fn space_heat_systems_from_input( Ok((space_heat_systems, energy_conn_names_for_systems)) } +type SpaceHeatSystemsWithEnergyConnections = ( + HashMap>>, + HashMap, +); + fn space_cool_systems_from_input( input: &SpaceCoolSystemInput, cool_system_names_for_zone: Vec<&str>, @@ -3222,7 +3206,7 @@ fn on_site_generation_from_input( .iter() .map(|(name, generation_details)| { Ok(((*name).clone(), { - let OnSiteGenerationDetails { + let OnSiteGenerationDetails::PhotovoltaicSystem { peak_power, ventilation_strategy, pitch, diff --git a/src/external_conditions.rs b/src/external_conditions.rs index 06e5af5..ba0861e 100644 --- a/src/external_conditions.rs +++ b/src/external_conditions.rs @@ -1981,7 +1981,7 @@ mod test { 6.75, 7.75, 8.75, 9.75, 10.75, 11.75, 12.75, 12.75, 11.75, 10.75, 9.75, 8.75, ]; let external_conditions = external_conditions.clone(); - for (i, simtime_step) in simulation_time_iterator.enumerate() { + for simtime_step in simulation_time_iterator { let month_idx = simtime_step.current_month().unwrap() as usize; assert_eq!( external_conditions.air_temp_monthly(simtime_step.current_month_start_end_hours()), @@ -1996,7 +1996,7 @@ mod test { wind_speeds: Vec, simulation_time_iterator: SimulationTimeIterator, ) { - let mut external_conditions = external_conditions.clone(); + let external_conditions = external_conditions.clone(); for (i, simtime_step) in simulation_time_iterator.enumerate() { assert_eq!( external_conditions.wind_speed(&simtime_step), diff --git a/src/input.rs b/src/input.rs index a00f9a1..8b10f29 100644 --- a/src/input.rs +++ b/src/input.rs @@ -40,14 +40,22 @@ pub struct Input { pub ventilation: Option, pub infiltration: Infiltration, pub zone: ZoneDictionary, + // following fields marked as possibly dead code are likely to be used by wrappers, but worth checking when compiling input schema + #[allow(dead_code)] #[serde(rename = "PartGcompliance")] part_g_compliance: Option, + #[allow(dead_code)] #[serde(rename = "PartO_active_cooling_required")] part_o_active_cooling_required: Option, + #[allow(dead_code)] ground_floor_area: Option, + #[allow(dead_code)] number_of_bedrooms: Option, + #[allow(dead_code)] number_of_wet_rooms: Option, + #[allow(dead_code)] heating_control_type: Option, + #[allow(dead_code)] #[serde(rename = "WaterHeatSchedDefault")] default_water_heating_schedule: Option, pub heat_source_wet: Option, @@ -63,7 +71,9 @@ pub struct Input { pub struct ExternalConditionsInput { pub air_temperatures: Option>, pub wind_speeds: Option>, - ground_temperatures: Option>, + // check upstream whether anything uses this + #[serde(rename = "ground_temperatures")] + _ground_temperatures: Option>, pub diffuse_horizontal_radiation: Option>, pub direct_beam_radiation: Option>, pub solar_reflectivity_of_ground: Option>, @@ -109,8 +119,9 @@ pub type ApplianceGains = HashMap; #[derive(Debug, Deserialize)] #[serde(deny_unknown_fields)] pub struct ApplianceGainsDetails { + // check upstream whether type is used here #[serde(rename(deserialize = "type"))] - gain_type: Option, + _gain_type: Option, pub start_day: u32, pub time_series_step: f64, pub gains_fraction: f64, @@ -821,7 +832,7 @@ pub enum SpaceHeatSystemDetails { heat_source: SpaceHeatSystemHeatSource, #[serde(alias = "Control")] control: Option, - // don't know possible values + // check upstream if this is used ecodesign_controller: EcoDesignController, design_flow_temp: i32, #[serde(alias = "Zone")] @@ -844,7 +855,9 @@ pub struct SpaceHeatSystemHeatSource { pub temp_flow_limit_upper: Option, } +// it is unclear whether this struct should be used - see reference to the struct above #[derive(Debug, Deserialize)] +#[allow(dead_code)] #[serde(deny_unknown_fields)] pub struct EcoDesignController { ecodesign_control_class: u32, @@ -972,15 +985,19 @@ pub struct ZoneInput { pub control_window_opening: Option, pub area: f64, pub volume: f64, + // check upstream whether this is used #[serde(rename = "Lighting")] - pub lighting: Option, - pub temp_setpnt_heat: Option, - pub temp_setpnt_cool: Option, + pub _lighting: Option, + // check upstream whether these two are used + #[serde(rename = "temp_setpnt_heat")] + _temp_setpnt_heat: Option, + #[serde(rename = "temp_setpnt_cool")] + _temp_setpnt_cool: Option, pub temp_setpnt_init: Option, #[serde(rename = "BuildingElement")] pub building_elements: IndexMap, #[serde(rename = "ThermalBridging")] - pub thermal_bridging: ThermalBridging, // this can be either a float or a hashmap of thermal bridging details - see commented out structs below + pub thermal_bridging: ThermalBridging, } #[derive(Debug, Deserialize)] @@ -994,7 +1011,8 @@ pub enum SpaceHeatControlType { #[derive(Debug, Deserialize)] #[serde(deny_unknown_fields)] pub struct ZoneLighting { - efficacy: f64, + #[serde(rename = "efficacy")] + _efficacy: f64, } #[derive(Clone, Debug, Deserialize)] @@ -1129,7 +1147,9 @@ pub type SpaceCoolSystem = HashMap; pub struct SpaceCoolSystemDetails { #[serde(rename(deserialize = "type"))] pub system_type: SpaceCoolSystemType, - temp_setback: Option, + // TODO check upstream whether this is used + #[serde(rename = "temp_setback")] + _temp_setback: Option, pub cooling_capacity: f64, pub efficiency: f64, pub frac_convective: f64, @@ -1305,26 +1325,21 @@ pub enum WwhrsType { pub type OnSiteGeneration = IndexMap; #[derive(Debug, Deserialize)] -#[serde(deny_unknown_fields)] -pub struct OnSiteGenerationDetails { - #[serde(rename = "type")] - generation_type: OnSiteGenerationType, - pub peak_power: f64, - pub ventilation_strategy: OnSiteGenerationVentilationStrategy, - pub pitch: f64, - #[serde(rename = "orientation360")] - #[serde(deserialize_with = "deserialize_orientation")] - pub orientation: f64, - pub base_height: f64, - pub height: f64, - pub width: f64, - #[serde(rename = "EnergySupply")] - pub energy_supply: EnergySupplyType, -} - -#[derive(Debug, Deserialize)] -pub enum OnSiteGenerationType { - PhotovoltaicSystem, +#[serde(tag = "type", deny_unknown_fields)] +pub enum OnSiteGenerationDetails { + PhotovoltaicSystem { + peak_power: f64, + ventilation_strategy: OnSiteGenerationVentilationStrategy, + pitch: f64, + #[serde(rename = "orientation360")] + #[serde(deserialize_with = "deserialize_orientation")] + orientation: f64, + base_height: f64, + height: f64, + width: f64, + #[serde(rename = "EnergySupply")] + energy_supply: EnergySupplyType, + }, } #[derive(Copy, Clone, Debug, Deserialize)] diff --git a/src/lib.rs b/src/lib.rs index 64739dd..edc0af7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,7 +48,7 @@ where input.simulation_time.clone(), ); - let mut corpus: Corpus = Corpus::from_inputs(input, external_conditions)?; + let mut corpus: Corpus = Corpus::from_inputs(input, Some(external_conditions))?; Ok(corpus.run()) }