diff --git a/hub/catalog_factories/data_models/energy_systems/__pycache__/generation_system.cpython-39.pyc b/hub/catalog_factories/data_models/energy_systems/__pycache__/generation_system.cpython-39.pyc index 81666400..59b6f604 100644 Binary files a/hub/catalog_factories/data_models/energy_systems/__pycache__/generation_system.cpython-39.pyc and b/hub/catalog_factories/data_models/energy_systems/__pycache__/generation_system.cpython-39.pyc differ diff --git a/hub/catalog_factories/data_models/energy_systems/__pycache__/non_pv_generation_system.cpython-39.pyc b/hub/catalog_factories/data_models/energy_systems/__pycache__/non_pv_generation_system.cpython-39.pyc index d66f0daa..82f4374c 100644 Binary files a/hub/catalog_factories/data_models/energy_systems/__pycache__/non_pv_generation_system.cpython-39.pyc and b/hub/catalog_factories/data_models/energy_systems/__pycache__/non_pv_generation_system.cpython-39.pyc differ diff --git a/hub/catalog_factories/data_models/energy_systems/__pycache__/pv_generation_system.cpython-39.pyc b/hub/catalog_factories/data_models/energy_systems/__pycache__/pv_generation_system.cpython-39.pyc index 489baa34..882f946d 100644 Binary files a/hub/catalog_factories/data_models/energy_systems/__pycache__/pv_generation_system.cpython-39.pyc and b/hub/catalog_factories/data_models/energy_systems/__pycache__/pv_generation_system.cpython-39.pyc differ diff --git a/hub/catalog_factories/data_models/energy_systems/__pycache__/thermal_storage_system.cpython-39.pyc b/hub/catalog_factories/data_models/energy_systems/__pycache__/thermal_storage_system.cpython-39.pyc index 31ec81fc..b80728fe 100644 Binary files a/hub/catalog_factories/data_models/energy_systems/__pycache__/thermal_storage_system.cpython-39.pyc and b/hub/catalog_factories/data_models/energy_systems/__pycache__/thermal_storage_system.cpython-39.pyc differ diff --git a/hub/catalog_factories/energy_systems/__pycache__/montreal_custom_catalog.cpython-39.pyc b/hub/catalog_factories/energy_systems/__pycache__/montreal_custom_catalog.cpython-39.pyc index 18eeb41c..3e998cac 100644 Binary files a/hub/catalog_factories/energy_systems/__pycache__/montreal_custom_catalog.cpython-39.pyc and b/hub/catalog_factories/energy_systems/__pycache__/montreal_custom_catalog.cpython-39.pyc differ diff --git a/hub/catalog_factories/energy_systems/__pycache__/montreal_future_system_catalogue.cpython-39.pyc b/hub/catalog_factories/energy_systems/__pycache__/montreal_future_system_catalogue.cpython-39.pyc index 0ab98f97..1f9f0180 100644 Binary files a/hub/catalog_factories/energy_systems/__pycache__/montreal_future_system_catalogue.cpython-39.pyc and b/hub/catalog_factories/energy_systems/__pycache__/montreal_future_system_catalogue.cpython-39.pyc differ diff --git a/hub/city_model_structure/building.py b/hub/city_model_structure/building.py index 95f0f167..12692fdf 100644 --- a/hub/city_model_structure/building.py +++ b/hub/city_model_structure/building.py @@ -90,10 +90,8 @@ class Building(CityObject): self._interior_slabs.append(surface) else: logging.error('Building %s [%s] has an unexpected surface type %s.', self.name, self.aliases, surface.type) - self._heating_consumption_disaggregated = {} self._domestic_hot_water_peak_load = None self._fuel_consumption_breakdown = {} - self._domestic_how_water_consumption_disaggregated = {} @property def shell(self) -> Polyhedron: @@ -844,38 +842,6 @@ class Building(CityObject): self._onsite_electrical_production[_key] = _results return self._onsite_electrical_production - @property - def heating_consumption_disaggregated(self) -> dict: - """ - Get energy consumed for heating from different fuels in J - return: dict - """ - return self._heating_consumption_disaggregated - - @heating_consumption_disaggregated.setter - def heating_consumption_disaggregated(self, value): - """ - Get energy consumed for heating from different fuels in J - return: dict - """ - self._heating_consumption_disaggregated = value - - @property - def domestic_how_water_consumption_disaggregated(self) -> dict: - """ - Get energy consumed for heating from different fuels in J - return: dict - """ - return self._domestic_how_water_consumption_disaggregated - - @domestic_how_water_consumption_disaggregated.setter - def domestic_how_water_consumption_disaggregated(self, value): - """ - Get energy consumed for heating from different fuels in J - return: dict - """ - self._domestic_how_water_consumption_disaggregated = value - @property def lower_corner(self): """ @@ -891,45 +857,12 @@ class Building(CityObject): return [self._max_x, self._max_y, self._max_z] @property - def fuel_consumption_breakdown(self) -> dict: + def energy_consumption_breakdown(self) -> dict: """ Get energy consumption of different sectors return: dict """ fuel_breakdown = {cte.ELECTRICITY: {cte.LIGHTING: self.lighting_electrical_demand[cte.YEAR][0], cte.APPLIANCES: self.appliances_electrical_demand[cte.YEAR][0]}} - energy_systems = self.energy_systems - for energy_system in energy_systems: - demand_types = energy_system.demand_types - generation_systems = energy_system.generation_systems - for demand_type in demand_types: - if demand_type == cte.COOLING: - fuel_breakdown[cte.ELECTRICITY][cte.COOLING] = self.cooling_consumption[cte.YEAR][0] / 3600 - elif demand_type == cte.HEATING: - heating_fuels = [generation_system.fuel_type for generation_system in generation_systems] - if len(heating_fuels) > 1: - for fuel in heating_fuels: - if fuel == cte.ELECTRICITY: - fuel_breakdown[cte.ELECTRICITY][cte.HEATING] = self._heating_consumption_disaggregated[cte.ELECTRICITY][cte.YEAR][0] - elif fuel not in fuel_breakdown.keys(): - fuel_breakdown[fuel] = {cte.HEATING: self._heating_consumption_disaggregated[fuel][cte.YEAR][0]} - else: - fuel_breakdown[fuel][cte.HEATING] = self._heating_consumption_disaggregated[fuel][cte.YEAR][0] - else: - fuel = heating_fuels[0] - if fuel == cte.ELECTRICITY: - fuel_breakdown[cte.ELECTRICITY][cte.HEATING] = self.heating_consumption[cte.YEAR][0] - elif fuel not in fuel_breakdown.keys(): - fuel_breakdown[fuel] = {cte.HEATING: self.heating_consumption[cte.YEAR][0]} - else: - fuel_breakdown[fuel][cte.HEATING] = self.heating_consumption[cte.YEAR][0] - elif demand_type == cte.DOMESTIC_HOT_WATER: - for generation_system in generation_systems: - if generation_system.fuel_type == cte.ELECTRICITY: - fuel_breakdown[cte.ELECTRICITY][cte.DOMESTIC_HOT_WATER] = self.domestic_hot_water_consumption[cte.YEAR][0] - elif generation_system.fuel_type not in fuel_breakdown.keys(): - fuel_breakdown[generation_system.fuel_type] = {cte.DOMESTIC_HOT_WATER: self.domestic_hot_water_consumption[cte.YEAR][0]} - else: - fuel_breakdown[generation_system.fuel_type][cte.DOMESTIC_HOT_WATER] = self.domestic_hot_water_consumption[cte.YEAR][0] self._fuel_consumption_breakdown = fuel_breakdown return self._fuel_consumption_breakdown diff --git a/hub/city_model_structure/energy_systems/__pycache__/generation_system.cpython-39.pyc b/hub/city_model_structure/energy_systems/__pycache__/generation_system.cpython-39.pyc index 4d2de077..6bbaea4e 100644 Binary files a/hub/city_model_structure/energy_systems/__pycache__/generation_system.cpython-39.pyc and b/hub/city_model_structure/energy_systems/__pycache__/generation_system.cpython-39.pyc differ diff --git a/hub/city_model_structure/energy_systems/__pycache__/non_pv_generation_system.cpython-39.pyc b/hub/city_model_structure/energy_systems/__pycache__/non_pv_generation_system.cpython-39.pyc index 0c6b8d45..da7a577d 100644 Binary files a/hub/city_model_structure/energy_systems/__pycache__/non_pv_generation_system.cpython-39.pyc and b/hub/city_model_structure/energy_systems/__pycache__/non_pv_generation_system.cpython-39.pyc differ diff --git a/hub/city_model_structure/energy_systems/__pycache__/thermal_storage_system.cpython-39.pyc b/hub/city_model_structure/energy_systems/__pycache__/thermal_storage_system.cpython-39.pyc index cb1c3543..073c98fa 100644 Binary files a/hub/city_model_structure/energy_systems/__pycache__/thermal_storage_system.cpython-39.pyc and b/hub/city_model_structure/energy_systems/__pycache__/thermal_storage_system.cpython-39.pyc differ diff --git a/hub/city_model_structure/energy_systems/non_pv_generation_system.py b/hub/city_model_structure/energy_systems/non_pv_generation_system.py index e5df16cd..614f0976 100644 --- a/hub/city_model_structure/energy_systems/non_pv_generation_system.py +++ b/hub/city_model_structure/energy_systems/non_pv_generation_system.py @@ -47,6 +47,7 @@ class NonPvGenerationSystem(GenerationSystem): self._cooling_supply_temperature = None self._reversible = None self._simultaneous_heat_cold = None + self._heating_fuel_consumption = {} @property def nominal_heat_output(self): @@ -520,3 +521,19 @@ class NonPvGenerationSystem(GenerationSystem): """ self._simultaneous_heat_cold = value + @property + def heating_fuel_consumption(self) -> dict: + """ + Get fuel consumption in W, m3, or kg + :return: dict{[float]} + """ + return self._heating_fuel_consumption + + @heating_fuel_consumption.setter + def heating_fuel_consumption(self, value): + """ + Set fuel consumption in W, m3, or kg + :param value: dict{[float]} + """ + self._heating_fuel_consumption = value + diff --git a/hub/data/energy_systems/montreal_future_systems.xml b/hub/data/energy_systems/montreal_future_systems.xml index 4437fe62..6ebf8b51 100644 --- a/hub/data/energy_systems/montreal_future_systems.xml +++ b/hub/data/energy_systems/montreal_future_systems.xml @@ -1311,7 +1311,6 @@ heating cooling - domestic_hot_water 21 @@ -1408,8 +1407,8 @@ cooling - 21 - 18 + 23 + 16 @@ -1444,6 +1443,7 @@ 7 1 + 10 diff --git a/hub/helpers/constants.py b/hub/helpers/constants.py index a48718bd..af22e94d 100644 --- a/hub/helpers/constants.py +++ b/hub/helpers/constants.py @@ -10,11 +10,10 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca KELVIN = 273.15 WATER_DENSITY = 1000 # kg/m3 WATER_HEAT_CAPACITY = 4182 # J/kgK - +NATURAL_GAS_LHV = 36.6e6 # J/m3 AIR_DENSITY = 1.293 # kg/m3 AIR_HEAT_CAPACITY = 1005.2 # J/kgK - # converters HOUR_TO_MINUTES = 60 MINUTES_TO_SECONDS = 60 diff --git a/hub/imports/energy_systems/__pycache__/montreal_custom_energy_system_parameters.cpython-39.pyc b/hub/imports/energy_systems/__pycache__/montreal_custom_energy_system_parameters.cpython-39.pyc index 4e8f384a..df20da86 100644 Binary files a/hub/imports/energy_systems/__pycache__/montreal_custom_energy_system_parameters.cpython-39.pyc and b/hub/imports/energy_systems/__pycache__/montreal_custom_energy_system_parameters.cpython-39.pyc differ diff --git a/hub/imports/energy_systems/__pycache__/montreal_future_energy_systems_parameters.cpython-39.pyc b/hub/imports/energy_systems/__pycache__/montreal_future_energy_systems_parameters.cpython-39.pyc index 24cbd513..c193a72a 100644 Binary files a/hub/imports/energy_systems/__pycache__/montreal_future_energy_systems_parameters.cpython-39.pyc and b/hub/imports/energy_systems/__pycache__/montreal_future_energy_systems_parameters.cpython-39.pyc differ diff --git a/main.py b/main.py index f89d37c9..9375e469 100644 --- a/main.py +++ b/main.py @@ -13,10 +13,8 @@ from scripts.energy_system_analysis_report import EnergySystemAnalysisReport from scripts import random_assignation from hub.imports.energy_systems_factory import EnergySystemsFactory from scripts.energy_system_sizing import SystemSizing -from scripts.system_simulation import SystemSimulation -from scripts.costs.cost import Cost -from costs.constants import CURRENT_STATUS, SKIN_RETROFIT, SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV, SYSTEM_RETROFIT_AND_PV from scripts.energy_system_retrofit_results import system_results, new_system_results +from scripts.energy_system_sizing_and_simulation_factory import EnergySystemsSimulationFactory # Specify the GeoJSON file path geojson_file = process_geojson(x=-73.5681295982132, y=45.49218262677643, diff=0.0001) @@ -43,15 +41,13 @@ random_assignation.call_random(city.buildings, random_assignation.residential_sy EnergySystemsFactory('montreal_custom', city).enrich() SystemSizing(city.buildings).montreal_custom() current_system = system_results(city.buildings) +random_assignation.call_random(city.buildings, random_assignation.residential_new_systems_percentage) +EnergySystemsFactory('montreal_future', city).enrich() +for building in city.buildings: + EnergySystemsSimulationFactory('archetype1', building=building,output_path=output_path).enrich() new_system = system_results(city.buildings) EnergySystemAnalysisReport(city, output_path).create_report(current_system, new_system) -for building in city.buildings: - costs = Cost(building, retrofit_scenario=SYSTEM_RETROFIT_AND_PV).life_cycle - Cost(building, retrofit_scenario=SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV).life_cycle.to_csv(output_path / f'{building.name}_lcc.csv') - costs.loc['global_capital_costs', f'Scenario {SYSTEM_RETROFIT_AND_PV}'].to_csv(output_path / f'{building.name}_global_capital.csv') - costs.loc['global_operational_costs', f'Scenario {SYSTEM_RETROFIT_AND_PV}'].to_csv( - output_path / f'{building.name}_global_operational.csv') diff --git a/scripts/costs/cost.py b/scripts/costs/cost.py index b040f063..c735570f 100644 --- a/scripts/costs/cost.py +++ b/scripts/costs/cost.py @@ -44,7 +44,7 @@ class Cost: if dictionary is None: dictionary = Dictionaries().hub_function_to_montreal_custom_costs_function self._building = building - fuel_type = self._building.fuel_consumption_breakdown.keys() + fuel_type = self._building.energy_consumption_breakdown.keys() self._configuration = Configuration(number_of_years, percentage_credit, interest_rate, credit_years, @@ -106,10 +106,10 @@ class Cost: ] additional_costs = [ global_operational_costs[f'Fixed Costs {fuel}'] for fuel in - self._building.fuel_consumption_breakdown.keys() if fuel != cte.ELECTRICITY + self._building.energy_consumption_breakdown.keys() if fuel != cte.ELECTRICITY ] + [ global_operational_costs[f'Variable Costs {fuel}'] for fuel in - self._building.fuel_consumption_breakdown.keys() if fuel != cte.ELECTRICITY + self._building.energy_consumption_breakdown.keys() if fuel != cte.ELECTRICITY ] df_operational_costs = sum(operational_costs_list + additional_costs) df_maintenance_costs = ( diff --git a/scripts/costs/total_operational_costs.py b/scripts/costs/total_operational_costs.py index 338baab1..3cdd8d00 100644 --- a/scripts/costs/total_operational_costs.py +++ b/scripts/costs/total_operational_costs.py @@ -35,14 +35,14 @@ class TotalOperationalCosts(CostBase): :return: pd.DataFrame """ building = self._building - fuel_consumption_breakdown = building.fuel_consumption_breakdown + fuel_consumption_breakdown = building.energy_consumption_breakdown archetype = self._archetype total_floor_area = self._total_floor_area if archetype.function == 'residential': factor = total_floor_area / 80 else: factor = 1 - total_electricity_consumption = sum(self._building.fuel_consumption_breakdown[cte.ELECTRICITY].values()) + total_electricity_consumption = sum(self._building.energy_consumption_breakdown[cte.ELECTRICITY].values()) peak_electricity_load = PeakLoad(self._building).electricity_peak_load peak_load_value = peak_electricity_load.max(axis=1) peak_electricity_demand = peak_load_value[1] / 1000 # self._peak_electricity_demand adapted to kW @@ -90,7 +90,7 @@ class TotalOperationalCosts(CostBase): def columns(self): columns_list = [] - fuels = [key for key in self._building.fuel_consumption_breakdown.keys()] + fuels = [key for key in self._building.energy_consumption_breakdown.keys()] for fuel in fuels: if fuel == cte.ELECTRICITY: columns_list.append('Fixed Costs Electricity Peak') diff --git a/scripts/energy_system_sizing.py b/scripts/energy_system_sizing.py index 7f49d6af..7e784c6a 100644 --- a/scripts/energy_system_sizing.py +++ b/scripts/energy_system_sizing.py @@ -31,7 +31,7 @@ class SystemSizing: if generation.energy_storage_systems is not None: for storage in generation.energy_storage_systems: if storage.type_energy_stored == 'thermal': - storage.volume = (sizing_demand * 1000) / (cte.WATER_HEAT_CAPACITY*cte.WATER_DENSITY) + storage.volume = building.heating_peak_load[cte.YEAR][0] / (cte.WATER_HEAT_CAPACITY*cte.WATER_DENSITY * 20) elif generation.system_type == 'Boiler': generation.nominal_heat_output = 0.4 * sizing_demand / 1000 diff --git a/scripts/energy_system_sizing_and_simulation_factory.py b/scripts/energy_system_sizing_and_simulation_factory.py index adef8151..95a4d4e8 100644 --- a/scripts/energy_system_sizing_and_simulation_factory.py +++ b/scripts/energy_system_sizing_and_simulation_factory.py @@ -6,6 +6,7 @@ Project Coder Saeed Ranjbar saeed.ranjbar@mail.concordia.ca """ from scripts.system_simulation_models.archetype13 import Archetype13 +from scripts.system_simulation_models.archetype1 import Archetype1 class EnergySystemsSimulationFactory: @@ -13,15 +14,24 @@ class EnergySystemsSimulationFactory: EnergySystemsFactory class """ - def __init__(self, handler, building): + def __init__(self, handler, building, output_path): + self._output_path = output_path self._handler = '_' + handler.lower() self._building = building + def _archetype1(self): + """ + Enrich the city by using the sizing and simulation model developed for archetype13 of montreal_future_systems + """ + Archetype1(self._building, self._output_path).enrich_buildings() + self._building.level_of_detail.energy_systems = 2 + self._building.level_of_detail.energy_systems = 2 + def _archetype13(self): """ Enrich the city by using the sizing and simulation model developed for archetype13 of montreal_future_systems """ - Archetype13(self._building).enrich_buildings() + Archetype13(self._building, self._output_path).enrich_buildings() self._building.level_of_detail.energy_systems = 2 self._building.level_of_detail.energy_systems = 2 diff --git a/scripts/system_simulation.py b/scripts/system_simulation.py index 24759f26..a097d0b0 100644 --- a/scripts/system_simulation.py +++ b/scripts/system_simulation.py @@ -81,7 +81,7 @@ class SystemSimulation: else: factor = 4 m_dis[i + 1] = self.maximum_heating_demand / (cte.WATER_HEAT_CAPACITY * factor * 3600) - t_return = T[i + 1] - self.heating_demand[i + 1] / (m_dis[i + 1] * cte.WATER_HEAT_CAPACITY) + t_return = T[i + 1] - self.heating_demand[i + 1] / (m_dis[i + 1] * cte.WATER_HEAT_CAPACITY * 3600) if m_dis[i + 1] == 0 or (m_dis[i + 1] > 0 and t_return < 25): T_ret[i + 1] = max(25, T[i + 1]) else: @@ -89,7 +89,7 @@ class SystemSimulation: tes_output = m_dis[i + 1] * cte.WATER_HEAT_CAPACITY * (T[i + 1] - T_ret[i + 1]) if tes_output < (self.heating_demand[i + 1] / 3600): q_aux[i + 1] = (self.heating_demand[i + 1] / 3600) - tes_output - aux_fuel[i + 1] = (q_aux[i + 1] * dt) / 50e6 + aux_fuel[i + 1] = (q_aux[i + 1] * dt) / 35.8e6 boiler_consumption[i + 1] = q_aux[i + 1] / boiler_efficiency heating_consumption[i + 1] = boiler_consumption[i + 1] + hp_electricity[i + 1] data = list(zip(T, T_sup, T_ret, m_ch, m_dis, q_hp, hp_electricity, aux_fuel, q_aux, self.heating_demand)) @@ -129,7 +129,7 @@ class SystemSimulation: disaggregated_consumption[generation_system.fuel_type][cte.HOUR]) disaggregated_consumption[generation_system.fuel_type][cte.YEAR] = [ sum(disaggregated_consumption[generation_system.fuel_type][cte.MONTH])] - self.building.heating_consumption_disaggregated = disaggregated_consumption + self.building.heating_fuel_consumption_disaggregated = disaggregated_consumption return self.building diff --git a/scripts/system_simulation_models/archetype1.py b/scripts/system_simulation_models/archetype1.py new file mode 100644 index 00000000..e24a5084 --- /dev/null +++ b/scripts/system_simulation_models/archetype1.py @@ -0,0 +1,137 @@ +import math +import csv +import hub.helpers.constants as cte +from hub.helpers.monthly_values import MonthlyValues + + +class Archetype1: + def __init__(self, building, output_path): + self._building = building + self._name = building.name + self._pv_system = building.energy_systems[1] + self._hvac_system = building.energy_systems[0] + self._dhw_system = building.energy_systems[-1] + self._heating_peak_load = building.heating_peak_load[cte.YEAR][0] + self._cooling_peak_load = building.cooling_peak_load[cte.YEAR][0] + self._domestic_hot_water_peak_load = building.domestic_hot_water_peak_load[cte.YEAR][0] + self._hourly_heating_demand = [0] + [demand / 3600 for demand in building.heating_demand[cte.HOUR]] + self._hourly_cooling_demand = [demand / 3600 for demand in building.cooling_demand[cte.HOUR]] + self._hourly_dhw_demand = building.domestic_hot_water_heat_demand[cte.HOUR] + self._output_path = output_path + self._t_out = building.external_temperature[cte.HOUR] + + def hvac_sizing(self): + storage_factor = 3 + heat_pump = self._hvac_system.generation_systems[0] + boiler = self._hvac_system.generation_systems[1] + thermal_storage = heat_pump.energy_storage_systems[0] + heat_pump.nominal_heat_output = round(0.5 * self._heating_peak_load / 3600) + heat_pump.nominal_cooling_output = round(self._cooling_peak_load / 3600) + boiler.nominal_heat_output = round(0.5 * self._heating_peak_load / 3600) + thermal_storage.volume = round( + (self._heating_peak_load * storage_factor) / (cte.WATER_HEAT_CAPACITY * cte.WATER_DENSITY * 30)) + return heat_pump, boiler, thermal_storage + + def hvac_simulation(self): + hp, boiler, tes = self.hvac_sizing() + demand = self._hourly_heating_demand + if hp.source_medium == cte.AIR: + hp.source_temperature = self._t_out + # Heating System Simulation + variable_names = ["t_sup_hp", "t_tank", "t_ret", "m_ch", "m_dis", "q_hp", "q_boiler", "hp_cop", + "hp_electricity", "boiler_gas", "boiler_consumption", "t_sup_boiler", "heating_consumption"] + num_hours = len(demand) + variables = {name: [0] * num_hours for name in variable_names} + (t_sup_hp, t_tank, t_ret, m_ch, m_dis, q_hp, q_boiler, hp_cop, + hp_electricity, boiler_gas, boiler_consumption, t_sup_boiler, heating_consumption) = [variables[name] for name in + variable_names] + + t_tank[0] = 30 + dt = 3600 + hp_heating_cap = hp.nominal_heat_output + hp_efficiency = float(hp.heat_efficiency) + boiler_efficiency = float(boiler.heat_efficiency) + v, h = float(tes.volume), float(tes.height) + r_tot = sum(float(layer.thickness) / float(layer.material.conductivity) for layer in + tes.layers) + u_tot = 1 / r_tot + d = math.sqrt((4 * v) / (math.pi * h)) + a_side = math.pi * d * h + a_top = math.pi * d ** 2 / 4 + ua = u_tot * (2 * a_top + a_side) + for i in range(len(demand) - 1): + t_tank[i + 1] = (t_tank[i] + + ((m_ch[i] * (t_sup_hp[i] - t_tank[i])) + + (ua * (self._t_out[i] - t_tank[i] + 5)) / cte.WATER_HEAT_CAPACITY - + m_dis[i] * (t_tank[i] - t_ret[i])) * (dt / (cte.WATER_DENSITY * v))) + if t_tank[i + 1] < 40: + q_hp[i + 1] = hp_heating_cap + m_ch[i + 1] = q_hp[i + 1] / (cte.WATER_HEAT_CAPACITY * 7) + t_sup_hp[i + 1] = (q_hp[i + 1] / (m_ch[i + 1] * cte.WATER_HEAT_CAPACITY)) + t_tank[i + 1] + elif 40 <= t_tank[i + 1] < 55 and q_hp[i] == 0: + q_hp[i + 1] = 0 + m_ch[i + 1] = 0 + t_sup_hp[i + 1] = t_tank[i + 1] + elif 40 <= t_tank[i + 1] < 55 and q_hp[i] > 0: + q_hp[i + 1] = hp_heating_cap + m_ch[i + 1] = q_hp[i + 1] / (cte.WATER_HEAT_CAPACITY * 3) + t_sup_hp[i + 1] = (q_hp[i + 1] / (m_ch[i + 1] * cte.WATER_HEAT_CAPACITY)) + t_tank[i + 1] + else: + q_hp[i + 1], m_ch[i + 1], t_sup_hp[i + 1] = 0, 0, t_tank[i + 1] + + hp_electricity[i + 1] = q_hp[i + 1] / hp_efficiency + if demand[i + 1] == 0: + m_dis[i + 1], t_return, t_ret[i + 1] = 0, t_tank[i + 1], t_tank[i + 1] + else: + if demand[i + 1] > 0.5 * self._heating_peak_load: + factor = 8 + else: + factor = 4 + m_dis[i + 1] = self._heating_peak_load / (cte.WATER_HEAT_CAPACITY * factor * dt) + t_return = t_tank[i + 1] - demand[i + 1] / (m_dis[i + 1] * cte.WATER_HEAT_CAPACITY * dt) + if m_dis[i + 1] == 0 or (m_dis[i + 1] > 0 and t_return < 25): + t_ret[i + 1] = max(25, t_tank[i + 1]) + else: + t_ret[i + 1] = t_tank[i + 1] - demand[i + 1] / (m_dis[i + 1] * cte.WATER_HEAT_CAPACITY * dt) + tes_output = m_dis[i + 1] * cte.WATER_HEAT_CAPACITY * (t_tank[i + 1] - t_ret[i + 1]) + if tes_output < (demand[i + 1] / dt): + q_boiler[i + 1] = (demand[i + 1] / dt) - tes_output + boiler_gas[i + 1] = (q_boiler[i + 1] * dt) / cte.NATURAL_GAS_LHV + if q_boiler[i + 1] > 0: + t_sup_boiler[i + 1] = q_boiler[i + 1] / (m_dis[i + 1] * cte.WATER_HEAT_CAPACITY) + t_tank[i + 1] + else: + t_sup_boiler[i + 1] = t_tank[i + 1] + boiler_consumption[i + 1] = q_boiler[i + 1] / boiler_efficiency + heating_consumption[i + 1] = boiler_consumption[i + 1] + hp_electricity[i + 1] + data = list(zip(q_hp, hp_electricity, hp_cop, m_ch, t_sup_hp, t_tank, m_dis, q_boiler, + boiler_gas, t_sup_boiler, t_ret, demand)) + file_name = f'simulation_results_{self._name}.csv' + with open(self._output_path / file_name, 'w', newline='') as csvfile: + output_file = csv.writer(csvfile) + # Write header + output_file.writerow(['HP_heat_output(W)', 'HP_electricity_consumption(W)', 'HP_COP', + 'TES_charge_flow_rate(kg/s)', 'TES_supply_temperature(C)', 'TES_temperature(C)', + 'TES_discharge_flow_rate(kg/s)', 'Boiler_heat_output(W)', 'Boiler_gas_consumption(m3)', + 'Boiler_supply_temperature(C)', 'Return_temperature(C)', 'heating_demand']) + # Write data + output_file.writerows(data) + return heating_consumption, hp_electricity, boiler_gas, t_sup_hp, t_sup_boiler + + def enrich_buildings(self): + (self._building.heating_consumption[cte.HOUR], hp_electricity, + boiler_gas, t_sup_hp, t_sup_boiler) = self.hvac_simulation() + self._building.heating_consumption[cte.MONTH] = MonthlyValues.get_total_month( + self._building.heating_consumption[cte.HOUR]) + self._building.heating_consumption[cte.YEAR] = [sum(self._building.heating_consumption[cte.MONTH])] + self._hvac_system.generation_systems[0].heating_fuel_consumption[cte.HOUR] = hp_electricity + self._hvac_system.generation_systems[0].heating_fuel_consumption[cte.MONTH] = MonthlyValues.get_total_month( + self._hvac_system.generation_systems[0].heating_fuel_consumption[cte.HOUR]) + self._hvac_system.generation_systems[0].heating_fuel_consumption[cte.YEAR] = \ + [sum(self._hvac_system.generation_systems[0].heating_fuel_consumption[cte.MONTH])] + self._hvac_system.generation_systems[1].heating_fuel_consumption[cte.HOUR] = boiler_gas + self._hvac_system.generation_systems[1].heating_fuel_consumption[cte.MONTH] = MonthlyValues.get_total_month( + self._hvac_system.generation_systems[1].heating_fuel_consumption[cte.HOUR]) + self._hvac_system.generation_systems[1].heating_fuel_consumption[cte.YEAR] = \ + [sum(self._hvac_system.generation_systems[1].heating_fuel_consumption[cte.MONTH])] + self._hvac_system.generation_systems[0].heat_supply_temperature = t_sup_hp + self._hvac_system.generation_systems[1].heat_supply_temperature = t_sup_boiler