diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index ae92306d..863c903c 100644 --- a/hisim/components/heat_distribution_system.py +++ b/hisim/components/heat_distribution_system.py @@ -1,4 +1,5 @@ """Heat Distribution Module.""" + # clean import importlib from enum import IntEnum @@ -7,10 +8,10 @@ from dataclasses_json import dataclass_json import pandas as pd +import numpy as np import hisim.component as cp from hisim.components.building import Building -from hisim.components.simple_hot_water_storage import SimpleHotWaterStorage from hisim.components.weather import Weather from hisim.simulationparameters import SimulationParameters from hisim.components.configuration import PhysicsConfig @@ -29,17 +30,34 @@ class HeatDistributionSystemType(IntEnum): - """Set Heating System Types.""" RADIATOR = 1 FLOORHEATING = 2 +class PositionHotWaterStorageInSystemSetup(IntEnum): + """Set Postion of Hot Water Storage in system setup. + + PARALLEL: + Hot Water Storage is parallel to heatpump and hds, massflow of heatpump and heat distribution system are independent of each other. + Heatpump massflow is calculated in hp model, hds massflow is calculated in hds model. + + SERIE: + Hot Water Storage in series to hp/hds, massflow of hds is an input and connected to hp, hot water storage is between output of hds and input of hp + + NO_STORAGE: + No Hot Water Storage in system setup for space heating + """ + + PARALLEL = 1 + SERIE = 2 + NO_STORAGE = 3 + + @dataclass_json @dataclass class HeatDistributionConfig(cp.ConfigBase): - """Configuration of the HeatingWaterStorage class.""" @classmethod @@ -48,8 +66,9 @@ def get_main_classname(cls): return HeatDistribution.get_full_classname() name: str - temperature_difference_between_flow_and_return_in_celsius: float water_mass_flow_rate_in_kg_per_second: float + absolute_conditioned_floor_area_in_m2: float + position_hot_water_storage_in_system: Union[PositionHotWaterStorageInSystemSetup, int] #: CO2 footprint of investment in kg co2_footprint: float #: cost for investment in Euro @@ -62,14 +81,16 @@ def get_main_classname(cls): @classmethod def get_default_heatdistributionsystem_config( cls, - temperature_difference_between_flow_and_return_in_celsius: float, water_mass_flow_rate_in_kg_per_second: float, + absolute_conditioned_floor_area_in_m2: float, + position_hot_water_storage_in_system: int = 1, ) -> Any: """Get a default heat distribution system config.""" config = HeatDistributionConfig( name="HeatDistributionSystem", - temperature_difference_between_flow_and_return_in_celsius=temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=water_mass_flow_rate_in_kg_per_second, + absolute_conditioned_floor_area_in_m2=absolute_conditioned_floor_area_in_m2, + position_hot_water_storage_in_system=position_hot_water_storage_in_system, co2_footprint=0, # Todo: check value cost=8000, # SOURCE: https://www.hausjournal.net/heizungsrohre-verlegen-kosten # Todo: use price per m2 in system_setups instead lifetime=50, # SOURCE: VDI2067-1 @@ -78,65 +99,24 @@ def get_default_heatdistributionsystem_config( return config -@dataclass_json -@dataclass -class HeatDistributionControllerConfig(cp.ConfigBase): - - """HeatDistribution Controller Config Class.""" - - @classmethod - def get_main_classname(cls): - """Returns the full class name of the base class.""" - return HeatDistributionController.get_full_classname() - - name: str - heating_system: Union[HeatDistributionSystemType, int] - set_heating_threshold_outside_temperature_in_celsius: Optional[float] - heating_reference_temperature_in_celsius: float - set_heating_temperature_for_building_in_celsius: float - set_cooling_temperature_for_building_in_celsius: float - heating_load_of_building_in_watt: float - - @classmethod - def get_default_heat_distribution_controller_config( - cls, - heating_load_of_building_in_watt: float, - set_heating_temperature_for_building_in_celsius: float, - set_cooling_temperature_for_building_in_celsius: float, - heating_reference_temperature_in_celsius: float = -7.0, - heating_system: Union[HeatDistributionSystemType, int] = HeatDistributionSystemType.FLOORHEATING, - ) -> "HeatDistributionControllerConfig": - """Gets a default HeatDistribution Controller.""" - - return HeatDistributionControllerConfig( - name="HeatDistributionController", - heating_system=heating_system, - set_heating_threshold_outside_temperature_in_celsius=16.0, - heating_reference_temperature_in_celsius=heating_reference_temperature_in_celsius, - set_heating_temperature_for_building_in_celsius=set_heating_temperature_for_building_in_celsius, - set_cooling_temperature_for_building_in_celsius=set_cooling_temperature_for_building_in_celsius, - heating_load_of_building_in_watt=heating_load_of_building_in_watt, - ) - - @dataclass class HeatDistributionSystemState: - """HeatDistributionSystemState class.""" - water_output_temperature_in_celsius: float = 25 - thermal_power_delivered_in_watt: float = 0 + water_output_temperature_in_celsius: float = 25.0 + water_input_temperature_in_celsius: float = 25.0 + thermal_power_delivered_in_watt: float = 0.0 def self_copy(self): """Copy the Heat Distribution State.""" return HeatDistributionSystemState( self.water_output_temperature_in_celsius, + self.water_input_temperature_in_celsius, self.thermal_power_delivered_in_watt, ) class HeatDistribution(cp.Component): - """Heat Distribution System. It simulates the heat exchange between heat generator and building. @@ -148,10 +128,14 @@ class HeatDistribution(cp.Component): WaterTemperatureInput = "WaterTemperatureInput" TheoreticalThermalBuildingDemand = "TheoreticalThermalBuildingDemand" ResidenceTemperatureIndoorAir = "ResidenceTemperatureIndoorAir" + WaterMassFlow = "WaterMassFlow" # Outputs + WaterTemperatureInlet = "WaterTemperatureInlet" WaterTemperatureOutput = "WaterTemperatureOutput" + WaterTemperatureDifference = "WaterTemperatureDifference" ThermalPowerDelivered = "ThermalPowerDelivered" + WaterMassFlowHDS = "WaterMassFlowHDS" # Similar components to connect to: # 1. Building @@ -173,18 +157,26 @@ def __init__( self.thermal_power_delivered_in_watt: float = 0.0 self.water_temperature_output_in_celsius: float = 21 - self.temperature_difference_between_flow_and_return_in_celsius = ( - self.heat_distribution_system_config.temperature_difference_between_flow_and_return_in_celsius - ) + self.water_input_temperature_in_celsius: float = 21 self.heating_distribution_system_water_mass_flow_rate_in_kg_per_second = ( self.heat_distribution_system_config.water_mass_flow_rate_in_kg_per_second ) + self.absolute_conditioned_floor_area_in_m2 = ( + self.heat_distribution_system_config.absolute_conditioned_floor_area_in_m2 + ) + + self.position_hot_water_storage_in_system = ( + self.heat_distribution_system_config.position_hot_water_storage_in_system + ) + self.build() self.state: HeatDistributionSystemState = HeatDistributionSystemState( - water_output_temperature_in_celsius=21, thermal_power_delivered_in_watt=0 + water_output_temperature_in_celsius=21.0, + water_input_temperature_in_celsius=21.0, + thermal_power_delivered_in_watt=0, ) self.previous_state = self.state.self_copy() @@ -192,6 +184,7 @@ def __init__( self.state_channel: cp.ComponentInput = self.add_input( self.component_name, self.State, lt.LoadTypes.ANY, lt.Units.ANY, True ) + self.theoretical_thermal_building_demand_channel: cp.ComponentInput = self.add_input( self.component_name, self.TheoreticalThermalBuildingDemand, @@ -216,14 +209,41 @@ def __init__( True, ) + if self.position_hot_water_storage_in_system in [ + PositionHotWaterStorageInSystemSetup.SERIE, + PositionHotWaterStorageInSystemSetup.NO_STORAGE, + ]: + # just important for heating system without parallel bufferstorage + self.water_mass_flow_rate_hp_in_kg_per_second_channel: cp.ComponentInput = self.add_input( + self.component_name, + self.WaterMassFlow, + lt.LoadTypes.WATER, + lt.Units.KG_PER_SEC, + True, + ) + # Outputs - self.water_temperature_output_channel: cp.ComponentOutput = self.add_output( + self.water_temperature_inlet_channel: cp.ComponentOutput = self.add_output( + self.component_name, + self.WaterTemperatureInlet, + lt.LoadTypes.WATER, + lt.Units.CELSIUS, + output_description=f"here a description for {self.WaterTemperatureInlet} will follow.", + ) + self.water_temperature_outlet_channel: cp.ComponentOutput = self.add_output( self.component_name, self.WaterTemperatureOutput, lt.LoadTypes.WATER, lt.Units.CELSIUS, output_description=f"here a description for {self.WaterTemperatureOutput} will follow.", ) + self.water_temperature_difference_channel: cp.ComponentOutput = self.add_output( + self.component_name, + self.WaterTemperatureDifference, + lt.LoadTypes.WATER, + lt.Units.KELVIN, + output_description=f"here a description for {self.WaterTemperatureDifference} will follow.", + ) self.thermal_power_delivered_channel: cp.ComponentOutput = self.add_output( self.component_name, self.ThermalPowerDelivered, @@ -231,10 +251,18 @@ def __init__( lt.Units.WATT, output_description=f"here a description for {self.ThermalPowerDelivered} will follow.", ) + self.water_mass_flow_channel: cp.ComponentOutput = self.add_output( + self.component_name, + self.WaterMassFlowHDS, + lt.LoadTypes.VOLUME, + lt.Units.KG_PER_SEC, + output_description=f"here a description for {self.WaterMassFlowHDS} will follow.", + ) self.add_default_connections(self.get_default_connections_from_heat_distribution_controller()) self.add_default_connections(self.get_default_connections_from_building()) - self.add_default_connections(self.get_default_connections_from_simple_hot_water_storage()) + if self.position_hot_water_storage_in_system == PositionHotWaterStorageInSystemSetup.PARALLEL: + self.add_default_connections(self.get_default_connections_from_simple_hot_water_storage()) def get_default_connections_from_heat_distribution_controller( self, @@ -305,6 +333,7 @@ def build( self.specific_heat_capacity_of_water_in_joule_per_kilogram_per_celsius = ( PhysicsConfig.water_specific_heat_capacity_in_joule_per_kilogram_per_kelvin ) + self.density_of_water = PhysicsConfig.water_density def i_prepare_simulation(self) -> None: """Prepare the simulation.""" @@ -336,46 +365,131 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg theoretical_thermal_building_demand_in_watt = stsv.get_input_value( self.theoretical_thermal_building_demand_channel ) - - water_temperature_input_in_celsius = stsv.get_input_value(self.water_temperature_input_channel) - residence_temperature_input_in_celsius = stsv.get_input_value(self.residence_temperature_input_channel) - # if state_controller == 1: - if state_controller in (1, -1): + if self.position_hot_water_storage_in_system == PositionHotWaterStorageInSystemSetup.PARALLEL: + water_mass_flow_rate_in_kg_per_second = ( + self.heating_distribution_system_water_mass_flow_rate_in_kg_per_second + ) + else: + # important for heating system without buffer storage + water_mass_flow_rate_in_kg_per_second = stsv.get_input_value( + self.water_mass_flow_rate_hp_in_kg_per_second_channel + ) + + if water_mass_flow_rate_in_kg_per_second == 0: + # important for heating system without buffer storage ( - self.water_temperature_output_in_celsius, - self.thermal_power_delivered_in_watt, - ) = self.determine_water_temperature_output_after_heat_exchange_with_building_and_effective_thermal_power( - water_temperature_input_in_celsius=water_temperature_input_in_celsius, - water_mass_flow_in_kg_per_second=self.heating_distribution_system_water_mass_flow_rate_in_kg_per_second, - theoretical_thermal_buiding_demand_in_watt=theoretical_thermal_building_demand_in_watt, + water_temperature_input_in_celsius, + water_temperature_output_in_celsius, + thermal_power_delivered_in_watt, + ) = self.determine_water_temperature_input_output_effective_thermal_power_without_massflow( residence_temperature_in_celsius=residence_temperature_input_in_celsius, ) + else: + water_temperature_input_in_celsius = stsv.get_input_value(self.water_temperature_input_channel) + # if state_controller == 1: + if state_controller in (1, -1): + ( + water_temperature_output_in_celsius, + thermal_power_delivered_in_watt, + ) = self.determine_water_temperature_output_after_heat_exchange_with_building_and_effective_thermal_power( + water_temperature_input_in_celsius=water_temperature_input_in_celsius, + water_mass_flow_in_kg_per_second=water_mass_flow_rate_in_kg_per_second, + theoretical_thermal_buiding_demand_in_watt=theoretical_thermal_building_demand_in_watt, + residence_temperature_in_celsius=residence_temperature_input_in_celsius, + ) - elif state_controller == 0: - self.thermal_power_delivered_in_watt = 0.0 - - self.water_temperature_output_in_celsius = water_temperature_input_in_celsius + elif state_controller == 0: + thermal_power_delivered_in_watt = 0.0 + water_temperature_output_in_celsius = water_temperature_input_in_celsius - else: - raise ValueError("unknown hds controller mode") + else: + raise ValueError("unknown hds controller mode") # Set outputs ----------------------------------------------------------------------------------------------------------- - stsv.set_output_value( - self.water_temperature_output_channel, - self.state.water_output_temperature_in_celsius - # self.water_temperature_output_in_celsius, + self.water_temperature_inlet_channel, + self.state.water_input_temperature_in_celsius, + # water_temperature_input_in_celsius + ) + stsv.set_output_value( + self.water_temperature_outlet_channel, + self.state.water_output_temperature_in_celsius, + # water_temperature_output_in_celsius, + ) + stsv.set_output_value( + self.water_temperature_difference_channel, + # water_temperature_input_in_celsius-water_temperature_output_in_celsius + self.state.water_input_temperature_in_celsius - self.state.water_output_temperature_in_celsius, ) stsv.set_output_value( self.thermal_power_delivered_channel, - self.state.thermal_power_delivered_in_watt - # self.thermal_power_delivered_in_watt, + self.state.thermal_power_delivered_in_watt, + # thermal_power_delivered_in_watt, + ) + stsv.set_output_value( + self.water_mass_flow_channel, + water_mass_flow_rate_in_kg_per_second, ) - self.state.water_output_temperature_in_celsius = self.water_temperature_output_in_celsius - self.state.thermal_power_delivered_in_watt = self.thermal_power_delivered_in_watt + # write values to state + self.state.water_output_temperature_in_celsius = water_temperature_output_in_celsius + self.state.water_input_temperature_in_celsius = water_temperature_input_in_celsius + self.state.thermal_power_delivered_in_watt = thermal_power_delivered_in_watt + + def determine_water_temperature_input_output_effective_thermal_power_without_massflow( + self, + residence_temperature_in_celsius: float, + ) -> Any: + """Calculate cooled or heated water temperature due to free convection after heat exchange between heat distribution system and building without massflow.""" + + # source1: https://www.mdpi.com/1996-1073/16/15/5850 + # source2: https://www.researchgate.net/publication/305659004_Modelling_and_Simulation_of_Underfloor_Heating_System_Supplied_from_Heat_Pump + # source3: https://www.sciencedirect.com/science/article/pii/S0378778816312749?via%3Dihub + # assumption1: https://www.heizsparer.de/heizung/heizkorper/fussbodenheizung/fussbodenheizung-planen-heizkreise-berechnen + # assumption2: heat transfer direction just to the room --> other direction is adiabatic + # assumption3: still air and no floor covering considered + + height_of_screed = 40 / 1000 # in m + thermal_conductivity_screed = 1.4 # in W/(m^2K) + heat_transfer_coefficient_screed_to_air = 5.8 # assumption3 + inner_pipe_diameter = 16 / 1000 # in m # Task 44 IEA Annex 38 + outer_pipe_diameter = (16 + 2) / 1000 # in m # Task 44 IEA Annex 38 + + heat_resistance_coefficient_hds_pipe_to_air = ( + height_of_screed / thermal_conductivity_screed + 1 / heat_transfer_coefficient_screed_to_air + ) + + length_of_hds_pipe = 8.8 * self.absolute_conditioned_floor_area_in_m2 # in m -> assumption1 + inner_volume_of_hds = (np.pi / 4) * ((inner_pipe_diameter) ** 2) * length_of_hds_pipe # in m^3 + + outer_surface_of_hds_pipe = np.pi * outer_pipe_diameter * length_of_hds_pipe # in m^2 + + mass_of_water_in_hds = inner_volume_of_hds * self.density_of_water + + time_constant_hds = ( + mass_of_water_in_hds * self.specific_heat_capacity_of_water_in_joule_per_kilogram_per_celsius + ) * (heat_resistance_coefficient_hds_pipe_to_air / outer_surface_of_hds_pipe) + + water_temperature_input_in_celsius = residence_temperature_in_celsius + ( + (self.state.water_input_temperature_in_celsius - residence_temperature_in_celsius) + * np.exp(-(self.my_simulation_parameters.seconds_per_timestep) / time_constant_hds) + ) + water_temperature_output_in_celsius = residence_temperature_in_celsius + ( + (self.state.water_output_temperature_in_celsius - residence_temperature_in_celsius) + * np.exp(-(self.my_simulation_parameters.seconds_per_timestep) / time_constant_hds) + ) + + thermal_power_delivered_effective_in_watt = self.state.thermal_power_delivered_in_watt * np.exp( + -(self.my_simulation_parameters.seconds_per_timestep) / time_constant_hds + ) + + return ( + water_temperature_input_in_celsius, + water_temperature_output_in_celsius, + thermal_power_delivered_effective_in_watt, + ) def determine_water_temperature_output_after_heat_exchange_with_building_and_effective_thermal_power( self, @@ -466,8 +580,47 @@ def get_cost_opex( return opex_cost_data_class -class HeatDistributionController(cp.Component): +@dataclass_json +@dataclass +class HeatDistributionControllerConfig(cp.ConfigBase): + """HeatDistribution Controller Config Class.""" + @classmethod + def get_main_classname(cls): + """Returns the full class name of the base class.""" + return HeatDistributionController.get_full_classname() + + name: str + heating_system: Union[HeatDistributionSystemType, int] + set_heating_threshold_outside_temperature_in_celsius: Optional[float] + heating_reference_temperature_in_celsius: float + set_heating_temperature_for_building_in_celsius: float + set_cooling_temperature_for_building_in_celsius: float + heating_load_of_building_in_watt: float + + @classmethod + def get_default_heat_distribution_controller_config( + cls, + heating_load_of_building_in_watt: float, + set_heating_temperature_for_building_in_celsius: float, + set_cooling_temperature_for_building_in_celsius: float, + heating_reference_temperature_in_celsius: float = -7.0, + heating_system: Union[HeatDistributionSystemType, int] = HeatDistributionSystemType.FLOORHEATING, + ) -> "HeatDistributionControllerConfig": + """Gets a default HeatDistribution Controller.""" + + return HeatDistributionControllerConfig( + name="HeatDistributionController", + heating_system=heating_system, + set_heating_threshold_outside_temperature_in_celsius=16.0, + heating_reference_temperature_in_celsius=heating_reference_temperature_in_celsius, + set_heating_temperature_for_building_in_celsius=set_heating_temperature_for_building_in_celsius, + set_cooling_temperature_for_building_in_celsius=set_cooling_temperature_for_building_in_celsius, + heating_load_of_building_in_watt=heating_load_of_building_in_watt, + ) + + +class HeatDistributionController(cp.Component): """Heat Distribution Controller. It takes data from the building, weather and water storage and sends signal to the heat distribution for @@ -478,13 +631,14 @@ class HeatDistributionController(cp.Component): # Inputs TheoreticalThermalBuildingDemand = "TheoreticalThermalBuildingDemand" DailyAverageOutsideTemperature = "DailyAverageOutsideTemperature" - WaterTemperatureInputFromHeatWaterStorage = "WaterTemperatureInputFromHeatWaterStorage" # Inputs -> energy management system BuildingTemperatureModifier = "BuildingTemperatureModifier" # Outputs State = "State" HeatingFlowTemperature = "HeatingFlowTemperature" + HeatingReturnTemperature = "HeatingReturnTemperature" + HeatingTemperatureDifference = "HeatingTemperatureDifference" # Similar components to connect to: # 1. Building @@ -537,13 +691,6 @@ def __init__( lt.Units.CELSIUS, True, ) - self.water_temperature_input_from_heat_water_storage_channel: cp.ComponentInput = self.add_input( - self.component_name, - self.WaterTemperatureInputFromHeatWaterStorage, - lt.LoadTypes.TEMPERATURE, - lt.Units.CELSIUS, - True, - ) self.building_temperature_modifier_channel: cp.ComponentInput = self.add_input( self.component_name, self.BuildingTemperatureModifier, @@ -566,12 +713,26 @@ def __init__( lt.Units.CELSIUS, output_description=f"here a description for {self.HeatingFlowTemperature} will follow.", ) + self.heating_return_temperature_channel: cp.ComponentOutput = self.add_output( + self.component_name, + self.HeatingReturnTemperature, + lt.LoadTypes.TEMPERATURE, + lt.Units.CELSIUS, + output_description=f"here a description for {self.HeatingReturnTemperature} will follow.", + ) + self.heating_temperature_difference_channel: cp.ComponentOutput = self.add_output( + self.component_name, + self.HeatingTemperatureDifference, + lt.LoadTypes.TEMPERATURE, + lt.Units.CELSIUS, + output_description=f"here a description for {self.HeatingTemperatureDifference} will follow.", + ) + self.controller_heat_distribution_mode: str = "off" self.previous_controller_heat_distribution_mode: str = "off" self.add_default_connections(self.get_default_connections_from_building()) self.add_default_connections(self.get_default_connections_from_weather()) - self.add_default_connections(self.get_default_connections_from_simple_hot_water_storage()) self.add_default_connections(self.get_default_connections_from_energy_management_system()) def get_default_connections_from_weather( @@ -606,22 +767,6 @@ def get_default_connections_from_building( ) return connections - def get_default_connections_from_simple_hot_water_storage( - self, - ): - """Get simple_hot_water_storage default connections.""" - - connections = [] - hws_classname = SimpleHotWaterStorage.get_classname() - connections.append( - cp.ComponentConnection( - HeatDistributionController.WaterTemperatureInputFromHeatWaterStorage, - hws_classname, - SimpleHotWaterStorage.WaterTemperatureToHeatDistribution, - ) - ) - return connections - def get_default_connections_from_energy_management_system( self, ): @@ -748,6 +893,16 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg self.heating_flow_temperature_channel, list_of_heating_distribution_system_flow_and_return_temperatures[0], ) + stsv.set_output_value( + self.heating_return_temperature_channel, + list_of_heating_distribution_system_flow_and_return_temperatures[1], + ) + + stsv.set_output_value( + self.heating_temperature_difference_channel, + list_of_heating_distribution_system_flow_and_return_temperatures[0] + - list_of_heating_distribution_system_flow_and_return_temperatures[1], + ) def conditions_for_opening_or_shutting_heat_distribution( self, @@ -875,7 +1030,6 @@ def calc_heat_distribution_flow_and_return_temperatures( @dataclass_json @dataclass class HeatDistributionControllerInformation: - """Class for collecting important heat distribution parameters to pass to other components.""" def __init__(self, config: HeatDistributionControllerConfig): diff --git a/hisim/components/more_advanced_heat_pump_hplib.py b/hisim/components/more_advanced_heat_pump_hplib.py index 7b06ebdf..59cd5d81 100644 --- a/hisim/components/more_advanced_heat_pump_hplib.py +++ b/hisim/components/more_advanced_heat_pump_hplib.py @@ -9,14 +9,17 @@ preparation on district heating for water/water heatpumps """ + import hashlib # clean import importlib +from enum import IntEnum from dataclasses import dataclass -from typing import Any, List, Optional, Tuple, Dict +from typing import Any, List, Optional, Tuple, Dict, Union import pandas as pd +import numpy as np from dataclass_wizard import JSONWizard from dataclasses_json import dataclass_json from hplib import hplib as hpl @@ -44,6 +47,7 @@ Euro, Years, KilowattHour, + KilogramPerSecond, ) from hisim.components.configuration import PhysicsConfig @@ -58,10 +62,28 @@ __status__ = "" +class PositionHotWaterStorageInSystemSetup(IntEnum): + """Set Postion of Hot Water Storage in system setup. + + PARALLEL: + Hot Water Storage is parallel to heatpump and hds, massflow of heatpump and heat distribution system are independent of each other. + Heatpump massflow is calculated in hp model, hds massflow is calculated in hds model. + + SERIE: + Hot Water Storage in series to hp/hds, massflow of hds is an input and connected to hp, hot water storage is between output of hds and input of hp + + NO_STORAGE: + No Hot Water Storage in system setup for space heating + """ + + PARALLEL = 1 + SERIE = 2 + NO_STORAGE = 3 + + @dataclass_json @dataclass class HeatPumpHplibWithTwoOutputsConfig(ConfigBase): - """HeatPumpHplibWithTwoOutputsConfig.""" @classmethod @@ -80,8 +102,12 @@ def get_main_classname(cls): minimum_running_time_in_seconds: Optional[Quantity[int, Seconds]] minimum_idle_time_in_seconds: Optional[Quantity[int, Seconds]] temperature_difference_primary_side: float - with_hot_water_storage: bool + position_hot_water_storage_in_system: Union[PositionHotWaterStorageInSystemSetup, int] with_domestic_hot_water_preparation: bool + minimum_massflow_secondary_side_in_kg_per_s: Optional[Quantity[float, KilogramPerSecond]] + maximum_massflow_secondary_side_in_kg_per_s: Optional[Quantity[float, KilogramPerSecond]] + massflow_nominal_secondary_side_in_kg_per_s: Quantity[float, KilogramPerSecond] + minimum_thermal_output_power_in_watt: Quantity[float, Watt] #: CO2 footprint of investment in kg co2_footprint: Quantity[float, Kilogram] #: cost for investment in Euro @@ -98,6 +124,10 @@ def get_default_generic_advanced_hp_lib( cls, set_thermal_output_power_in_watt: Quantity[float, Watt] = Quantity(8000, Watt), heating_reference_temperature_in_celsius: Quantity[float, Celsius] = Quantity(-7.0, Celsius), + massflow_nominal_secondary_side_in_kg_per_s: Quantity[float, KilogramPerSecond] = Quantity( + 0.333, KilogramPerSecond + ), + minimum_thermal_output_power_in_watt: Quantity[float, Watt] = Quantity(3800, Watt), ) -> "HeatPumpHplibWithTwoOutputsConfig": """Gets a default HPLib Heat Pump. @@ -116,19 +146,17 @@ def get_default_generic_advanced_hp_lib( minimum_running_time_in_seconds=Quantity(3600, Seconds), minimum_idle_time_in_seconds=Quantity(3600, Seconds), temperature_difference_primary_side=2, - with_hot_water_storage=True, + position_hot_water_storage_in_system=1, with_domestic_hot_water_preparation=False, + minimum_massflow_secondary_side_in_kg_per_s=massflow_nominal_secondary_side_in_kg_per_s, + maximum_massflow_secondary_side_in_kg_per_s=massflow_nominal_secondary_side_in_kg_per_s, + massflow_nominal_secondary_side_in_kg_per_s=massflow_nominal_secondary_side_in_kg_per_s, + minimum_thermal_output_power_in_watt=minimum_thermal_output_power_in_watt, # value from emission_factors_and_costs_devices.csv - co2_footprint=Quantity( - set_thermal_output_power_in_watt.value * 1e-3 * 165.84, Kilogram - ), + co2_footprint=Quantity(set_thermal_output_power_in_watt.value * 1e-3 * 165.84, Kilogram), # value from emission_factors_and_costs_devices.csv - cost=Quantity( - set_thermal_output_power_in_watt.value * 1e-3 * 1513.74, Euro - ), - lifetime=Quantity( - 10, Years - ), # value from emission_factors_and_costs_devices.csv + cost=Quantity(set_thermal_output_power_in_watt.value * 1e-3 * 1513.74, Euro), + lifetime=Quantity(10, Years), # value from emission_factors_and_costs_devices.csv maintenance_cost_as_percentage_of_investment=0.025, # source: VDI2067-1 consumption=Quantity(0, KilowattHour), ) @@ -138,6 +166,10 @@ def get_scaled_advanced_hp_lib( cls, heating_load_of_building_in_watt: Quantity[float, Watt], heating_reference_temperature_in_celsius: Quantity[float, Celsius] = Quantity(-7.0, Celsius), + massflow_nominal_secondary_side_in_kg_per_s: Quantity[float, KilogramPerSecond] = Quantity( + 0.333, KilogramPerSecond + ), + minimum_thermal_output_power_in_watt: Quantity[float, Watt] = Quantity(3800, Watt), ) -> "HeatPumpHplibWithTwoOutputsConfig": """Gets a default heat pump with scaling according to heating load of the building.""" @@ -155,16 +187,16 @@ def get_scaled_advanced_hp_lib( minimum_running_time_in_seconds=Quantity(3600, Seconds), minimum_idle_time_in_seconds=Quantity(3600, Seconds), temperature_difference_primary_side=2, - with_hot_water_storage=True, + position_hot_water_storage_in_system=1, with_domestic_hot_water_preparation=False, + minimum_massflow_secondary_side_in_kg_per_s=massflow_nominal_secondary_side_in_kg_per_s, + maximum_massflow_secondary_side_in_kg_per_s=massflow_nominal_secondary_side_in_kg_per_s, + massflow_nominal_secondary_side_in_kg_per_s=massflow_nominal_secondary_side_in_kg_per_s, + minimum_thermal_output_power_in_watt=minimum_thermal_output_power_in_watt, # value from emission_factros_and_costs_devices.csv - co2_footprint=Quantity( - set_thermal_output_power_in_watt.value * 1e-3 * 165.84, Kilogram - ), + co2_footprint=Quantity(set_thermal_output_power_in_watt.value * 1e-3 * 165.84, Kilogram), # value from emission_factros_and_costs_devices.csv - cost=Quantity( - set_thermal_output_power_in_watt.value * 1e-3 * 1513.74, Euro - ), + cost=Quantity(set_thermal_output_power_in_watt.value * 1e-3 * 1513.74, Euro), # value from emission_factros_and_costs_devices.csv lifetime=Quantity(10, Years), maintenance_cost_as_percentage_of_investment=0.025, # source: VDI2067-1 @@ -173,7 +205,6 @@ def get_scaled_advanced_hp_lib( class HeatPumpHplibWithTwoOutputs(Component): - """Simulate the heat pump. Outputs are heat pump efficiency (cop) as well as electrical (p_el) and @@ -192,6 +223,7 @@ class HeatPumpHplibWithTwoOutputs(Component): TemperatureInputSecondary_SH = "TemperatureInputSecondarySpaceHeating" # °C TemperatureInputSecondary_DHW = "TemperatureInputSecondaryDWH" # °C TemperatureAmbient = "TemperatureAmbient" # °C + SetHeatingTemperatureSpaceHeating = "SetHeatingTemperatureSpaceHeating" # Outputs ThermalOutputPowerSH = "ThermalOutputPowerSpaceHeating" # W @@ -204,6 +236,7 @@ class HeatPumpHplibWithTwoOutputs(Component): COP = "COP" # - EER = "EER" # - HeatPumpOnOffState = "OnOffStateHeatpump" + TemperatureInputSH = "TemperatureInputSpaceHeating" # °C TemperatureOutputSH = "TemperatureOutputSpaceHeating" # °C TemperatureOutputDHW = "TemperatureOutputDHW" # °C MassFlowOutputSH = "MassFlowOutputSpaceHeating" # kg/s @@ -230,6 +263,7 @@ class HeatPumpHplibWithTwoOutputs(Component): CounterSwitchToSH = "CounterSwitchToSH" # Counter of switching to SH != onOff Switch! CounterSwitchToDHW = "CounterSwitchToDHW" # Counter of switching to DHW != onOff Switch! CounterOnOff = "CounterOnOff" # Counter of starting the hp + DeltaTHeatpump = "DeltaTHeatpump" # Temperature difference between input and output of HP secondary side def __init__( self, @@ -260,10 +294,42 @@ def __init__( self.cycling_mode = config.cycling_mode - self.with_hot_water_storage = config.with_hot_water_storage - self.with_domestic_hot_water_preparation = config.with_domestic_hot_water_preparation + self.position_hot_water_storage_in_system = config.position_hot_water_storage_in_system + + # self.m_dot_ref = float( + # config.massflow_nominal_secondary_side_in_kg_per_s.value + # if config.massflow_nominal_secondary_side_in_kg_per_s + # else config.massflow_nominal_secondary_side_in_kg_per_s + # ) + + # self.minimum_thermal_output_power = ( + # config.minimum_thermal_output_power_in_watt.value + # if config.minimum_thermal_output_power_in_watt + # else config.minimum_thermal_output_power_in_watt + # ) + + self.m_dot_ref = config.massflow_nominal_secondary_side_in_kg_per_s.value + + self.minimum_thermal_output_power = config.minimum_thermal_output_power_in_watt.value + + if self.position_hot_water_storage_in_system in [ + PositionHotWaterStorageInSystemSetup.SERIE, + PositionHotWaterStorageInSystemSetup.NO_STORAGE, + ]: + if ( + self.m_dot_ref is None + or self.m_dot_ref == 0 + or self.minimum_thermal_output_power is None + or self.minimum_thermal_output_power == 0 + ): + raise ValueError( + """If system setup is without parallel hot water storage, nominal massflow and minimum + thermal power of the heat pump must be given an integer value due to constant massflow + of water pump.""" + ) + self.heat_source = config.heat_source self.temperature_difference_primary_side = config.temperature_difference_primary_side @@ -300,11 +366,14 @@ def __init__( counter_switch_sh=0, counter_switch_dhw=0, counter_onoff=0, + delta_t=5, ) self.previous_state = self.state.self_copy() # Load parameters from heat pump database self.parameters = hpl.get_parameters(self.model, self.group_id, self.t_in, self.t_out_val, self.p_th_set) + self.heatpump = hpl.HeatPump(self.parameters) + self.heatpump.delta_t = 5 self.specific_heat_capacity_of_water_in_joule_per_kilogram_per_celsius = ( PhysicsConfig.water_specific_heat_capacity_in_joule_per_kilogram_per_kelvin @@ -387,6 +456,18 @@ def __init__( mandatory=True, ) + if self.position_hot_water_storage_in_system in [ + PositionHotWaterStorageInSystemSetup.SERIE, + PositionHotWaterStorageInSystemSetup.NO_STORAGE, + ]: + self.set_temperature_hp_sh: ComponentInput = self.add_input( + self.component_name, + self.SetHeatingTemperatureSpaceHeating, + LoadTypes.TEMPERATURE, + Units.CELSIUS, + True, + ) + # Define component outputs self.p_th_sh: ComponentOutput = self.add_output( object_name=self.component_name, @@ -440,6 +521,14 @@ def __init__( output_description="OnOffState", ) + self.t_in_sh: ComponentOutput = self.add_output( + object_name=self.component_name, + field_name=self.TemperatureInputSH, + load_type=LoadTypes.HEATING, + unit=Units.CELSIUS, + output_description="Temperature Input SpaceHeating in °C", + ) + self.t_out_sh: ComponentOutput = self.add_output( object_name=self.component_name, field_name=self.TemperatureOutputSH, @@ -578,6 +667,14 @@ def __init__( output_description=f"here a description for {self.CumulativeElectricalEnergyTotal} will follow.", ) + self.delta_t_hp_channel: ComponentOutput = self.add_output( + object_name=self.component_name, + field_name=self.DeltaTHeatpump, + load_type=LoadTypes.TEMPERATURE, + unit=Units.KELVIN, + output_description=f"{self.DeltaTHeatpump} is a counter of starting procedures hp.", + ) + if self.with_domestic_hot_water_preparation: self.p_th_dhw: ComponentOutput = self.add_output( object_name=self.component_name, @@ -685,7 +782,9 @@ def __init__( self.add_default_connections(self.get_default_connections_from_heat_pump_controller_space_heating()) self.add_default_connections(self.get_default_connections_from_weather()) - self.add_default_connections(self.get_default_connections_from_simple_hot_water_storage()) + + if self.position_hot_water_storage_in_system == PositionHotWaterStorageInSystemSetup.PARALLEL: + self.add_default_connections(self.get_default_connections_from_simple_hot_water_storage()) if self.with_domestic_hot_water_preparation: self.add_default_connections(self.get_default_connections_from_heat_pump_controller_dhw()) @@ -823,13 +922,24 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc time_on_cooling = self.state.time_on_cooling time_off = self.state.time_off + if self.position_hot_water_storage_in_system in [ + PositionHotWaterStorageInSystemSetup.SERIE, + PositionHotWaterStorageInSystemSetup.NO_STORAGE, + ]: + set_temperature_hp_sh = stsv.get_input_value(self.set_temperature_hp_sh) + if self.with_domestic_hot_water_preparation: on_off_dhw: float = stsv.get_input_value(self.on_off_switch_dhw) const_thermal_power_truefalse_dhw: bool = bool(stsv.get_input_value(self.const_thermal_power_truefalse_dhw)) const_thermal_power_value_dhw = stsv.get_input_value(self.const_thermal_power_value_dhw) t_in_secondary_dhw = stsv.get_input_value(self.t_in_secondary_dhw) + else: + on_off_dhw = 0 + const_thermal_power_truefalse_dhw = False + const_thermal_power_value_dhw = 0 + t_in_secondary_dhw = 0 - if self.with_domestic_hot_water_preparation and on_off_dhw != 0: + if on_off_dhw != 0: on_off = on_off_dhw else: on_off = on_off_sh @@ -864,102 +974,199 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc raise ValueError("Cycling mode of the advanced hplib unknown.") if on_off == 1: # Calculation for building heating - results = self.get_cached_results_or_run_hplib_simulation( - force_convergence=force_convergence, - t_in_primary=t_in_primary, - t_in_secondary=t_in_secondary_sh, - parameters=self.parameters, - t_amb=t_amb, - mode=1, - ) + if self.position_hot_water_storage_in_system == PositionHotWaterStorageInSystemSetup.PARALLEL: + self.heatpump.delta_t = 5 + results = self.get_cached_results_or_run_hplib_simulation( + force_convergence=force_convergence, + t_in_primary=t_in_primary, + t_in_secondary=t_in_secondary_sh, + t_amb=t_amb, + mode=1, + ) - p_th_sh = results["P_th"].values[0] - p_th_dhw = 0.0 - p_el_sh = results["P_el"].values[0] - p_el_dhw = 0 - p_el_cooling = 0 - cop = results["COP"].values[0] - eer = results["EER"].values[0] - t_out_sh = results["T_out"].values[0] - t_out_dhw = t_in_secondary_dhw if self.with_domestic_hot_water_preparation else 0 - m_dot_sh = results["m_dot"].values[0] - m_dot_dhw = 0 - time_on_heating = time_on_heating + self.my_simulation_parameters.seconds_per_timestep - time_on_cooling = 0 - time_off = 0 + p_th_sh = results["P_th"] + p_th_dhw = 0.0 + p_el_sh = results["P_el"] + p_el_dhw = 0.0 + p_el_cooling = 0.0 + cop = results["COP"] + eer = results["EER"] + t_out_sh = results["T_out"] + t_out_dhw = t_in_secondary_dhw if self.with_domestic_hot_water_preparation else 0.0 + m_dot_sh = results["m_dot"] + m_dot_dhw = 0.0 + time_on_heating = time_on_heating + self.my_simulation_parameters.seconds_per_timestep + time_on_cooling = 0 + time_off = 0 + + else: + m_dot_sh = self.m_dot_ref + + self.heatpump.delta_t = min(set_temperature_hp_sh - t_in_secondary_sh, 5) + + if self.heatpump.delta_t == 0: + self.heatpump.delta_t = 0.00000001 + + results = self.get_cached_results_or_run_hplib_simulation( + force_convergence=force_convergence, + t_in_primary=t_in_primary, + t_in_secondary=t_in_secondary_sh, + t_amb=t_amb, + mode=1, + ) + + cop = results["COP"] + eer = results["EER"] + + p_th_sh_theoretical = ( + m_dot_sh + * self.specific_heat_capacity_of_water_in_joule_per_kilogram_per_celsius + * self.heatpump.delta_t + ) + p_el_sh_theoretical = p_th_sh_theoretical / cop + + if p_th_sh_theoretical <= self.minimum_thermal_output_power: + p_th_sh = self.minimum_thermal_output_power + p_el_sh = p_th_sh / cop + else: + p_el_sh = p_el_sh_theoretical + p_th_sh = p_th_sh_theoretical + + p_el_sh = p_el_sh * (1 - np.exp(-time_on_heating / 360)) # time shifting while start of hp + p_th_sh = p_th_sh * (1 - np.exp(-time_on_heating / 360)) + + t_out_sh = t_in_secondary_sh + p_th_sh / ( + m_dot_sh * self.specific_heat_capacity_of_water_in_joule_per_kilogram_per_celsius + ) + + self.heatpump.delta_t = t_out_sh - t_in_secondary_sh + + t_out_dhw = t_in_secondary_dhw if self.with_domestic_hot_water_preparation else 0.0 + p_th_dhw = 0.0 + p_el_dhw = 0.0 + p_el_cooling = 0.0 + m_dot_dhw = 0.0 + time_on_heating = time_on_heating + self.my_simulation_parameters.seconds_per_timestep + time_on_cooling = 0 + time_off = 0 elif on_off == 2: # Calculate outputs for dhw mode - results = self.get_cached_results_or_run_hplib_simulation( - force_convergence=force_convergence, - t_in_primary=t_in_primary, - t_in_secondary=t_in_secondary_dhw, - parameters=self.parameters, - t_amb=t_amb, - mode=1, - ) + self.heatpump.delta_t = 5 + if self.position_hot_water_storage_in_system == PositionHotWaterStorageInSystemSetup.PARALLEL: + results = self.get_cached_results_or_run_hplib_simulation( + force_convergence=force_convergence, + t_in_primary=t_in_primary, + t_in_secondary=t_in_secondary_dhw, + t_amb=t_amb, + mode=1, + ) - p_th_sh = 0.0 - p_el_sh = 0 - p_el_cooling = 0 - cop = results["COP"].values[0] - eer = results["EER"].values[0] - t_out_sh = t_in_secondary_sh - t_out_dhw = results["T_out"].values[0] - m_dot_sh = 0 - m_dot_dhw = results["m_dot"].values[0] - if const_thermal_power_truefalse_dhw is True: # True = constant thermal power output for dhw - p_th_dhw = const_thermal_power_value_dhw - p_el_dhw = p_th_dhw / cop - if ( - const_thermal_power_truefalse_dhw is False or const_thermal_power_truefalse_dhw == 0 - ): # False = modulation - p_th_dhw = results["P_th"].values[0] - p_el_dhw = results["P_el"].values[0] - time_on_heating = time_on_heating + self.my_simulation_parameters.seconds_per_timestep - time_on_cooling = 0 - time_off = 0 + p_th_sh = 0.0 + p_el_sh = 0.0 + p_el_cooling = 0.0 + cop = results["COP"] + eer = results["EER"] + t_out_sh = t_in_secondary_sh + t_out_dhw = results["T_out"] + m_dot_sh = 0.0 + m_dot_dhw = results["m_dot"] + if const_thermal_power_truefalse_dhw is True: # True = constant thermal power output for dhw + p_th_dhw = const_thermal_power_value_dhw + p_el_dhw = p_th_dhw / cop + if ( + const_thermal_power_truefalse_dhw is False or const_thermal_power_truefalse_dhw == 0 + ): # False = modulation + p_th_dhw = results["P_th"] + p_el_dhw = results["P_el"] + time_on_heating = time_on_heating + self.my_simulation_parameters.seconds_per_timestep + time_on_cooling = 0 + time_off = 0 + + else: + m_dot_dhw = self.m_dot_ref + + results = self.get_cached_results_or_run_hplib_simulation( + force_convergence=force_convergence, + t_in_primary=t_in_primary, + t_in_secondary=t_in_secondary_dhw, + t_amb=t_amb, + mode=1, + ) + + cop = results["COP"] + eer = results["EER"] + + p_th_dhw_theoretical = ( + m_dot_dhw + * self.specific_heat_capacity_of_water_in_joule_per_kilogram_per_celsius + * self.heatpump.delta_t + ) + p_el_dhw_theoretical = p_th_dhw_theoretical / cop + + if p_th_dhw_theoretical <= self.minimum_thermal_output_power: + p_th_dhw = self.minimum_thermal_output_power + p_el_dhw = p_th_dhw / cop + else: + p_el_dhw = p_el_dhw_theoretical + p_th_dhw = p_th_dhw_theoretical + + p_el_dhw = p_el_dhw * (1 - np.exp(-time_on_heating / 360)) + p_th_dhw = p_th_dhw * (1 - np.exp(-time_on_heating / 360)) + + t_out_dhw = t_in_secondary_dhw + p_th_dhw / ( + m_dot_dhw * self.specific_heat_capacity_of_water_in_joule_per_kilogram_per_celsius + ) + + t_out_sh = t_in_secondary_sh + p_th_sh = 0.0 + p_el_sh = 0.0 + p_el_cooling = 0.0 + m_dot_sh = 0.0 + time_on_heating = time_on_heating + self.my_simulation_parameters.seconds_per_timestep + time_on_cooling = 0 + time_off = 0 elif on_off == -1: # Calulate outputs for cooling mode + self.heatpump.delta_t = 5 results = self.get_cached_results_or_run_hplib_simulation( force_convergence=force_convergence, t_in_primary=t_in_primary, t_in_secondary=t_in_secondary_sh, - parameters=self.parameters, t_amb=t_amb, mode=2, ) - p_th_sh = results["P_th"].values[0] + p_th_sh = results["P_th"] p_th_dhw = 0.0 - p_el_sh = results["P_el"].values[0] - p_el_dhw = 0 + p_el_sh = results["P_el"] + p_el_dhw = 0.0 p_el_cooling = p_el_sh - cop = results["COP"].values[0] - eer = results["EER"].values[0] - t_out_sh = results["T_out"].values[0] - t_out_dhw = t_in_secondary_dhw if self.with_domestic_hot_water_preparation else 0 - m_dot_sh = results["m_dot"].values[0] - m_dot_dhw = 0 + cop = results["COP"] + eer = results["EER"] + t_out_sh = results["T_out"] + t_out_dhw = t_in_secondary_dhw if self.with_domestic_hot_water_preparation else 0.0 + m_dot_sh = results["m_dot"] + m_dot_dhw = 0.0 time_on_cooling = time_on_cooling + self.my_simulation_parameters.seconds_per_timestep time_on_heating = 0 time_off = 0 elif on_off == 0: # Calulate outputs for off mode - p_th_sh = 0 - p_th_dhw = 0 - p_el_sh = 0 - p_el_dhw = 0 - p_el_cooling = 0 + p_th_sh = 0.0 + p_th_dhw = 0.0 + p_el_sh = 0.0 + p_el_dhw = 0.0 + p_el_cooling = 0.0 # None values or nans will cause troubles in post processing, that is why there are not used here # cop = None # t_out = None - cop = 0 - eer = 0 + cop = 0.0 + eer = 0.0 t_out_sh = t_in_secondary_sh - t_out_dhw = t_in_secondary_dhw if self.with_domestic_hot_water_preparation else 0 - m_dot_sh = 0 - m_dot_dhw = 0 + t_out_dhw = t_in_secondary_dhw if self.with_domestic_hot_water_preparation else 0.0 + m_dot_sh = 0.0 + m_dot_dhw = 0.0 time_off = time_off + self.my_simulation_parameters.seconds_per_timestep time_on_heating = 0 time_on_cooling = 0 @@ -1043,6 +1250,7 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc stsv.set_output_value(self.cop, cop) stsv.set_output_value(self.eer, eer) stsv.set_output_value(self.heatpump_state, on_off) + stsv.set_output_value(self.t_in_sh, t_in_secondary_sh) stsv.set_output_value(self.t_out_sh, t_out_sh) stsv.set_output_value(self.m_dot_sh, m_dot_sh) stsv.set_output_value(self.time_on_heating, time_on_heating) @@ -1066,6 +1274,7 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc self.cumulative_hp_electrical_energy_sh_channel, cumulative_hp_electrical_energy_sh_in_watt_hour ) stsv.set_output_value(self.counter_on_off_channel, counter_onoff) + stsv.set_output_value(self.delta_t_hp_channel, self.heatpump.delta_t) if self.with_domestic_hot_water_preparation: stsv.set_output_value(self.p_th_dhw, p_th_dhw) @@ -1097,6 +1306,7 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc self.state.counter_switch_sh = counter_switch_sh self.state.counter_switch_dhw = counter_switch_dhw self.state.counter_onoff = counter_onoff + self.state.delta_t = self.heatpump.delta_t @staticmethod def get_cost_capex(config: HeatPumpHplibWithTwoOutputsConfig) -> Tuple[float, float, float]: @@ -1115,8 +1325,7 @@ def get_cost_opex( """ for index, output in enumerate(all_outputs): if ( - output.component_name == "HeatPumpHplibWithTwoOutputs" - and output.load_type == LoadTypes.ELECTRICITY + output.component_name == "HeatPumpHplibWithTwoOutputs" and output.load_type == LoadTypes.ELECTRICITY ): # Todo: check component name from system_setups: find another way of using only heatpump-outputs self.config.consumption = round( sum(postprocessing_results.iloc[:, index]) @@ -1137,7 +1346,6 @@ def get_cached_results_or_run_hplib_simulation( force_convergence: bool, t_in_primary: float, t_in_secondary: float, - parameters: pd.DataFrame, t_amb: float, mode: int, ) -> Any: @@ -1161,7 +1369,7 @@ def get_cached_results_or_run_hplib_simulation( if my_hash_key in self.calculation_cache: results = self.calculation_cache[my_hash_key] else: - results = hpl.simulate(t_in_primary, t_in_secondary, parameters, t_amb, mode=mode) + results = self.heatpump.simulate(t_in_primary, t_in_secondary, t_amb, mode=mode) self.calculation_cache[my_hash_key] = results @@ -1170,7 +1378,6 @@ def get_cached_results_or_run_hplib_simulation( @dataclass class HeatPumpWithTwoOutputsState: - """HeatPumpWithTwoOutputsState class.""" time_on_heating: int @@ -1186,6 +1393,7 @@ class HeatPumpWithTwoOutputsState: counter_switch_sh: int counter_switch_dhw: int counter_onoff: int + delta_t: float def self_copy( self, @@ -1205,6 +1413,7 @@ def self_copy( self.counter_switch_sh, self.counter_switch_dhw, self.counter_onoff, + self.delta_t, ) @@ -1226,7 +1435,6 @@ def get_key(self): @dataclass_json @dataclass class HeatPumpHplibControllerSpaceHeatingConfig(ConfigBase): - """HeatPump Controller Config Class for building heating.""" @classmethod @@ -1244,7 +1452,10 @@ def get_main_classname(cls): @classmethod def get_default_space_heating_controller_config( - cls, heat_distribution_system_type: Any + cls, + heat_distribution_system_type: Any, + upper_temperature_offset_for_state_conditions_in_celsius: float = 5.0, + lower_temperature_offset_for_state_conditions_in_celsius: float = 5.0, ) -> "HeatPumpHplibControllerSpaceHeatingConfig": """Gets a default Generic Heat Pump Controller.""" return HeatPumpHplibControllerSpaceHeatingConfig( @@ -1252,14 +1463,13 @@ def get_default_space_heating_controller_config( mode=1, set_heating_threshold_outside_temperature_in_celsius=16.0, set_cooling_threshold_outside_temperature_in_celsius=20.0, - upper_temperature_offset_for_state_conditions_in_celsius=5.0, - lower_temperature_offset_for_state_conditions_in_celsius=5.0, + upper_temperature_offset_for_state_conditions_in_celsius=upper_temperature_offset_for_state_conditions_in_celsius, + lower_temperature_offset_for_state_conditions_in_celsius=lower_temperature_offset_for_state_conditions_in_celsius, heat_distribution_system_type=heat_distribution_system_type, ) class HeatPumpHplibControllerSpaceHeating(Component): - """Heat Pump Controller for Space Heating. It takes data from other @@ -1282,7 +1492,7 @@ class HeatPumpHplibControllerSpaceHeating(Component): """ # Inputs - WaterTemperatureInputFromHeatWaterStorage = "WaterTemperatureInputFromHeatWaterStorage" + WaterTemperatureInput = "WaterTemperatureInput" HeatingFlowTemperatureFromHeatDistributionSystem = "HeatingFlowTemperatureFromHeatDistributionSystem" DailyAverageOutsideTemperature = "DailyAverageOutsideTemperature" @@ -1316,7 +1526,7 @@ def __init__( self.water_temperature_input_channel: ComponentInput = self.add_input( self.component_name, - self.WaterTemperatureInputFromHeatWaterStorage, + self.WaterTemperatureInput, LoadTypes.TEMPERATURE, Units.CELSIUS, True, @@ -1398,7 +1608,7 @@ def get_default_connections_from_simple_hot_water_storage( hws_classname = simple_hot_water_storage.SimpleHotWaterStorage.get_classname() connections.append( ComponentConnection( - HeatPumpHplibControllerSpaceHeating.WaterTemperatureInputFromHeatWaterStorage, + HeatPumpHplibControllerSpaceHeating.WaterTemperatureInput, hws_classname, simple_hot_water_storage.SimpleHotWaterStorage.WaterTemperatureToHeatGenerator, ) @@ -1456,9 +1666,7 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc else: # Retrieves inputs - water_temperature_input_from_heat_water_storage_in_celsius = stsv.get_input_value( - self.water_temperature_input_channel - ) + water_temperature_input_in_celsius = stsv.get_input_value(self.water_temperature_input_channel) heating_flow_temperature_from_heat_distribution_system = stsv.get_input_value( self.heating_flow_temperature_from_heat_distribution_system_channel @@ -1481,7 +1689,7 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc # mode 1 is on/off controller if self.mode == 1: self.conditions_on_off( - water_temperature_input_in_celsius=water_temperature_input_from_heat_water_storage_in_celsius, + water_temperature_input_in_celsius=water_temperature_input_in_celsius, set_heating_flow_temperature_in_celsius=heating_flow_temperature_from_heat_distribution_system, summer_heating_mode=summer_heating_mode, storage_temperature_modifier=storage_temperature_modifier, @@ -1497,7 +1705,7 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc set_cooling_threshold_temperature_in_celsius=self.heatpump_controller_config.set_cooling_threshold_outside_temperature_in_celsius, ) self.conditions_heating_cooling_off( - water_temperature_input_in_celsius=water_temperature_input_from_heat_water_storage_in_celsius, + water_temperature_input_in_celsius=water_temperature_input_in_celsius, set_heating_flow_temperature_in_celsius=heating_flow_temperature_from_heat_distribution_system, summer_heating_mode=summer_heating_mode, summer_cooling_mode=summer_cooling_mode, @@ -1586,13 +1794,18 @@ def conditions_heating_cooling_off( if ( water_temperature_input_in_celsius >= heating_set_temperature + + upper_temperature_offset_for_state_conditions_in_celsius + storage_temperature_modifier # Todo: Check if storage_temperature_modifier is neccessary here or summer_heating_mode == "off" ): self.controller_heatpumpmode = "off" return elif self.controller_heatpumpmode == "cooling": - if water_temperature_input_in_celsius <= cooling_set_temperature or summer_cooling_mode == "off": + if ( + water_temperature_input_in_celsius + <= cooling_set_temperature - lower_temperature_offset_for_state_conditions_in_celsius + or summer_cooling_mode == "off" + ): self.controller_heatpumpmode = "off" return @@ -1682,7 +1895,6 @@ def summer_cooling_condition( @dataclass_json @dataclass class HeatPumpHplibControllerDHWConfig(ConfigBase): - """HeatPump Controller Config Class.""" @classmethod @@ -1713,7 +1925,6 @@ def get_default_dhw_controller_config(cls): class HeatPumpHplibControllerDHW(Component): - """Heat Pump Controller for DHW. It takes data from DHW Storage --> generic hot water storage modular @@ -1825,8 +2036,7 @@ def build( """ self.state_dhw = 0 - self.water_temperature_input_from_dhw_storage_in_celsius = 50.0 - self.water_temperature_input_from_dhw_storage_in_celsius_previous = 50.0 + self.water_temperature_input_from_dhw_storage_in_celsius = 40.0 self.thermalpower_dhw_is_constant = self.config.thermalpower_dhw_is_constant self.p_th_max_dhw = self.config.p_th_max_dhw_in_watt @@ -1869,10 +2079,11 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc # self.state_dhw = self.previous_state_dhw pass else: - water_temperature_input_from_dhw_storage_in_celsius = stsv.get_input_value( + self.water_temperature_input_from_dhw_storage_in_celsius = stsv.get_input_value( self.water_temperature_input_channel ) if self.water_temperature_input_from_dhw_storage_in_celsius == 0: + # for avoiding errors: sometimes timestep output of dhw storage sends zero as input, so hp will switch to dhw, even this is not necessary self.water_temperature_input_from_dhw_storage_in_celsius = ( self.water_temperature_input_from_dhw_storage_in_celsius_previous ) @@ -1882,18 +2093,18 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc t_min_dhw_storage_in_celsius = self.config.t_min_dhw_storage_in_celsius t_max_dhw_storage_in_celsius = self.config.t_max_dhw_storage_in_celsius - if water_temperature_input_from_dhw_storage_in_celsius < t_min_dhw_storage_in_celsius: # on + if self.water_temperature_input_from_dhw_storage_in_celsius < t_min_dhw_storage_in_celsius: # on self.state_dhw = 2 if ( - water_temperature_input_from_dhw_storage_in_celsius + self.water_temperature_input_from_dhw_storage_in_celsius > t_max_dhw_storage_in_celsius + temperature_modifier ): # off self.state_dhw = 0 if ( temperature_modifier > 0 - and water_temperature_input_from_dhw_storage_in_celsius < t_max_dhw_storage_in_celsius + and self.water_temperature_input_from_dhw_storage_in_celsius < t_max_dhw_storage_in_celsius ): # aktiviren wenn strom überschuss self.state_dhw = 2 diff --git a/hisim/components/simple_hot_water_storage.py b/hisim/components/simple_hot_water_storage.py index 087ae1f7..1d8d5d59 100644 --- a/hisim/components/simple_hot_water_storage.py +++ b/hisim/components/simple_hot_water_storage.py @@ -36,6 +36,14 @@ class HotWaterStorageSizingEnum(Enum): SIZE_ACCORDING_TO_GENERAL_HEATING_SYSTEM = 2 +class PositionWaterStorageInSystemEnum(Enum): + + """Set Simple Hot Water Storage Position options.""" + + PARALLEL_TO_HEAT_PUMP = 1 + SERIE_TO_HEAT_PUMP = 2 + + @dataclass_json @dataclass class SimpleHotWaterStorageConfig(cp.ConfigBase): @@ -50,9 +58,9 @@ def get_main_classname(cls): volume_heating_water_storage_in_liter: float heat_transfer_coefficient_in_watt_per_m2_per_kelvin: float heat_exchanger_is_present: bool + position_of_storage_in_system: PositionWaterStorageInSystemEnum # it should be checked how much energy the storage lost during the simulated period (see guidelines below, p.2, accepted loss in kWh/days) # https://www.bdh-industrie.de/fileadmin/user_upload/ISH2019/Infoblaetter/Infoblatt_Nr_74_Energetische_Bewertung_Warmwasserspeicher.pdf - water_mass_flow_rate_from_hds_in_kg_per_second: float #: CO2 footprint of investment in kg co2_footprint: float #: cost for investment in Euro @@ -64,16 +72,16 @@ def get_main_classname(cls): @classmethod def get_default_simplehotwaterstorage_config( - cls, water_mass_flow_rate_from_hds_in_kg_per_second: float + cls, ) -> "SimpleHotWaterStorageConfig": """Get a default simplehotwaterstorage config.""" volume_heating_water_storage_in_liter: float = 500 config = SimpleHotWaterStorageConfig( name="SimpleHotWaterStorage", volume_heating_water_storage_in_liter=volume_heating_water_storage_in_liter, - water_mass_flow_rate_from_hds_in_kg_per_second=water_mass_flow_rate_from_hds_in_kg_per_second, heat_transfer_coefficient_in_watt_per_m2_per_kelvin=2.0, heat_exchanger_is_present=True, # until now stratified mode is causing problems, so heat exchanger mode is recommended + position_of_storage_in_system=PositionWaterStorageInSystemEnum.PARALLEL_TO_HEAT_PUMP, co2_footprint=100, # Todo: check value cost=volume_heating_water_storage_in_liter * 14.51, # value from emission_factros_and_costs_devices.csv lifetime=25, # value from emission_factors_and_costs_devices.csv @@ -85,9 +93,8 @@ def get_default_simplehotwaterstorage_config( def get_scaled_hot_water_storage( cls, max_thermal_power_in_watt_of_heating_system: float, - water_mass_flow_rate_from_hds_in_kg_per_second: float, temperature_difference_between_flow_and_return_in_celsius: float = 7.0, - sizing_option: HotWaterStorageSizingEnum = HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_GENERAL_HEATING_SYSTEM + sizing_option: HotWaterStorageSizingEnum = HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_GENERAL_HEATING_SYSTEM, ) -> "SimpleHotWaterStorageConfig": """Gets a default storage with scaling according to heating load of the building. @@ -126,10 +133,10 @@ def get_scaled_hot_water_storage( config = SimpleHotWaterStorageConfig( name="SimpleHotWaterStorage", - water_mass_flow_rate_from_hds_in_kg_per_second=water_mass_flow_rate_from_hds_in_kg_per_second, volume_heating_water_storage_in_liter=volume_heating_water_storage_in_liter, heat_transfer_coefficient_in_watt_per_m2_per_kelvin=2.0, heat_exchanger_is_present=True, # until now stratified mode is causing problems, so heat exchanger mode is recommended + position_of_storage_in_system=PositionWaterStorageInSystemEnum.PARALLEL_TO_HEAT_PUMP, co2_footprint=100, # Todo: check value cost=volume_heating_water_storage_in_liter * 14.51, # value from emission_factros_and_costs_devices.csv lifetime=100, # value from emission_factros_and_costs_devices.csv @@ -163,6 +170,7 @@ class SimpleHotWaterStorage(cp.Component): WaterTemperatureFromHeatDistribution = "WaterTemperatureFromHeatDistribution" WaterTemperatureFromHeatGenerator = "WaterTemperaturefromHeatGenerator" WaterMassFlowRateFromHeatGenerator = "WaterMassFlowRateFromHeatGenerator" + WaterMassFlowRateFromHeatDistributionSystem = "WaterMassFlowRateFromHeatDistributionSystem" State = "State" # Output @@ -202,10 +210,6 @@ def __init__( self.mean_water_temperature_in_water_storage_in_celsius: float = 21 - self.water_mass_flow_rate_from_heat_distribution_system_in_kg_per_second = ( - self.waterstorageconfig.water_mass_flow_rate_from_hds_in_kg_per_second - ) - if SingletonSimRepository().exist_entry(key=SingletonDictKeyEnum.WATERMASSFLOWRATEOFHEATGENERATOR): self.water_mass_flow_rate_from_heat_generator_in_kg_per_second_from_singleton_sim_repo = ( SingletonSimRepository().get_entry(key=SingletonDictKeyEnum.WATERMASSFLOWRATEOFHEATGENERATOR) @@ -213,6 +217,7 @@ def __init__( else: self.water_mass_flow_rate_from_heat_generator_in_kg_per_second_from_singleton_sim_repo = None + self.position_of_storage_in_system = self.waterstorageconfig.position_of_storage_in_system self.build(heat_exchanger_is_present=self.waterstorageconfig.heat_exchanger_is_present) self.state: SimpleHotWaterStorageState = SimpleHotWaterStorageState( @@ -231,21 +236,31 @@ def __init__( lt.Units.CELSIUS, True, ) - self.water_temperature_heat_generator_input_channel: ComponentInput = self.add_input( - self.component_name, - self.WaterTemperatureFromHeatGenerator, - lt.LoadTypes.TEMPERATURE, - lt.Units.CELSIUS, - True, - ) - self.water_mass_flow_rate_heat_generator_input_channel: ComponentInput = self.add_input( + self.water_mass_flow_rate_heat_distribution_system_input_channel: ComponentInput = self.add_input( self.component_name, - self.WaterMassFlowRateFromHeatGenerator, + self.WaterMassFlowRateFromHeatDistributionSystem, lt.LoadTypes.WARM_WATER, lt.Units.KG_PER_SEC, False, ) + if self.position_of_storage_in_system == PositionWaterStorageInSystemEnum.PARALLEL_TO_HEAT_PUMP: + self.water_temperature_heat_generator_input_channel: ComponentInput = self.add_input( + self.component_name, + self.WaterTemperatureFromHeatGenerator, + lt.LoadTypes.TEMPERATURE, + lt.Units.CELSIUS, + True, + ) + + self.water_mass_flow_rate_heat_generator_input_channel: ComponentInput = self.add_input( + self.component_name, + self.WaterMassFlowRateFromHeatGenerator, + lt.LoadTypes.WARM_WATER, + lt.Units.KG_PER_SEC, + False, + ) + self.state_channel: cp.ComponentInput = self.add_input( self.component_name, self.State, lt.LoadTypes.ANY, lt.Units.ANY, False ) @@ -337,6 +352,13 @@ def get_default_connections_from_heat_distribution_system( component_class.WaterTemperatureOutput, ) ) + connections.append( + cp.ComponentConnection( + SimpleHotWaterStorage.WaterMassFlowRateFromHeatDistributionSystem, + hds_classname, + component_class.WaterMassFlowHDS, + ) + ) return connections def get_default_connections_from_advanced_heat_pump( @@ -421,19 +443,28 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc water_temperature_from_heat_distribution_system_in_celsius = stsv.get_input_value( self.water_temperature_heat_distribution_system_input_channel ) - water_temperature_from_heat_generator_in_celsius = stsv.get_input_value( - self.water_temperature_heat_generator_input_channel + + water_mass_flow_rate_from_hds_in_kg_per_second = stsv.get_input_value( + self.water_mass_flow_rate_heat_distribution_system_input_channel ) - # get water mass flow rate of heat generator either from singleton sim repo or from input value - if self.water_mass_flow_rate_from_heat_generator_in_kg_per_second_from_singleton_sim_repo is not None: - water_mass_flow_rate_from_heat_generator_in_kg_per_second = ( - self.water_mass_flow_rate_from_heat_generator_in_kg_per_second_from_singleton_sim_repo + if self.position_of_storage_in_system == PositionWaterStorageInSystemEnum.PARALLEL_TO_HEAT_PUMP: + water_temperature_from_heat_generator_in_celsius = stsv.get_input_value( + self.water_temperature_heat_generator_input_channel ) + + # get water mass flow rate of heat generator either from singleton sim repo or from input value + if self.water_mass_flow_rate_from_heat_generator_in_kg_per_second_from_singleton_sim_repo is not None: + water_mass_flow_rate_from_heat_generator_in_kg_per_second = ( + self.water_mass_flow_rate_from_heat_generator_in_kg_per_second_from_singleton_sim_repo + ) + else: + water_mass_flow_rate_from_heat_generator_in_kg_per_second = stsv.get_input_value( + self.water_mass_flow_rate_heat_generator_input_channel + ) else: - water_mass_flow_rate_from_heat_generator_in_kg_per_second = stsv.get_input_value( - self.water_mass_flow_rate_heat_generator_input_channel - ) + water_temperature_from_heat_generator_in_celsius = 0 + water_mass_flow_rate_from_heat_generator_in_kg_per_second = 0 # Water Temperature Limit Check -------------------------------------------------------------------------------------------------------- @@ -454,7 +485,7 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc water_mass_from_heat_distribution_system_in_kg, ) = self.calculate_masses_of_water_flows( water_mass_flow_rate_from_heat_generator_in_kg_per_second=water_mass_flow_rate_from_heat_generator_in_kg_per_second, - water_mass_flow_rate_from_heat_distribution_system_in_kg_per_second=self.water_mass_flow_rate_from_heat_distribution_system_in_kg_per_second, + water_mass_flow_rate_from_heat_distribution_system_in_kg_per_second=water_mass_flow_rate_from_hds_in_kg_per_second, seconds_per_timestep=self.seconds_per_timestep, ) @@ -537,11 +568,11 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc raise ValueError("unknown storage controller state.") # Set outputs ------------------------------------------------------------------------------------------------------- - - stsv.set_output_value( - self.water_temperature_heat_distribution_system_output_channel, - water_temperature_to_heat_distribution_system_in_celsius, - ) + if self.position_of_storage_in_system == PositionWaterStorageInSystemEnum.PARALLEL_TO_HEAT_PUMP: + stsv.set_output_value( + self.water_temperature_heat_distribution_system_output_channel, + water_temperature_to_heat_distribution_system_in_celsius, + ) stsv.set_output_value( self.water_temperature_heat_generator_output_channel, diff --git a/hisim/postprocessing/compute_kpis.py b/hisim/postprocessing/compute_kpis.py index 4a5fc4fd..c68c1e8e 100644 --- a/hisim/postprocessing/compute_kpis.py +++ b/hisim/postprocessing/compute_kpis.py @@ -19,7 +19,7 @@ from hisim.components.building import Building from hisim.components.loadprofilegenerator_utsp_connector import UtspLpgConnector from hisim.components.more_advanced_heat_pump_hplib import HeatPumpHplibWithTwoOutputs -from hisim.components.simple_hot_water_storage import SimpleHotWaterStorage +# from hisim.components.simple_hot_water_storage import SimpleHotWaterStorage from hisim.components.electricity_meter import ElectricityMeter from hisim.components.generic_heat_pump_modular import ModularHeatPump from hisim.components.controller_l2_energy_management_system import L2GenericEnergyManagementSystem @@ -1288,7 +1288,7 @@ def get_heat_distribution_system_kpis(self, building_conditioned_floor_area_in_m min_temperature_difference_between_flow_and_return_in_celsius, ) = self.get_flow_and_return_temperatures( results=self.results, - output_name_flow_temperature=SimpleHotWaterStorage.WaterTemperatureToHeatDistribution, + output_name_flow_temperature=HeatDistribution.WaterTemperatureInlet, output_name_return_temperature=HeatDistribution.WaterTemperatureOutput, ) @@ -1628,7 +1628,7 @@ def get_space_heating_heat_pump_kpis( ) = self.get_flow_and_return_temperatures( results=self.results, output_name_flow_temperature=HeatPumpHplibWithTwoOutputs.TemperatureOutputSH, - output_name_return_temperature=SimpleHotWaterStorage.WaterTemperatureToHeatGenerator + output_name_return_temperature=HeatPumpHplibWithTwoOutputs.TemperatureInputSH ) break diff --git a/system_setups/automatic_default_connections.py b/system_setups/automatic_default_connections.py index c9a7486b..999cdcbf 100644 --- a/system_setups/automatic_default_connections.py +++ b/system_setups/automatic_default_connections.py @@ -131,7 +131,7 @@ def setup_function(my_sim: Any, my_simulation_parameters: Optional[SimulationPar # Build Heat Distribution System my_heat_distribution_system_config = heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) my_heat_distribution_system = heat_distribution_system.HeatDistribution( config=my_heat_distribution_system_config, @@ -143,7 +143,6 @@ def setup_function(my_sim: Any, my_simulation_parameters: Optional[SimulationPar max_thermal_power_in_watt_of_heating_system=my_building_information.max_thermal_building_demand_in_watt, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) my_simple_hot_water_storage = simple_hot_water_storage.SimpleHotWaterStorage( config=my_simple_heat_water_storage_config, diff --git a/system_setups/household_1_advanced_hp_diesel_car.py b/system_setups/household_1_advanced_hp_diesel_car.py index 5e3f9509..8772f480 100644 --- a/system_setups/household_1_advanced_hp_diesel_car.py +++ b/system_setups/household_1_advanced_hp_diesel_car.py @@ -136,8 +136,8 @@ def get_scaled_default( hds_controller_config=hds_controller_config, hds_config=( heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) ), hp_controller_config=advanced_heat_pump_hplib.HeatPumpHplibControllerL1Config.get_default_generic_heat_pump_controller_config( @@ -151,7 +151,6 @@ def get_scaled_default( max_thermal_power_in_watt_of_heating_system=my_building_information.max_thermal_building_demand_in_watt, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ), dhw_heatpump_config=generic_heat_pump_modular.HeatPumpConfig.get_scaled_waterheating_to_number_of_apartments( number_of_apartments=int(my_building_information.number_of_apartments) diff --git a/system_setups/household_1b_more_advanced_hp_diesel_car.py b/system_setups/household_1b_more_advanced_hp_diesel_car.py index c53ed334..e953858e 100644 --- a/system_setups/household_1b_more_advanced_hp_diesel_car.py +++ b/system_setups/household_1b_more_advanced_hp_diesel_car.py @@ -133,8 +133,8 @@ def get_scaled_default( hds_controller_config=hds_controller_config, hds_config=( heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) ), sh_controller_config=more_advanced_heat_pump_hplib.HeatPumpHplibControllerSpaceHeatingConfig.get_default_space_heating_controller_config( @@ -151,7 +151,6 @@ def get_scaled_default( max_thermal_power_in_watt_of_heating_system=my_building_information.max_thermal_building_demand_in_watt, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ), dhw_heatpump_controller_config=more_advanced_heat_pump_hplib.HeatPumpHplibControllerDHWConfig.get_default_dhw_controller_config(), dhw_storage_config=generic_hot_water_storage_modular.StorageConfig.get_scaled_config_for_boiler_to_number_of_apartments( @@ -357,7 +356,7 @@ def setup_function( ################################# my_heat_distribution_controller.connect_only_predefined_connections( - my_weather, my_building, my_hot_water_storage + my_weather, my_building ) my_heat_distribution.connect_only_predefined_connections( diff --git a/system_setups/household_1c_more_advanced_hp_dhw_hp_diesel_car.py b/system_setups/household_1c_more_advanced_hp_dhw_hp_diesel_car.py index 8abddce0..18e8492f 100644 --- a/system_setups/household_1c_more_advanced_hp_dhw_hp_diesel_car.py +++ b/system_setups/household_1c_more_advanced_hp_dhw_hp_diesel_car.py @@ -33,6 +33,7 @@ from system_setups.modular_example import cleanup_old_lpg_requests + __authors__ = ["Markus Blasberg", "Kevin Knosala"] __copyright__ = "Copyright 2023, FZJ-IEK-3" __credits__ = ["Noah Pflugradt"] @@ -138,8 +139,8 @@ def get_scaled_default( hds_controller_config=hds_controller_config, hds_config=( heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) ), hp_controller_config=more_advanced_heat_pump_hplib.HeatPumpHplibControllerSpaceHeatingConfig.get_default_space_heating_controller_config( @@ -157,7 +158,6 @@ def get_scaled_default( max_thermal_power_in_watt_of_heating_system=my_building_information.max_thermal_building_demand_in_watt, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ), dhw_heatpump_config=generic_heat_pump_modular.HeatPumpConfig.get_scaled_waterheating_to_number_of_apartments( number_of_apartments=int(my_building_information.number_of_apartments) diff --git a/system_setups/household_1d_more_advanced_hp_dhw_hp_no_hot_water_storage.py b/system_setups/household_1d_more_advanced_hp_dhw_hp_no_hot_water_storage.py new file mode 100644 index 00000000..cc325f88 --- /dev/null +++ b/system_setups/household_1d_more_advanced_hp_dhw_hp_no_hot_water_storage.py @@ -0,0 +1,432 @@ +""" Household system setup with more advanced heat pump, dhw heat pump and diesel car. """ + +# clean + +from typing import List, Optional, Any +from pathlib import Path +from dataclasses import dataclass +from os import listdir +from utspclient.helpers.lpgdata import ( + ChargingStationSets, + Households, + TransportationDeviceSets, + TravelRouteSets, + EnergyIntensityType, +) + +from hisim import loadtypes as lt +from hisim.simulator import SimulationParameters +from hisim.components import loadprofilegenerator_utsp_connector +from hisim.components import weather +from hisim.components import more_advanced_heat_pump_hplib +from hisim.components import heat_distribution_system +from hisim.components import building +from hisim.components import generic_car +from hisim.components import generic_heat_pump_modular +from hisim.components import controller_l1_heatpump +from hisim.components import generic_hot_water_storage_modular +from hisim.components import electricity_meter +from hisim.components.configuration import HouseholdWarmWaterDemandConfig +from hisim.system_setup_configuration import SystemSetupConfigBase +from hisim import utils +from hisim.units import Quantity, Watt, Celsius, Seconds, KilogramPerSecond + +from system_setups.modular_example import cleanup_old_lpg_requests + + +__authors__ = ["Jonas Hoppe"] +__copyright__ = "" +__credits__ = [" "] +__license__ = "" +__version__ = "" +__maintainer__ = " " +__status__ = "" + + +@dataclass +class HouseholdMoreAdvancedHPDHWHPNoStorageOptions: + """Set options for the system setup.""" + + pass + + +@dataclass +class HouseholdMoreAdvancedHPDHWHPNoStorageConfig(SystemSetupConfigBase): + """Configuration for with advanced heat pump and diesel car.""" + + building_type: str + number_of_apartments: int + occupancy_config: loadprofilegenerator_utsp_connector.UtspLpgConnectorConfig + building_config: building.BuildingConfig + hds_controller_config: heat_distribution_system.HeatDistributionControllerConfig + hds_config: heat_distribution_system.HeatDistributionConfig + hp_controller_config: more_advanced_heat_pump_hplib.HeatPumpHplibControllerSpaceHeatingConfig + hp_config: more_advanced_heat_pump_hplib.HeatPumpHplibWithTwoOutputsConfig + dhw_heatpump_config: generic_heat_pump_modular.HeatPumpConfig + dhw_heatpump_controller_config: controller_l1_heatpump.L1HeatPumpConfig + dhw_storage_config: generic_hot_water_storage_modular.StorageConfig + car_config: generic_car.CarConfig + electricity_meter_config: electricity_meter.ElectricityMeterConfig + + @classmethod + def get_default_options(cls): + """Get default options.""" + return HouseholdMoreAdvancedHPDHWHPNoStorageOptions() + + @classmethod + def get_default(cls) -> "HouseholdMoreAdvancedHPDHWHPNoStorageConfig": + """Get default HouseholdAdvancedHPDieselCarConfig.""" + + heating_reference_temperature_in_celsius: float = -7 + + building_config = building.BuildingConfig.get_default_german_single_family_home( + heating_reference_temperature_in_celsius=heating_reference_temperature_in_celsius + ) + + household_config = cls.get_scaled_default(building_config) + + household_config.hp_config.set_thermal_output_power_in_watt = Quantity( + 6000, Watt # default value leads to switching on-off very often + ) + household_config.hp_config.with_domestic_hot_water_preparation = False + + household_config.dhw_storage_config.volume = 250 # default(volume = 230) leads to an error + + return household_config + + @classmethod + def get_scaled_default( + cls, + building_config: building.BuildingConfig, + options: HouseholdMoreAdvancedHPDHWHPNoStorageOptions = HouseholdMoreAdvancedHPDHWHPNoStorageOptions(), + ) -> "HouseholdMoreAdvancedHPDHWHPNoStorageConfig": + """Get scaled default HouseholdAdvancedHPDieselCarConfig.""" + + set_heating_threshold_outside_temperature_in_celsius: float = 16.0 + + my_building_information = building.BuildingInformation(config=building_config) + + hds_controller_config = heat_distribution_system.HeatDistributionControllerConfig.get_default_heat_distribution_controller_config( + set_heating_temperature_for_building_in_celsius=my_building_information.set_heating_temperature_for_building_in_celsius, + set_cooling_temperature_for_building_in_celsius=my_building_information.set_cooling_temperature_for_building_in_celsius, + heating_load_of_building_in_watt=my_building_information.max_thermal_building_demand_in_watt, + heating_reference_temperature_in_celsius=my_building_information.heating_reference_temperature_in_celsius, + ) + my_hds_controller_information = heat_distribution_system.HeatDistributionControllerInformation( + config=hds_controller_config + ) + household_config = HouseholdMoreAdvancedHPDHWHPNoStorageConfig( + building_type="blub", + number_of_apartments=int(my_building_information.number_of_apartments), + occupancy_config=loadprofilegenerator_utsp_connector.UtspLpgConnectorConfig( + data_acquisition_mode=loadprofilegenerator_utsp_connector.LpgDataAcquisitionMode.USE_UTSP, + household=Households.CHR01_Couple_both_at_Work, + energy_intensity=EnergyIntensityType.EnergySaving, + result_dir_path=utils.HISIMPATH["utsp_results"], + travel_route_set=TravelRouteSets.Travel_Route_Set_for_10km_Commuting_Distance, + transportation_device_set=TransportationDeviceSets.Bus_and_one_30_km_h_Car, + charging_station_set=ChargingStationSets.Charging_At_Home_with_11_kW, + name="UTSPConnector", + consumption=0.0, + profile_with_washing_machine_and_dishwasher=True, + predictive_control=False, + predictive=False, + ), + building_config=building_config, + hds_controller_config=hds_controller_config, + hds_config=( + heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( + water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2, + position_hot_water_storage_in_system=3, + ) + ), + hp_controller_config=more_advanced_heat_pump_hplib.HeatPumpHplibControllerSpaceHeatingConfig.get_default_space_heating_controller_config( + heat_distribution_system_type=my_hds_controller_information.heat_distribution_system_type, + upper_temperature_offset_for_state_conditions_in_celsius=10, + lower_temperature_offset_for_state_conditions_in_celsius=0, + ), + hp_config=more_advanced_heat_pump_hplib.HeatPumpHplibWithTwoOutputsConfig.get_scaled_advanced_hp_lib( + heating_load_of_building_in_watt=Quantity( + my_building_information.max_thermal_building_demand_in_watt, Watt + ), + heating_reference_temperature_in_celsius=Quantity( + my_building_information.heating_reference_temperature_in_celsius, Celsius + ), + massflow_nominal_secondary_side_in_kg_per_s=Quantity(0.333, KilogramPerSecond), + minimum_thermal_output_power_in_watt=Quantity(1700, Watt), + ), + dhw_heatpump_config=generic_heat_pump_modular.HeatPumpConfig.get_scaled_waterheating_to_number_of_apartments( + number_of_apartments=int(my_building_information.number_of_apartments) + ), + dhw_heatpump_controller_config=controller_l1_heatpump.L1HeatPumpConfig.get_default_config_heat_source_controller_dhw( + name="DHWHeatpumpController" + ), + dhw_storage_config=generic_hot_water_storage_modular.StorageConfig.get_scaled_config_for_boiler_to_number_of_apartments( + number_of_apartments=int(my_building_information.number_of_apartments) + ), + car_config=generic_car.CarConfig.get_default_diesel_config(), + electricity_meter_config=electricity_meter.ElectricityMeterConfig.get_electricity_meter_default_config(), + ) + + # adjust HeatPump + household_config.hp_config.group_id = 1 # use modulating heatpump as default + household_config.hp_controller_config.mode = 2 # use heating and cooling as default + household_config.hp_config.minimum_idle_time_in_seconds = Quantity( + 900, Seconds # default value leads to switching on-off very often + ) + household_config.hp_config.minimum_running_time_in_seconds = Quantity( + 900, Seconds # default value leads to switching on-off very often + ) + household_config.hp_config.with_domestic_hot_water_preparation = False + household_config.hp_config.position_hot_water_storage_in_system = 3 + household_config.hp_config.cycling_mode = False + + # set same heating threshold + household_config.hds_controller_config.set_heating_threshold_outside_temperature_in_celsius = ( + set_heating_threshold_outside_temperature_in_celsius + ) + household_config.hds_config.with_hot_water_storage = False + household_config.hp_controller_config.set_heating_threshold_outside_temperature_in_celsius = ( + set_heating_threshold_outside_temperature_in_celsius + ) + + household_config.hp_config.flow_temperature_in_celsius = Quantity(35, Celsius) # Todo: check value + + return household_config + + +def setup_function( + my_sim: Any, + my_simulation_parameters: Optional[SimulationParameters] = None, +) -> None: # noqa: too-many-statements + """System setup with advanced hp and diesel car. + + This setup function emulates a household with some basic components. Here the residents have their + electricity and heating needs covered by a the advanced heat pump. + + - Simulation Parameters + - Components + - Occupancy (Residents' Demands) + - Weather + - Building + - Electricity Meter + - Advanced Heat Pump HPlib + - Advanced Heat Pump HPlib Controller + - Heat Distribution System + - Heat Distribution System Controller + - Simple Hot Water Storage + + - DHW (Heatpump, Heatpumpcontroller, Storage; copied from modular_example) + - Car (Diesel) + """ + + # cleanup old lpg requests, mandatory to change number of cars + # Todo: change cleanup-function if result_path from occupancy is not utils.HISIMPATH["results"] + if Path(utils.HISIMPATH["utsp_results"]).exists(): + cleanup_old_lpg_requests() + else: + Path(utils.HISIMPATH["utsp_results"]).mkdir(parents=False, exist_ok=False) + + if my_sim.my_module_config: + my_config = HouseholdMoreAdvancedHPDHWHPNoStorageConfig.load_from_json(my_sim.my_module_config) + else: + my_config = HouseholdMoreAdvancedHPDHWHPNoStorageConfig.get_default() + + # Todo: save file leads to use of file in next run. File was just produced to check how it looks like + # my_config_json = my_config.to_json() + # with open(config_filename, "w", encoding="utf8") as system_config_file: + # system_config_file.write(my_config_json) + + # ================================================================================================================================= + # Set System Parameters + + # Set Simulation Parameters + year = 2021 + seconds_per_timestep = 60 + + # ================================================================================================================================= + # Build Components + + # Build Simulation Parameters + if my_simulation_parameters is None: + my_simulation_parameters = SimulationParameters.one_week_with_only_plots( + year=year, seconds_per_timestep=seconds_per_timestep + ) + my_sim.set_simulation_parameters(my_simulation_parameters) + + # Build heat Distribution System Controller + my_heat_distribution_controller = heat_distribution_system.HeatDistributionController( + config=my_config.hds_controller_config, + my_simulation_parameters=my_simulation_parameters, + ) + + # Build Occupancy + my_occupancy_config = my_config.occupancy_config + my_occupancy = loadprofilegenerator_utsp_connector.UtspLpgConnector( + config=my_occupancy_config, my_simulation_parameters=my_simulation_parameters + ) + + # Build Weather + my_weather = weather.Weather( + config=weather.WeatherConfig.get_default(weather.LocationEnum.AACHEN), + my_simulation_parameters=my_simulation_parameters, + ) + + # Build Building + my_building = building.Building( + config=my_config.building_config, + my_simulation_parameters=my_simulation_parameters, + ) + + # Build Heat Distribution System + my_heat_distribution = heat_distribution_system.HeatDistribution( + my_simulation_parameters=my_simulation_parameters, config=my_config.hds_config + ) + + # Build Heat Pump Controller + my_heat_pump_controller_config = my_config.hp_controller_config + my_heat_pump_controller_config.name = "HeatPumpHplibController" + + my_heat_pump_controller = more_advanced_heat_pump_hplib.HeatPumpHplibControllerSpaceHeating( + config=my_heat_pump_controller_config, + my_simulation_parameters=my_simulation_parameters, + ) + + # Build Heat Pump + my_heat_pump_config = my_config.hp_config + my_heat_pump_config.name = "HeatPumpHPLib" + + my_heat_pump = more_advanced_heat_pump_hplib.HeatPumpHplibWithTwoOutputs( + config=my_heat_pump_config, + my_simulation_parameters=my_simulation_parameters, + ) + + # Build DHW + my_dhw_heatpump_config = my_config.dhw_heatpump_config + my_dhw_heatpump_config.power_th = ( + my_occupancy.max_hot_water_demand + * (4180 / 3600) + * 0.5 + * (3600 / my_simulation_parameters.seconds_per_timestep) + * (HouseholdWarmWaterDemandConfig.ww_temperature_demand - HouseholdWarmWaterDemandConfig.freshwater_temperature) + ) + + my_dhw_heatpump_controller_config = my_config.dhw_heatpump_controller_config + + my_dhw_storage_config = my_config.dhw_storage_config + my_dhw_storage_config.name = "DHWStorage" + my_dhw_storage_config.compute_default_cycle( + temperature_difference_in_kelvin=my_dhw_heatpump_controller_config.t_max_heating_in_celsius + - my_dhw_heatpump_controller_config.t_min_heating_in_celsius + ) + + my_domnestic_hot_water_storage = generic_hot_water_storage_modular.HotWaterStorage( + my_simulation_parameters=my_simulation_parameters, config=my_dhw_storage_config + ) + + my_domnestic_hot_water_heatpump_controller = controller_l1_heatpump.L1HeatPumpController( + my_simulation_parameters=my_simulation_parameters, + config=my_dhw_heatpump_controller_config, + ) + + my_domnestic_hot_water_heatpump = generic_heat_pump_modular.ModularHeatPump( + config=my_dhw_heatpump_config, my_simulation_parameters=my_simulation_parameters + ) + + # Build Diesel-Car(s) + # get names of all available cars + filepaths = listdir(utils.HISIMPATH["utsp_results"]) + filepaths_location = [elem for elem in filepaths if "CarLocation." in elem] + names = [elem.partition(",")[0].partition(".")[2] for elem in filepaths_location] + + my_car_config = my_config.car_config + my_car_config.name = "DieselCar" + + # create all cars + my_cars: List[generic_car.Car] = [] + for car in names: + my_car_config.name = car + my_cars.append( + generic_car.Car( + my_simulation_parameters=my_simulation_parameters, + config=my_car_config, + occupancy_config=my_occupancy_config, + ) + ) + + # Build Electricity Meter + my_electricity_meter = electricity_meter.ElectricityMeter( + my_simulation_parameters=my_simulation_parameters, + config=my_config.electricity_meter_config, + ) + + my_heat_pump.connect_only_predefined_connections(my_heat_pump_controller, my_weather) + + # Verknüpfung mit Luft als Umgebungswärmequelle + if my_heat_pump.parameters["Group"].iloc[0] == 1.0 or my_heat_pump.parameters["Group"].iloc[0] == 4.0: + my_heat_pump.connect_input( + my_heat_pump.TemperatureInputPrimary, + my_weather.component_name, + my_weather.DailyAverageOutsideTemperatures, + ) + else: + raise KeyError("Water/Water HP or Brine/Water HP will follow.") + + my_heat_pump_controller.connect_only_predefined_connections(my_heat_distribution_controller, my_weather) + + my_heat_pump_controller.connect_input( + my_heat_pump_controller.WaterTemperatureInput, + my_heat_distribution.component_name, + my_heat_distribution.WaterTemperatureOutput, + ) + + my_heat_pump.connect_input( + my_heat_pump.SetHeatingTemperatureSpaceHeating, + my_heat_distribution_controller.component_name, + my_heat_distribution_controller.HeatingFlowTemperature, + ) + + my_heat_pump.connect_input( + my_heat_pump.TemperatureInputSecondary_SH, + my_heat_distribution.component_name, + my_heat_distribution.WaterTemperatureOutput, + ) + + my_heat_distribution.connect_input( + my_heat_distribution.WaterTemperatureInput, + my_heat_pump.component_name, + my_heat_pump.TemperatureOutputSH, + ) + + my_heat_distribution.connect_input( + my_heat_distribution.WaterMassFlow, + my_heat_pump.component_name, + my_heat_pump.MassFlowOutputSH, + ) + + my_electricity_meter.add_component_input_and_connect( + source_object_name=my_heat_pump.component_name, + source_component_output=my_heat_pump.ElectricalInputPowerTotal, + source_load_type=lt.LoadTypes.ELECTRICITY, + source_unit=lt.Units.WATT, + source_tags=[ + lt.InandOutputType.ELECTRICITY_CONSUMPTION_UNCONTROLLED, + ], + source_weight=999, + ) + # ================================================================================================================================= + # Add Components to Simulation Parameters + my_sim.add_component(my_occupancy) + my_sim.add_component(my_weather) + my_sim.add_component(my_building, connect_automatically=True) + my_sim.add_component(my_heat_pump) + my_sim.add_component(my_heat_pump_controller) + my_sim.add_component(my_heat_distribution, connect_automatically=True) + my_sim.add_component(my_heat_distribution_controller, connect_automatically=True) + my_sim.add_component(my_domnestic_hot_water_storage, connect_automatically=True) + my_sim.add_component(my_domnestic_hot_water_heatpump_controller, connect_automatically=True) + my_sim.add_component(my_domnestic_hot_water_heatpump, connect_automatically=True) + my_sim.add_component(my_electricity_meter, connect_automatically=True) + for my_car in my_cars: + my_sim.add_component(my_car) diff --git a/system_setups/household_2_advanced_hp_diesel_car_pv.py b/system_setups/household_2_advanced_hp_diesel_car_pv.py index 66fe55d5..2c1a4d99 100644 --- a/system_setups/household_2_advanced_hp_diesel_car_pv.py +++ b/system_setups/household_2_advanced_hp_diesel_car_pv.py @@ -128,8 +128,8 @@ def get_default(cls): hds_controller_config=hds_controller_config, hds_config=( heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) ), hp_controller_config=advanced_heat_pump_hplib.HeatPumpHplibControllerL1Config.get_default_generic_heat_pump_controller_config( @@ -148,7 +148,6 @@ def get_default(cls): max_thermal_power_in_watt_of_heating_system=my_building_information.max_thermal_building_demand_in_watt, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) ), dhw_heatpump_config=( diff --git a/system_setups/household_3_advanced_hp_diesel_car_pv_battery.py b/system_setups/household_3_advanced_hp_diesel_car_pv_battery.py index e1d5e39d..81a7eb47 100644 --- a/system_setups/household_3_advanced_hp_diesel_car_pv_battery.py +++ b/system_setups/household_3_advanced_hp_diesel_car_pv_battery.py @@ -130,8 +130,8 @@ def get_default(cls): hds_controller_config=hds_controller_config, hds_config=( heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) ), hp_controller_config=advanced_heat_pump_hplib.HeatPumpHplibControllerL1Config.get_default_generic_heat_pump_controller_config( @@ -148,7 +148,6 @@ def get_default(cls): max_thermal_power_in_watt_of_heating_system=my_building_information.max_thermal_building_demand_in_watt, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) ), dhw_heatpump_config=( diff --git a/system_setups/household_4a_with_car_priority_advanced_hp_ev_pv.py b/system_setups/household_4a_with_car_priority_advanced_hp_ev_pv.py index cb31b15c..3e025e9a 100644 --- a/system_setups/household_4a_with_car_priority_advanced_hp_ev_pv.py +++ b/system_setups/household_4a_with_car_priority_advanced_hp_ev_pv.py @@ -134,8 +134,8 @@ def get_default(cls): hds_controller_config=hds_controller_config, hds_config=( heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) ), hp_controller_config=advanced_heat_pump_hplib.HeatPumpHplibControllerL1Config.get_default_generic_heat_pump_controller_config( @@ -152,7 +152,6 @@ def get_default(cls): max_thermal_power_in_watt_of_heating_system=my_building_information.max_thermal_building_demand_in_watt, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) ), dhw_heatpump_config=( diff --git a/system_setups/household_5a_with_car_priority_advanced_hp_ev_pv_battery.py b/system_setups/household_5a_with_car_priority_advanced_hp_ev_pv_battery.py index aaf0ec67..0a7562a7 100644 --- a/system_setups/household_5a_with_car_priority_advanced_hp_ev_pv_battery.py +++ b/system_setups/household_5a_with_car_priority_advanced_hp_ev_pv_battery.py @@ -138,8 +138,8 @@ def get_default(cls): hds_controller_config=hds_controller_config, hds_config=( heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) ), hp_controller_config=advanced_heat_pump_hplib.HeatPumpHplibControllerL1Config.get_default_generic_heat_pump_controller_config( @@ -156,7 +156,6 @@ def get_default(cls): max_thermal_power_in_watt_of_heating_system=my_building_information.max_thermal_building_demand_in_watt, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) ), dhw_heatpump_config=( diff --git a/system_setups/household_cluster_advanced_hp_pv_battery_ems.py b/system_setups/household_cluster_advanced_hp_pv_battery_ems.py index 429c8147..550186fd 100644 --- a/system_setups/household_cluster_advanced_hp_pv_battery_ems.py +++ b/system_setups/household_cluster_advanced_hp_pv_battery_ems.py @@ -243,8 +243,8 @@ def setup_function( # Build Heat Distribution System my_heat_distribution_system_config = heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) my_heat_distribution_system = heat_distribution_system.HeatDistribution( config=my_heat_distribution_system_config, my_simulation_parameters=my_simulation_parameters, @@ -257,7 +257,6 @@ def setup_function( max_thermal_power_in_watt_of_heating_system=my_heat_pump_config.set_thermal_output_power_in_watt.value, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) my_simple_hot_water_storage = simple_hot_water_storage.SimpleHotWaterStorage( config=my_simple_heat_water_storage_config, my_simulation_parameters=my_simulation_parameters, diff --git a/system_setups/household_cluster_reference_advanced_hp.py b/system_setups/household_cluster_reference_advanced_hp.py index b59b7d7e..47fad980 100644 --- a/system_setups/household_cluster_reference_advanced_hp.py +++ b/system_setups/household_cluster_reference_advanced_hp.py @@ -245,8 +245,8 @@ def setup_function( # Build Heat Distribution System my_heat_distribution_system_config = heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) my_heat_distribution_system = heat_distribution_system.HeatDistribution( config=my_heat_distribution_system_config, my_simulation_parameters=my_simulation_parameters, @@ -256,7 +256,6 @@ def setup_function( max_thermal_power_in_watt_of_heating_system=my_heat_pump_config.set_thermal_output_power_in_watt.value, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) my_simple_hot_water_storage = simple_hot_water_storage.SimpleHotWaterStorage( config=my_simple_heat_water_storage_config, my_simulation_parameters=my_simulation_parameters, diff --git a/system_setups/household_gas_heater.py b/system_setups/household_gas_heater.py index 01230383..6ff5289a 100644 --- a/system_setups/household_gas_heater.py +++ b/system_setups/household_gas_heater.py @@ -153,8 +153,8 @@ def get_scaled_default( hds_controller_config=hds_controller_config, hds_config=( heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) ), gas_heater_controller_config=( @@ -169,7 +169,6 @@ def get_scaled_default( simple_hot_water_storage.SimpleHotWaterStorageConfig.get_scaled_hot_water_storage( max_thermal_power_in_watt_of_heating_system=my_building_information.max_thermal_building_demand_in_watt, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_GENERAL_HEATING_SYSTEM, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) ), dhw_heatpump_config=( diff --git a/system_setups/household_heat_pump.py b/system_setups/household_heat_pump.py index d6ac2433..a100858e 100644 --- a/system_setups/household_heat_pump.py +++ b/system_setups/household_heat_pump.py @@ -163,8 +163,8 @@ def get_scaled_default( hds_controller_config=hds_controller_config, hds_config=( heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) ), hp_controller_config=advanced_heat_pump_hplib.HeatPumpHplibControllerL1Config.get_default_generic_heat_pump_controller_config( @@ -185,7 +185,6 @@ def get_scaled_default( simple_hot_water_storage.SimpleHotWaterStorageConfig.get_scaled_hot_water_storage( max_thermal_power_in_watt_of_heating_system=my_building_information.max_thermal_building_demand_in_watt, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) ), dhw_heatpump_config=( diff --git a/system_setups/household_hp_hws_hds_pv_battery_ems.py b/system_setups/household_hp_hws_hds_pv_battery_ems.py index e9b3c2ef..3014db49 100644 --- a/system_setups/household_hp_hws_hds_pv_battery_ems.py +++ b/system_setups/household_hp_hws_hds_pv_battery_ems.py @@ -145,8 +145,8 @@ def setup_function( # Build Heat Distribution System my_heat_distribution_system_config = heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) my_heat_distribution_system = heat_distribution_system.HeatDistribution( config=my_heat_distribution_system_config, @@ -158,7 +158,6 @@ def setup_function( max_thermal_power_in_watt_of_heating_system=my_heat_pump_config.set_thermal_output_power_in_watt.value, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) my_simple_hot_water_storage = simple_hot_water_storage.SimpleHotWaterStorage( config=my_simple_heat_water_storage_config, diff --git a/system_setups/household_reference_gas_heater_diesel_car.py b/system_setups/household_reference_gas_heater_diesel_car.py index 2732a4f8..8b716ab6 100644 --- a/system_setups/household_reference_gas_heater_diesel_car.py +++ b/system_setups/household_reference_gas_heater_diesel_car.py @@ -107,8 +107,8 @@ def get_default(cls): hds_controller_config=hds_controller_config, hds_config=( heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) ), gasheater_controller_config=( @@ -123,7 +123,6 @@ def get_default(cls): simple_hot_water_storage.SimpleHotWaterStorageConfig.get_scaled_hot_water_storage( max_thermal_power_in_watt_of_heating_system=my_building_information.max_thermal_building_demand_in_watt, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_GENERAL_HEATING_SYSTEM, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) ), dhw_heatpump_config=( diff --git a/system_setups/household_with_advanced_hp_hws_hds_pv_battery_ems.py b/system_setups/household_with_advanced_hp_hws_hds_pv_battery_ems.py index cdbe628c..e3dd3467 100644 --- a/system_setups/household_with_advanced_hp_hws_hds_pv_battery_ems.py +++ b/system_setups/household_with_advanced_hp_hws_hds_pv_battery_ems.py @@ -145,8 +145,8 @@ def setup_function( # Build Heat Distribution System my_heat_distribution_system_config = heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) my_heat_distribution_system = heat_distribution_system.HeatDistribution( config=my_heat_distribution_system_config, @@ -158,7 +158,6 @@ def setup_function( max_thermal_power_in_watt_of_heating_system=my_heat_pump_config.set_thermal_output_power_in_watt.value, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) my_simple_hot_water_storage = simple_hot_water_storage.SimpleHotWaterStorage( config=my_simple_heat_water_storage_config, diff --git a/system_setups/household_with_more_advanced_hp_hws_dhw_hds.py b/system_setups/household_with_more_advanced_hp_hws_dhw_hds.py index 325012a7..62f93b8e 100644 --- a/system_setups/household_with_more_advanced_hp_hws_dhw_hds.py +++ b/system_setups/household_with_more_advanced_hp_hws_dhw_hds.py @@ -155,8 +155,8 @@ def setup_function( # Build Heat Distribution System my_heat_distribution_config = heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) my_heat_distribution = heat_distribution_system.HeatDistribution( @@ -169,7 +169,6 @@ def setup_function( max_thermal_power_in_watt_of_heating_system=my_heatpump_config.set_thermal_output_power_in_watt.value, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) my_hot_water_storage = simple_hot_water_storage.SimpleHotWaterStorage( diff --git a/tests/test_controller_l2_energy_management_system.py b/tests/test_controller_l2_energy_management_system.py index c3696885..6858a427 100644 --- a/tests/test_controller_l2_energy_management_system.py +++ b/tests/test_controller_l2_energy_management_system.py @@ -162,8 +162,8 @@ def test_house( # Build Heat Distribution System my_heat_distribution_system_config = heat_distribution_system.HeatDistributionConfig.get_default_heatdistributionsystem_config( - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) my_heat_distribution_system = heat_distribution_system.HeatDistribution( config=my_heat_distribution_system_config, @@ -177,7 +177,6 @@ def test_house( max_thermal_power_in_watt_of_heating_system=my_heat_pump_config.set_thermal_output_power_in_watt.value, temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, - water_mass_flow_rate_from_hds_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, ) my_simple_hot_water_storage = simple_hot_water_storage.SimpleHotWaterStorage( config=my_simple_heat_water_storage_config, diff --git a/tests/test_heat_distribution_system.py b/tests/test_heat_distribution_system.py index 151a4cee..9545a463 100644 --- a/tests/test_heat_distribution_system.py +++ b/tests/test_heat_distribution_system.py @@ -130,8 +130,9 @@ def simulate_and_calculate_hds_outputs_for_a_given_theoretical_heating_demand_fr cost=8000, lifetime=50, maintenance_cost_as_percentage_of_investment=0.01, - temperature_difference_between_flow_and_return_in_celsius=my_hds_controller_information.temperature_difference_between_flow_and_return_in_celsius, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, + position_hot_water_storage_in_system=1, + absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) my_heat_distribution_system = heat_distribution_system.HeatDistribution( @@ -219,10 +220,10 @@ def simulate_and_calculate_hds_outputs_for_a_given_theoretical_heating_demand_fr # if in hds component the state values are set as output values, # then here the water_temp_output and the thermal_power_delivered should be set, not the stsv.values[4] and [5] water_output_temperature_in_celsius_from_simulation = ( - my_heat_distribution_system.water_temperature_output_in_celsius + my_heat_distribution_system.state.water_output_temperature_in_celsius ) # stsv.values[4] effective_thermal_power_delivered_in_watt = ( - my_heat_distribution_system.thermal_power_delivered_in_watt + my_heat_distribution_system.state.thermal_power_delivered_in_watt ) # stsv.values[5] # Test if water output of hds is correct for different theoretical thermal demands from building diff --git a/tests/test_more_advanced_heat_pump_hplib.py b/tests/test_more_advanced_heat_pump_hplib.py index d884113a..d030c972 100644 --- a/tests/test_more_advanced_heat_pump_hplib.py +++ b/tests/test_more_advanced_heat_pump_hplib.py @@ -11,7 +11,7 @@ from hisim import loadtypes as lt from hisim.simulationparameters import SimulationParameters from hisim import log -from hisim.units import KilowattHour, Quantity, Watt, Celsius, Seconds, Kilogram, Euro, Years +from hisim.units import KilowattHour, Quantity, Watt, Celsius, Seconds, Kilogram, Euro, Years, KilogramPerSecond @pytest.mark.base @@ -58,8 +58,12 @@ def test_heat_pump_hplib_new(): minimum_idle_time_in_seconds=Quantity(600, Seconds), minimum_running_time_in_seconds=Quantity(600, Seconds), temperature_difference_primary_side=2, - with_hot_water_storage=True, + position_hot_water_storage_in_system=1, with_domestic_hot_water_preparation=with_domestic_hot_water_preparation, + minimum_massflow_secondary_side_in_kg_per_s=None, + maximum_massflow_secondary_side_in_kg_per_s=None, + massflow_nominal_secondary_side_in_kg_per_s=Quantity(0.333, KilogramPerSecond), + minimum_thermal_output_power_in_watt=Quantity(3800, Watt), co2_footprint=Quantity(p_th_set.value * 1e-3 * 165.84, Kilogram), cost=Quantity(p_th_set.value * 1e-3 * 1513.74, Euro), lifetime=Quantity(10, Years), @@ -81,6 +85,7 @@ def test_heat_pump_hplib_new(): counter_switch_sh=0, counter_switch_dhw=0, counter_onoff=0, + delta_t=5, ) number_of_outputs = fft.get_number_of_outputs( diff --git a/tests/test_more_advanced_heat_pump_hplib_only_sh.py b/tests/test_more_advanced_heat_pump_hplib_only_sh.py index dd6ea1bc..96954784 100644 --- a/tests/test_more_advanced_heat_pump_hplib_only_sh.py +++ b/tests/test_more_advanced_heat_pump_hplib_only_sh.py @@ -11,7 +11,7 @@ from hisim import loadtypes as lt from hisim.simulationparameters import SimulationParameters from hisim import log -from hisim.units import KilowattHour, Quantity, Watt, Celsius, Seconds, Kilogram, Euro, Years +from hisim.units import KilowattHour, Quantity, Watt, Celsius, Seconds, Kilogram, Euro, Years, KilogramPerSecond @pytest.mark.base @@ -51,8 +51,12 @@ def test_heat_pump_hplib_new(): minimum_idle_time_in_seconds=Quantity(600, Seconds), minimum_running_time_in_seconds=Quantity(600, Seconds), temperature_difference_primary_side=2, - with_hot_water_storage=True, + position_hot_water_storage_in_system=1, with_domestic_hot_water_preparation=with_domestic_hot_water_preparation, + minimum_massflow_secondary_side_in_kg_per_s=None, + maximum_massflow_secondary_side_in_kg_per_s=None, + massflow_nominal_secondary_side_in_kg_per_s=Quantity(0.333, KilogramPerSecond), + minimum_thermal_output_power_in_watt=Quantity(3800, Watt), co2_footprint=Quantity(p_th_set.value * 1e-3 * 165.84, Kilogram), cost=Quantity(p_th_set.value * 1e-3 * 1513.74, Euro), lifetime=Quantity(10, Years), @@ -74,6 +78,7 @@ def test_heat_pump_hplib_new(): counter_switch_sh=0, counter_switch_dhw=0, counter_onoff=0, + delta_t=5, ) number_of_outputs = fft.get_number_of_outputs( diff --git a/tests/test_simple_hot_water_storage.py b/tests/test_simple_hot_water_storage.py index 2ecf7f95..d9e9e5a0 100644 --- a/tests/test_simple_hot_water_storage.py +++ b/tests/test_simple_hot_water_storage.py @@ -41,7 +41,6 @@ def simulate_simple_water_storage( hws_name = "SimpleHeatWaterStorage" volume_heating_water_storage_in_liter = 100 - water_mass_flow_rate_from_heat_distribution_system = 0.787 # =================================================================================================================== # Build Heat Water Storage my_simple_heat_water_storage_config = simple_hot_water_storage.SimpleHotWaterStorageConfig( @@ -49,17 +48,24 @@ def simulate_simple_water_storage( volume_heating_water_storage_in_liter=volume_heating_water_storage_in_liter, heat_transfer_coefficient_in_watt_per_m2_per_kelvin=2.0, heat_exchanger_is_present=False, + position_of_storage_in_system=simple_hot_water_storage.PositionWaterStorageInSystemEnum.PARALLEL_TO_HEAT_PUMP, co2_footprint=100, cost=volume_heating_water_storage_in_liter * 14.51, lifetime=100, maintenance_cost_as_percentage_of_investment=0.0, - water_mass_flow_rate_from_hds_in_kg_per_second=water_mass_flow_rate_from_heat_distribution_system, ) my_simple_heat_water_storage = simple_hot_water_storage.SimpleHotWaterStorage( config=my_simple_heat_water_storage_config, my_simulation_parameters=my_simulation_parameters, ) + water_mass_flow_rate_hds = cp.ComponentOutput( + "FakeWaterInputTemperatureFromHds", + "WaterMassFlowRateFromHeatDistributionSystem", + lt.LoadTypes.WARM_WATER, + lt.Units.KG_PER_SEC, + ) + water_temperature_input_from_heat_distribution_system = cp.ComponentOutput( "FakeWaterInputTemperatureFromHds", "WaterTemperatureInputFromHeatDistributionSystem", @@ -86,6 +92,9 @@ def simulate_simple_water_storage( ) # connect fake inputs to simple hot water storage + my_simple_heat_water_storage.water_mass_flow_rate_heat_distribution_system_input_channel.source_output = ( + water_mass_flow_rate_hds + ) my_simple_heat_water_storage.water_temperature_heat_distribution_system_input_channel.source_output = ( water_temperature_input_from_heat_distribution_system ) @@ -101,6 +110,7 @@ def simulate_simple_water_storage( number_of_outputs = fft.get_number_of_outputs( [ + water_mass_flow_rate_hds, water_temperature_input_from_heat_distribution_system, water_temperature_input_from_heat_generator, water_mass_flow_rate_from_heat_generator, @@ -113,6 +123,7 @@ def simulate_simple_water_storage( # Add Global Index and set values for fake Inputs fft.add_global_index_of_components( [ + water_mass_flow_rate_hds, water_temperature_input_from_heat_distribution_system, water_temperature_input_from_heat_generator, water_mass_flow_rate_from_heat_generator, @@ -120,7 +131,7 @@ def simulate_simple_water_storage( my_simple_heat_water_storage, ] ) - + stsv.values[water_mass_flow_rate_hds.global_index] = 0.787 stsv.values[water_temperature_input_from_heat_distribution_system.global_index] = 48 stsv.values[water_temperature_input_from_heat_generator.global_index] = 52 stsv.values[water_mass_flow_rate_from_heat_generator.global_index] = 0.59 @@ -133,12 +144,13 @@ def simulate_simple_water_storage( previous_mean_temperature_in_celsius = 50.0 my_simple_heat_water_storage.i_simulate(timestep, stsv, False) - water_temperature_output_in_celsius_to_heat_distribution_system = stsv.values[4] - water_temperature_output_in_celsius_to_heat_generator = stsv.values[5] + water_temperature_output_in_celsius_to_heat_distribution_system = stsv.values[5] + water_temperature_output_in_celsius_to_heat_generator = stsv.values[6] # test mean water temperature calculation in storage mass_water_hds_in_kg = ( - water_mass_flow_rate_from_heat_distribution_system * seconds_per_timestep + stsv.values[water_mass_flow_rate_hds.global_index] + * seconds_per_timestep ) mass_water_hp_in_kg = ( stsv.values[water_mass_flow_rate_from_heat_generator.global_index] diff --git a/tests/test_sizing_energy_systems.py b/tests/test_sizing_energy_systems.py index db28c99f..9bd21f74 100644 --- a/tests/test_sizing_energy_systems.py +++ b/tests/test_sizing_energy_systems.py @@ -198,7 +198,6 @@ def simulation_for_one_timestep( my_simple_hot_water_storage_config = simple_hot_water_storage.SimpleHotWaterStorageConfig.get_scaled_hot_water_storage( max_thermal_power_in_watt_of_heating_system=my_hplib_config.set_thermal_output_power_in_watt.value, sizing_option=simple_hot_water_storage.HotWaterStorageSizingEnum.SIZE_ACCORDING_TO_HEAT_PUMP, - water_mass_flow_rate_from_hds_in_kg_per_second=0.787 ) # Set Battery diff --git a/tests/test_system_setups_household_1d_more_advanced_hp_dhw_hp_no_hot_water_storage.py b/tests/test_system_setups_household_1d_more_advanced_hp_dhw_hp_no_hot_water_storage.py new file mode 100644 index 00000000..876d6234 --- /dev/null +++ b/tests/test_system_setups_household_1d_more_advanced_hp_dhw_hp_no_hot_water_storage.py @@ -0,0 +1,28 @@ +""" Tests for the basic household system setup. """ +# clean +import os +from pathlib import Path +import pytest + +from hisim import hisim_main +from hisim.simulationparameters import SimulationParameters +from hisim import log +from hisim import utils +from hisim.postprocessingoptions import PostProcessingOptions + + +# @pytest.mark.system_setups +@pytest.mark.utsp +@utils.measure_execution_time +def test_basic_household(): + """Single day.""" + + config_filename = "household_1d_more_advanced_hp_dhw_hp_no_hot_water_storage.py.json" + if Path(config_filename).is_file(): + os.remove(config_filename) + + path = "../system_setups/household_1d_more_advanced_hp_dhw_hp_no_hot_water_storage.py" + mysimpar = SimulationParameters.one_day_only(year=2019, seconds_per_timestep=60) + mysimpar.post_processing_options.append(PostProcessingOptions.MAKE_NETWORK_CHARTS) + hisim_main.main(path, mysimpar) + log.information(os.getcwd())