added lod to the city_objects
This commit is contained in:
parent
ef7addd5b5
commit
e48dec81cf
|
@ -13,7 +13,7 @@ import pandas as pd
|
||||||
|
|
||||||
from hub.hub_logger import logger
|
from hub.hub_logger import logger
|
||||||
import hub.helpers.constants as cte
|
import hub.helpers.constants as cte
|
||||||
import hub.helpers.peak_loads as pl
|
from hub.helpers.peak_loads import PeakLoads
|
||||||
from hub.city_model_structure.building_demand.surface import Surface
|
from hub.city_model_structure.building_demand.surface import Surface
|
||||||
from hub.city_model_structure.city_object import CityObject
|
from hub.city_model_structure.city_object import CityObject
|
||||||
from hub.city_model_structure.building_demand.household import Household
|
from hub.city_model_structure.building_demand.household import Household
|
||||||
|
@ -50,8 +50,6 @@ class Building(CityObject):
|
||||||
self._domestic_hot_water_heat_demand = dict()
|
self._domestic_hot_water_heat_demand = dict()
|
||||||
self._heating_consumption = dict()
|
self._heating_consumption = dict()
|
||||||
self._cooling_consumption = dict()
|
self._cooling_consumption = dict()
|
||||||
self._lighting_electrical_consumption = dict()
|
|
||||||
self._appliances_electrical_consumption = dict()
|
|
||||||
self._domestic_hot_water_consumption = dict()
|
self._domestic_hot_water_consumption = dict()
|
||||||
self._onsite_electrical_production = dict()
|
self._onsite_electrical_production = dict()
|
||||||
self._eave_height = None
|
self._eave_height = None
|
||||||
|
@ -367,31 +365,40 @@ class Building(CityObject):
|
||||||
self._domestic_hot_water_heat_demand = value
|
self._domestic_hot_water_heat_demand = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def heating_peak_load(self) -> dict:
|
def heating_peak_load(self) -> Union[None, dict]:
|
||||||
"""
|
"""
|
||||||
Get heating peak load in W
|
Get heating peak load in W
|
||||||
:return: dict{DataFrame(float)}
|
:return: dict{DataFrame(float)}
|
||||||
"""
|
"""
|
||||||
results = {}
|
results = {}
|
||||||
|
# todo: needed??
|
||||||
|
monthly_values = None
|
||||||
if cte.HOUR in self.heating:
|
if cte.HOUR in self.heating:
|
||||||
monthly_values = pl.peak_loads_from_hourly(self.heating[cte.HOUR][next(iter(self.heating[cte.HOUR]))].values)
|
monthly_values = PeakLoads().\
|
||||||
|
peak_loads_from_hourly(self.heating[cte.HOUR][next(iter(self.heating[cte.HOUR]))].values)
|
||||||
else:
|
else:
|
||||||
monthly_values = pl.heating_peak_loads_from_methodology(self)
|
monthly_values = PeakLoads(self).heating_peak_loads_from_methodology
|
||||||
|
if monthly_values is None:
|
||||||
|
return None
|
||||||
results[cte.MONTH] = pd.DataFrame(monthly_values, columns=['heating peak loads'])
|
results[cte.MONTH] = pd.DataFrame(monthly_values, columns=['heating peak loads'])
|
||||||
results[cte.YEAR] = pd.DataFrame([max(monthly_values)], columns=['heating peak loads'])
|
results[cte.YEAR] = pd.DataFrame([max(monthly_values)], columns=['heating peak loads'])
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cooling_peak_load(self) -> dict:
|
def cooling_peak_load(self) -> Union[None, dict]:
|
||||||
"""
|
"""
|
||||||
Get cooling peak load in W
|
Get cooling peak load in W
|
||||||
:return: dict{DataFrame(float)}
|
:return: dict{DataFrame(float)}
|
||||||
"""
|
"""
|
||||||
results = {}
|
results = {}
|
||||||
|
monthly_values = None
|
||||||
if cte.HOUR in self.cooling:
|
if cte.HOUR in self.cooling:
|
||||||
monthly_values = pl.peak_loads_from_hourly(self.cooling[cte.HOUR][next(iter(self.cooling[cte.HOUR]))])
|
# todo: .values???????? Like heating
|
||||||
|
monthly_values = PeakLoads().peak_loads_from_hourly(self.cooling[cte.HOUR][next(iter(self.cooling[cte.HOUR]))])
|
||||||
else:
|
else:
|
||||||
monthly_values = pl.cooling_peak_loads_from_methodology(self)
|
monthly_values = PeakLoads(self).cooling_peak_loads_from_methodology
|
||||||
|
if monthly_values is None:
|
||||||
|
return None
|
||||||
results[cte.MONTH] = pd.DataFrame(monthly_values, columns=['cooling peak loads'])
|
results[cte.MONTH] = pd.DataFrame(monthly_values, columns=['cooling peak loads'])
|
||||||
results[cte.YEAR] = pd.DataFrame([max(monthly_values)], columns=['cooling peak loads'])
|
results[cte.YEAR] = pd.DataFrame([max(monthly_values)], columns=['cooling peak loads'])
|
||||||
return results
|
return results
|
||||||
|
@ -532,7 +539,7 @@ class Building(CityObject):
|
||||||
return: dict
|
return: dict
|
||||||
"""
|
"""
|
||||||
for heating_demand_key in self.heating:
|
for heating_demand_key in self.heating:
|
||||||
demand = self.heating[heating_demand_key][0]
|
demand = self.heating[heating_demand_key][cte.INSEL_MEB]
|
||||||
consumption_type = cte.HEATING
|
consumption_type = cte.HEATING
|
||||||
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
|
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
|
||||||
self._heating_consumption[heating_demand_key] = final_energy_consumed
|
self._heating_consumption[heating_demand_key] = final_energy_consumed
|
||||||
|
@ -545,7 +552,7 @@ class Building(CityObject):
|
||||||
return: dict
|
return: dict
|
||||||
"""
|
"""
|
||||||
for cooling_demand_key in self.cooling:
|
for cooling_demand_key in self.cooling:
|
||||||
demand = self.cooling[cooling_demand_key][0]
|
demand = self.cooling[cooling_demand_key][cte.INSEL_MEB]
|
||||||
consumption_type = cte.COOLING
|
consumption_type = cte.COOLING
|
||||||
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
|
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
|
||||||
self._cooling_consumption[cooling_demand_key] = final_energy_consumed
|
self._cooling_consumption[cooling_demand_key] = final_energy_consumed
|
||||||
|
@ -558,44 +565,18 @@ class Building(CityObject):
|
||||||
return: dict
|
return: dict
|
||||||
"""
|
"""
|
||||||
for domestic_hot_water_demand_key in self.domestic_hot_water_heat_demand:
|
for domestic_hot_water_demand_key in self.domestic_hot_water_heat_demand:
|
||||||
demand = self.domestic_hot_water_heat_demand[domestic_hot_water_demand_key][0]
|
demand = self.domestic_hot_water_heat_demand[domestic_hot_water_demand_key][cte.INSEL_MEB]
|
||||||
consumption_type = cte.DOMESTIC_HOT_WATER
|
consumption_type = cte.DOMESTIC_HOT_WATER
|
||||||
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
|
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
|
||||||
self._domestic_hot_water_consumption[domestic_hot_water_demand_key] = final_energy_consumed
|
self._domestic_hot_water_consumption[domestic_hot_water_demand_key] = final_energy_consumed
|
||||||
return self._domestic_hot_water_consumption
|
return self._domestic_hot_water_consumption
|
||||||
|
|
||||||
@property
|
|
||||||
def lighting_electrical_consumption(self):
|
|
||||||
"""
|
|
||||||
Get energy consumption for lighting according to the electricity system installed
|
|
||||||
return: dict
|
|
||||||
"""
|
|
||||||
for lighting_demand_key in self.lighting_electrical_demand:
|
|
||||||
demand = self.lighting_electrical_demand[lighting_demand_key][0]
|
|
||||||
consumption_type = cte.ELECTRICITY
|
|
||||||
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
|
|
||||||
self._lighting_electrical_consumption[lighting_demand_key] = final_energy_consumed
|
|
||||||
return self._lighting_electrical_consumption
|
|
||||||
|
|
||||||
@property
|
|
||||||
def appliances_electrical_consumption(self):
|
|
||||||
"""
|
|
||||||
Get energy consumption for appliances according to the electricity system installed
|
|
||||||
return: dict
|
|
||||||
"""
|
|
||||||
for appliances_demand_key in self.appliances_electrical_demand:
|
|
||||||
demand = self.appliances_electrical_demand[appliances_demand_key][0]
|
|
||||||
consumption_type = cte.ELECTRICITY
|
|
||||||
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
|
|
||||||
self._appliances_electrical_consumption[appliances_demand_key] = final_energy_consumed
|
|
||||||
return self._appliances_electrical_consumption
|
|
||||||
|
|
||||||
def _calculate_consumption(self, consumption_type, demand):
|
def _calculate_consumption(self, consumption_type, demand):
|
||||||
# todo: modify when COP depends on the hour
|
# todo: modify when COP depends on the hour
|
||||||
coefficient_of_performance = 0
|
coefficient_of_performance = 0
|
||||||
for energy_system in self.energy_systems:
|
for energy_system in self.energy_systems:
|
||||||
for demand_type in energy_system.demand_types:
|
for demand_type in energy_system.demand_types:
|
||||||
if demand_type == consumption_type:
|
if demand_type.lower() == consumption_type.lower():
|
||||||
if consumption_type == cte.HEATING or consumption_type == cte.DOMESTIC_HOT_WATER:
|
if consumption_type == cte.HEATING or consumption_type == cte.DOMESTIC_HOT_WATER:
|
||||||
coefficient_of_performance = energy_system.generation_system.heat_efficiency
|
coefficient_of_performance = energy_system.generation_system.heat_efficiency
|
||||||
elif consumption_type == cte.COOLING:
|
elif consumption_type == cte.COOLING:
|
||||||
|
@ -620,18 +601,11 @@ class Building(CityObject):
|
||||||
for energy_system in self.energy_systems:
|
for energy_system in self.energy_systems:
|
||||||
if energy_system.generation_system.type == cte.PHOTOVOLTAIC:
|
if energy_system.generation_system.type == cte.PHOTOVOLTAIC:
|
||||||
_efficiency = energy_system.generation_system.electricity_efficiency
|
_efficiency = energy_system.generation_system.electricity_efficiency
|
||||||
_temporal_cases = self.roofs[0].global_irradiance.keys()
|
|
||||||
self._onsite_electrical_production = {}
|
self._onsite_electrical_production = {}
|
||||||
for _case in _temporal_cases:
|
for _key in self.roofs[0].global_irradiance.keys():
|
||||||
_results = []
|
_results = [0 for _ in range(0, len(self.roofs[0].global_irradiance[_key]))]
|
||||||
for surface in self.surfaces:
|
for surface in self.surfaces:
|
||||||
for i, value in enumerate(surface.global_irradiance[_case]):
|
_results = [x + y * _efficiency * surface.perimeter_area * surface.solar_collectors_area_reduction_factor
|
||||||
if len(_results) == 0:
|
for x, y in zip(_results, surface.global_irradiance[_key])]
|
||||||
_collector_production = value * _efficiency \
|
self._onsite_electrical_production[_key] = _results
|
||||||
* surface.perimeter_area * surface.solar_collectors_area_reduction_factor
|
|
||||||
else:
|
|
||||||
_collector_production = _results[i] * value * _efficiency \
|
|
||||||
* surface.perimeter_area * surface.solar_collectors_area_reduction_factor
|
|
||||||
_results.append(_collector_production)
|
|
||||||
self._onsite_electrical_production[_case] = _results
|
|
||||||
return self._onsite_electrical_production
|
return self._onsite_electrical_production
|
||||||
|
|
|
@ -8,6 +8,7 @@ Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from typing import List, Union
|
from typing import List, Union
|
||||||
|
|
||||||
|
from hub.city_model_structure.level_of_detail import LevelOfDetail
|
||||||
from hub.city_model_structure.iot.sensor import Sensor
|
from hub.city_model_structure.iot.sensor import Sensor
|
||||||
from hub.city_model_structure.building_demand.surface import Surface
|
from hub.city_model_structure.building_demand.surface import Surface
|
||||||
from hub.city_model_structure.attributes.polyhedron import Polyhedron
|
from hub.city_model_structure.attributes.polyhedron import Polyhedron
|
||||||
|
@ -21,6 +22,7 @@ class CityObject:
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, surfaces):
|
def __init__(self, name, surfaces):
|
||||||
self._name = name
|
self._name = name
|
||||||
|
self._level_of_detail = LevelOfDetail()
|
||||||
self._surfaces = surfaces
|
self._surfaces = surfaces
|
||||||
self._type = None
|
self._type = None
|
||||||
self._city_object_lower_corner = None
|
self._city_object_lower_corner = None
|
||||||
|
@ -43,6 +45,14 @@ class CityObject:
|
||||||
self._sensors = []
|
self._sensors = []
|
||||||
self._neighbours = None
|
self._neighbours = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def level_of_detail(self) -> LevelOfDetail:
|
||||||
|
"""
|
||||||
|
Get level of detail of different aspects of the city: geometry, construction and usage
|
||||||
|
:return: LevelOfDetail
|
||||||
|
"""
|
||||||
|
return self._level_of_detail
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -26,7 +26,9 @@ class GenericGenerationSystem:
|
||||||
self._source_temperature = None
|
self._source_temperature = None
|
||||||
self._source_mass_flow = None
|
self._source_mass_flow = None
|
||||||
self._storage_capacity = None
|
self._storage_capacity = None
|
||||||
|
self._storage = None
|
||||||
self._auxiliary_equipment = None
|
self._auxiliary_equipment = None
|
||||||
|
self._peak_coverages = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type(self):
|
def type(self):
|
||||||
|
@ -82,6 +84,15 @@ class GenericGenerationSystem:
|
||||||
Get heat_power in W
|
Get heat_power in W
|
||||||
:return: float
|
:return: float
|
||||||
"""
|
"""
|
||||||
|
if building.heating_peak_load is not None:
|
||||||
|
_generation_system.heat_power = building.heating_peak_load
|
||||||
|
if building.cooling_peak_load is not None:
|
||||||
|
_generation_system.cooling_power = building.cooling_peak_load
|
||||||
|
# the only system that generates electricity in the montreal custom catalog is PV systems
|
||||||
|
_generation_system.electricity_power = 0
|
||||||
|
if archetype_generation_equipment.storage:
|
||||||
|
# todo: calculate storage capacity in J
|
||||||
|
_generation_system.storage_capacity = 0
|
||||||
return self._heat_power
|
return self._heat_power
|
||||||
|
|
||||||
@heat_power.setter
|
@heat_power.setter
|
||||||
|
@ -220,6 +231,22 @@ class GenericGenerationSystem:
|
||||||
"""
|
"""
|
||||||
self._storage_capacity = value
|
self._storage_capacity = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def storage(self):
|
||||||
|
"""
|
||||||
|
Get boolean storage exists
|
||||||
|
:return: bool
|
||||||
|
"""
|
||||||
|
return self._storage
|
||||||
|
|
||||||
|
@storage.setter
|
||||||
|
def storage(self, value):
|
||||||
|
"""
|
||||||
|
Set boolean storage exists
|
||||||
|
:return: bool
|
||||||
|
"""
|
||||||
|
self._storage = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def auxiliary_equipment(self) -> Union[None, GenericGenerationSystem]:
|
def auxiliary_equipment(self) -> Union[None, GenericGenerationSystem]:
|
||||||
"""
|
"""
|
||||||
|
@ -235,3 +262,19 @@ class GenericGenerationSystem:
|
||||||
:param value: GenerationSystem
|
:param value: GenerationSystem
|
||||||
"""
|
"""
|
||||||
self._auxiliary_equipment = value
|
self._auxiliary_equipment = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def peak_coverages(self) -> dict:
|
||||||
|
"""
|
||||||
|
Get ratio of each energy type power peak covered by the system
|
||||||
|
:return: dict {Heating: value, Cooling: value, Domestic Hot Water: value, Electricity: value}
|
||||||
|
"""
|
||||||
|
return self._peak_coverages
|
||||||
|
|
||||||
|
@peak_coverages.setter
|
||||||
|
def peak_coverages(self, value):
|
||||||
|
"""
|
||||||
|
Set ratio of each energy type power peak covered by the system
|
||||||
|
:param value: dict
|
||||||
|
"""
|
||||||
|
self._peak_coverages = value
|
||||||
|
|
|
@ -51,7 +51,6 @@ class InselMonthlyEnergyBalance(Insel):
|
||||||
)
|
)
|
||||||
self._export()
|
self._export()
|
||||||
|
|
||||||
|
|
||||||
def _export(self):
|
def _export(self):
|
||||||
for i_file, content in enumerate(self._contents):
|
for i_file, content in enumerate(self._contents):
|
||||||
file_name = self._insel_files_paths[i_file]
|
file_name = self._insel_files_paths[i_file]
|
||||||
|
@ -63,7 +62,7 @@ class InselMonthlyEnergyBalance(Insel):
|
||||||
levels_of_detail = self._city.level_of_detail
|
levels_of_detail = self._city.level_of_detail
|
||||||
if levels_of_detail.geometry is None:
|
if levels_of_detail.geometry is None:
|
||||||
raise Exception(f'Level of detail of geometry not assigned')
|
raise Exception(f'Level of detail of geometry not assigned')
|
||||||
if levels_of_detail.geometry < 0.5:
|
if levels_of_detail.geometry < 1:
|
||||||
raise Exception(f'Level of detail of geometry = {levels_of_detail.geometry}. Required minimum level 0.5')
|
raise Exception(f'Level of detail of geometry = {levels_of_detail.geometry}. Required minimum level 0.5')
|
||||||
if levels_of_detail.construction is None:
|
if levels_of_detail.construction is None:
|
||||||
raise Exception(f'Level of detail of construction not assigned')
|
raise Exception(f'Level of detail of construction not assigned')
|
||||||
|
@ -73,13 +72,15 @@ class InselMonthlyEnergyBalance(Insel):
|
||||||
raise Exception(f'Level of detail of usage not assigned')
|
raise Exception(f'Level of detail of usage not assigned')
|
||||||
if levels_of_detail.usage < 1:
|
if levels_of_detail.usage < 1:
|
||||||
raise Exception(f'Level of detail of usage = {levels_of_detail.usage}. Required minimum level 1')
|
raise Exception(f'Level of detail of usage = {levels_of_detail.usage}. Required minimum level 1')
|
||||||
for building in self._city.buildings:
|
if levels_of_detail.weather is None:
|
||||||
if cte.MONTH not in building.external_temperature:
|
raise Exception(f'Level of detail of usage not assigned')
|
||||||
raise Exception(f'Building {building.name} does not have external temperature assigned')
|
if levels_of_detail.weather < 1:
|
||||||
for surface in building.surfaces:
|
raise Exception(f'Level of detail of weather = {levels_of_detail.weather}. Required minimum level 1')
|
||||||
if surface.type != cte.GROUND:
|
if levels_of_detail.surface_radiation is None:
|
||||||
if cte.MONTH not in surface.global_irradiance:
|
raise Exception(f'Level of detail of usage not assigned')
|
||||||
raise Exception(f'Building {building.name} does not have global irradiance on surfaces assigned')
|
if levels_of_detail.surface_radiation < 1:
|
||||||
|
raise Exception(f'Level of detail of surface radiation = {levels_of_detail.surface_radiation}. '
|
||||||
|
f'Required minimum level 1')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _generate_meb_template(building, insel_outputs_path, radiation_calculation_method, weather_format):
|
def _generate_meb_template(building, insel_outputs_path, radiation_calculation_method, weather_format):
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
"""
|
||||||
|
Dictionaries module for Montreal system catalog demand types to hub energy demand types
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2023 Concordia CERC group
|
||||||
|
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
|
"""
|
||||||
|
|
||||||
|
import hub.helpers.constants as cte
|
||||||
|
|
||||||
|
|
||||||
|
class MontrealDemandTypeToHubEnergyDemandType:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._dictionary = {'heating': cte.HEATING,
|
||||||
|
'cooling': cte.COOLING,
|
||||||
|
'domestic_hot_water': cte.DOMESTIC_HOT_WATER,
|
||||||
|
'electricity': cte.ELECTRICITY,
|
||||||
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dictionary(self) -> dict:
|
||||||
|
return self._dictionary
|
|
@ -15,6 +15,7 @@ from hub.helpers.data.hub_usage_to_comnet_usage import HubUsageToComnetUsage
|
||||||
from hub.helpers.data.hub_usage_to_hft_usage import HubUsageToHftUsage
|
from hub.helpers.data.hub_usage_to_hft_usage import HubUsageToHftUsage
|
||||||
from hub.helpers.data.hub_usage_to_nrcan_usage import HubUsageToNrcanUsage
|
from hub.helpers.data.hub_usage_to_nrcan_usage import HubUsageToNrcanUsage
|
||||||
from hub.helpers.data.montreal_system_to_hub_energy_generation_system import MontrealSystemToHubEnergyGenerationSystem
|
from hub.helpers.data.montreal_system_to_hub_energy_generation_system import MontrealSystemToHubEnergyGenerationSystem
|
||||||
|
from hub.helpers.data.montreal_demand_type_to_hub_energy_demand_type import MontrealDemandTypeToHubEnergyDemandType
|
||||||
from hub.helpers.data.hub_function_to_montreal_custom_costs_function import HubFunctionToMontrealCustomCostsFunction
|
from hub.helpers.data.hub_function_to_montreal_custom_costs_function import HubFunctionToMontrealCustomCostsFunction
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,6 +100,14 @@ class Dictionaries:
|
||||||
Get montreal custom system names to hub energy system names, transformation dictionary
|
Get montreal custom system names to hub energy system names, transformation dictionary
|
||||||
"""
|
"""
|
||||||
return MontrealSystemToHubEnergyGenerationSystem().dictionary
|
return MontrealSystemToHubEnergyGenerationSystem().dictionary
|
||||||
|
|
||||||
|
@property
|
||||||
|
def montreal_demand_type_to_hub_energy_demand_type(self):
|
||||||
|
"""
|
||||||
|
Get montreal custom system demand type to hub energy demand type, transformation dictionary
|
||||||
|
"""
|
||||||
|
return MontrealDemandTypeToHubEnergyDemandType().dictionary
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hub_function_to_montreal_custom_costs_function(self) -> dict:
|
def hub_function_to_montreal_custom_costs_function(self) -> dict:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,71 +1,121 @@
|
||||||
|
"""
|
||||||
|
Cooling and Heating peak loads module
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2023 Concordia CERC group
|
||||||
|
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
|
Code contributors: Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
from hub.hub_logger import logger
|
||||||
import hub.helpers.constants as cte
|
import hub.helpers.constants as cte
|
||||||
from hub.helpers.peak_calculation.loads_calculation import LoadsCalculation
|
from hub.helpers.peak_calculation.loads_calculation import LoadsCalculation
|
||||||
|
|
||||||
_MONTH_STARTING_HOUR = [0, 744, 1416, 2160, 2880, 3624, 4344, 5088, 5832, 6552, 7296, 8016, math.inf]
|
_MONTH_STARTING_HOUR = [0, 744, 1416, 2160, 2880, 3624, 4344, 5088, 5832, 6552, 7296, 8016, math.inf]
|
||||||
|
|
||||||
def peak_loads_from_hourly(hourly_values):
|
|
||||||
month = 1
|
|
||||||
peaks = [0 for _ in range(12)]
|
|
||||||
for i, value in enumerate(hourly_values):
|
|
||||||
if _MONTH_STARTING_HOUR[month] <= i:
|
|
||||||
month += 1
|
|
||||||
if value > peaks[month-1]:
|
|
||||||
peaks[month-1] = value
|
|
||||||
return peaks
|
|
||||||
|
|
||||||
def heating_peak_loads_from_methodology(building):
|
class PeakLoads:
|
||||||
monthly_heating_loads = []
|
"""
|
||||||
ambient_temperature = building.external_temperature[cte.HOUR]['epw']
|
PeakLoads class
|
||||||
for month in range(0, 12):
|
"""
|
||||||
ground_temperature = building.ground_temperature[cte.MONTH]['2'][month]
|
def __init__(self, building=None):
|
||||||
heating_ambient_temperature = 100
|
self._building = building
|
||||||
start_hour = _MONTH_STARTING_HOUR[month]
|
|
||||||
end_hour = 8760
|
|
||||||
if month < 11:
|
|
||||||
end_hour = _MONTH_STARTING_HOUR[month + 1]
|
|
||||||
for hour in range(start_hour, end_hour):
|
|
||||||
temperature = ambient_temperature[hour]
|
|
||||||
if temperature < heating_ambient_temperature:
|
|
||||||
heating_ambient_temperature = temperature
|
|
||||||
loads = LoadsCalculation(building)
|
|
||||||
heating_load_transmitted = loads.get_heating_transmitted_load(heating_ambient_temperature, ground_temperature)
|
|
||||||
heating_load_ventilation_sensible = loads.get_heating_ventilation_load_sensible(heating_ambient_temperature)
|
|
||||||
heating_load_ventilation_latent = 0
|
|
||||||
heating_load = heating_load_transmitted + heating_load_ventilation_sensible + heating_load_ventilation_latent
|
|
||||||
if heating_load < 0:
|
|
||||||
heating_load = 0
|
|
||||||
monthly_heating_loads.append(heating_load)
|
|
||||||
return monthly_heating_loads
|
|
||||||
|
|
||||||
def cooling_peak_loads_from_methodology(building):
|
def _can_be_calculated(self):
|
||||||
monthly_cooling_loads = []
|
levels_of_detail = self._building.level_of_detail
|
||||||
ambient_temperature = building.external_temperature[cte.HOUR]['epw']
|
can_be_calculated = True
|
||||||
for month in range(0, 12):
|
if levels_of_detail.geometry is None:
|
||||||
ground_temperature = building.ground_temperature[cte.MONTH]['2'][month]
|
can_be_calculated = False
|
||||||
cooling_ambient_temperature = -100
|
if levels_of_detail.geometry < 1:
|
||||||
cooling_calculation_hour = -1
|
can_be_calculated = False
|
||||||
start_hour = _MONTH_STARTING_HOUR[month]
|
if levels_of_detail.construction is None:
|
||||||
end_hour = 8760
|
can_be_calculated = False
|
||||||
if month < 11:
|
if levels_of_detail.construction < 1:
|
||||||
end_hour = _MONTH_STARTING_HOUR[month + 1]
|
can_be_calculated = False
|
||||||
for hour in range(start_hour, end_hour):
|
if levels_of_detail.usage is None:
|
||||||
temperature = ambient_temperature[hour]
|
can_be_calculated = False
|
||||||
if temperature > cooling_ambient_temperature:
|
if levels_of_detail.usage < 1:
|
||||||
cooling_ambient_temperature = temperature
|
can_be_calculated = False
|
||||||
cooling_calculation_hour = hour
|
if levels_of_detail.weather is None:
|
||||||
loads = LoadsCalculation(building)
|
can_be_calculated = False
|
||||||
cooling_load_transmitted = loads.get_cooling_transmitted_load(cooling_ambient_temperature, ground_temperature)
|
if levels_of_detail.weather < 2:
|
||||||
cooling_load_renovation_sensible = loads.get_cooling_ventilation_load_sensible(cooling_ambient_temperature)
|
can_be_calculated = False
|
||||||
cooling_load_internal_gains_sensible = loads.get_internal_load_sensible()
|
if levels_of_detail.surface_radiation is None:
|
||||||
cooling_load_radiation = loads.get_radiation_load('sra', cooling_calculation_hour)
|
can_be_calculated = False
|
||||||
cooling_load_sensible = cooling_load_transmitted + cooling_load_renovation_sensible - cooling_load_radiation \
|
if levels_of_detail.surface_radiation < 2:
|
||||||
- cooling_load_internal_gains_sensible
|
can_be_calculated = False
|
||||||
|
return can_be_calculated
|
||||||
|
|
||||||
cooling_load_latent = 0
|
@staticmethod
|
||||||
cooling_load = cooling_load_sensible + cooling_load_latent
|
def peak_loads_from_hourly(hourly_values):
|
||||||
if cooling_load > 0:
|
month = 1
|
||||||
cooling_load = 0
|
peaks = [0 for _ in range(12)]
|
||||||
monthly_cooling_loads.append(abs(cooling_load))
|
for i, value in enumerate(hourly_values):
|
||||||
return monthly_cooling_loads
|
if _MONTH_STARTING_HOUR[month] <= i:
|
||||||
|
month += 1
|
||||||
|
if value > peaks[month-1]:
|
||||||
|
peaks[month-1] = value
|
||||||
|
return peaks
|
||||||
|
|
||||||
|
@property
|
||||||
|
def heating_peak_loads_from_methodology(self):
|
||||||
|
if self._can_be_calculated():
|
||||||
|
return None
|
||||||
|
monthly_heating_loads = []
|
||||||
|
ambient_temperature = self._building.external_temperature[cte.HOUR]['epw']
|
||||||
|
for month in range(0, 12):
|
||||||
|
ground_temperature = self._building.ground_temperature[cte.MONTH]['2'][month]
|
||||||
|
heating_ambient_temperature = 100
|
||||||
|
start_hour = _MONTH_STARTING_HOUR[month]
|
||||||
|
end_hour = 8760
|
||||||
|
if month < 11:
|
||||||
|
end_hour = _MONTH_STARTING_HOUR[month + 1]
|
||||||
|
for hour in range(start_hour, end_hour):
|
||||||
|
temperature = ambient_temperature[hour]
|
||||||
|
if temperature < heating_ambient_temperature:
|
||||||
|
heating_ambient_temperature = temperature
|
||||||
|
loads = LoadsCalculation(self._building)
|
||||||
|
heating_load_transmitted = loads.get_heating_transmitted_load(heating_ambient_temperature, ground_temperature)
|
||||||
|
heating_load_ventilation_sensible = loads.get_heating_ventilation_load_sensible(heating_ambient_temperature)
|
||||||
|
heating_load_ventilation_latent = 0
|
||||||
|
heating_load = heating_load_transmitted + heating_load_ventilation_sensible + heating_load_ventilation_latent
|
||||||
|
if heating_load < 0:
|
||||||
|
heating_load = 0
|
||||||
|
monthly_heating_loads.append(heating_load)
|
||||||
|
return monthly_heating_loads
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cooling_peak_loads_from_methodology(self):
|
||||||
|
if self._can_be_calculated():
|
||||||
|
return None
|
||||||
|
monthly_cooling_loads = []
|
||||||
|
ambient_temperature = self._building.external_temperature[cte.HOUR]['epw']
|
||||||
|
for month in range(0, 12):
|
||||||
|
ground_temperature = self._building.ground_temperature[cte.MONTH]['2'][month]
|
||||||
|
cooling_ambient_temperature = -100
|
||||||
|
cooling_calculation_hour = -1
|
||||||
|
start_hour = _MONTH_STARTING_HOUR[month]
|
||||||
|
end_hour = 8760
|
||||||
|
if month < 11:
|
||||||
|
end_hour = _MONTH_STARTING_HOUR[month + 1]
|
||||||
|
for hour in range(start_hour, end_hour):
|
||||||
|
temperature = ambient_temperature[hour]
|
||||||
|
if temperature > cooling_ambient_temperature:
|
||||||
|
cooling_ambient_temperature = temperature
|
||||||
|
cooling_calculation_hour = hour
|
||||||
|
loads = LoadsCalculation(self._building)
|
||||||
|
cooling_load_transmitted = loads.get_cooling_transmitted_load(cooling_ambient_temperature, ground_temperature)
|
||||||
|
cooling_load_renovation_sensible = loads.get_cooling_ventilation_load_sensible(cooling_ambient_temperature)
|
||||||
|
cooling_load_internal_gains_sensible = loads.get_internal_load_sensible()
|
||||||
|
cooling_load_radiation = loads.get_radiation_load('sra', cooling_calculation_hour)
|
||||||
|
cooling_load_sensible = cooling_load_transmitted + cooling_load_renovation_sensible - cooling_load_radiation \
|
||||||
|
- cooling_load_internal_gains_sensible
|
||||||
|
|
||||||
|
cooling_load_latent = 0
|
||||||
|
cooling_load = cooling_load_sensible + cooling_load_latent
|
||||||
|
if cooling_load > 0:
|
||||||
|
cooling_load = 0
|
||||||
|
monthly_cooling_loads.append(abs(cooling_load))
|
||||||
|
return monthly_cooling_loads
|
||||||
|
|
|
@ -33,6 +33,8 @@ class ConstructionFactory:
|
||||||
"""
|
"""
|
||||||
NrelPhysicsParameters(self._city).enrich_buildings()
|
NrelPhysicsParameters(self._city).enrich_buildings()
|
||||||
self._city.level_of_detail.construction = 2
|
self._city.level_of_detail.construction = 2
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.level_of_detail.construction = 2
|
||||||
|
|
||||||
def _nrcan(self):
|
def _nrcan(self):
|
||||||
"""
|
"""
|
||||||
|
@ -40,6 +42,8 @@ class ConstructionFactory:
|
||||||
"""
|
"""
|
||||||
NrcanPhysicsParameters(self._city).enrich_buildings()
|
NrcanPhysicsParameters(self._city).enrich_buildings()
|
||||||
self._city.level_of_detail.construction = 2
|
self._city.level_of_detail.construction = 2
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.level_of_detail.construction = 2
|
||||||
|
|
||||||
def enrich(self):
|
def enrich(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -7,14 +7,13 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from hub.hub_logger import get_logger
|
from hub.hub_logger import logger
|
||||||
from hub.catalog_factories.energy_systems_catalog_factory import EnergySystemsCatalogFactory
|
from hub.catalog_factories.energy_systems_catalog_factory import EnergySystemsCatalogFactory
|
||||||
from hub.city_model_structure.energy_systems.generic_energy_system import GenericEnergySystem
|
from hub.city_model_structure.energy_systems.generic_energy_system import GenericEnergySystem
|
||||||
from hub.city_model_structure.energy_systems.generic_generation_system import GenericGenerationSystem
|
from hub.city_model_structure.energy_systems.generic_generation_system import GenericGenerationSystem
|
||||||
from hub.city_model_structure.energy_systems.generic_distribution_system import GenericDistributionSystem
|
from hub.city_model_structure.energy_systems.generic_distribution_system import GenericDistributionSystem
|
||||||
from hub.helpers.dictionaries import Dictionaries
|
from hub.helpers.dictionaries import Dictionaries
|
||||||
|
import hub.helpers.constants as cte
|
||||||
logger = get_logger()
|
|
||||||
|
|
||||||
|
|
||||||
class MontrealCustomEnergySystemParameters:
|
class MontrealCustomEnergySystemParameters:
|
||||||
|
@ -48,17 +47,15 @@ class MontrealCustomEnergySystemParameters:
|
||||||
building_systems = []
|
building_systems = []
|
||||||
for equipment in archetype.equipments:
|
for equipment in archetype.equipments:
|
||||||
energy_system = GenericEnergySystem()
|
energy_system = GenericEnergySystem()
|
||||||
energy_system.demand_types = equipment.demand_types
|
_hub_demand_types = []
|
||||||
|
for demand_type in equipment.demand_types:
|
||||||
|
_hub_demand_types.append(Dictionaries().montreal_demand_type_to_hub_energy_demand_type[demand_type])
|
||||||
|
energy_system.demand_types = _hub_demand_types
|
||||||
_generation_system = GenericGenerationSystem()
|
_generation_system = GenericGenerationSystem()
|
||||||
archetype_generation_equipment = equipment.generation_system
|
archetype_generation_equipment = equipment.generation_system
|
||||||
_type = str(equipment.name).split('_')[0]
|
_type = str(equipment.name).split('_')[0]
|
||||||
_generation_system.type = Dictionaries().montreal_system_to_hub_energy_generation_system[
|
_generation_system.type = Dictionaries().montreal_system_to_hub_energy_generation_system[
|
||||||
_type]
|
_type]
|
||||||
# dhw peak does not add anything to the total heat peak
|
|
||||||
_generation_system.heat_power = building.heating_peak_load
|
|
||||||
_generation_system.cooling_power = building.cooling_peak_load
|
|
||||||
# the only system that generates electricity in the montreal custom catalog is PV systems
|
|
||||||
_generation_system.electricity_power = 0
|
|
||||||
_generation_system.fuel_type = archetype_generation_equipment.fuel_type
|
_generation_system.fuel_type = archetype_generation_equipment.fuel_type
|
||||||
_generation_system.source_types = archetype_generation_equipment.source_types
|
_generation_system.source_types = archetype_generation_equipment.source_types
|
||||||
_generation_system.heat_efficiency = archetype_generation_equipment.heat_efficiency
|
_generation_system.heat_efficiency = archetype_generation_equipment.heat_efficiency
|
||||||
|
@ -66,10 +63,12 @@ class MontrealCustomEnergySystemParameters:
|
||||||
_generation_system.electricity_efficiency = archetype_generation_equipment.electricity_efficiency
|
_generation_system.electricity_efficiency = archetype_generation_equipment.electricity_efficiency
|
||||||
_generation_system.source_temperature = archetype_generation_equipment.source_temperature
|
_generation_system.source_temperature = archetype_generation_equipment.source_temperature
|
||||||
_generation_system.source_mass_flow = archetype_generation_equipment.source_mass_flow
|
_generation_system.source_mass_flow = archetype_generation_equipment.source_mass_flow
|
||||||
if archetype_generation_equipment.storage:
|
# dhw peak does not add anything to the total heat peak
|
||||||
# todo: calculate storage capacity in J
|
_generation_system.peak_coverages = {cte.HEATING: 1,
|
||||||
_generation_system.storage_capacity = 0
|
cte.COOLING: 1,
|
||||||
|
cte.DOMESTIC_HOT_WATER: 0,
|
||||||
|
cte.ELECTRICITY: 0}
|
||||||
|
_generation_system.storage = archetype_generation_equipment.storage
|
||||||
_generation_system.auxiliary_equipment = None
|
_generation_system.auxiliary_equipment = None
|
||||||
|
|
||||||
energy_system.generation_system = _generation_system
|
energy_system.generation_system = _generation_system
|
||||||
|
@ -84,6 +83,7 @@ class MontrealCustomEnergySystemParameters:
|
||||||
energy_system.distribution_system = _distribution_system
|
energy_system.distribution_system = _distribution_system
|
||||||
|
|
||||||
building_systems.append(energy_system)
|
building_systems.append(energy_system)
|
||||||
|
building.energy_systems = building_systems
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _search_archetypes(catalog, name):
|
def _search_archetypes(catalog, name):
|
||||||
|
|
|
@ -37,19 +37,27 @@ class EnergySystemsFactory:
|
||||||
Enrich the city by using xlsx heat pump information
|
Enrich the city by using xlsx heat pump information
|
||||||
"""
|
"""
|
||||||
AirSourceHeatPumpParameters(self._city, self._base_path).enrich_city()
|
AirSourceHeatPumpParameters(self._city, self._base_path).enrich_city()
|
||||||
|
self._city.level_of_detail.energy_systems = 0
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.level_of_detail.energy_systems = 0
|
||||||
|
|
||||||
def _water_to_water_hp(self):
|
def _water_to_water_hp(self):
|
||||||
"""
|
"""
|
||||||
Enrich the city by using water to water heat pump information
|
Enrich the city by using water to water heat pump information
|
||||||
"""
|
"""
|
||||||
WaterToWaterHPParameters(self._city, self._base_path).enrich_city()
|
WaterToWaterHPParameters(self._city, self._base_path).enrich_city()
|
||||||
|
self._city.level_of_detail.energy_systems = 0
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.level_of_detail.energy_systems = 0
|
||||||
|
|
||||||
def _montreal_custom(self):
|
def _montreal_custom(self):
|
||||||
"""
|
"""
|
||||||
Enrich the city by using montreal custom energy systems catalog information
|
Enrich the city by using montreal custom energy systems catalog information
|
||||||
"""
|
"""
|
||||||
self._city.level_of_detail.energy_systems = 1
|
|
||||||
MontrealCustomEnergySystemParameters(self._city).enrich_buildings()
|
MontrealCustomEnergySystemParameters(self._city).enrich_buildings()
|
||||||
|
self._city.level_of_detail.energy_systems = 1
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.level_of_detail.energy_systems = 1
|
||||||
|
|
||||||
def enrich(self):
|
def enrich(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -166,4 +166,6 @@ class CityGml:
|
||||||
else:
|
else:
|
||||||
self._city.add_city_object(self._create_building(city_object))
|
self._city.add_city_object(self._create_building(city_object))
|
||||||
self._city.level_of_detail.geometry = self._lod
|
self._city.level_of_detail.geometry = self._lod
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.level_of_detail.geometry = self._lod
|
||||||
return self._city
|
return self._city
|
||||||
|
|
|
@ -177,7 +177,7 @@ class Geojson:
|
||||||
extrusion_height = 0
|
extrusion_height = 0
|
||||||
if self._extrusion_height_field is not None:
|
if self._extrusion_height_field is not None:
|
||||||
extrusion_height = float(feature['properties'][self._extrusion_height_field])
|
extrusion_height = float(feature['properties'][self._extrusion_height_field])
|
||||||
lod = 0.5
|
lod = 1
|
||||||
year_of_construction = None
|
year_of_construction = None
|
||||||
if self._year_of_construction_field is not None:
|
if self._year_of_construction_field is not None:
|
||||||
year_of_construction = int(feature['properties'][self._year_of_construction_field])
|
year_of_construction = int(feature['properties'][self._year_of_construction_field])
|
||||||
|
@ -215,6 +215,8 @@ class Geojson:
|
||||||
if building.floor_area >= 25:
|
if building.floor_area >= 25:
|
||||||
self._city.add_city_object(building)
|
self._city.add_city_object(building)
|
||||||
self._city.level_of_detail.geometry = lod
|
self._city.level_of_detail.geometry = lod
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.level_of_detail.geometry = lod
|
||||||
if lod > 0:
|
if lod > 0:
|
||||||
lines_information = GeometryHelper.city_mapping(self._city, plot=False)
|
lines_information = GeometryHelper.city_mapping(self._city, plot=False)
|
||||||
self._store_shared_percentage_to_walls(self._city, lines_information)
|
self._store_shared_percentage_to_walls(self._city, lines_information)
|
||||||
|
|
|
@ -83,6 +83,8 @@ class GPandas:
|
||||||
building = Building(name, surfaces, year_of_construction, function, terrains=None)
|
building = Building(name, surfaces, year_of_construction, function, terrains=None)
|
||||||
self._city.add_city_object(building)
|
self._city.add_city_object(building)
|
||||||
self._city.level_of_detail.geometry = lod
|
self._city.level_of_detail.geometry = lod
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.level_of_detail.geometry = lod
|
||||||
return self._city
|
return self._city
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -81,4 +81,7 @@ class Obj:
|
||||||
building = Building(name, surfaces, year_of_construction, function, terrains=None)
|
building = Building(name, surfaces, year_of_construction, function, terrains=None)
|
||||||
self._city.add_city_object(building)
|
self._city.add_city_object(building)
|
||||||
self._city.level_of_detail.geometry = lod
|
self._city.level_of_detail.geometry = lod
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.level_of_detail.geometry = lod
|
||||||
|
|
||||||
return self._city
|
return self._city
|
||||||
|
|
|
@ -133,5 +133,6 @@ class Rhino:
|
||||||
|
|
||||||
for building in buildings:
|
for building in buildings:
|
||||||
city.add_city_object(building)
|
city.add_city_object(building)
|
||||||
|
building.level_of_detail.geometry = 3
|
||||||
city.level_of_detail.geometry = 3
|
city.level_of_detail.geometry = 3
|
||||||
return city
|
return city
|
||||||
|
|
|
@ -87,9 +87,20 @@ class InselMonthlyEnergyBalance:
|
||||||
total_dhw_demand += total_day * cte.DAYS_A_MONTH[day_type][month] * demand
|
total_dhw_demand += total_day * cte.DAYS_A_MONTH[day_type][month] * demand
|
||||||
domestic_hot_water_demand.append(total_dhw_demand * area)
|
domestic_hot_water_demand.append(total_dhw_demand * area)
|
||||||
|
|
||||||
building.domestic_hot_water_heat_demand[cte.MONTH] = pd.DataFrame(domestic_hot_water_demand, columns=[cte.INSEL_MEB])
|
building.domestic_hot_water_heat_demand[cte.MONTH] = pd.DataFrame(domestic_hot_water_demand,
|
||||||
|
columns=[cte.INSEL_MEB])
|
||||||
|
yearly_domestic_hot_water_demand = [sum(domestic_hot_water_demand)]
|
||||||
|
building.domestic_hot_water_heat_demand[cte.YEAR] = pd.DataFrame(yearly_domestic_hot_water_demand,
|
||||||
|
columns=[cte.INSEL_MEB])
|
||||||
building.lighting_electrical_demand[cte.MONTH] = pd.DataFrame(lighting_demand, columns=[cte.INSEL_MEB])
|
building.lighting_electrical_demand[cte.MONTH] = pd.DataFrame(lighting_demand, columns=[cte.INSEL_MEB])
|
||||||
|
yearly_lighting_electrical_demand = [sum(lighting_demand)]
|
||||||
|
building.lighting_electrical_demand[cte.YEAR] = pd.DataFrame(yearly_lighting_electrical_demand,
|
||||||
|
columns=[cte.INSEL_MEB])
|
||||||
building.appliances_electrical_demand[cte.MONTH] = pd.DataFrame(appliances_demand, columns=[cte.INSEL_MEB])
|
building.appliances_electrical_demand[cte.MONTH] = pd.DataFrame(appliances_demand, columns=[cte.INSEL_MEB])
|
||||||
|
yearly_appliances_electrical_demand = [sum(appliances_demand)]
|
||||||
|
building.appliances_electrical_demand[cte.YEAR] = pd.DataFrame(yearly_appliances_electrical_demand,
|
||||||
|
columns=[cte.INSEL_MEB])
|
||||||
|
|
||||||
|
|
||||||
def enrich(self):
|
def enrich(self):
|
||||||
for building in self._city.buildings:
|
for building in self._city.buildings:
|
||||||
|
|
|
@ -95,3 +95,6 @@ class SimplifiedRadiosityAlgorithm:
|
||||||
if cte.YEAR not in surface.global_irradiance:
|
if cte.YEAR not in surface.global_irradiance:
|
||||||
surface.global_irradiance[cte.YEAR] = self._get_yearly_mean_values(new_value)
|
surface.global_irradiance[cte.YEAR] = self._get_yearly_mean_values(new_value)
|
||||||
self._city.level_of_detail.surface_radiation = 2
|
self._city.level_of_detail.surface_radiation = 2
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.level_of_detail.surface_radiation = 2
|
||||||
|
|
||||||
|
|
|
@ -32,15 +32,19 @@ class UsageFactory:
|
||||||
"""
|
"""
|
||||||
Enrich the city with COMNET usage library
|
Enrich the city with COMNET usage library
|
||||||
"""
|
"""
|
||||||
self._city.level_of_detail.usage = 2
|
|
||||||
ComnetUsageParameters(self._city).enrich_buildings()
|
ComnetUsageParameters(self._city).enrich_buildings()
|
||||||
|
self._city.level_of_detail.usage = 2
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.level_of_detail.usage = 2
|
||||||
|
|
||||||
def _nrcan(self):
|
def _nrcan(self):
|
||||||
"""
|
"""
|
||||||
Enrich the city with NRCAN usage library
|
Enrich the city with NRCAN usage library
|
||||||
"""
|
"""
|
||||||
self._city.level_of_detail.usage = 2
|
|
||||||
NrcanUsageParameters(self._city).enrich_buildings()
|
NrcanUsageParameters(self._city).enrich_buildings()
|
||||||
|
self._city.level_of_detail.usage = 2
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.level_of_detail.usage = 2
|
||||||
|
|
||||||
def enrich(self):
|
def enrich(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -160,3 +160,6 @@ class EpwWeatherParameters:
|
||||||
usage.domestic_hot_water.density = density
|
usage.domestic_hot_water.density = density
|
||||||
|
|
||||||
self._city.level_of_detail.weather = 2
|
self._city.level_of_detail.weather = 2
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.level_of_detail.weather = 2
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,7 @@ from pathlib import Path
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
import hub.exports.exports_factory
|
import hub.exports.exports_factory
|
||||||
from hub.imports.usage_factory import UsageFactory
|
from hub.helpers.dictionaries import MontrealFunctionToHubFunction
|
||||||
|
|
||||||
from hub.exports.energy_building_exports_factory import EnergyBuildingsExportsFactory
|
|
||||||
from hub.helpers.dictionaries import MontrealFunctionToHubFunction, Dictionaries
|
|
||||||
from hub.helpers.geometry_helper import GeometryHelper
|
from hub.helpers.geometry_helper import GeometryHelper
|
||||||
from hub.imports.construction_factory import ConstructionFactory
|
from hub.imports.construction_factory import ConstructionFactory
|
||||||
from hub.imports.geometry_factory import GeometryFactory
|
from hub.imports.geometry_factory import GeometryFactory
|
||||||
|
|
|
@ -5,11 +5,17 @@ Copyright © 2023 Concordia CERC group
|
||||||
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
from hub.imports.geometry_factory import GeometryFactory
|
import hub.helpers.constants as cte
|
||||||
|
from hub.exports.energy_building_exports_factory import EnergyBuildingsExportsFactory
|
||||||
|
from hub.exports.exports_factory import ExportsFactory
|
||||||
|
from hub.helpers.dictionaries import Dictionaries
|
||||||
from hub.imports.construction_factory import ConstructionFactory
|
from hub.imports.construction_factory import ConstructionFactory
|
||||||
|
from hub.imports.geometry_factory import GeometryFactory
|
||||||
|
from hub.imports.results_factory import ResultFactory
|
||||||
from hub.imports.usage_factory import UsageFactory
|
from hub.imports.usage_factory import UsageFactory
|
||||||
from hub.imports.energy_systems_factory import EnergySystemsFactory
|
from hub.imports.energy_systems_factory import EnergySystemsFactory
|
||||||
|
|
||||||
|
@ -20,39 +26,50 @@ class TestSystemsFactory(TestCase):
|
||||||
"""
|
"""
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
"""
|
"""
|
||||||
Configure test environment
|
Test setup
|
||||||
:return:
|
:return: None
|
||||||
"""
|
"""
|
||||||
self._city = None
|
|
||||||
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
|
self._example_path = (Path(__file__).parent / 'tests_data').resolve()
|
||||||
|
self._gml_path = (self._example_path / 'FZK_Haus_LoD_2.gml').resolve()
|
||||||
def _get_citygml(self, file):
|
self._output_path = (Path(__file__).parent / 'tests_outputs').resolve()
|
||||||
file_path = (self._example_path / file).resolve()
|
self._city = GeometryFactory('citygml',
|
||||||
self._city = GeometryFactory('citygml', path=file_path).city
|
self._gml_path,
|
||||||
self.assertIsNotNone(self._city, 'city is none')
|
function_to_hub=Dictionaries().alkis_function_to_hub_function).city
|
||||||
self.assertIsNotNone(self._city.level_of_detail.geometry, 'wrong construction level of detail')
|
|
||||||
return self._city
|
|
||||||
|
|
||||||
def test_montreal_custom_system_factory(self):
|
def test_montreal_custom_system_factory(self):
|
||||||
"""
|
"""
|
||||||
Enrich the city with the construction information and verify it
|
Enrich the city with the construction information and verify it
|
||||||
"""
|
"""
|
||||||
file = 'one_building_in_kelowna.gml'
|
for building in self._city.buildings:
|
||||||
city = self._get_citygml(file)
|
|
||||||
for building in city.buildings:
|
|
||||||
building.energy_systems_archetype_name = 'system 1 gas'
|
building.energy_systems_archetype_name = 'system 1 gas'
|
||||||
|
|
||||||
EnergySystemsFactory('montreal_custom', city).enrich()
|
EnergySystemsFactory('montreal_custom', self._city).enrich()
|
||||||
for building in city.buildings:
|
for building in self._city.buildings:
|
||||||
print(building.energy_systems)
|
self.assertEqual(2, len(building.energy_systems[0].demand_types))
|
||||||
|
self.assertEqual(1, len(building.energy_systems[1].demand_types))
|
||||||
|
|
||||||
def test_montreal_custom_system_results(self):
|
def test_montreal_custom_system_results(self):
|
||||||
"""
|
"""
|
||||||
Enrich the city with the construction information and verify it
|
Enrich the city with the construction information and verify it
|
||||||
"""
|
"""
|
||||||
file = 'one_building_in_kelowna.gml'
|
ConstructionFactory('nrcan', self._city).enrich()
|
||||||
city = self._get_citygml(file)
|
UsageFactory('nrcan', self._city).enrich()
|
||||||
for building in city.buildings:
|
weather_file = (self._example_path / 'CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').resolve()
|
||||||
building.year_of_construction = 1980
|
ExportsFactory('sra', self._city, self._output_path, weather_file=weather_file, weather_format='epw').export()
|
||||||
ConstructionFactory('nrcan', city).enrich()
|
sra_path = (self._output_path / f'{self._city.name}_sra.xml').resolve()
|
||||||
UsageFactory('nrcan', city).enrich()
|
subprocess.run(['sra', str(sra_path)])
|
||||||
|
ResultFactory('sra', self._city, self._output_path).enrich()
|
||||||
|
EnergyBuildingsExportsFactory('insel_monthly_energy_balance', self._city, self._output_path).export()
|
||||||
|
for building in self._city.buildings:
|
||||||
|
insel_path = (self._output_path / f'{building.name}.insel')
|
||||||
|
subprocess.run(['insel', str(insel_path)])
|
||||||
|
ResultFactory('insel_monthly_energy_balance', self._city, self._output_path).enrich()
|
||||||
|
|
||||||
|
for building in self._city.buildings:
|
||||||
|
building.energy_systems_archetype_name = 'system 1 gas'
|
||||||
|
EnergySystemsFactory('montreal_custom', self._city).enrich()
|
||||||
|
|
||||||
|
for building in self._city.buildings:
|
||||||
|
self.assertLess(0, building.heating_consumption[cte.YEAR][0])
|
||||||
|
self.assertLess(0, building.cooling_consumption[cte.YEAR][0])
|
||||||
|
self.assertLess(0, building.domestic_hot_water_consumption[cte.YEAR][0])
|
||||||
|
|
Loading…
Reference in New Issue
Block a user