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