From b9713d228c23551f81d2fafaba4155fddc162a8a Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Tue, 9 Apr 2024 17:11:26 +0200 Subject: [PATCH 01/21] optimization of hds model - if no heating storage is implemented (Hp connected directly with hds) the massflow of hds system is calculated by hp model --- hisim/components/heat_distribution_system.py | 90 ++++++++++++++++++-- 1 file changed, 84 insertions(+), 6 deletions(-) diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index c5b53cd6d..cead4a5fc 100644 --- a/hisim/components/heat_distribution_system.py +++ b/hisim/components/heat_distribution_system.py @@ -146,10 +146,14 @@ class HeatDistribution(cp.Component): WaterTemperatureInput = "WaterTemperatureInput" TheoreticalThermalBuildingDemand = "TheoreticalThermalBuildingDemand" ResidenceTemperatureIndoorAir = "ResidenceTemperatureIndoorAir" + WaterMassFlow = "WaterMassFlow" # Outputs + WaterTemperatureInput = "WaterTemperatureInput" WaterTemperatureOutput = "WaterTemperatureOutput" + WaterTemperatureDifference = "WaterTemperatureDifference" ThermalPowerDelivered = "ThermalPowerDelivered" + WaterMassFlow = "WaterMassFlow" # Similar components to connect to: # 1. Building @@ -214,14 +218,37 @@ def __init__( True, ) + #just important for heating system without bufferstorage + self.water_mass_flow_rate_hp_in_kg_per_second_channel: cp.ComponentInput = self.add_input( + self.component_name, + self.WaterMassFlow, + lt.LoadTypes.VOLUME, + lt.Units.KG_PER_SEC, + False, + ) + # 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.WaterTemperatureInput, + lt.LoadTypes.WATER, + lt.Units.CELSIUS, + output_description=f"here a description for {self.WaterTemperatureInput} 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, @@ -229,6 +256,13 @@ 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.WaterMassFlow, + lt.LoadTypes.VOLUME, + lt.Units.KG_PER_SEC, + output_description=f"here a description for {self.WaterMassFlow} will follow.", + ) self.add_default_connections(self.get_default_connections_from_heat_distribution_controller()) self.add_default_connections(self.get_default_connections_from_building()) @@ -339,6 +373,14 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg residence_temperature_input_in_celsius = stsv.get_input_value(self.residence_temperature_input_channel) + water_mass_flow_rate_hp_in_kg_per_second = stsv.get_input_value(self.water_mass_flow_rate_hp_in_kg_per_second_channel) + #just important for heating system without bufferstorage + + if water_mass_flow_rate_hp_in_kg_per_second == 0: + water_mass_flow_rate_in_kg_per_second = self.heating_distribution_system_water_mass_flow_rate_in_kg_per_second + else: + water_mass_flow_rate_in_kg_per_second = water_mass_flow_rate_hp_in_kg_per_second + # if state_controller == 1: if state_controller in (1, -1): ( @@ -346,7 +388,7 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg 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, + 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, ) @@ -360,16 +402,27 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg raise ValueError("unknown hds controller mode") # Set outputs ----------------------------------------------------------------------------------------------------------- - stsv.set_output_value( - self.water_temperature_output_channel, + self.water_temperature_inlet_channel, + water_temperature_input_in_celsius + ) + stsv.set_output_value( + self.water_temperature_outlet_channel, self.state.water_output_temperature_in_celsius - # self.water_temperature_output_in_celsius, + # self.water_temperature_output_in_celsius, + ) + stsv.set_output_value( + self.water_temperature_difference_channel, + water_temperature_input_in_celsius-self.water_temperature_output_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.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 @@ -483,6 +536,8 @@ class HeatDistributionController(cp.Component): # Outputs State = "State" HeatingFlowTemperature = "HeatingFlowTemperature" + HeatingReturnTemperature = "HeatingReturnTemperature" + HeatingTemperatureDifference = "HeatingTemperatureDifference" # Similar components to connect to: # 1. Building @@ -564,6 +619,21 @@ 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.KELVIN, + 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" @@ -726,6 +796,14 @@ 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, From 3feb9e689d530ae20e38a76024132a0ed14a8129 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Wed, 10 Apr 2024 17:07:31 +0200 Subject: [PATCH 02/21] only restructuring and renaming --- hisim/components/heat_distribution_system.py | 91 ++++++++++---------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index cead4a5fc..7b79f380b 100644 --- a/hisim/components/heat_distribution_system.py +++ b/hisim/components/heat_distribution_system.py @@ -77,46 +77,6 @@ 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: HeatDistributionSystemType - 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, - ) -> "HeatDistributionControllerConfig": - """Gets a default HeatDistribution Controller.""" - return HeatDistributionControllerConfig( - name="HeatDistributionController", - heating_system=HeatDistributionSystemType.FLOORHEATING, - 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: @@ -149,11 +109,11 @@ class HeatDistribution(cp.Component): WaterMassFlow = "WaterMassFlow" # Outputs - WaterTemperatureInput = "WaterTemperatureInput" + WaterTemperatureInlet = "WaterTemperatureInlet" WaterTemperatureOutput = "WaterTemperatureOutput" WaterTemperatureDifference = "WaterTemperatureDifference" ThermalPowerDelivered = "ThermalPowerDelivered" - WaterMassFlow = "WaterMassFlow" + WaterMassFlowHDS = "WaterMassFlowHDS" # Similar components to connect to: # 1. Building @@ -222,7 +182,7 @@ def __init__( self.water_mass_flow_rate_hp_in_kg_per_second_channel: cp.ComponentInput = self.add_input( self.component_name, self.WaterMassFlow, - lt.LoadTypes.VOLUME, + lt.LoadTypes.WATER, lt.Units.KG_PER_SEC, False, ) @@ -230,10 +190,10 @@ def __init__( # Outputs self.water_temperature_inlet_channel: cp.ComponentOutput = self.add_output( self.component_name, - self.WaterTemperatureInput, + self.WaterTemperatureInlet, lt.LoadTypes.WATER, lt.Units.CELSIUS, - output_description=f"here a description for {self.WaterTemperatureInput} will follow.", + output_description=f"here a description for {self.WaterTemperatureInlet} will follow.", ) self.water_temperature_outlet_channel: cp.ComponentOutput = self.add_output( self.component_name, @@ -258,10 +218,10 @@ def __init__( ) self.water_mass_flow_channel: cp.ComponentOutput = self.add_output( self.component_name, - self.WaterMassFlow, + self.WaterMassFlowHDS, lt.LoadTypes.VOLUME, lt.Units.KG_PER_SEC, - output_description=f"here a description for {self.WaterMassFlow} will follow.", + output_description=f"here a description for {self.WaterMassFlowHDS} will follow.", ) self.add_default_connections(self.get_default_connections_from_heat_distribution_controller()) @@ -516,6 +476,43 @@ def get_cost_opex( return opex_cost_data_class +@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: HeatDistributionSystemType + 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, + ) -> "HeatDistributionControllerConfig": + """Gets a default HeatDistribution Controller.""" + return HeatDistributionControllerConfig( + name="HeatDistributionController", + heating_system=HeatDistributionSystemType.FLOORHEATING, + 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): From 864181b8a239a0ab3c232873084b5375eaad8015 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Fri, 12 Apr 2024 19:37:12 +0200 Subject: [PATCH 03/21] running function for massflow=0, more literature and tsting --- hisim/components/heat_distribution_system.py | 238 +++++++++++++++---- 1 file changed, 194 insertions(+), 44 deletions(-) diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index 7b79f380b..8bb11dea3 100644 --- a/hisim/components/heat_distribution_system.py +++ b/hisim/components/heat_distribution_system.py @@ -7,6 +7,7 @@ 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 @@ -39,7 +40,6 @@ class HeatDistributionSystemType(IntEnum): @dataclass_json @dataclass class HeatDistributionConfig(cp.ConfigBase): - """Configuration of the HeatingWaterStorage class.""" @classmethod @@ -77,18 +77,21 @@ def get_default_heatdistributionsystem_config( ) return config + @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 = 21.0 + water_input_temperature_in_celsius: float = 21.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, ) @@ -133,8 +136,8 @@ def __init__( ) self.heat_distribution_system_config = config - self.thermal_power_delivered_in_watt: float = 0.0 - self.water_temperature_output_in_celsius: float = 21 + # 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 ) @@ -146,13 +149,19 @@ def __init__( 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.0, ) self.previous_state = self.state.self_copy() # Inputs self.state_channel: cp.ComponentInput = self.add_input( - self.component_name, self.State, lt.LoadTypes.ANY, lt.Units.ANY, True + 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, @@ -322,71 +331,211 @@ def write_to_report(self) -> List[str]: def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_convergence: bool) -> None: """Simulate the heat distribution system.""" - + print("---------------------------------------------------") # Get inputs ------------------------------------------------------------------------------------------------------------ state_controller = stsv.get_input_value(self.state_channel) - 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) - + theoretical_thermal_building_demand_in_watt = stsv.get_input_value(self.theoretical_thermal_building_demand_channel) residence_temperature_input_in_celsius = stsv.get_input_value(self.residence_temperature_input_channel) + + # just important for heating system without bufferstorage + # #todo: abfrage ob speoihcer verbunden, wenn nein massenstrom so sosnt wie vorher self.heating_distribution_system_water_mass_flow_rate_in_kg_per_second water_mass_flow_rate_hp_in_kg_per_second = stsv.get_input_value(self.water_mass_flow_rate_hp_in_kg_per_second_channel) - #just important for heating system without bufferstorage - if water_mass_flow_rate_hp_in_kg_per_second == 0: - water_mass_flow_rate_in_kg_per_second = self.heating_distribution_system_water_mass_flow_rate_in_kg_per_second - else: - water_mass_flow_rate_in_kg_per_second = water_mass_flow_rate_hp_in_kg_per_second - - # if state_controller == 1: - if state_controller in (1, -1): - ( - 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=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, - ) + # if water_mass_flow_rate_hp_in_kg_per_second == 0: + # water_mass_flow_rate_in_kg_per_second = self.heating_distribution_system_water_mass_flow_rate_in_kg_per_second + # else: + water_mass_flow_rate_in_kg_per_second = water_mass_flow_rate_hp_in_kg_per_second + + print(water_mass_flow_rate_in_kg_per_second) - elif state_controller == 0: - self.thermal_power_delivered_in_watt = 0.0 - self.water_temperature_output_in_celsius = water_temperature_input_in_celsius + if water_mass_flow_rate_in_kg_per_second == 0: + + (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( + theoretical_thermal_buiding_demand_in_watt = theoretical_thermal_building_demand_in_watt, + residence_temperature_in_celsius = residence_temperature_input_in_celsius, + ) else: - raise ValueError("unknown hds controller mode") + water_temperature_input_in_celsius = stsv.get_input_value(self.water_temperature_input_channel) + + # if state_controller == 1: + if state_controller in (1, -1): + print("state=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: + thermal_power_delivered_in_watt = 0.0 + + water_temperature_output_in_celsius = water_temperature_input_in_celsius + + else: + raise ValueError("unknown hds controller mode") + + # Set outputs ----------------------------------------------------------------------------------------------------------- stsv.set_output_value( self.water_temperature_inlet_channel, - water_temperature_input_in_celsius + 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 - # self.water_temperature_output_in_celsius, + # water_temperature_output_in_celsius, ) stsv.set_output_value( self.water_temperature_difference_channel, - water_temperature_input_in_celsius-self.water_temperature_output_in_celsius + # 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, + # 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, + theoretical_thermal_buiding_demand_in_watt: float, + residence_temperature_in_celsius: float, + ) -> Any: + """Calculate cooled or heated water temperature after heat exchange between heat distribution system and building without massflow.""" + # freie Konvektion + # quelle1: https://www.mdpi.com/1996-1073/16/15/5850 + # quelle2: https://www.researchgate.net/publication/305659004_Modelling_and_Simulation_of_Underfloor_Heating_System_Supplied_from_Heat_Pump + # quelle3: https://www.sciencedirect.com/science/article/pii/S0378778816312749?via%3Dihub + # annahme: Wärmeleitung nur richtung Raum --> andere Richtung adiabat + + thermal_resistance_heatingsystem = 0.02 #quelle 1 und 2 + + + #Annahmen: https://www.heizsparer.de/heizung/heizkorper/fussbodenheizung/fussbodenheizung-planen-heizkreise-berechnen #todo: wissenschaftliche Quelle raussuchen + # Verlegeabstand = 10 cm zwischen Rohren --> 8,8 m ROhr pro m^2 + + # Fläche geb = 140m^2 todo: A aus building übergeben + + inner_pipe_diameter = 17/1000 #m # Rohrinnendurchmesser = 17 + outer_pipe_diameter = (17+2.2)/1000 # m # Rohraußendurchmesser = 17+2,2mm + lenght_of_hds = 8.8*140 + + dichte_wasser = 997 #kg/m^3 + + volume_of_hds = ((np.pi/4)*((inner_pipe_diameter)**2)*lenght_of_hds) # in m^3 #todo: annahmen für rohrleitungdimensionen um volumen zu bestimme nin abhängigkeit von fgeb gfläche + + rohroberfläche_hds = np.pi*outer_pipe_diameter*lenght_of_hds # in m^2 + + mass_of_water_in_hds = volume_of_hds * dichte_wasser + # ggf aus vorherigen volumenstrom und fläche des gebäudes auf wassermasse im heizkreis schließen + + time_constant_hds=(mass_of_water_in_hds*self.specific_heat_capacity_of_water_in_joule_per_kilogram_per_celsius)*(thermal_resistance_heatingsystem/rohroberfläche_hds) # /3600 + + print(time_constant_hds) + + #water_temperature_input_in_celsius = self.state.water_input_temperature_in_celsius-0.5#theoretical_thermal_buiding_demand_in_watt/thermal_resistance_heatingsystem + + # water_temperature_input_in_celsius = ((self.state.water_input_temperature_in_celsius-residence_temperature_in_celsius)*np.exp(-time_constant_hds))+residence_temperature_in_celsius # -1 + + # water_temperature_input_in_celsius = ((self.state.water_input_temperature_in_celsius - 20) * np.exp(-(self.my_simulation_parameters.seconds_per_timestep) /time_constant_hds)) + 20 # -1 + + # water_temperature_input_in_celsius = ((self.state.water_input_temperature_in_celsius-residence_temperature_in_celsius) + + # ((residence_temperature_in_celsius) * np.exp(-(self.my_simulation_parameters.seconds_per_timestep)*3600 / time_constant_hds))) + + 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)) + + # todo: falls annahme genommen wird werte für tau raussuchen und mit literatur belegen bzw gucken wie berechnen anhand von geb daten etc. + + #todo: zeit irgencddeas /3600 teilen damit ggf tau besser wird??? + + #todo: mehr e-funktion verlauf hin krtiegfebn --> porobieren wie + + # water_temperature_output_in_celsius= self.state.water_output_temperature_in_celsius-0.5#theoretical_thermal_buiding_demand_in_watt/thermal_resistance_heatingsystem + + #water_temperature_output_in_celsius = ((self.state.water_output_temperature_in_celsius - residence_temperature_in_celsius) * np.exp(-time_constant_hds)) + residence_temperature_in_celsius + # water_temperature_output_in_celsius = ((self.state.water_output_temperature_in_celsius - residence_temperature_in_celsius) + ((residence_temperature_in_celsius) * np.exp(-( self.my_simulation_parameters.seconds_per_timestep)*3600 / 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)) + + if theoretical_thermal_buiding_demand_in_watt > 0: + # water in hds must be warmer than the building in order to exchange heat + if water_temperature_input_in_celsius > residence_temperature_in_celsius: + # prevent that water output temperature in hds gets colder than residence temperature in building when heating + water_temperature_output_in_celsius = max( + water_temperature_output_in_celsius, + residence_temperature_in_celsius, + ) + thermal_power_delivered_effective_in_watt = thermal_resistance_heatingsystem*(water_temperature_input_in_celsius - water_temperature_output_in_celsius) + + else: + # water in hds is not warmer than the building, therefore heat exchange is not possible + water_temperature_input_in_celsius = self.state.water_input_temperature_in_celsius + water_temperature_output_in_celsius = self.state.water_output_temperature_in_celsius + thermal_power_delivered_effective_in_watt = 0 + + elif theoretical_thermal_buiding_demand_in_watt < 0: + # water in hds must be cooler than the building in order to cool building down + if water_temperature_input_in_celsius < residence_temperature_in_celsius: + # prevent that water output temperature in hds gets hotter than residence temperature in building when cooling + water_temperature_output_in_celsius = min( + water_temperature_output_in_celsius, + residence_temperature_in_celsius, + ) + thermal_power_delivered_effective_in_watt = thermal_resistance_heatingsystem * ( + water_temperature_input_in_celsius - water_temperature_output_in_celsius) + + else: + # water in hds is not colder than building and therefore cooling is not possible + water_temperature_input_in_celsius = self.state.water_input_temperature_in_celsius + water_temperature_output_in_celsius = self.state.water_output_temperature_in_celsius + thermal_power_delivered_effective_in_watt = 0 + + # in case no heating or cooling needed, water output is equal to water input + elif theoretical_thermal_buiding_demand_in_watt == 0: + water_temperature_input_in_celsius = self.state.water_input_temperature_in_celsius + water_temperature_output_in_celsius = self.state.water_output_temperature_in_celsius + thermal_power_delivered_effective_in_watt = 0 + else: + raise ValueError( + f"Theoretical thermal demand has unacceptable value here {theoretical_thermal_buiding_demand_in_watt}." + ) + + print("+++++++++++++++++++++++++++++") + print(self.state.water_input_temperature_in_celsius) + print(water_temperature_input_in_celsius) + print("------") + print(self.state.water_output_temperature_in_celsius) + print(water_temperature_output_in_celsius) + print("+++++++++++++++++++++++++++++") + + + 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, @@ -758,6 +907,9 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg ) ) + set_temperature_difference = list_of_heating_distribution_system_flow_and_return_temperatures[0] - list_of_heating_distribution_system_flow_and_return_temperatures[1] + + self.conditions_for_opening_or_shutting_heat_distribution( theoretical_thermal_building_demand_in_watt=theoretical_thermal_building_demand_in_watt, ) @@ -798,9 +950,7 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg 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], - ) + self.heating_temperature_difference_channel,set_temperature_difference) def conditions_for_opening_or_shutting_heat_distribution( self, From d58020318729737bf609fd07e834cc5d8d5167cf Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Wed, 17 Apr 2024 18:38:46 +0200 Subject: [PATCH 04/21] additional inputs and equations for calculating heat transfer without massflow and hot water storage some todos to fix and verification of constants --- hisim/components/heat_distribution_system.py | 200 ++++++------------- 1 file changed, 59 insertions(+), 141 deletions(-) diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index 8bb11dea3..2c5b678ae 100644 --- a/hisim/components/heat_distribution_system.py +++ b/hisim/components/heat_distribution_system.py @@ -50,6 +50,8 @@ def get_main_classname(cls): 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 + with_hot_water_storage: bool #: CO2 footprint of investment in kg co2_footprint: float #: cost for investment in Euro @@ -64,12 +66,16 @@ 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, + with_hot_water_storage: bool, ) -> 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, + with_hot_water_storage=with_hot_water_storage, 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 @@ -146,6 +152,10 @@ def __init__( 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.heat_distribution_system_with_storage = self.heat_distribution_system_config.with_hot_water_storage + self.build() self.state: HeatDistributionSystemState = HeatDistributionSystemState( @@ -163,6 +173,7 @@ def __init__( lt.Units.ANY, True ) + self.theoretical_thermal_building_demand_channel: cp.ComponentInput = self.add_input( self.component_name, self.TheoreticalThermalBuildingDemand, @@ -187,14 +198,15 @@ def __init__( True, ) - #just important for heating system without 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, - False, - ) + if not self.heat_distribution_system_with_storage: + # just important for heating system without 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_inlet_channel: cp.ComponentOutput = self.add_output( @@ -306,6 +318,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.""" @@ -331,41 +344,37 @@ def write_to_report(self) -> List[str]: def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_convergence: bool) -> None: """Simulate the heat distribution system.""" - print("---------------------------------------------------") + # Get inputs ------------------------------------------------------------------------------------------------------------ state_controller = stsv.get_input_value(self.state_channel) theoretical_thermal_building_demand_in_watt = stsv.get_input_value(self.theoretical_thermal_building_demand_channel) residence_temperature_input_in_celsius = stsv.get_input_value(self.residence_temperature_input_channel) + if self.heat_distribution_system_with_storage: + 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 bufferstorage + water_mass_flow_rate_hp_in_kg_per_second = stsv.get_input_value( + self.water_mass_flow_rate_hp_in_kg_per_second_channel) + water_mass_flow_rate_in_kg_per_second = water_mass_flow_rate_hp_in_kg_per_second - # just important for heating system without bufferstorage - # #todo: abfrage ob speoihcer verbunden, wenn nein massenstrom so sosnt wie vorher self.heating_distribution_system_water_mass_flow_rate_in_kg_per_second - water_mass_flow_rate_hp_in_kg_per_second = stsv.get_input_value(self.water_mass_flow_rate_hp_in_kg_per_second_channel) - - # if water_mass_flow_rate_hp_in_kg_per_second == 0: - # water_mass_flow_rate_in_kg_per_second = self.heating_distribution_system_water_mass_flow_rate_in_kg_per_second - # else: - water_mass_flow_rate_in_kg_per_second = water_mass_flow_rate_hp_in_kg_per_second - - print(water_mass_flow_rate_in_kg_per_second) + #todo: alle variablen namen universell umbenennen, nicht iurgendwas from oder to storage oder sowas if water_mass_flow_rate_in_kg_per_second == 0: - + # important for heating system without bufferstorage (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( - theoretical_thermal_buiding_demand_in_watt = theoretical_thermal_building_demand_in_watt, residence_temperature_in_celsius = residence_temperature_input_in_celsius, + theoretical_thermal_buiding_demand_in_watt=theoretical_thermal_building_demand_in_watt, ) 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): - print("state=1") ( water_temperature_output_in_celsius, thermal_power_delivered_in_watt, @@ -377,15 +386,16 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg ) elif state_controller == 0: - thermal_power_delivered_in_watt = 0.0 - - water_temperature_output_in_celsius = water_temperature_input_in_celsius + if self.heat_distribution_system_with_storage: + thermal_power_delivered_in_watt = 0.0 + water_temperature_output_in_celsius = water_temperature_input_in_celsius + else: + # if no hot water storage, state is transfer to HP model to turn hp off due to no thermal demand + pass else: raise ValueError("unknown hds controller mode") - - # Set outputs ----------------------------------------------------------------------------------------------------------- stsv.set_output_value( self.water_temperature_inlet_channel, @@ -399,7 +409,7 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg ) stsv.set_output_value( self.water_temperature_difference_channel, - # water_temperature_input_in_celsius-water_temperature_output_in_celsius + # 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( @@ -417,118 +427,40 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg 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, - theoretical_thermal_buiding_demand_in_watt: float, residence_temperature_in_celsius: float, + theoretical_thermal_buiding_demand_in_watt: float ) -> Any: - """Calculate cooled or heated water temperature after heat exchange between heat distribution system and building without massflow.""" - # freie Konvektion - # quelle1: https://www.mdpi.com/1996-1073/16/15/5850 - # quelle2: https://www.researchgate.net/publication/305659004_Modelling_and_Simulation_of_Underfloor_Heating_System_Supplied_from_Heat_Pump - # quelle3: https://www.sciencedirect.com/science/article/pii/S0378778816312749?via%3Dihub - # annahme: Wärmeleitung nur richtung Raum --> andere Richtung adiabat - - thermal_resistance_heatingsystem = 0.02 #quelle 1 und 2 - - - #Annahmen: https://www.heizsparer.de/heizung/heizkorper/fussbodenheizung/fussbodenheizung-planen-heizkreise-berechnen #todo: wissenschaftliche Quelle raussuchen - # Verlegeabstand = 10 cm zwischen Rohren --> 8,8 m ROhr pro m^2 - - # Fläche geb = 140m^2 todo: A aus building übergeben - - inner_pipe_diameter = 17/1000 #m # Rohrinnendurchmesser = 17 - outer_pipe_diameter = (17+2.2)/1000 # m # Rohraußendurchmesser = 17+2,2mm - lenght_of_hds = 8.8*140 - - dichte_wasser = 997 #kg/m^3 - - volume_of_hds = ((np.pi/4)*((inner_pipe_diameter)**2)*lenght_of_hds) # in m^3 #todo: annahmen für rohrleitungdimensionen um volumen zu bestimme nin abhängigkeit von fgeb gfläche - - rohroberfläche_hds = np.pi*outer_pipe_diameter*lenght_of_hds # in m^2 - - mass_of_water_in_hds = volume_of_hds * dichte_wasser - # ggf aus vorherigen volumenstrom und fläche des gebäudes auf wassermasse im heizkreis schließen + """Calculate cooled or heated water temperature due to free convection after heat exchange between heat distribution system and building without massflow.""" - time_constant_hds=(mass_of_water_in_hds*self.specific_heat_capacity_of_water_in_joule_per_kilogram_per_celsius)*(thermal_resistance_heatingsystem/rohroberfläche_hds) # /3600 + # 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 + # assumption: https://www.heizsparer.de/heizung/heizkorper/fussbodenheizung/fussbodenheizung-planen-heizkreise-berechnen + # assumption: heat transfer direction just to the room --> other direction is adiabatic - print(time_constant_hds) + heat_resistance_coefficient_hds_pipe_to_air = 0.07 # 0.02 # (m^2*K)/W # source 1 and 2 # todo: Wert raussuchen bzw aus daten berechnen - #water_temperature_input_in_celsius = self.state.water_input_temperature_in_celsius-0.5#theoretical_thermal_buiding_demand_in_watt/thermal_resistance_heatingsystem + inner_pipe_diameter = 17/1000 # in m # source 1 + outer_pipe_diameter = (17+4.4)/1000 # in m # source 1 + lenght_of_hds_pipe = 8.8*self.absolute_conditioned_floor_area_in_m2 # in m # todo: andere Werte für verlege abstand etc auch mit rein nehmen und entweder mittelwert bilden aus allen oder abfreage welche genutzt werden soll in config --> hier dann sowas wie medium,low,high analog zu building capacity class - # water_temperature_input_in_celsius = ((self.state.water_input_temperature_in_celsius-residence_temperature_in_celsius)*np.exp(-time_constant_hds))+residence_temperature_in_celsius # -1 + inner_volume_of_hds = ((np.pi/4)*((inner_pipe_diameter)**2)*lenght_of_hds_pipe) # in m^3 - # water_temperature_input_in_celsius = ((self.state.water_input_temperature_in_celsius - 20) * np.exp(-(self.my_simulation_parameters.seconds_per_timestep) /time_constant_hds)) + 20 # -1 + outer_surface_of_hds_pipe = np.pi*outer_pipe_diameter*lenght_of_hds_pipe # in m^2 - # water_temperature_input_in_celsius = ((self.state.water_input_temperature_in_celsius-residence_temperature_in_celsius) + - # ((residence_temperature_in_celsius) * np.exp(-(self.my_simulation_parameters.seconds_per_timestep)*3600 / time_constant_hds))) + heating_surface_hds_pipe = outer_pipe_diameter*lenght_of_hds_pipe # in m^2 --> projezierte fläche??#todo: macht das sinn? - 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)) + mass_of_water_in_hds = inner_volume_of_hds * self.density_of_water - # todo: falls annahme genommen wird werte für tau raussuchen und mit literatur belegen bzw gucken wie berechnen anhand von geb daten etc. + 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) - #todo: zeit irgencddeas /3600 teilen damit ggf tau besser wird??? - - #todo: mehr e-funktion verlauf hin krtiegfebn --> porobieren wie - - # water_temperature_output_in_celsius= self.state.water_output_temperature_in_celsius-0.5#theoretical_thermal_buiding_demand_in_watt/thermal_resistance_heatingsystem - - #water_temperature_output_in_celsius = ((self.state.water_output_temperature_in_celsius - residence_temperature_in_celsius) * np.exp(-time_constant_hds)) + residence_temperature_in_celsius - # water_temperature_output_in_celsius = ((self.state.water_output_temperature_in_celsius - residence_temperature_in_celsius) + ((residence_temperature_in_celsius) * np.exp(-( self.my_simulation_parameters.seconds_per_timestep)*3600 / 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)) - - if theoretical_thermal_buiding_demand_in_watt > 0: - # water in hds must be warmer than the building in order to exchange heat - if water_temperature_input_in_celsius > residence_temperature_in_celsius: - # prevent that water output temperature in hds gets colder than residence temperature in building when heating - water_temperature_output_in_celsius = max( - water_temperature_output_in_celsius, - residence_temperature_in_celsius, - ) - thermal_power_delivered_effective_in_watt = thermal_resistance_heatingsystem*(water_temperature_input_in_celsius - water_temperature_output_in_celsius) - - else: - # water in hds is not warmer than the building, therefore heat exchange is not possible - water_temperature_input_in_celsius = self.state.water_input_temperature_in_celsius - water_temperature_output_in_celsius = self.state.water_output_temperature_in_celsius - thermal_power_delivered_effective_in_watt = 0 - - elif theoretical_thermal_buiding_demand_in_watt < 0: - # water in hds must be cooler than the building in order to cool building down - if water_temperature_input_in_celsius < residence_temperature_in_celsius: - # prevent that water output temperature in hds gets hotter than residence temperature in building when cooling - water_temperature_output_in_celsius = min( - water_temperature_output_in_celsius, - residence_temperature_in_celsius, - ) - thermal_power_delivered_effective_in_watt = thermal_resistance_heatingsystem * ( - water_temperature_input_in_celsius - water_temperature_output_in_celsius) - - else: - # water in hds is not colder than building and therefore cooling is not possible - water_temperature_input_in_celsius = self.state.water_input_temperature_in_celsius - water_temperature_output_in_celsius = self.state.water_output_temperature_in_celsius - thermal_power_delivered_effective_in_watt = 0 - - # in case no heating or cooling needed, water output is equal to water input - elif theoretical_thermal_buiding_demand_in_watt == 0: - water_temperature_input_in_celsius = self.state.water_input_temperature_in_celsius - water_temperature_output_in_celsius = self.state.water_output_temperature_in_celsius - thermal_power_delivered_effective_in_watt = 0 - else: - raise ValueError( - f"Theoretical thermal demand has unacceptable value here {theoretical_thermal_buiding_demand_in_watt}." - ) - - print("+++++++++++++++++++++++++++++") - print(self.state.water_input_temperature_in_celsius) - print(water_temperature_input_in_celsius) - print("------") - print(self.state.water_output_temperature_in_celsius) - print(water_temperature_output_in_celsius) - print("+++++++++++++++++++++++++++++") + 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, @@ -536,7 +468,6 @@ def determine_water_temperature_input_output_effective_thermal_power_without_mas thermal_power_delivered_effective_in_watt, ) - def determine_water_temperature_output_after_heat_exchange_with_building_and_effective_thermal_power( self, water_mass_flow_in_kg_per_second: float, @@ -683,7 +614,6 @@ class HeatDistributionController(cp.Component): State = "State" HeatingFlowTemperature = "HeatingFlowTemperature" HeatingReturnTemperature = "HeatingReturnTemperature" - HeatingTemperatureDifference = "HeatingTemperatureDifference" # Similar components to connect to: # 1. Building @@ -772,13 +702,6 @@ def __init__( 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.KELVIN, - 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" @@ -907,9 +830,6 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg ) ) - set_temperature_difference = list_of_heating_distribution_system_flow_and_return_temperatures[0] - list_of_heating_distribution_system_flow_and_return_temperatures[1] - - self.conditions_for_opening_or_shutting_heat_distribution( theoretical_thermal_building_demand_in_watt=theoretical_thermal_building_demand_in_watt, ) @@ -949,8 +869,6 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg self.heating_return_temperature_channel, list_of_heating_distribution_system_flow_and_return_temperatures[1], ) - stsv.set_output_value( - self.heating_temperature_difference_channel,set_temperature_difference) def conditions_for_opening_or_shutting_heat_distribution( self, From ea77c435ca638f4cc84179e0e34f2e39e37dc6a4 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Wed, 24 Apr 2024 12:53:10 +0200 Subject: [PATCH 05/21] back to "original" if-condition for state_controller == 0 --- hisim/components/heat_distribution_system.py | 25 +++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index c690baad5..899330bf0 100644 --- a/hisim/components/heat_distribution_system.py +++ b/hisim/components/heat_distribution_system.py @@ -161,7 +161,7 @@ def __init__( self.state: HeatDistributionSystemState = HeatDistributionSystemState( water_output_temperature_in_celsius=21.0, water_input_temperature_in_celsius=21.0, - thermal_power_delivered_in_watt=0.0, + thermal_power_delivered_in_watt=0, ) self.previous_state = self.state.self_copy() @@ -386,12 +386,8 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg ) elif state_controller == 0: - if self.heat_distribution_system_with_storage: - thermal_power_delivered_in_watt = 0.0 - water_temperature_output_in_celsius = water_temperature_input_in_celsius - else: - # if no hot water storage, state is transfer to HP model to turn hp off due to no thermal demand - pass + thermal_power_delivered_in_watt = 0.0 + water_temperature_output_in_celsius = water_temperature_input_in_celsius else: raise ValueError("unknown hds controller mode") @@ -450,8 +446,6 @@ def determine_water_temperature_input_output_effective_thermal_power_without_mas outer_surface_of_hds_pipe = np.pi*outer_pipe_diameter*lenght_of_hds_pipe # in m^2 - heating_surface_hds_pipe = outer_pipe_diameter*lenght_of_hds_pipe # in m^2 --> projezierte fläche??#todo: macht das sinn? - 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) * ( @@ -614,6 +608,7 @@ class HeatDistributionController(cp.Component): State = "State" HeatingFlowTemperature = "HeatingFlowTemperature" HeatingReturnTemperature = "HeatingReturnTemperature" + HeatingTemperatureDifference = "HeatingTemperatureDifference" # Similar components to connect to: # 1. Building @@ -702,6 +697,13 @@ def __init__( 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" @@ -890,6 +892,11 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg 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, theoretical_thermal_building_demand_in_watt: float, From 536ed67e741ce01ae727c05ace9cbb7a55bd89b2 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Wed, 24 Apr 2024 18:11:50 +0200 Subject: [PATCH 06/21] calculation of heat_resistance_coefficient_hds_pipe_to_air with height and thermal conductivity of screed and heat transfer screed to air --- hisim/components/heat_distribution_system.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index 899330bf0..b7b6e43bf 100644 --- a/hisim/components/heat_distribution_system.py +++ b/hisim/components/heat_distribution_system.py @@ -433,15 +433,19 @@ def determine_water_temperature_input_output_effective_thermal_power_without_mas # 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 - # assumption: https://www.heizsparer.de/heizung/heizkorper/fussbodenheizung/fussbodenheizung-planen-heizkreise-berechnen - # assumption: heat transfer direction just to the room --> other direction is adiabatic + # 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 - heat_resistance_coefficient_hds_pipe_to_air = 0.07 # 0.02 # (m^2*K)/W # source 1 and 2 # todo: Wert raussuchen bzw aus daten berechnen + height_of_screed = 45/1000 # in m + thermal_conductivity_screed = 1.4 # in W/(m^2K) + heat_transfer_coefficient_screed_to_air = 5.8 # assumption3 + inner_pipe_diameter = 17 / 1000 # in m # source 1 + outer_pipe_diameter = (17 + 4.4) / 1000 # in m # source 1 - inner_pipe_diameter = 17/1000 # in m # source 1 - outer_pipe_diameter = (17+4.4)/1000 # in m # source 1 - lenght_of_hds_pipe = 8.8*self.absolute_conditioned_floor_area_in_m2 # in m # todo: andere Werte für verlege abstand etc auch mit rein nehmen und entweder mittelwert bilden aus allen oder abfreage welche genutzt werden soll in config --> hier dann sowas wie medium,low,high analog zu building capacity class + heat_resistance_coefficient_hds_pipe_to_air = height_of_screed/thermal_conductivity_screed + 1 / heat_transfer_coefficient_screed_to_air + lenght_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)*lenght_of_hds_pipe) # in m^3 outer_surface_of_hds_pipe = np.pi*outer_pipe_diameter*lenght_of_hds_pipe # in m^2 From cd8e5ed6ed61230466e4bb15d09c03d3e2bcda8d Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Fri, 26 Apr 2024 17:29:23 +0200 Subject: [PATCH 07/21] - restructuring hds model - calculation of time constant if no massflow based on flexible parameters - add new parameters from hds model in system setups - fixing bug in hds tester --- hisim/components/heat_distribution_system.py | 165 ++++++------------ .../automatic_default_connections.py | 1 + .../household_1_advanced_hp_diesel_car.py | 1 + .../household_2_advanced_hp_diesel_car_pv.py | 1 + ...old_3_advanced_hp_diesel_car_pv_battery.py | 1 + ..._4a_with_car_priority_advanced_hp_ev_pv.py | 1 + ..._car_priority_advanced_hp_ev_pv_battery.py | 1 + ...hold_cluster_advanced_hp_pv_battery_ems.py | 1 + ...household_cluster_reference_advanced_hp.py | 1 + system_setups/household_gas_heater.py | 1 + system_setups/household_heat_pump.py | 1 + .../household_hp_hws_hds_pv_battery_ems.py | 1 + ...usehold_reference_gas_heater_diesel_car.py | 1 + ...with_advanced_hp_hws_hds_pv_battery_ems.py | 1 + ..._controller_l2_energy_management_system.py | 1 + tests/test_heat_distribution_system.py | 6 +- 16 files changed, 76 insertions(+), 109 deletions(-) diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index c43012f45..f1c1d3eeb 100644 --- a/hisim/components/heat_distribution_system.py +++ b/hisim/components/heat_distribution_system.py @@ -11,7 +11,6 @@ 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 @@ -68,7 +67,7 @@ def get_default_heatdistributionsystem_config( 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, - with_hot_water_storage: bool, + with_hot_water_storage: bool = True, ) -> Any: """Get a default heat distribution system config.""" config = HeatDistributionConfig( @@ -85,52 +84,13 @@ 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: HeatDistributionSystemType - 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, - ) -> "HeatDistributionControllerConfig": - """Gets a default HeatDistribution Controller.""" - return HeatDistributionControllerConfig( - name="HeatDistributionController", - heating_system=HeatDistributionSystemType.FLOORHEATING, - 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 = 21.0 - water_input_temperature_in_celsius: float = 21.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): @@ -184,6 +144,7 @@ def __init__( self.thermal_power_delivered_in_watt: float = 0.0 self.water_temperature_output_in_celsius: float = 21 + self.water_input_temperature_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 ) @@ -192,7 +153,9 @@ def __init__( 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.absolute_conditioned_floor_area_in_m2 = ( + self.heat_distribution_system_config.absolute_conditioned_floor_area_in_m2 + ) self.heat_distribution_system_with_storage = self.heat_distribution_system_config.with_hot_water_storage @@ -207,11 +170,7 @@ def __init__( # Inputs self.state_channel: cp.ComponentInput = self.add_input( - self.component_name, - self.State, - lt.LoadTypes.ANY, - lt.Units.ANY, - True + self.component_name, self.State, lt.LoadTypes.ANY, lt.Units.ANY, True ) self.theoretical_thermal_building_demand_channel: cp.ComponentInput = self.add_input( @@ -287,7 +246,8 @@ def __init__( 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.heat_distribution_system_with_storage: + self.add_default_connections(self.get_default_connections_from_simple_hot_water_storage()) def get_default_connections_from_heat_distribution_controller( self, @@ -387,33 +347,34 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg # Get inputs ------------------------------------------------------------------------------------------------------------ state_controller = stsv.get_input_value(self.state_channel) - theoretical_thermal_building_demand_in_watt = stsv.get_input_value(self.theoretical_thermal_building_demand_channel) + theoretical_thermal_building_demand_in_watt = stsv.get_input_value( + self.theoretical_thermal_building_demand_channel + ) residence_temperature_input_in_celsius = stsv.get_input_value(self.residence_temperature_input_channel) if self.heat_distribution_system_with_storage: - water_mass_flow_rate_in_kg_per_second = self.heating_distribution_system_water_mass_flow_rate_in_kg_per_second + 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 bufferstorage + # important for heating system without buffer storage water_mass_flow_rate_hp_in_kg_per_second = stsv.get_input_value( - self.water_mass_flow_rate_hp_in_kg_per_second_channel) + self.water_mass_flow_rate_hp_in_kg_per_second_channel + ) water_mass_flow_rate_in_kg_per_second = water_mass_flow_rate_hp_in_kg_per_second - #todo: alle variablen namen universell umbenennen, nicht iurgendwas from oder to storage oder sowas - - if water_mass_flow_rate_in_kg_per_second == 0: - # important for heating system without bufferstorage - (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, - theoretical_thermal_buiding_demand_in_watt=theoretical_thermal_building_demand_in_watt, + # important for heating system without buffer storage + ( + 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 == 1: if state_controller in (1, -1): ( water_temperature_output_in_celsius, @@ -436,22 +397,22 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg stsv.set_output_value( self.water_temperature_inlet_channel, self.state.water_input_temperature_in_celsius - # water_temperature_input_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, + # 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 + # 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 - # thermal_power_delivered_in_watt, + # thermal_power_delivered_in_watt, ) stsv.set_output_value( self.water_mass_flow_channel, @@ -466,7 +427,6 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg def determine_water_temperature_input_output_effective_thermal_power_without_massflow( self, residence_temperature_in_celsius: float, - theoretical_thermal_buiding_demand_in_watt: float ) -> Any: """Calculate cooled or heated water temperature due to free convection after heat exchange between heat distribution system and building without massflow.""" @@ -477,28 +437,39 @@ def determine_water_temperature_input_output_effective_thermal_power_without_mas # assumption2: heat transfer direction just to the room --> other direction is adiabatic # assumption3: still air and no floor covering considered - height_of_screed = 45/1000 # in m + height_of_screed = 45 / 1000 # in m thermal_conductivity_screed = 1.4 # in W/(m^2K) heat_transfer_coefficient_screed_to_air = 5.8 # assumption3 inner_pipe_diameter = 17 / 1000 # in m # source 1 outer_pipe_diameter = (17 + 4.4) / 1000 # in m # source 1 - heat_resistance_coefficient_hds_pipe_to_air = height_of_screed/thermal_conductivity_screed + 1 / heat_transfer_coefficient_screed_to_air + heat_resistance_coefficient_hds_pipe_to_air = ( + height_of_screed / thermal_conductivity_screed + 1 / heat_transfer_coefficient_screed_to_air + ) lenght_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)*lenght_of_hds_pipe) # in m^3 + inner_volume_of_hds = (np.pi / 4) * ((inner_pipe_diameter) ** 2) * lenght_of_hds_pipe # in m^3 - outer_surface_of_hds_pipe = np.pi*outer_pipe_diameter*lenght_of_hds_pipe # in m^2 + outer_surface_of_hds_pipe = np.pi * outer_pipe_diameter * lenght_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) + 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)) + 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) + 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, @@ -562,8 +533,11 @@ def determine_water_temperature_output_after_heat_exchange_with_building_and_eff # in case no heating or cooling needed, water output is equal to water input elif theoretical_thermal_buiding_demand_in_watt == 0: + print(water_temperature_output_in_celsius) water_temperature_output_in_celsius = water_temperature_input_in_celsius thermal_power_delivered_effective_in_watt = 0 + print(water_temperature_input_in_celsius) + print(water_temperature_output_in_celsius) else: raise ValueError( f"Theoretical thermal demand has unacceptable value here {theoretical_thermal_buiding_demand_in_watt}." @@ -594,6 +568,7 @@ def get_cost_opex( return opex_cost_data_class + @dataclass_json @dataclass class HeatDistributionControllerConfig(cp.ConfigBase): @@ -647,7 +622,6 @@ class HeatDistributionController(cp.Component): # Inputs TheoreticalThermalBuildingDemand = "TheoreticalThermalBuildingDemand" DailyAverageOutsideTemperature = "DailyAverageOutsideTemperature" - WaterTemperatureInputFromHeatWaterStorage = "WaterTemperatureInputFromHeatWaterStorage" # Inputs -> energy management system BuildingTemperatureModifier = "BuildingTemperatureModifier" @@ -708,13 +682,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, @@ -757,7 +724,6 @@ def __init__( 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( @@ -792,22 +758,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, ): @@ -941,7 +891,8 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg 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], + 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( diff --git a/system_setups/automatic_default_connections.py b/system_setups/automatic_default_connections.py index c9a7486b5..49d8ec09e 100644 --- a/system_setups/automatic_default_connections.py +++ b/system_setups/automatic_default_connections.py @@ -132,6 +132,7 @@ def setup_function(my_sim: Any, my_simulation_parameters: Optional[SimulationPar 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, diff --git a/system_setups/household_1_advanced_hp_diesel_car.py b/system_setups/household_1_advanced_hp_diesel_car.py index 5e3f9509a..8da289eb2 100644 --- a/system_setups/household_1_advanced_hp_diesel_car.py +++ b/system_setups/household_1_advanced_hp_diesel_car.py @@ -138,6 +138,7 @@ def get_scaled_default( 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( 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 66fe55d5d..d03e22e21 100644 --- a/system_setups/household_2_advanced_hp_diesel_car_pv.py +++ b/system_setups/household_2_advanced_hp_diesel_car_pv.py @@ -130,6 +130,7 @@ def get_default(cls): 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( 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 e1d5e39d4..3e58a1ba5 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 @@ -132,6 +132,7 @@ def get_default(cls): 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( 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 cb31b15cc..4af32e09f 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 @@ -136,6 +136,7 @@ def get_default(cls): 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( 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 aaf0ec679..202601049 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 @@ -140,6 +140,7 @@ def get_default(cls): 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( 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 429c81472..a68a433f5 100644 --- a/system_setups/household_cluster_advanced_hp_pv_battery_ems.py +++ b/system_setups/household_cluster_advanced_hp_pv_battery_ems.py @@ -245,6 +245,7 @@ def setup_function( 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, diff --git a/system_setups/household_cluster_reference_advanced_hp.py b/system_setups/household_cluster_reference_advanced_hp.py index b59b7d7eb..18388d4ad 100644 --- a/system_setups/household_cluster_reference_advanced_hp.py +++ b/system_setups/household_cluster_reference_advanced_hp.py @@ -247,6 +247,7 @@ def setup_function( 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, diff --git a/system_setups/household_gas_heater.py b/system_setups/household_gas_heater.py index 012303833..501fc70a3 100644 --- a/system_setups/household_gas_heater.py +++ b/system_setups/household_gas_heater.py @@ -155,6 +155,7 @@ def get_scaled_default( 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=( diff --git a/system_setups/household_heat_pump.py b/system_setups/household_heat_pump.py index d6ac2433a..a58e0e100 100644 --- a/system_setups/household_heat_pump.py +++ b/system_setups/household_heat_pump.py @@ -165,6 +165,7 @@ def get_scaled_default( 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( 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 e9b3c2efc..22307b384 100644 --- a/system_setups/household_hp_hws_hds_pv_battery_ems.py +++ b/system_setups/household_hp_hws_hds_pv_battery_ems.py @@ -147,6 +147,7 @@ def setup_function( 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, diff --git a/system_setups/household_reference_gas_heater_diesel_car.py b/system_setups/household_reference_gas_heater_diesel_car.py index 2732a4f8d..4f9f78edc 100644 --- a/system_setups/household_reference_gas_heater_diesel_car.py +++ b/system_setups/household_reference_gas_heater_diesel_car.py @@ -109,6 +109,7 @@ def get_default(cls): 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=( 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 cdbe628c7..ec33053cc 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 @@ -147,6 +147,7 @@ def setup_function( 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, diff --git a/tests/test_controller_l2_energy_management_system.py b/tests/test_controller_l2_energy_management_system.py index 031f0ccd3..c2758fae3 100644 --- a/tests/test_controller_l2_energy_management_system.py +++ b/tests/test_controller_l2_energy_management_system.py @@ -164,6 +164,7 @@ def test_house( 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, diff --git a/tests/test_heat_distribution_system.py b/tests/test_heat_distribution_system.py index 151a4ceee..b908580b8 100644 --- a/tests/test_heat_distribution_system.py +++ b/tests/test_heat_distribution_system.py @@ -132,6 +132,8 @@ def simulate_and_calculate_hds_outputs_for_a_given_theoretical_heating_demand_fr 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, + with_hot_water_storage=True, + 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 +221,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 From b0b34f059cd4d3b71660d2f1a2693d782d2e8856 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Mon, 29 Apr 2024 10:21:51 +0200 Subject: [PATCH 08/21] - get flow rate of hds part of simple_hot_water_storage.py from output of hds model --> more flexible for future models --- hisim/components/heat_distribution_system.py | 3 +- hisim/components/simple_hot_water_storage.py | 33 +++++++++++++------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index f1c1d3eeb..19ca27ba0 100644 --- a/hisim/components/heat_distribution_system.py +++ b/hisim/components/heat_distribution_system.py @@ -358,10 +358,9 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg ) else: # important for heating system without buffer storage - water_mass_flow_rate_hp_in_kg_per_second = stsv.get_input_value( + water_mass_flow_rate_in_kg_per_second = stsv.get_input_value( self.water_mass_flow_rate_hp_in_kg_per_second_channel ) - water_mass_flow_rate_in_kg_per_second = water_mass_flow_rate_hp_in_kg_per_second if water_mass_flow_rate_in_kg_per_second == 0: # important for heating system without buffer storage diff --git a/hisim/components/simple_hot_water_storage.py b/hisim/components/simple_hot_water_storage.py index 43b776e0b..aede1cd34 100644 --- a/hisim/components/simple_hot_water_storage.py +++ b/hisim/components/simple_hot_water_storage.py @@ -52,7 +52,6 @@ def get_main_classname(cls): heat_exchanger_is_present: bool # 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,14 +63,13 @@ 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 co2_footprint=100, # Todo: check value @@ -85,9 +83,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,7 +123,6 @@ 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 @@ -163,6 +159,7 @@ class SimpleHotWaterStorage(cp.Component): WaterTemperatureFromHeatDistribution = "WaterTemperatureFromHeatDistribution" WaterTemperatureFromHeatGenerator = "WaterTemperaturefromHeatGenerator" WaterMassFlowRateFromHeatGenerator = "WaterMassFlowRateFromHeatGenerator" + WaterMassFlowRateFromHeatDistributionSystem = "WaterMassFlowRateFromHeatDistributionSystem" State = "State" # Output @@ -202,10 +199,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) @@ -245,6 +238,13 @@ def __init__( lt.Units.KG_PER_SEC, False, ) + self.water_mass_flow_rate_hds_input_channel: ComponentInput = self.add_input( + self.component_name, + self.WaterMassFlowRateFromHeatDistributionSystem, + 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 +337,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( @@ -435,6 +442,10 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc self.water_mass_flow_rate_heat_generator_input_channel ) + water_mass_flow_rate_from_hds_in_kg_per_second = stsv.get_input_value( + self.water_mass_flow_rate_hds_input_channel + ) + # Water Temperature Limit Check -------------------------------------------------------------------------------------------------------- if ( @@ -454,7 +465,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, ) From b6a0d93236b398945c81cd970ad1e5444c786ad1 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Mon, 29 Apr 2024 12:40:44 +0200 Subject: [PATCH 09/21] adapt system setups and tests to hot water storage model --- hisim/components/simple_hot_water_storage.py | 4 ++-- .../automatic_default_connections.py | 1 - .../household_1_advanced_hp_diesel_car.py | 1 - .../household_2_advanced_hp_diesel_car_pv.py | 1 - ...old_3_advanced_hp_diesel_car_pv_battery.py | 1 - ..._4a_with_car_priority_advanced_hp_ev_pv.py | 1 - ..._car_priority_advanced_hp_ev_pv_battery.py | 1 - ...hold_cluster_advanced_hp_pv_battery_ems.py | 1 - ...household_cluster_reference_advanced_hp.py | 1 - system_setups/household_gas_heater.py | 1 - system_setups/household_heat_pump.py | 1 - .../household_hp_hws_hds_pv_battery_ems.py | 1 - ...usehold_reference_gas_heater_diesel_car.py | 1 - ...with_advanced_hp_hws_hds_pv_battery_ems.py | 1 - ..._controller_l2_energy_management_system.py | 1 - tests/test_simple_hot_water_storage.py | 23 ++++++++++++++----- tests/test_sizing_energy_systems.py | 1 - 17 files changed, 19 insertions(+), 23 deletions(-) diff --git a/hisim/components/simple_hot_water_storage.py b/hisim/components/simple_hot_water_storage.py index aede1cd34..8edc4ff5e 100644 --- a/hisim/components/simple_hot_water_storage.py +++ b/hisim/components/simple_hot_water_storage.py @@ -238,7 +238,7 @@ def __init__( lt.Units.KG_PER_SEC, False, ) - self.water_mass_flow_rate_hds_input_channel: ComponentInput = self.add_input( + self.water_mass_flow_rate_heat_distribution_system_input_channel: ComponentInput = self.add_input( self.component_name, self.WaterMassFlowRateFromHeatDistributionSystem, lt.LoadTypes.WARM_WATER, @@ -443,7 +443,7 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc ) water_mass_flow_rate_from_hds_in_kg_per_second = stsv.get_input_value( - self.water_mass_flow_rate_hds_input_channel + self.water_mass_flow_rate_heat_distribution_system_input_channel ) # Water Temperature Limit Check -------------------------------------------------------------------------------------------------------- diff --git a/system_setups/automatic_default_connections.py b/system_setups/automatic_default_connections.py index 49d8ec09e..eda1ef94a 100644 --- a/system_setups/automatic_default_connections.py +++ b/system_setups/automatic_default_connections.py @@ -144,7 +144,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 8da289eb2..c22b681a4 100644 --- a/system_setups/household_1_advanced_hp_diesel_car.py +++ b/system_setups/household_1_advanced_hp_diesel_car.py @@ -152,7 +152,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_2_advanced_hp_diesel_car_pv.py b/system_setups/household_2_advanced_hp_diesel_car_pv.py index d03e22e21..5b6fdf119 100644 --- a/system_setups/household_2_advanced_hp_diesel_car_pv.py +++ b/system_setups/household_2_advanced_hp_diesel_car_pv.py @@ -149,7 +149,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 3e58a1ba5..485499189 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 @@ -149,7 +149,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 4af32e09f..bd71d7cd2 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 @@ -153,7 +153,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 202601049..de1464029 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 @@ -157,7 +157,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 a68a433f5..419ec15b8 100644 --- a/system_setups/household_cluster_advanced_hp_pv_battery_ems.py +++ b/system_setups/household_cluster_advanced_hp_pv_battery_ems.py @@ -258,7 +258,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 18388d4ad..8260162a6 100644 --- a/system_setups/household_cluster_reference_advanced_hp.py +++ b/system_setups/household_cluster_reference_advanced_hp.py @@ -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_gas_heater.py b/system_setups/household_gas_heater.py index 501fc70a3..ad80e0073 100644 --- a/system_setups/household_gas_heater.py +++ b/system_setups/household_gas_heater.py @@ -170,7 +170,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 a58e0e100..fa74f8708 100644 --- a/system_setups/household_heat_pump.py +++ b/system_setups/household_heat_pump.py @@ -186,7 +186,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 22307b384..71718288e 100644 --- a/system_setups/household_hp_hws_hds_pv_battery_ems.py +++ b/system_setups/household_hp_hws_hds_pv_battery_ems.py @@ -159,7 +159,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 4f9f78edc..83b360e38 100644 --- a/system_setups/household_reference_gas_heater_diesel_car.py +++ b/system_setups/household_reference_gas_heater_diesel_car.py @@ -124,7 +124,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 ec33053cc..e32442fac 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 @@ -159,7 +159,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/tests/test_controller_l2_energy_management_system.py b/tests/test_controller_l2_energy_management_system.py index c2758fae3..1cd0b8c74 100644 --- a/tests/test_controller_l2_energy_management_system.py +++ b/tests/test_controller_l2_energy_management_system.py @@ -178,7 +178,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_simple_hot_water_storage.py b/tests/test_simple_hot_water_storage.py index 2ecf7f95b..3f87e3a6a 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( @@ -53,13 +52,19 @@ def simulate_simple_water_storage( 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 +91,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 +109,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 +122,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 +130,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 +143,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 db28c99f0..9bd21f747 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 From 8ed1ab823b03e3c4ae740a0f9fe6385a5df2610a Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Thu, 2 May 2024 14:14:36 +0200 Subject: [PATCH 10/21] use parameters of task 44 iea Annex 38 for calculation of heat transfer --- hisim/components/heat_distribution_system.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index 19ca27ba0..847b4cfc5 100644 --- a/hisim/components/heat_distribution_system.py +++ b/hisim/components/heat_distribution_system.py @@ -436,11 +436,11 @@ def determine_water_temperature_input_output_effective_thermal_power_without_mas # assumption2: heat transfer direction just to the room --> other direction is adiabatic # assumption3: still air and no floor covering considered - height_of_screed = 45 / 1000 # in m + 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 = 17 / 1000 # in m # source 1 - outer_pipe_diameter = (17 + 4.4) / 1000 # in m # source 1 + 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 From 0b73c1ade0661158380e09395556bf8b01b83a05 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Thu, 2 May 2024 17:55:17 +0200 Subject: [PATCH 11/21] clear code --- hisim/components/heat_distribution_system.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index 847b4cfc5..3bb6860ac 100644 --- a/hisim/components/heat_distribution_system.py +++ b/hisim/components/heat_distribution_system.py @@ -532,11 +532,8 @@ def determine_water_temperature_output_after_heat_exchange_with_building_and_eff # in case no heating or cooling needed, water output is equal to water input elif theoretical_thermal_buiding_demand_in_watt == 0: - print(water_temperature_output_in_celsius) water_temperature_output_in_celsius = water_temperature_input_in_celsius thermal_power_delivered_effective_in_watt = 0 - print(water_temperature_input_in_celsius) - print(water_temperature_output_in_celsius) else: raise ValueError( f"Theoretical thermal demand has unacceptable value here {theoretical_thermal_buiding_demand_in_watt}." From edd358cb7b85ee22799d428be81d0dc6f3418629 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Thu, 2 May 2024 23:30:36 +0200 Subject: [PATCH 12/21] dateiname mit "00" beginnen, damit im result ornder ganz oben und schnell zu finden zwischen ergebnis csv --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 25f492540..4b5c796c0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,6 +25,6 @@ ordered_set typing_extensions python-dotenv windpowerlib==0.2.1 -wetterdienst==0.68.0 +wetterdienst cdsapi xarray \ No newline at end of file From 1f158dc8f0727f29dccdf10642ab74a5ae0f6789 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Mon, 6 May 2024 10:33:32 +0200 Subject: [PATCH 13/21] - add new fuctions in hp model for simulating system setups without hot water storage --> connection heat pump to hds directly - adapt system setups and tests to "new" parameters from hds model and hp model - new system setup example for heating systems without hot water storage --- .../more_advanced_heat_pump_hplib.py | 258 ++++++++--- ...ousehold_1b_more_advanced_hp_diesel_car.py | 4 +- ...d_1c_more_advanced_hp_dhw_hp_diesel_car.py | 3 +- ...advanced_hp_dhw_hp_no_hot_water_storage.py | 432 ++++++++++++++++++ ...ehold_with_more_advanced_hp_hws_dhw_hds.py | 2 +- tests/test_more_advanced_heat_pump_hplib.py | 7 +- ...t_more_advanced_heat_pump_hplib_only_sh.py | 7 +- ...advanced_hp_dhw_hp_no_hot_water_storage.py | 28 ++ 8 files changed, 661 insertions(+), 80 deletions(-) create mode 100644 system_setups/household_1d_more_advanced_hp_dhw_hp_no_hot_water_storage.py create mode 100644 tests/test_system_setups_household_1d_more_advanced_hp_dhw_hp_no_hot_water_storage.py diff --git a/hisim/components/more_advanced_heat_pump_hplib.py b/hisim/components/more_advanced_heat_pump_hplib.py index 7b06ebdfe..008481f64 100644 --- a/hisim/components/more_advanced_heat_pump_hplib.py +++ b/hisim/components/more_advanced_heat_pump_hplib.py @@ -9,6 +9,7 @@ preparation on district heating for water/water heatpumps """ + import hashlib # clean @@ -17,6 +18,7 @@ from typing import Any, List, Optional, Tuple, Dict 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 +46,7 @@ Euro, Years, KilowattHour, + KilogramPerSecond, ) from hisim.components.configuration import PhysicsConfig @@ -61,7 +64,6 @@ @dataclass_json @dataclass class HeatPumpHplibWithTwoOutputsConfig(ConfigBase): - """HeatPumpHplibWithTwoOutputsConfig.""" @classmethod @@ -82,6 +84,10 @@ def get_main_classname(cls): temperature_difference_primary_side: float with_hot_water_storage: bool 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: Optional[Quantity[float, KilogramPerSecond]] + minimum_thermal_output_power_in_watt: Optional[Quantity[float, Watt]] #: CO2 footprint of investment in kg co2_footprint: Quantity[float, Kilogram] #: cost for investment in Euro @@ -98,6 +104,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. @@ -118,17 +128,15 @@ def get_default_generic_advanced_hp_lib( temperature_difference_primary_side=2, with_hot_water_storage=True, 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 +146,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.""" @@ -157,14 +169,14 @@ def get_scaled_advanced_hp_lib( temperature_difference_primary_side=2, with_hot_water_storage=True, 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 +185,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 +203,7 @@ class HeatPumpHplibWithTwoOutputs(Component): TemperatureInputSecondary_SH = "TemperatureInputSecondarySpaceHeating" # °C TemperatureInputSecondary_DHW = "TemperatureInputSecondaryDWH" # °C TemperatureAmbient = "TemperatureAmbient" # °C + HeatingFlowTemperatureHDSController = "HeatingFlowTemperatureHDSController" # Outputs ThermalOutputPowerSH = "ThermalOutputPowerSpaceHeating" # W @@ -230,6 +242,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, @@ -262,6 +275,18 @@ def __init__( self.with_hot_water_storage = config.with_hot_water_storage + self.m_dot_ref = ( + 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.with_domestic_hot_water_preparation = config.with_domestic_hot_water_preparation self.heat_source = config.heat_source @@ -300,11 +325,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 +415,15 @@ def __init__( mandatory=True, ) + if not self.with_hot_water_storage: + self.heating_flow_temperature_hds_controller: ComponentInput = self.add_input( + self.component_name, + self.HeatingFlowTemperatureHDSController, + LoadTypes.TEMPERATURE, + Units.CELSIUS, + True, + ) + # Define component outputs self.p_th_sh: ComponentOutput = self.add_output( object_name=self.component_name, @@ -578,6 +615,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 +730,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.with_hot_water_storage: + 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 +870,21 @@ 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 not self.with_hot_water_storage: + heating_flow_temperature_hds_controller = stsv.get_input_value(self.heating_flow_temperature_hds_controller) + 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,36 +919,86 @@ 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.with_hot_water_storage: + 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 + p_el_cooling = 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 + m_dot_sh = results["m_dot"] + m_dot_dhw = 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 + t_out_set = heating_flow_temperature_hds_controller + + self.heatpump.delta_t = min(t_out_set - t_in_secondary_sh, 5) + + print(self.heatpump.delta_t) + + 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 + ) + + t_out_dhw = t_in_secondary_dhw + p_th_dhw = 0.0 + p_el_dhw = 0 + p_el_cooling = 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 elif on_off == 2: # Calculate outputs for dhw 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_dhw, - parameters=self.parameters, t_amb=t_amb, mode=1, ) @@ -901,44 +1006,44 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc p_th_sh = 0.0 p_el_sh = 0 p_el_cooling = 0 - cop = results["COP"].values[0] - eer = results["EER"].values[0] + cop = results["COP"] + eer = results["EER"] t_out_sh = t_in_secondary_sh - t_out_dhw = results["T_out"].values[0] + t_out_dhw = results["T_out"] m_dot_sh = 0 - m_dot_dhw = results["m_dot"].values[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"].values[0] - p_el_dhw = results["P_el"].values[0] + 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 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_sh = results["P_el"] p_el_dhw = 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] + 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 - m_dot_sh = results["m_dot"].values[0] + m_dot_sh = results["m_dot"] m_dot_dhw = 0 time_on_cooling = time_on_cooling + self.my_simulation_parameters.seconds_per_timestep time_on_heating = 0 @@ -1066,6 +1171,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 +1203,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 +1222,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 +1243,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 +1266,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 +1275,6 @@ def get_cached_results_or_run_hplib_simulation( @dataclass class HeatPumpWithTwoOutputsState: - """HeatPumpWithTwoOutputsState class.""" time_on_heating: int @@ -1186,6 +1290,7 @@ class HeatPumpWithTwoOutputsState: counter_switch_sh: int counter_switch_dhw: int counter_onoff: int + delta_t: float def self_copy( self, @@ -1205,6 +1310,7 @@ def self_copy( self.counter_switch_sh, self.counter_switch_dhw, self.counter_onoff, + self.delta_t, ) @@ -1226,7 +1332,6 @@ def get_key(self): @dataclass_json @dataclass class HeatPumpHplibControllerSpaceHeatingConfig(ConfigBase): - """HeatPump Controller Config Class for building heating.""" @classmethod @@ -1244,7 +1349,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 +1360,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 +1389,7 @@ class HeatPumpHplibControllerSpaceHeating(Component): """ # Inputs - WaterTemperatureInputFromHeatWaterStorage = "WaterTemperatureInputFromHeatWaterStorage" + WaterTemperatureInputSecondarySide = "WaterTemperatureInputSecondarySide" HeatingFlowTemperatureFromHeatDistributionSystem = "HeatingFlowTemperatureFromHeatDistributionSystem" DailyAverageOutsideTemperature = "DailyAverageOutsideTemperature" @@ -1316,7 +1423,7 @@ def __init__( self.water_temperature_input_channel: ComponentInput = self.add_input( self.component_name, - self.WaterTemperatureInputFromHeatWaterStorage, + self.WaterTemperatureInputSecondarySide, LoadTypes.TEMPERATURE, Units.CELSIUS, True, @@ -1398,7 +1505,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.WaterTemperatureInputSecondarySide, hws_classname, simple_hot_water_storage.SimpleHotWaterStorage.WaterTemperatureToHeatGenerator, ) @@ -1456,7 +1563,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( + water_temperature_input_secondary_side_in_celsius = stsv.get_input_value( self.water_temperature_input_channel ) @@ -1481,7 +1588,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_secondary_side_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 +1604,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_secondary_side_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 +1693,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 +1794,6 @@ def summer_cooling_condition( @dataclass_json @dataclass class HeatPumpHplibControllerDHWConfig(ConfigBase): - """HeatPump Controller Config Class.""" @classmethod @@ -1713,7 +1824,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 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 c53ed3341..05d385415 100644 --- a/system_setups/household_1b_more_advanced_hp_diesel_car.py +++ b/system_setups/household_1b_more_advanced_hp_diesel_car.py @@ -135,6 +135,7 @@ def get_scaled_default( 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 +152,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 +357,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 8abddce08..751611cfb 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"] @@ -140,6 +141,7 @@ def get_scaled_default( 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 +159,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 000000000..ae4b99eca --- /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( + 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( + 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.with_hot_water_storage = False + 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.WaterTemperatureInputSecondarySide, + my_heat_distribution.component_name, + my_heat_distribution.WaterTemperatureOutput, + ) + + my_heat_pump.connect_input( + my_heat_pump.HeatingFlowTemperatureHDSController, + 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_with_more_advanced_hp_hws_dhw_hds.py b/system_setups/household_with_more_advanced_hp_hws_dhw_hds.py index 325012a74..11a4e115d 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 @@ -157,6 +157,7 @@ def setup_function( 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 +170,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_more_advanced_heat_pump_hplib.py b/tests/test_more_advanced_heat_pump_hplib.py index d884113ac..0033d1248 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 @@ -60,6 +60,10 @@ def test_heat_pump_hplib_new(): temperature_difference_primary_side=2, with_hot_water_storage=True, 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 dd6ea1bc4..134dcbb6f 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 @@ -53,6 +53,10 @@ def test_heat_pump_hplib_new(): temperature_difference_primary_side=2, with_hot_water_storage=True, 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_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 000000000..876d6234e --- /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()) From b9c07aebbc33be0868b92a94c582dd5d70ad78ac Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Wed, 8 May 2024 15:58:29 +0200 Subject: [PATCH 14/21] - some renaming - clean up hds config in system setups - additional usage of simple_hot_water_storage.py for system setup with storage in serie to hds and hp --- hisim/components/heat_distribution_system.py | 20 ++--- .../more_advanced_heat_pump_hplib.py | 44 +++++----- hisim/components/simple_hot_water_storage.py | 84 ++++++++++++------- .../automatic_default_connections.py | 1 - .../household_1_advanced_hp_diesel_car.py | 1 - ...ousehold_1b_more_advanced_hp_diesel_car.py | 1 - ...d_1c_more_advanced_hp_dhw_hp_diesel_car.py | 1 - ...advanced_hp_dhw_hp_no_hot_water_storage.py | 5 +- .../household_2_advanced_hp_diesel_car_pv.py | 1 - ...old_3_advanced_hp_diesel_car_pv_battery.py | 1 - ..._4a_with_car_priority_advanced_hp_ev_pv.py | 1 - ..._car_priority_advanced_hp_ev_pv_battery.py | 1 - ...hold_cluster_advanced_hp_pv_battery_ems.py | 1 - ...household_cluster_reference_advanced_hp.py | 1 - system_setups/household_gas_heater.py | 1 - system_setups/household_heat_pump.py | 1 - .../household_hp_hws_hds_pv_battery_ems.py | 1 - ...usehold_reference_gas_heater_diesel_car.py | 1 - ...with_advanced_hp_hws_hds_pv_battery_ems.py | 1 - ...ehold_with_more_advanced_hp_hws_dhw_hds.py | 1 - ..._controller_l2_energy_management_system.py | 1 - tests/test_heat_distribution_system.py | 3 +- tests/test_more_advanced_heat_pump_hplib.py | 2 +- ...t_more_advanced_heat_pump_hplib_only_sh.py | 2 +- tests/test_simple_hot_water_storage.py | 1 + 25 files changed, 88 insertions(+), 90 deletions(-) diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index 3bb6860ac..e42bec10b 100644 --- a/hisim/components/heat_distribution_system.py +++ b/hisim/components/heat_distribution_system.py @@ -48,10 +48,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 - with_hot_water_storage: bool + with_parallel_hot_water_storage: bool #: CO2 footprint of investment in kg co2_footprint: float #: cost for investment in Euro @@ -64,18 +63,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, - with_hot_water_storage: bool = True, + with_parallel_hot_water_storage: bool = True, ) -> 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, - with_hot_water_storage=with_hot_water_storage, + with_parallel_hot_water_storage=with_parallel_hot_water_storage, 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 @@ -145,9 +142,6 @@ def __init__( self.thermal_power_delivered_in_watt: float = 0.0 self.water_temperature_output_in_celsius: float = 21 self.water_input_temperature_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.heating_distribution_system_water_mass_flow_rate_in_kg_per_second = ( self.heat_distribution_system_config.water_mass_flow_rate_in_kg_per_second @@ -157,7 +151,7 @@ def __init__( self.heat_distribution_system_config.absolute_conditioned_floor_area_in_m2 ) - self.heat_distribution_system_with_storage = self.heat_distribution_system_config.with_hot_water_storage + self.heat_distribution_system_with_parallel_storage = self.heat_distribution_system_config.with_parallel_hot_water_storage self.build() @@ -197,7 +191,7 @@ def __init__( True, ) - if not self.heat_distribution_system_with_storage: + if not self.heat_distribution_system_with_parallel_storage: # just important for heating system without bufferstorage self.water_mass_flow_rate_hp_in_kg_per_second_channel: cp.ComponentInput = self.add_input( self.component_name, @@ -246,7 +240,7 @@ def __init__( self.add_default_connections(self.get_default_connections_from_heat_distribution_controller()) self.add_default_connections(self.get_default_connections_from_building()) - if self.heat_distribution_system_with_storage: + if self.heat_distribution_system_with_parallel_storage: self.add_default_connections(self.get_default_connections_from_simple_hot_water_storage()) def get_default_connections_from_heat_distribution_controller( @@ -352,7 +346,7 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg ) residence_temperature_input_in_celsius = stsv.get_input_value(self.residence_temperature_input_channel) - if self.heat_distribution_system_with_storage: + if self.heat_distribution_system_with_parallel_storage: water_mass_flow_rate_in_kg_per_second = ( self.heating_distribution_system_water_mass_flow_rate_in_kg_per_second ) diff --git a/hisim/components/more_advanced_heat_pump_hplib.py b/hisim/components/more_advanced_heat_pump_hplib.py index 008481f64..a48d5cda9 100644 --- a/hisim/components/more_advanced_heat_pump_hplib.py +++ b/hisim/components/more_advanced_heat_pump_hplib.py @@ -82,7 +82,7 @@ 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 + with_parallel_hot_water_storage: bool 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]] @@ -126,7 +126,7 @@ 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, + with_parallel_hot_water_storage=True, 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, @@ -167,7 +167,7 @@ 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, + with_parallel_hot_water_storage=True, 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, @@ -203,7 +203,7 @@ class HeatPumpHplibWithTwoOutputs(Component): TemperatureInputSecondary_SH = "TemperatureInputSecondarySpaceHeating" # °C TemperatureInputSecondary_DHW = "TemperatureInputSecondaryDWH" # °C TemperatureAmbient = "TemperatureAmbient" # °C - HeatingFlowTemperatureHDSController = "HeatingFlowTemperatureHDSController" + SetHeatingTemperatureSpaceHeating = "SetHeatingTemperatureSpaceHeating" # Outputs ThermalOutputPowerSH = "ThermalOutputPowerSpaceHeating" # W @@ -273,7 +273,7 @@ def __init__( self.cycling_mode = config.cycling_mode - self.with_hot_water_storage = config.with_hot_water_storage + self.with_parallel_hot_water_storage = config.with_parallel_hot_water_storage self.m_dot_ref = ( config.massflow_nominal_secondary_side_in_kg_per_s.value @@ -415,10 +415,10 @@ def __init__( mandatory=True, ) - if not self.with_hot_water_storage: - self.heating_flow_temperature_hds_controller: ComponentInput = self.add_input( + if not self.with_parallel_hot_water_storage: + self.set_temperature_hp_sh: ComponentInput = self.add_input( self.component_name, - self.HeatingFlowTemperatureHDSController, + self.SetHeatingTemperatureSpaceHeating, LoadTypes.TEMPERATURE, Units.CELSIUS, True, @@ -731,7 +731,7 @@ 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()) - if self.with_hot_water_storage: + if self.with_parallel_hot_water_storage: self.add_default_connections(self.get_default_connections_from_simple_hot_water_storage()) if self.with_domestic_hot_water_preparation: @@ -870,8 +870,8 @@ 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 not self.with_hot_water_storage: - heating_flow_temperature_hds_controller = stsv.get_input_value(self.heating_flow_temperature_hds_controller) + if not self.with_parallel_hot_water_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) @@ -919,7 +919,7 @@ 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 - if self.with_hot_water_storage: + if self.with_parallel_hot_water_storage: self.heatpump.delta_t = 5 results = self.get_cached_results_or_run_hplib_simulation( force_convergence=force_convergence, @@ -946,11 +946,11 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc else: m_dot_sh = self.m_dot_ref - t_out_set = heating_flow_temperature_hds_controller - self.heatpump.delta_t = min(t_out_set - t_in_secondary_sh, 5) + self.heatpump.delta_t = min(set_temperature_hp_sh - t_in_secondary_sh, 5) - print(self.heatpump.delta_t) + 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, @@ -984,6 +984,8 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc 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 p_th_dhw = 0.0 p_el_dhw = 0 @@ -1389,7 +1391,7 @@ class HeatPumpHplibControllerSpaceHeating(Component): """ # Inputs - WaterTemperatureInputSecondarySide = "WaterTemperatureInputSecondarySide" + WaterTemperatureInput = "WaterTemperatureInput" HeatingFlowTemperatureFromHeatDistributionSystem = "HeatingFlowTemperatureFromHeatDistributionSystem" DailyAverageOutsideTemperature = "DailyAverageOutsideTemperature" @@ -1423,7 +1425,7 @@ def __init__( self.water_temperature_input_channel: ComponentInput = self.add_input( self.component_name, - self.WaterTemperatureInputSecondarySide, + self.WaterTemperatureInput, LoadTypes.TEMPERATURE, Units.CELSIUS, True, @@ -1505,7 +1507,7 @@ def get_default_connections_from_simple_hot_water_storage( hws_classname = simple_hot_water_storage.SimpleHotWaterStorage.get_classname() connections.append( ComponentConnection( - HeatPumpHplibControllerSpaceHeating.WaterTemperatureInputSecondarySide, + HeatPumpHplibControllerSpaceHeating.WaterTemperatureInput, hws_classname, simple_hot_water_storage.SimpleHotWaterStorage.WaterTemperatureToHeatGenerator, ) @@ -1563,7 +1565,7 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc else: # Retrieves inputs - water_temperature_input_secondary_side_in_celsius = stsv.get_input_value( + water_temperature_input_in_celsius = stsv.get_input_value( self.water_temperature_input_channel ) @@ -1588,7 +1590,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_secondary_side_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, @@ -1604,7 +1606,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_secondary_side_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, diff --git a/hisim/components/simple_hot_water_storage.py b/hisim/components/simple_hot_water_storage.py index 8edc4ff5e..8883b5884 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,6 +58,7 @@ 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 #: CO2 footprint of investment in kg @@ -72,6 +81,7 @@ def get_default_simplehotwaterstorage_config( 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 @@ -126,6 +136,7 @@ def get_scaled_hot_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=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 @@ -206,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( @@ -224,20 +236,6 @@ 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.component_name, - self.WaterMassFlowRateFromHeatGenerator, - lt.LoadTypes.WARM_WATER, - lt.Units.KG_PER_SEC, - False, - ) self.water_mass_flow_rate_heat_distribution_system_input_channel: ComponentInput = self.add_input( self.component_name, self.WaterMassFlowRateFromHeatDistributionSystem, @@ -246,6 +244,23 @@ def __init__( 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 ) @@ -428,24 +443,29 @@ 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 - ) - - # 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 - ) water_mass_flow_rate_from_hds_in_kg_per_second = stsv.get_input_value( self.water_mass_flow_rate_heat_distribution_system_input_channel ) + 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_temperature_from_heat_generator_in_celsius = 0 + water_mass_flow_rate_from_heat_generator_in_kg_per_second = 0 + # Water Temperature Limit Check -------------------------------------------------------------------------------------------------------- if ( @@ -548,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/system_setups/automatic_default_connections.py b/system_setups/automatic_default_connections.py index eda1ef94a..999cdcbf6 100644 --- a/system_setups/automatic_default_connections.py +++ b/system_setups/automatic_default_connections.py @@ -131,7 +131,6 @@ 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( diff --git a/system_setups/household_1_advanced_hp_diesel_car.py b/system_setups/household_1_advanced_hp_diesel_car.py index c22b681a4..8772f4800 100644 --- a/system_setups/household_1_advanced_hp_diesel_car.py +++ b/system_setups/household_1_advanced_hp_diesel_car.py @@ -136,7 +136,6 @@ 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 ) 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 05d385415..e953858eb 100644 --- a/system_setups/household_1b_more_advanced_hp_diesel_car.py +++ b/system_setups/household_1b_more_advanced_hp_diesel_car.py @@ -133,7 +133,6 @@ 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 ) 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 751611cfb..18e8492fc 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 @@ -139,7 +139,6 @@ 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 ) 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 index ae4b99eca..38b6032d9 100644 --- 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 @@ -136,7 +136,6 @@ 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, ) @@ -376,13 +375,13 @@ def setup_function( my_heat_pump_controller.connect_only_predefined_connections(my_heat_distribution_controller, my_weather) my_heat_pump_controller.connect_input( - my_heat_pump_controller.WaterTemperatureInputSecondarySide, + my_heat_pump_controller.WaterTemperatureInput, my_heat_distribution.component_name, my_heat_distribution.WaterTemperatureOutput, ) my_heat_pump.connect_input( - my_heat_pump.HeatingFlowTemperatureHDSController, + my_heat_pump.SetHeatingTemperatureSpaceHeating, my_heat_distribution_controller.component_name, my_heat_distribution_controller.HeatingFlowTemperature, ) 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 5b6fdf119..2c1a4d995 100644 --- a/system_setups/household_2_advanced_hp_diesel_car_pv.py +++ b/system_setups/household_2_advanced_hp_diesel_car_pv.py @@ -128,7 +128,6 @@ 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 ) 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 485499189..81a7eb473 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,7 +130,6 @@ 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 ) 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 bd71d7cd2..3e025e9a1 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,7 +134,6 @@ 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 ) 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 de1464029..0a7562a7e 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,7 +138,6 @@ 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 ) 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 419ec15b8..550186fdf 100644 --- a/system_setups/household_cluster_advanced_hp_pv_battery_ems.py +++ b/system_setups/household_cluster_advanced_hp_pv_battery_ems.py @@ -243,7 +243,6 @@ 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 ) diff --git a/system_setups/household_cluster_reference_advanced_hp.py b/system_setups/household_cluster_reference_advanced_hp.py index 8260162a6..47fad980c 100644 --- a/system_setups/household_cluster_reference_advanced_hp.py +++ b/system_setups/household_cluster_reference_advanced_hp.py @@ -245,7 +245,6 @@ 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 ) diff --git a/system_setups/household_gas_heater.py b/system_setups/household_gas_heater.py index ad80e0073..6ff5289ac 100644 --- a/system_setups/household_gas_heater.py +++ b/system_setups/household_gas_heater.py @@ -153,7 +153,6 @@ 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 ) diff --git a/system_setups/household_heat_pump.py b/system_setups/household_heat_pump.py index fa74f8708..a100858ed 100644 --- a/system_setups/household_heat_pump.py +++ b/system_setups/household_heat_pump.py @@ -163,7 +163,6 @@ 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 ) 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 71718288e..3014db497 100644 --- a/system_setups/household_hp_hws_hds_pv_battery_ems.py +++ b/system_setups/household_hp_hws_hds_pv_battery_ems.py @@ -145,7 +145,6 @@ 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 ) diff --git a/system_setups/household_reference_gas_heater_diesel_car.py b/system_setups/household_reference_gas_heater_diesel_car.py index 83b360e38..8b716ab69 100644 --- a/system_setups/household_reference_gas_heater_diesel_car.py +++ b/system_setups/household_reference_gas_heater_diesel_car.py @@ -107,7 +107,6 @@ 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 ) 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 e32442fac..e3dd34672 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,7 +145,6 @@ 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 ) 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 11a4e115d..62f93b8e4 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,7 +155,6 @@ 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 ) diff --git a/tests/test_controller_l2_energy_management_system.py b/tests/test_controller_l2_energy_management_system.py index 8d3588da5..6858a427c 100644 --- a/tests/test_controller_l2_energy_management_system.py +++ b/tests/test_controller_l2_energy_management_system.py @@ -162,7 +162,6 @@ 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 ) diff --git a/tests/test_heat_distribution_system.py b/tests/test_heat_distribution_system.py index b908580b8..5c4486cdf 100644 --- a/tests/test_heat_distribution_system.py +++ b/tests/test_heat_distribution_system.py @@ -130,9 +130,8 @@ 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, - with_hot_water_storage=True, + with_parallel_hot_water_storage=True, absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) diff --git a/tests/test_more_advanced_heat_pump_hplib.py b/tests/test_more_advanced_heat_pump_hplib.py index 0033d1248..939e5aa41 100644 --- a/tests/test_more_advanced_heat_pump_hplib.py +++ b/tests/test_more_advanced_heat_pump_hplib.py @@ -58,7 +58,7 @@ 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, + with_parallel_hot_water_storage=True, 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, 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 134dcbb6f..356694c4f 100644 --- a/tests/test_more_advanced_heat_pump_hplib_only_sh.py +++ b/tests/test_more_advanced_heat_pump_hplib_only_sh.py @@ -51,7 +51,7 @@ 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, + with_parallel_hot_water_storage=True, 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, diff --git a/tests/test_simple_hot_water_storage.py b/tests/test_simple_hot_water_storage.py index 3f87e3a6a..d9e9e5a0f 100644 --- a/tests/test_simple_hot_water_storage.py +++ b/tests/test_simple_hot_water_storage.py @@ -48,6 +48,7 @@ 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, From 45ccdb4e0fbcd8c9969b6cb1b7bd7dd5458c17b9 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Wed, 8 May 2024 16:09:46 +0200 Subject: [PATCH 15/21] fix parameters in system setup household 1b --- ...ousehold_1d_more_advanced_hp_dhw_hp_no_hot_water_storage.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 index 38b6032d9..2fc9a8057 100644 --- 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 @@ -138,6 +138,7 @@ def get_scaled_default( 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, + with_parallel_hot_water_storage=False, ) ), hp_controller_config=more_advanced_heat_pump_hplib.HeatPumpHplibControllerSpaceHeatingConfig.get_default_space_heating_controller_config( @@ -178,7 +179,7 @@ def get_scaled_default( 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.with_hot_water_storage = False + household_config.hp_config.with_parallel_hot_water_storage = False household_config.hp_config.cycling_mode = False # set same heating threshold From e04f6e659ea05c0697aea62cc81094eb16132c1e Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Mon, 13 May 2024 18:17:03 +0200 Subject: [PATCH 16/21] - use nominal water massflow in dhw part also, if there is no parallel storage --> water pump runs in both operation modes with constant massflow (checked with polysun simulation if operation modes are right) - some restructuring due to errors with mypy in combination with units and Quantity class --- .../more_advanced_heat_pump_hplib.py | 185 ++++++++++++------ 1 file changed, 121 insertions(+), 64 deletions(-) diff --git a/hisim/components/more_advanced_heat_pump_hplib.py b/hisim/components/more_advanced_heat_pump_hplib.py index a48d5cda9..7fb48fcb5 100644 --- a/hisim/components/more_advanced_heat_pump_hplib.py +++ b/hisim/components/more_advanced_heat_pump_hplib.py @@ -86,8 +86,8 @@ def get_main_classname(cls): 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: Optional[Quantity[float, KilogramPerSecond]] - minimum_thermal_output_power_in_watt: Optional[Quantity[float, Watt]] + 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 @@ -273,21 +273,38 @@ def __init__( self.cycling_mode = config.cycling_mode + self.with_domestic_hot_water_preparation = config.with_domestic_hot_water_preparation + self.with_parallel_hot_water_storage = config.with_parallel_hot_water_storage - self.m_dot_ref = ( - 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.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.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.with_domestic_hot_water_preparation = config.with_domestic_hot_water_preparation + 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 not self.with_parallel_hot_water_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 @@ -932,14 +949,14 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc p_th_sh = results["P_th"] p_th_dhw = 0.0 p_el_sh = results["P_el"] - p_el_dhw = 0 - p_el_cooling = 0 + 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 + 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 + 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 @@ -986,45 +1003,87 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc self.heatpump.delta_t = t_out_sh - t_in_secondary_sh - t_out_dhw = t_in_secondary_dhw + 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 - p_el_cooling = 0 - m_dot_dhw = 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 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_dhw, - t_amb=t_amb, - mode=1, - ) + if self.with_parallel_hot_water_storage: + 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"] - eer = results["EER"] - t_out_sh = t_in_secondary_sh - t_out_dhw = results["T_out"] - m_dot_sh = 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 + 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.heatpump.simulate( + 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 + 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 @@ -1039,34 +1098,34 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc p_th_sh = results["P_th"] p_th_dhw = 0.0 p_el_sh = results["P_el"] - p_el_dhw = 0 + p_el_dhw = 0.0 p_el_cooling = p_el_sh 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 + 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 + 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 @@ -1565,9 +1624,7 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc else: # Retrieves inputs - water_temperature_input_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 From 71f777056a170e2601fc11ea9a4db8d5b9801889 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Thu, 23 May 2024 15:23:16 +0200 Subject: [PATCH 17/21] - rename parameter if system setup have hot water storage --- hisim/components/heat_distribution_system.py | 60 ++++++++++++------- .../more_advanced_heat_pump_hplib.py | 51 ++++++++++++---- ...advanced_hp_dhw_hp_no_hot_water_storage.py | 4 +- tests/test_heat_distribution_system.py | 2 +- tests/test_more_advanced_heat_pump_hplib.py | 2 +- ...t_more_advanced_heat_pump_hplib_only_sh.py | 2 +- 6 files changed, 84 insertions(+), 37 deletions(-) diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index e42bec10b..0d99848f7 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 @@ -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 if hp is massflow of hds, 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 @@ -50,7 +68,7 @@ def get_main_classname(cls): name: str water_mass_flow_rate_in_kg_per_second: float absolute_conditioned_floor_area_in_m2: float - with_parallel_hot_water_storage: bool + position_hot_water_storage_in_system: Union[PositionHotWaterStorageInSystemSetup, int] #: CO2 footprint of investment in kg co2_footprint: float #: cost for investment in Euro @@ -65,14 +83,14 @@ def get_default_heatdistributionsystem_config( cls, water_mass_flow_rate_in_kg_per_second: float, absolute_conditioned_floor_area_in_m2: float, - with_parallel_hot_water_storage: bool = True, + position_hot_water_storage_in_system: int = 1, ) -> Any: """Get a default heat distribution system config.""" config = HeatDistributionConfig( name="HeatDistributionSystem", 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, - with_parallel_hot_water_storage=with_parallel_hot_water_storage, + 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 @@ -83,7 +101,6 @@ def get_default_heatdistributionsystem_config( @dataclass class HeatDistributionSystemState: - """HeatDistributionSystemState class.""" water_output_temperature_in_celsius: float = 25.0 @@ -100,7 +117,6 @@ def self_copy(self): class HeatDistribution(cp.Component): - """Heat Distribution System. It simulates the heat exchange between heat generator and building. @@ -151,7 +167,9 @@ def __init__( self.heat_distribution_system_config.absolute_conditioned_floor_area_in_m2 ) - self.heat_distribution_system_with_parallel_storage = self.heat_distribution_system_config.with_parallel_hot_water_storage + self.position_hot_water_storage_in_system = ( + self.heat_distribution_system_config.position_hot_water_storage_in_system + ) self.build() @@ -191,8 +209,11 @@ def __init__( True, ) - if not self.heat_distribution_system_with_parallel_storage: - # just important for heating system without bufferstorage + 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, @@ -240,7 +261,7 @@ def __init__( self.add_default_connections(self.get_default_connections_from_heat_distribution_controller()) self.add_default_connections(self.get_default_connections_from_building()) - if self.heat_distribution_system_with_parallel_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( @@ -346,7 +367,7 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg ) residence_temperature_input_in_celsius = stsv.get_input_value(self.residence_temperature_input_channel) - if self.heat_distribution_system_with_parallel_storage: + 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 ) @@ -389,12 +410,12 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg # Set outputs ----------------------------------------------------------------------------------------------------------- stsv.set_output_value( self.water_temperature_inlet_channel, - self.state.water_input_temperature_in_celsius + 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 + self.state.water_output_temperature_in_celsius, # water_temperature_output_in_celsius, ) stsv.set_output_value( @@ -404,7 +425,7 @@ def i_simulate(self, timestep: int, stsv: cp.SingleTimeStepValues, force_converg ) stsv.set_output_value( self.thermal_power_delivered_channel, - self.state.thermal_power_delivered_in_watt + self.state.thermal_power_delivered_in_watt, # thermal_power_delivered_in_watt, ) stsv.set_output_value( @@ -440,10 +461,10 @@ def determine_water_temperature_input_output_effective_thermal_power_without_mas height_of_screed / thermal_conductivity_screed + 1 / heat_transfer_coefficient_screed_to_air ) - lenght_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) * lenght_of_hds_pipe # in m^3 + 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 * lenght_of_hds_pipe # in m^2 + 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 @@ -562,7 +583,6 @@ def get_cost_opex( @dataclass_json @dataclass class HeatDistributionControllerConfig(cp.ConfigBase): - """HeatDistribution Controller Config Class.""" @classmethod @@ -601,7 +621,6 @@ def get_default_heat_distribution_controller_config( 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 @@ -1011,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 7fb48fcb5..6ba4148c5 100644 --- a/hisim/components/more_advanced_heat_pump_hplib.py +++ b/hisim/components/more_advanced_heat_pump_hplib.py @@ -14,8 +14,9 @@ # 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 @@ -61,6 +62,25 @@ __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 if hp is massflow of hds, 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): @@ -82,7 +102,7 @@ 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_parallel_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]] @@ -126,7 +146,7 @@ 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_parallel_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, @@ -167,7 +187,7 @@ 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_parallel_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, @@ -275,7 +295,7 @@ def __init__( self.with_domestic_hot_water_preparation = config.with_domestic_hot_water_preparation - self.with_parallel_hot_water_storage = config.with_parallel_hot_water_storage + 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 @@ -293,7 +313,10 @@ def __init__( self.minimum_thermal_output_power = config.minimum_thermal_output_power_in_watt.value - if not self.with_parallel_hot_water_storage: + 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 @@ -432,7 +455,10 @@ def __init__( mandatory=True, ) - if not self.with_parallel_hot_water_storage: + 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, @@ -748,7 +774,7 @@ 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()) - if self.with_parallel_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: @@ -887,7 +913,10 @@ 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 not self.with_parallel_hot_water_storage: + 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: @@ -936,7 +965,7 @@ 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 - if self.with_parallel_hot_water_storage: + 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, @@ -1014,7 +1043,7 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc elif on_off == 2: # Calculate outputs for dhw mode self.heatpump.delta_t = 5 - if self.with_parallel_hot_water_storage: + 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, 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 index 2fc9a8057..cc325f883 100644 --- 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 @@ -138,7 +138,7 @@ def get_scaled_default( 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, - with_parallel_hot_water_storage=False, + position_hot_water_storage_in_system=3, ) ), hp_controller_config=more_advanced_heat_pump_hplib.HeatPumpHplibControllerSpaceHeatingConfig.get_default_space_heating_controller_config( @@ -179,7 +179,7 @@ def get_scaled_default( 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.with_parallel_hot_water_storage = False + household_config.hp_config.position_hot_water_storage_in_system = 3 household_config.hp_config.cycling_mode = False # set same heating threshold diff --git a/tests/test_heat_distribution_system.py b/tests/test_heat_distribution_system.py index 5c4486cdf..9545a4633 100644 --- a/tests/test_heat_distribution_system.py +++ b/tests/test_heat_distribution_system.py @@ -131,7 +131,7 @@ def simulate_and_calculate_hds_outputs_for_a_given_theoretical_heating_demand_fr lifetime=50, maintenance_cost_as_percentage_of_investment=0.01, water_mass_flow_rate_in_kg_per_second=my_hds_controller_information.water_mass_flow_rate_in_kp_per_second, - with_parallel_hot_water_storage=True, + position_hot_water_storage_in_system=1, absolute_conditioned_floor_area_in_m2=my_building_information.scaled_conditioned_floor_area_in_m2 ) diff --git a/tests/test_more_advanced_heat_pump_hplib.py b/tests/test_more_advanced_heat_pump_hplib.py index 939e5aa41..d030c9727 100644 --- a/tests/test_more_advanced_heat_pump_hplib.py +++ b/tests/test_more_advanced_heat_pump_hplib.py @@ -58,7 +58,7 @@ 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_parallel_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, 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 356694c4f..96954784b 100644 --- a/tests/test_more_advanced_heat_pump_hplib_only_sh.py +++ b/tests/test_more_advanced_heat_pump_hplib_only_sh.py @@ -51,7 +51,7 @@ 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_parallel_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, From 155cb9a5ddff3db1532708e643aedad2e38e1973 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Thu, 23 May 2024 17:10:17 +0200 Subject: [PATCH 18/21] correction in comments of PositionHotWaterStorageInSystemSetup class --- hisim/components/heat_distribution_system.py | 2 +- hisim/components/more_advanced_heat_pump_hplib.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hisim/components/heat_distribution_system.py b/hisim/components/heat_distribution_system.py index 0d99848f7..863c903cb 100644 --- a/hisim/components/heat_distribution_system.py +++ b/hisim/components/heat_distribution_system.py @@ -44,7 +44,7 @@ class PositionHotWaterStorageInSystemSetup(IntEnum): Heatpump massflow is calculated in hp model, hds massflow is calculated in hds model. SERIE: - Hot Water Storage in series to hp/hds, massflow if hp is massflow of hds, hot water storage is between output of hds and input of hp + 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 diff --git a/hisim/components/more_advanced_heat_pump_hplib.py b/hisim/components/more_advanced_heat_pump_hplib.py index 6ba4148c5..89c018169 100644 --- a/hisim/components/more_advanced_heat_pump_hplib.py +++ b/hisim/components/more_advanced_heat_pump_hplib.py @@ -70,7 +70,7 @@ class PositionHotWaterStorageInSystemSetup(IntEnum): Heatpump massflow is calculated in hp model, hds massflow is calculated in hds model. SERIE: - Hot Water Storage in series to hp/hds, massflow if hp is massflow of hds, hot water storage is between output of hds and input of hp + 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 From 26573901646ac9c9ed8271dfed009eb0cf96f7ec Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Fri, 24 May 2024 10:48:47 +0200 Subject: [PATCH 19/21] correction in calculation of dhw --> p_el_cooling was missing --- hisim/components/more_advanced_heat_pump_hplib.py | 1 + 1 file changed, 1 insertion(+) diff --git a/hisim/components/more_advanced_heat_pump_hplib.py b/hisim/components/more_advanced_heat_pump_hplib.py index 89c018169..8c04a8e9c 100644 --- a/hisim/components/more_advanced_heat_pump_hplib.py +++ b/hisim/components/more_advanced_heat_pump_hplib.py @@ -1109,6 +1109,7 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc 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 From bb25b63a39ee145f1d4695d6d797162430466689 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Fri, 24 May 2024 14:41:58 +0200 Subject: [PATCH 20/21] some debugging for dhw - in some timestep dhw storage sends zero as input to dhw controller of hp - leads to more switching of hp between sh and dhw mode - solution: save last temperature input in dhw controller and if there will be a zero restore this temperature --- .../components/more_advanced_heat_pump_hplib.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/hisim/components/more_advanced_heat_pump_hplib.py b/hisim/components/more_advanced_heat_pump_hplib.py index 8c04a8e9c..7b5e16eb5 100644 --- a/hisim/components/more_advanced_heat_pump_hplib.py +++ b/hisim/components/more_advanced_heat_pump_hplib.py @@ -1076,12 +1076,14 @@ def i_simulate(self, timestep: int, stsv: SingleTimeStepValues, force_convergenc else: m_dot_dhw = self.m_dot_ref - results = self.heatpump.simulate( + 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"] @@ -2024,8 +2026,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 @@ -2068,10 +2069,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 ) @@ -2081,18 +2083,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 From ec220f278a8f7e1e5dfa7f83728e35d3ea89f5f0 Mon Sep 17 00:00:00 2001 From: Hoppe-J Date: Tue, 18 Jun 2024 13:55:51 +0200 Subject: [PATCH 21/21] - add new output in hp - use hp output for calculating kpis --> now calculation without hot water storage possible --- hisim/components/more_advanced_heat_pump_hplib.py | 10 ++++++++++ hisim/postprocessing/compute_kpis.py | 6 +++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/hisim/components/more_advanced_heat_pump_hplib.py b/hisim/components/more_advanced_heat_pump_hplib.py index 7b5e16eb5..59cd5d818 100644 --- a/hisim/components/more_advanced_heat_pump_hplib.py +++ b/hisim/components/more_advanced_heat_pump_hplib.py @@ -236,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 @@ -520,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, @@ -1241,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) diff --git a/hisim/postprocessing/compute_kpis.py b/hisim/postprocessing/compute_kpis.py index 4a5fc4fd6..c68c1e8e3 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