Compare commits
No commits in common. "a147afe76fbf9deac752f373b1503b52ea27eee6" and "1a8dbe7f87af7796e4c491dd7c6ef3f8516fddb5" have entirely different histories.
a147afe76f
...
1a8dbe7f87
@ -41,7 +41,7 @@ class Building(CityObject):
|
|||||||
self._floor_area = None
|
self._floor_area = None
|
||||||
self._roof_type = None
|
self._roof_type = None
|
||||||
self._internal_zones = None
|
self._internal_zones = None
|
||||||
self._thermal_zones_from_internal_zones = None
|
self._thermal_zones = None
|
||||||
self._shell = None
|
self._shell = None
|
||||||
self._aliases = []
|
self._aliases = []
|
||||||
self._type = 'building'
|
self._type = 'building'
|
||||||
@ -114,23 +114,26 @@ class Building(CityObject):
|
|||||||
:return: [InternalZone]
|
:return: [InternalZone]
|
||||||
"""
|
"""
|
||||||
if self._internal_zones is None:
|
if self._internal_zones is None:
|
||||||
self._internal_zones = [InternalZone(self.surfaces, self.floor_area, self.volume)]
|
self._internal_zones = [InternalZone(self.surfaces, self.floor_area)]
|
||||||
return self._internal_zones
|
return self._internal_zones
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def thermal_zones_from_internal_zones(self) -> Union[None, List[ThermalZone]]:
|
def thermal_zones(self) -> Union[None, List[ThermalZone]]:
|
||||||
"""
|
"""
|
||||||
Get building thermal zones
|
Get building thermal zones
|
||||||
|
For Lod up to 3, there can be more than one thermal zone per internal zone.
|
||||||
|
In LoD 4, there can be more than one internal zone, and therefore, only one thermal zone per internal zone
|
||||||
:return: [ThermalZone]
|
:return: [ThermalZone]
|
||||||
"""
|
"""
|
||||||
if self._thermal_zones_from_internal_zones is None:
|
if self._thermal_zones is None:
|
||||||
self._thermal_zones_from_internal_zones = []
|
self._thermal_zones = []
|
||||||
for internal_zone in self.internal_zones:
|
for internal_zone in self.internal_zones:
|
||||||
if internal_zone.thermal_zones_from_internal_zones is None:
|
if internal_zone.thermal_zones is None:
|
||||||
self._thermal_zones_from_internal_zones = None
|
self._thermal_zones = None
|
||||||
return self._thermal_zones_from_internal_zones
|
return self._thermal_zones
|
||||||
self._thermal_zones_from_internal_zones.append(internal_zone.thermal_zones_from_internal_zones[0])
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
return self._thermal_zones_from_internal_zones
|
self._thermal_zones.append(thermal_zone)
|
||||||
|
return self._thermal_zones
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def grounds(self) -> List[Surface]:
|
def grounds(self) -> List[Surface]:
|
||||||
@ -618,7 +621,7 @@ class Building(CityObject):
|
|||||||
def _calculate_working_hours(self):
|
def _calculate_working_hours(self):
|
||||||
_working_hours = {}
|
_working_hours = {}
|
||||||
for internal_zone in self.internal_zones:
|
for internal_zone in self.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
_working_hours_per_thermal_zone = {}
|
_working_hours_per_thermal_zone = {}
|
||||||
for schedule in thermal_zone.thermal_control.hvac_availability_schedules:
|
for schedule in thermal_zone.thermal_control.hvac_availability_schedules:
|
||||||
_working_hours_per_schedule = [0] * len(schedule.values)
|
_working_hours_per_schedule = [0] * len(schedule.values)
|
||||||
|
@ -1,134 +0,0 @@
|
|||||||
"""
|
|
||||||
Construction thermal parameters
|
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|
||||||
Copyright © 2023 Concordia CERC group
|
|
||||||
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
|
||||||
"""
|
|
||||||
|
|
||||||
from hub.city_model_structure.building_demand.layer import Layer
|
|
||||||
|
|
||||||
|
|
||||||
class Construction:
|
|
||||||
"""
|
|
||||||
Construction class
|
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
self._type = None
|
|
||||||
self._layers = None
|
|
||||||
self._window_ratio = None
|
|
||||||
self._window_frame_ratio = None
|
|
||||||
self._window_g_value = None
|
|
||||||
self._window_overall_u_value = None
|
|
||||||
self._window_type = None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def type(self):
|
|
||||||
"""
|
|
||||||
Get construction type
|
|
||||||
:return: str
|
|
||||||
"""
|
|
||||||
return self._type
|
|
||||||
|
|
||||||
@type.setter
|
|
||||||
def type(self, value):
|
|
||||||
"""
|
|
||||||
Set construction type
|
|
||||||
:param value: str
|
|
||||||
"""
|
|
||||||
self._type = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def layers(self) -> [Layer]:
|
|
||||||
"""
|
|
||||||
Get layers
|
|
||||||
:return: [layer]
|
|
||||||
"""
|
|
||||||
return self._layers
|
|
||||||
|
|
||||||
@layers.setter
|
|
||||||
def layers(self, value):
|
|
||||||
"""
|
|
||||||
Set layers
|
|
||||||
:param value: [layer]
|
|
||||||
"""
|
|
||||||
self._layers = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def window_ratio(self):
|
|
||||||
"""
|
|
||||||
Get window ratio
|
|
||||||
:return: dict
|
|
||||||
"""
|
|
||||||
return self._window_ratio
|
|
||||||
|
|
||||||
@window_ratio.setter
|
|
||||||
def window_ratio(self, value):
|
|
||||||
"""
|
|
||||||
Set window ratio
|
|
||||||
:param value: dict
|
|
||||||
"""
|
|
||||||
self._window_ratio = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def window_frame_ratio(self):
|
|
||||||
"""
|
|
||||||
Get window frame ratio
|
|
||||||
:return: float
|
|
||||||
"""
|
|
||||||
return self._window_frame_ratio
|
|
||||||
|
|
||||||
@window_frame_ratio.setter
|
|
||||||
def window_frame_ratio(self, value):
|
|
||||||
"""
|
|
||||||
Set window frame ratio
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
self._window_frame_ratio = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def window_g_value(self):
|
|
||||||
"""
|
|
||||||
Get transparent surface g-value
|
|
||||||
:return: float
|
|
||||||
"""
|
|
||||||
return self._window_g_value
|
|
||||||
|
|
||||||
@window_g_value.setter
|
|
||||||
def window_g_value(self, value):
|
|
||||||
"""
|
|
||||||
Set transparent surface g-value
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
self._window_g_value = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def window_overall_u_value(self):
|
|
||||||
"""
|
|
||||||
Get transparent surface overall U-value in W/m2K
|
|
||||||
:return: float
|
|
||||||
"""
|
|
||||||
return self._window_overall_u_value
|
|
||||||
|
|
||||||
@window_overall_u_value.setter
|
|
||||||
def window_overall_u_value(self, value):
|
|
||||||
"""
|
|
||||||
Set transparent surface overall U-value in W/m2K
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
self._window_overall_u_value = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def window_type(self):
|
|
||||||
"""
|
|
||||||
Get transparent surface type, 'window' or 'skylight'
|
|
||||||
:return: str
|
|
||||||
"""
|
|
||||||
return self._window_type
|
|
||||||
|
|
||||||
@window_type.setter
|
|
||||||
def window_type(self, value):
|
|
||||||
"""
|
|
||||||
Set transparent surface type, 'window' or 'skylight'
|
|
||||||
:return: str
|
|
||||||
"""
|
|
||||||
self._window_type = value
|
|
@ -9,7 +9,6 @@ import uuid
|
|||||||
from typing import Union, List
|
from typing import Union, List
|
||||||
from hub.city_model_structure.building_demand.usage import Usage
|
from hub.city_model_structure.building_demand.usage import Usage
|
||||||
from hub.city_model_structure.building_demand.thermal_zone import ThermalZone
|
from hub.city_model_structure.building_demand.thermal_zone import ThermalZone
|
||||||
from hub.city_model_structure.building_demand.thermal_boundary import ThermalBoundary
|
|
||||||
from hub.city_model_structure.attributes.polyhedron import Polyhedron
|
from hub.city_model_structure.attributes.polyhedron import Polyhedron
|
||||||
from hub.city_model_structure.energy_systems.hvac_system import HvacSystem
|
from hub.city_model_structure.energy_systems.hvac_system import HvacSystem
|
||||||
|
|
||||||
@ -18,13 +17,13 @@ class InternalZone:
|
|||||||
"""
|
"""
|
||||||
InternalZone class
|
InternalZone class
|
||||||
"""
|
"""
|
||||||
def __init__(self, surfaces, area, volume):
|
def __init__(self, surfaces, area):
|
||||||
self._surfaces = surfaces
|
self._surfaces = surfaces
|
||||||
self._id = None
|
self._id = None
|
||||||
self._geometry = None
|
self._geometry = None
|
||||||
self._volume = volume
|
self._volume = None
|
||||||
self._area = area
|
self._area = area
|
||||||
self._thermal_zones_from_internal_zones = None
|
self._thermal_zones = None
|
||||||
self._usages = None
|
self._usages = None
|
||||||
self._hvac_system = None
|
self._hvac_system = None
|
||||||
|
|
||||||
@ -65,7 +64,7 @@ class InternalZone:
|
|||||||
Get internal zone volume in cubic meters
|
Get internal zone volume in cubic meters
|
||||||
:return: float
|
:return: float
|
||||||
"""
|
"""
|
||||||
return self._volume
|
return self.geometry.volume
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def area(self):
|
def area(self):
|
||||||
@ -108,29 +107,17 @@ class InternalZone:
|
|||||||
self._hvac_system = value
|
self._hvac_system = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def thermal_zones_from_internal_zones(self) -> Union[None, List[ThermalZone]]:
|
def thermal_zones(self) -> Union[None, List[ThermalZone]]:
|
||||||
"""
|
"""
|
||||||
Get building thermal zones as one per internal zone
|
Get building thermal zones
|
||||||
:return: [ThermalZone]
|
:return: [ThermalZone]
|
||||||
"""
|
"""
|
||||||
_thermal_boundaries = []
|
return self._thermal_zones
|
||||||
for surface in self.surfaces:
|
|
||||||
if surface.holes_polygons is None:
|
|
||||||
windows_areas = None
|
|
||||||
else:
|
|
||||||
windows_areas = []
|
|
||||||
for hole in surface.holes_polygons:
|
|
||||||
windows_areas.append(hole.area)
|
|
||||||
_thermal_boundary = ThermalBoundary(surface, surface.solid_polygon.area, windows_areas)
|
|
||||||
_thermal_boundaries.append(_thermal_boundary)
|
|
||||||
_thermal_zone = ThermalZone(_thermal_boundaries, self, self.volume, self.area)
|
|
||||||
self._thermal_zones_from_internal_zones = [_thermal_zone]
|
|
||||||
return self._thermal_zones_from_internal_zones
|
|
||||||
|
|
||||||
@thermal_zones_from_internal_zones.setter
|
@thermal_zones.setter
|
||||||
def thermal_zones_from_internal_zones(self, value):
|
def thermal_zones(self, value):
|
||||||
"""
|
"""
|
||||||
Set city object thermal zones as one per internal zone
|
Set city object thermal zones
|
||||||
:param value: [ThermalZone]
|
:param value: [ThermalZone]
|
||||||
"""
|
"""
|
||||||
self._thermal_zones_from_internal_zones = value
|
self._thermal_zones = value
|
||||||
|
@ -4,9 +4,9 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||||||
Copyright © 2022 Concordia CERC group
|
Copyright © 2022 Concordia CERC group
|
||||||
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
from hub.city_model_structure.building_demand.material import Material
|
||||||
|
|
||||||
|
|
||||||
class Layer:
|
class Layer:
|
||||||
@ -14,17 +14,9 @@ class Layer:
|
|||||||
Layer class
|
Layer class
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self._material = None
|
||||||
self._thickness = None
|
self._thickness = None
|
||||||
self._id = None
|
self._id = None
|
||||||
self._name = None
|
|
||||||
self._conductivity = None
|
|
||||||
self._specific_heat = None
|
|
||||||
self._density = None
|
|
||||||
self._solar_absorptance = None
|
|
||||||
self._thermal_absorptance = None
|
|
||||||
self._visible_absorptance = None
|
|
||||||
self._no_mass = False
|
|
||||||
self._thermal_resistance = None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self):
|
def id(self):
|
||||||
@ -36,6 +28,22 @@ class Layer:
|
|||||||
self._id = uuid.uuid4()
|
self._id = uuid.uuid4()
|
||||||
return self._id
|
return self._id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def material(self) -> Material:
|
||||||
|
"""
|
||||||
|
Get layer material
|
||||||
|
:return: Material
|
||||||
|
"""
|
||||||
|
return self._material
|
||||||
|
|
||||||
|
@material.setter
|
||||||
|
def material(self, value):
|
||||||
|
"""
|
||||||
|
Set layer material
|
||||||
|
:param value: Material
|
||||||
|
"""
|
||||||
|
self._material = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def thickness(self) -> Union[None, float]:
|
def thickness(self) -> Union[None, float]:
|
||||||
"""
|
"""
|
||||||
@ -52,155 +60,3 @@ class Layer:
|
|||||||
"""
|
"""
|
||||||
if value is not None:
|
if value is not None:
|
||||||
self._thickness = float(value)
|
self._thickness = float(value)
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
"""
|
|
||||||
Get material name
|
|
||||||
:return: str
|
|
||||||
"""
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
@name.setter
|
|
||||||
def name(self, value):
|
|
||||||
"""
|
|
||||||
Set material name
|
|
||||||
:param value: string
|
|
||||||
"""
|
|
||||||
self._name = str(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def conductivity(self) -> Union[None, float]:
|
|
||||||
"""
|
|
||||||
Get material conductivity in W/mK
|
|
||||||
:return: None or float
|
|
||||||
"""
|
|
||||||
return self._conductivity
|
|
||||||
|
|
||||||
@conductivity.setter
|
|
||||||
def conductivity(self, value):
|
|
||||||
"""
|
|
||||||
Set material conductivity in W/mK
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
if value is not None:
|
|
||||||
self._conductivity = float(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def specific_heat(self) -> Union[None, float]:
|
|
||||||
"""
|
|
||||||
Get material conductivity in J/kgK
|
|
||||||
:return: None or float
|
|
||||||
"""
|
|
||||||
return self._specific_heat
|
|
||||||
|
|
||||||
@specific_heat.setter
|
|
||||||
def specific_heat(self, value):
|
|
||||||
"""
|
|
||||||
Get material conductivity in J/kgK
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
if value is not None:
|
|
||||||
self._specific_heat = float(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def density(self) -> Union[None, float]:
|
|
||||||
"""
|
|
||||||
Get material density in kg/m3
|
|
||||||
:return: None or float
|
|
||||||
"""
|
|
||||||
return self._density
|
|
||||||
|
|
||||||
@density.setter
|
|
||||||
def density(self, value):
|
|
||||||
"""
|
|
||||||
Set material density
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
if value is not None:
|
|
||||||
self._density = float(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def solar_absorptance(self) -> Union[None, float]:
|
|
||||||
"""
|
|
||||||
Get material solar absorptance
|
|
||||||
:return: None or float
|
|
||||||
"""
|
|
||||||
return self._solar_absorptance
|
|
||||||
|
|
||||||
@solar_absorptance.setter
|
|
||||||
def solar_absorptance(self, value):
|
|
||||||
"""
|
|
||||||
Set material solar absorptance
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
if value is not None:
|
|
||||||
self._solar_absorptance = float(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def thermal_absorptance(self) -> Union[None, float]:
|
|
||||||
"""
|
|
||||||
Get material thermal absorptance
|
|
||||||
:return: None or float
|
|
||||||
"""
|
|
||||||
return self._thermal_absorptance
|
|
||||||
|
|
||||||
@thermal_absorptance.setter
|
|
||||||
def thermal_absorptance(self, value):
|
|
||||||
"""
|
|
||||||
Set material thermal absorptance
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
if value is not None:
|
|
||||||
self._thermal_absorptance = float(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def visible_absorptance(self) -> Union[None, float]:
|
|
||||||
"""
|
|
||||||
Get material visible absorptance
|
|
||||||
:return: None or float
|
|
||||||
"""
|
|
||||||
return self._visible_absorptance
|
|
||||||
|
|
||||||
@visible_absorptance.setter
|
|
||||||
def visible_absorptance(self, value):
|
|
||||||
"""
|
|
||||||
Set material visible absorptance
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
if value is not None:
|
|
||||||
self._visible_absorptance = float(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def no_mass(self) -> Union[None, bool]:
|
|
||||||
"""
|
|
||||||
Get material no mass flag
|
|
||||||
:return: None or Boolean
|
|
||||||
"""
|
|
||||||
return self._no_mass
|
|
||||||
|
|
||||||
@no_mass.setter
|
|
||||||
def no_mass(self, value):
|
|
||||||
"""
|
|
||||||
Set material no mass flag
|
|
||||||
:param value: Boolean
|
|
||||||
"""
|
|
||||||
if value is not None:
|
|
||||||
self._no_mass = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def thermal_resistance(self) -> Union[None, float]:
|
|
||||||
"""
|
|
||||||
Get material thermal resistance in m2K/W
|
|
||||||
:return: None or float
|
|
||||||
"""
|
|
||||||
return self._thermal_resistance
|
|
||||||
|
|
||||||
@thermal_resistance.setter
|
|
||||||
def thermal_resistance(self, value):
|
|
||||||
"""
|
|
||||||
Set material thermal resistance in m2K/W
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
if value is not None:
|
|
||||||
self._thermal_resistance = float(value)
|
|
||||||
|
193
hub/city_model_structure/building_demand/material.py
Normal file
193
hub/city_model_structure/building_demand/material.py
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
"""
|
||||||
|
Material module
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2022 Concordia CERC group
|
||||||
|
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
|
||||||
|
class Material:
|
||||||
|
"""
|
||||||
|
Material class
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
self._id = None
|
||||||
|
self._name = None
|
||||||
|
self._conductivity = None
|
||||||
|
self._specific_heat = None
|
||||||
|
self._density = None
|
||||||
|
self._solar_absorptance = None
|
||||||
|
self._thermal_absorptance = None
|
||||||
|
self._visible_absorptance = None
|
||||||
|
self._no_mass = False
|
||||||
|
self._thermal_resistance = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def id(self):
|
||||||
|
"""
|
||||||
|
Get material id
|
||||||
|
:return: str
|
||||||
|
"""
|
||||||
|
return self._id
|
||||||
|
|
||||||
|
@id.setter
|
||||||
|
def id(self, value):
|
||||||
|
"""
|
||||||
|
Set material id
|
||||||
|
:param value: str
|
||||||
|
"""
|
||||||
|
self._id = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""
|
||||||
|
Get material name
|
||||||
|
:return: str
|
||||||
|
"""
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@name.setter
|
||||||
|
def name(self, value):
|
||||||
|
"""
|
||||||
|
Set material name
|
||||||
|
:param value: string
|
||||||
|
"""
|
||||||
|
self._name = str(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def conductivity(self) -> Union[None, float]:
|
||||||
|
"""
|
||||||
|
Get material conductivity in W/mK
|
||||||
|
:return: None or float
|
||||||
|
"""
|
||||||
|
return self._conductivity
|
||||||
|
|
||||||
|
@conductivity.setter
|
||||||
|
def conductivity(self, value):
|
||||||
|
"""
|
||||||
|
Set material conductivity in W/mK
|
||||||
|
:param value: float
|
||||||
|
"""
|
||||||
|
if value is not None:
|
||||||
|
self._conductivity = float(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def specific_heat(self) -> Union[None, float]:
|
||||||
|
"""
|
||||||
|
Get material conductivity in J/kgK
|
||||||
|
:return: None or float
|
||||||
|
"""
|
||||||
|
return self._specific_heat
|
||||||
|
|
||||||
|
@specific_heat.setter
|
||||||
|
def specific_heat(self, value):
|
||||||
|
"""
|
||||||
|
Get material conductivity in J/kgK
|
||||||
|
:param value: float
|
||||||
|
"""
|
||||||
|
if value is not None:
|
||||||
|
self._specific_heat = float(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def density(self) -> Union[None, float]:
|
||||||
|
"""
|
||||||
|
Get material density in kg/m3
|
||||||
|
:return: None or float
|
||||||
|
"""
|
||||||
|
return self._density
|
||||||
|
|
||||||
|
@density.setter
|
||||||
|
def density(self, value):
|
||||||
|
"""
|
||||||
|
Set material density
|
||||||
|
:param value: float
|
||||||
|
"""
|
||||||
|
if value is not None:
|
||||||
|
self._density = float(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def solar_absorptance(self) -> Union[None, float]:
|
||||||
|
"""
|
||||||
|
Get material solar absorptance
|
||||||
|
:return: None or float
|
||||||
|
"""
|
||||||
|
return self._solar_absorptance
|
||||||
|
|
||||||
|
@solar_absorptance.setter
|
||||||
|
def solar_absorptance(self, value):
|
||||||
|
"""
|
||||||
|
Set material solar absorptance
|
||||||
|
:param value: float
|
||||||
|
"""
|
||||||
|
if value is not None:
|
||||||
|
self._solar_absorptance = float(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def thermal_absorptance(self) -> Union[None, float]:
|
||||||
|
"""
|
||||||
|
Get material thermal absorptance
|
||||||
|
:return: None or float
|
||||||
|
"""
|
||||||
|
return self._thermal_absorptance
|
||||||
|
|
||||||
|
@thermal_absorptance.setter
|
||||||
|
def thermal_absorptance(self, value):
|
||||||
|
"""
|
||||||
|
Set material thermal absorptance
|
||||||
|
:param value: float
|
||||||
|
"""
|
||||||
|
if value is not None:
|
||||||
|
self._thermal_absorptance = float(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def visible_absorptance(self) -> Union[None, float]:
|
||||||
|
"""
|
||||||
|
Get material visible absorptance
|
||||||
|
:return: None or float
|
||||||
|
"""
|
||||||
|
return self._visible_absorptance
|
||||||
|
|
||||||
|
@visible_absorptance.setter
|
||||||
|
def visible_absorptance(self, value):
|
||||||
|
"""
|
||||||
|
Set material visible absorptance
|
||||||
|
:param value: float
|
||||||
|
"""
|
||||||
|
if value is not None:
|
||||||
|
self._visible_absorptance = float(value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def no_mass(self) -> Union[None, bool]:
|
||||||
|
"""
|
||||||
|
Get material no mass flag
|
||||||
|
:return: None or Boolean
|
||||||
|
"""
|
||||||
|
return self._no_mass
|
||||||
|
|
||||||
|
@no_mass.setter
|
||||||
|
def no_mass(self, value):
|
||||||
|
"""
|
||||||
|
Set material no mass flag
|
||||||
|
:param value: Boolean
|
||||||
|
"""
|
||||||
|
if value is not None:
|
||||||
|
self._no_mass = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def thermal_resistance(self) -> Union[None, float]:
|
||||||
|
"""
|
||||||
|
Get material thermal resistance in m2K/W
|
||||||
|
:return: None or float
|
||||||
|
"""
|
||||||
|
return self._thermal_resistance
|
||||||
|
|
||||||
|
@thermal_resistance.setter
|
||||||
|
def thermal_resistance(self, value):
|
||||||
|
"""
|
||||||
|
Set material thermal resistance in m2K/W
|
||||||
|
:param value: float
|
||||||
|
"""
|
||||||
|
if value is not None:
|
||||||
|
self._thermal_resistance = float(value)
|
@ -1,126 +0,0 @@
|
|||||||
"""
|
|
||||||
Thermal archetype module
|
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|
||||||
Copyright © 2022 Concordia CERC group
|
|
||||||
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
|
||||||
"""
|
|
||||||
|
|
||||||
from hub.city_model_structure.building_demand.construction import Construction
|
|
||||||
|
|
||||||
|
|
||||||
class ThermalArchetype:
|
|
||||||
"""
|
|
||||||
ThermalArchetype class
|
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
self._constructions = None
|
|
||||||
self._average_storey_height = None
|
|
||||||
self._thermal_capacity = None
|
|
||||||
self._extra_loses_due_to_thermal_bridges = None
|
|
||||||
self._indirect_heated_ratio = None
|
|
||||||
self._infiltration_rate_for_ventilation_system_off = None
|
|
||||||
self._infiltration_rate_for_ventilation_system_on = None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def constructions(self) -> [Construction]:
|
|
||||||
"""
|
|
||||||
Get archetype constructions
|
|
||||||
:return: [Construction]
|
|
||||||
"""
|
|
||||||
return self._constructions
|
|
||||||
|
|
||||||
@property
|
|
||||||
def average_storey_height(self):
|
|
||||||
"""
|
|
||||||
Get average storey height in m
|
|
||||||
:return: float
|
|
||||||
"""
|
|
||||||
return self._average_storey_height
|
|
||||||
|
|
||||||
@average_storey_height.setter
|
|
||||||
def average_storey_height(self, value):
|
|
||||||
"""
|
|
||||||
Set average storey height in m
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
self._average_storey_height = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def thermal_capacity(self):
|
|
||||||
"""
|
|
||||||
Get thermal capacity in J/m3K
|
|
||||||
:return: float
|
|
||||||
"""
|
|
||||||
return self._thermal_capacity
|
|
||||||
|
|
||||||
@thermal_capacity.setter
|
|
||||||
def thermal_capacity(self, value):
|
|
||||||
"""
|
|
||||||
Set thermal capacity in J/m3K
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
self._thermal_capacity = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def extra_loses_due_to_thermal_bridges(self):
|
|
||||||
"""
|
|
||||||
Get extra loses due to thermal bridges in W/m2K
|
|
||||||
:return: float
|
|
||||||
"""
|
|
||||||
return self._extra_loses_due_to_thermal_bridges
|
|
||||||
|
|
||||||
@extra_loses_due_to_thermal_bridges.setter
|
|
||||||
def extra_loses_due_to_thermal_bridges(self, value):
|
|
||||||
"""
|
|
||||||
Set extra loses due to thermal bridges in W/m2K
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
self._extra_loses_due_to_thermal_bridges = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def indirect_heated_ratio(self):
|
|
||||||
"""
|
|
||||||
Get indirect heated area ratio
|
|
||||||
:return: float
|
|
||||||
"""
|
|
||||||
return self._indirect_heated_ratio
|
|
||||||
|
|
||||||
@indirect_heated_ratio.setter
|
|
||||||
def indirect_heated_ratio(self, value):
|
|
||||||
"""
|
|
||||||
Set indirect heated area ratio
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
self._indirect_heated_ratio = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def infiltration_rate_for_ventilation_system_off(self):
|
|
||||||
"""
|
|
||||||
Get infiltration rate for ventilation system off in ACH
|
|
||||||
:return: float
|
|
||||||
"""
|
|
||||||
return self._infiltration_rate_for_ventilation_system_off
|
|
||||||
|
|
||||||
@infiltration_rate_for_ventilation_system_off.setter
|
|
||||||
def infiltration_rate_for_ventilation_system_off(self, value):
|
|
||||||
"""
|
|
||||||
Set infiltration rate for ventilation system off in ACH
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
self._infiltration_rate_for_ventilation_system_off = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def infiltration_rate_for_ventilation_system_on(self):
|
|
||||||
"""
|
|
||||||
Get infiltration rate for ventilation system on in ACH
|
|
||||||
:return: float
|
|
||||||
"""
|
|
||||||
return self._infiltration_rate_for_ventilation_system_on
|
|
||||||
|
|
||||||
@infiltration_rate_for_ventilation_system_on.setter
|
|
||||||
def infiltration_rate_for_ventilation_system_on(self, value):
|
|
||||||
"""
|
|
||||||
Set infiltration rate for ventilation system on in ACH
|
|
||||||
:param value: float
|
|
||||||
"""
|
|
||||||
self._infiltration_rate_for_ventilation_system_on = value
|
|
@ -221,44 +221,16 @@ class ThermalZone:
|
|||||||
Get thermal zone view factors matrix
|
Get thermal zone view factors matrix
|
||||||
:return: [[float]]
|
:return: [[float]]
|
||||||
"""
|
"""
|
||||||
# todo: review method if windows not in window_ratio but in geometry
|
|
||||||
if self._view_factors_matrix is None:
|
|
||||||
total_area = 0
|
|
||||||
for thermal_boundary in self.thermal_boundaries:
|
|
||||||
total_area += thermal_boundary.opaque_area
|
|
||||||
for thermal_opening in thermal_boundary.thermal_openings:
|
|
||||||
total_area += thermal_opening.area
|
|
||||||
|
|
||||||
view_factors_matrix = []
|
|
||||||
for thermal_boundary_1 in self.thermal_boundaries:
|
|
||||||
values = []
|
|
||||||
for thermal_boundary_2 in self.thermal_boundaries:
|
|
||||||
value = 0
|
|
||||||
if thermal_boundary_1.id != thermal_boundary_2.id:
|
|
||||||
value = thermal_boundary_2.opaque_area / (total_area - thermal_boundary_1.opaque_area)
|
|
||||||
values.append(value)
|
|
||||||
for thermal_boundary in self.thermal_boundaries:
|
|
||||||
for thermal_opening in thermal_boundary.thermal_openings:
|
|
||||||
value = thermal_opening.area / (total_area - thermal_boundary_1.opaque_area)
|
|
||||||
values.append(value)
|
|
||||||
view_factors_matrix.append(values)
|
|
||||||
|
|
||||||
for thermal_boundary_1 in self.thermal_boundaries:
|
|
||||||
values = []
|
|
||||||
for thermal_opening_1 in thermal_boundary_1.thermal_openings:
|
|
||||||
for thermal_boundary_2 in self.thermal_boundaries:
|
|
||||||
value = thermal_boundary_2.opaque_area / (total_area - thermal_opening_1.area)
|
|
||||||
values.append(value)
|
|
||||||
for thermal_boundary in self.thermal_boundaries:
|
|
||||||
for thermal_opening_2 in thermal_boundary.thermal_openings:
|
|
||||||
value = 0
|
|
||||||
if thermal_opening_1.id != thermal_opening_2.id:
|
|
||||||
value = thermal_opening_2.area / (total_area - thermal_opening_1.area)
|
|
||||||
values.append(value)
|
|
||||||
view_factors_matrix.append(values)
|
|
||||||
self._view_factors_matrix = view_factors_matrix
|
|
||||||
return self._view_factors_matrix
|
return self._view_factors_matrix
|
||||||
|
|
||||||
|
@view_factors_matrix.setter
|
||||||
|
def view_factors_matrix(self, value):
|
||||||
|
"""
|
||||||
|
Set thermal zone view factors matrix
|
||||||
|
:param value: [[float]]
|
||||||
|
"""
|
||||||
|
self._view_factors_matrix = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def usage_name(self) -> Union[None, str]:
|
def usage_name(self) -> Union[None, str]:
|
||||||
"""
|
"""
|
||||||
|
@ -335,7 +335,7 @@ class EnergyAde:
|
|||||||
def _thermal_zones(self, building, city):
|
def _thermal_zones(self, building, city):
|
||||||
thermal_zones = []
|
thermal_zones = []
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
for index, thermal_zone in enumerate(internal_zone.thermal_zones_from_internal_zones):
|
for index, thermal_zone in enumerate(internal_zone.thermal_zones):
|
||||||
usages = []
|
usages = []
|
||||||
for usage in internal_zone.usages:
|
for usage in internal_zone.usages:
|
||||||
usages.append({'@xlink:href': f'#GML_{usage.id}'})
|
usages.append({'@xlink:href': f'#GML_{usage.id}'})
|
||||||
|
@ -510,9 +510,9 @@ class Idf:
|
|||||||
for building in self._city.buildings:
|
for building in self._city.buildings:
|
||||||
print('building name', building.name)
|
print('building name', building.name)
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
if internal_zone.thermal_zones_from_internal_zones is None:
|
if internal_zone.thermal_zones is None:
|
||||||
continue
|
continue
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
self._add_construction(thermal_boundary)
|
self._add_construction(thermal_boundary)
|
||||||
if thermal_boundary.parent_surface.vegetation is not None:
|
if thermal_boundary.parent_surface.vegetation is not None:
|
||||||
@ -556,7 +556,7 @@ class Idf:
|
|||||||
self._add_dhw(thermal_zone, building.name)
|
self._add_dhw(thermal_zone, building.name)
|
||||||
if self._export_type == "Surfaces":
|
if self._export_type == "Surfaces":
|
||||||
if building.name in self._target_buildings or building.name in self._adjacent_buildings:
|
if building.name in self._target_buildings or building.name in self._adjacent_buildings:
|
||||||
if building.internal_zones[0].thermal_zones_from_internal_zones is not None:
|
if building.internal_zones[0].thermal_zones is not None:
|
||||||
self._add_surfaces(building, building.name)
|
self._add_surfaces(building, building.name)
|
||||||
else:
|
else:
|
||||||
self._add_pure_geometry(building, building.name)
|
self._add_pure_geometry(building, building.name)
|
||||||
@ -611,7 +611,7 @@ class Idf:
|
|||||||
num_stories=int(building.storeys_above_ground))
|
num_stories=int(building.storeys_above_ground))
|
||||||
|
|
||||||
for surface in self._idf.idfobjects[self._SURFACE]:
|
for surface in self._idf.idfobjects[self._SURFACE]:
|
||||||
for thermal_zone in building.thermal_zones_from_internal_zones:
|
for thermal_zone in building.thermal_zones:
|
||||||
for boundary in thermal_zone.thermal_boundaries:
|
for boundary in thermal_zone.thermal_boundaries:
|
||||||
if surface.Type == self.idf_surfaces[boundary.surface.type]:
|
if surface.Type == self.idf_surfaces[boundary.surface.type]:
|
||||||
surface.Construction_Name = boundary.construction_name
|
surface.Construction_Name = boundary.construction_name
|
||||||
@ -664,7 +664,7 @@ class Idf:
|
|||||||
idf_surface.setcoords(coordinates)
|
idf_surface.setcoords(coordinates)
|
||||||
if self._lod >= 3:
|
if self._lod >= 3:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
for boundary in thermal_zone.thermal_boundaries:
|
for boundary in thermal_zone.thermal_boundaries:
|
||||||
self._add_windows_by_vertices(boundary)
|
self._add_windows_by_vertices(boundary)
|
||||||
else:
|
else:
|
||||||
@ -674,7 +674,7 @@ class Idf:
|
|||||||
|
|
||||||
def _add_surfaces(self, building, zone_name):
|
def _add_surfaces(self, building, zone_name):
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
for boundary in thermal_zone.thermal_boundaries:
|
for boundary in thermal_zone.thermal_boundaries:
|
||||||
idf_surface_type = self.idf_surfaces[boundary.parent_surface.type]
|
idf_surface_type = self.idf_surfaces[boundary.parent_surface.type]
|
||||||
outside_boundary_condition = 'Outdoors'
|
outside_boundary_condition = 'Outdoors'
|
||||||
@ -711,7 +711,7 @@ class Idf:
|
|||||||
|
|
||||||
if self._lod >= 3:
|
if self._lod >= 3:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
for boundary in thermal_zone.thermal_boundaries:
|
for boundary in thermal_zone.thermal_boundaries:
|
||||||
self._add_windows_by_vertices(boundary)
|
self._add_windows_by_vertices(boundary)
|
||||||
else:
|
else:
|
||||||
|
@ -44,7 +44,7 @@ class InselMonthlyEnergyBalance:
|
|||||||
self._insel_files_paths.append(building.name + '.insel')
|
self._insel_files_paths.append(building.name + '.insel')
|
||||||
file_name_out = building.name + '.out'
|
file_name_out = building.name + '.out'
|
||||||
output_path = Path(self._path / file_name_out).resolve()
|
output_path = Path(self._path / file_name_out).resolve()
|
||||||
if building.thermal_zones_from_internal_zones is None:
|
if building.thermal_zones is None:
|
||||||
logging.warning('Building %s has missing values. Monthly Energy Balance cannot be processed', building.name)
|
logging.warning('Building %s has missing values. Monthly Energy Balance cannot be processed', building.name)
|
||||||
|
|
||||||
self._contents.append(
|
self._contents.append(
|
||||||
@ -126,7 +126,7 @@ class InselMonthlyEnergyBalance:
|
|||||||
|
|
||||||
# todo: this method and the insel model have to be reviewed for more than one internal zone
|
# todo: this method and the insel model have to be reviewed for more than one internal zone
|
||||||
internal_zone = building.internal_zones[0]
|
internal_zone = building.internal_zones[0]
|
||||||
thermal_zone = internal_zone.thermal_zones_from_internal_zones[0]
|
thermal_zone = internal_zone.thermal_zones[0]
|
||||||
parameters.append(f'{thermal_zone.indirectly_heated_area_ratio} % BP(6) Indirectly heated area ratio')
|
parameters.append(f'{thermal_zone.indirectly_heated_area_ratio} % BP(6) Indirectly heated area ratio')
|
||||||
parameters.append(f'{thermal_zone.effective_thermal_capacity / 3600 / building.average_storey_height}'
|
parameters.append(f'{thermal_zone.effective_thermal_capacity / 3600 / building.average_storey_height}'
|
||||||
f' % BP(7) Effective heat capacity (Wh/m2K)')
|
f' % BP(7) Effective heat capacity (Wh/m2K)')
|
||||||
@ -139,7 +139,7 @@ class InselMonthlyEnergyBalance:
|
|||||||
|
|
||||||
for i, usage in enumerate(internal_zone.usages):
|
for i, usage in enumerate(internal_zone.usages):
|
||||||
percentage_usage = usage.percentage
|
percentage_usage = usage.percentage
|
||||||
parameters.append(f'{internal_zone.thermal_zones_from_internal_zones[0].total_floor_area * percentage_usage} '
|
parameters.append(f'{internal_zone.thermal_zones[0].total_floor_area * percentage_usage} '
|
||||||
f'% BP(11) #1 Area of zone {i + 1} (m2)')
|
f'% BP(11) #1 Area of zone {i + 1} (m2)')
|
||||||
total_internal_gain = 0
|
total_internal_gain = 0
|
||||||
for i_gain in usage.internal_gains:
|
for i_gain in usage.internal_gains:
|
||||||
@ -169,11 +169,11 @@ class InselMonthlyEnergyBalance:
|
|||||||
infiltration_day = 0
|
infiltration_day = 0
|
||||||
for value in schedule.values:
|
for value in schedule.values:
|
||||||
if value == 0:
|
if value == 0:
|
||||||
infiltration_day += internal_zone.thermal_zones_from_internal_zones[0].infiltration_rate_system_off / 24
|
infiltration_day += internal_zone.thermal_zones[0].infiltration_rate_system_off / 24
|
||||||
ventilation_day += 0
|
ventilation_day += 0
|
||||||
else:
|
else:
|
||||||
ventilation_value = usage.mechanical_air_change * value
|
ventilation_value = usage.mechanical_air_change * value
|
||||||
infiltration_value = internal_zone.thermal_zones_from_internal_zones[0].infiltration_rate_system_off * value
|
infiltration_value = internal_zone.thermal_zones[0].infiltration_rate_system_off * value
|
||||||
if ventilation_value >= infiltration_value:
|
if ventilation_value >= infiltration_value:
|
||||||
ventilation_day += ventilation_value / 24
|
ventilation_day += ventilation_value / 24
|
||||||
infiltration_day += 0
|
infiltration_day += 0
|
||||||
|
@ -65,7 +65,7 @@ class LoadsCalculation:
|
|||||||
"""
|
"""
|
||||||
heating_load_transmitted = 0
|
heating_load_transmitted = 0
|
||||||
for internal_zone in self._building.internal_zones:
|
for internal_zone in self._building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
internal_temperature = thermal_zone.thermal_control.mean_heating_set_point
|
internal_temperature = thermal_zone.thermal_control.mean_heating_set_point
|
||||||
heating_load_transmitted += self._get_load_transmitted(thermal_zone, internal_temperature, ambient_temperature,
|
heating_load_transmitted += self._get_load_transmitted(thermal_zone, internal_temperature, ambient_temperature,
|
||||||
ground_temperature)
|
ground_temperature)
|
||||||
@ -78,7 +78,7 @@ class LoadsCalculation:
|
|||||||
"""
|
"""
|
||||||
cooling_load_transmitted = 0
|
cooling_load_transmitted = 0
|
||||||
for internal_zone in self._building.internal_zones:
|
for internal_zone in self._building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
internal_temperature = thermal_zone.thermal_control.mean_cooling_set_point
|
internal_temperature = thermal_zone.thermal_control.mean_cooling_set_point
|
||||||
cooling_load_transmitted += self._get_load_transmitted(thermal_zone, internal_temperature, ambient_temperature,
|
cooling_load_transmitted += self._get_load_transmitted(thermal_zone, internal_temperature, ambient_temperature,
|
||||||
ground_temperature)
|
ground_temperature)
|
||||||
@ -91,7 +91,7 @@ class LoadsCalculation:
|
|||||||
"""
|
"""
|
||||||
heating_ventilation_load = 0
|
heating_ventilation_load = 0
|
||||||
for internal_zone in self._building.internal_zones:
|
for internal_zone in self._building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
internal_temperature = thermal_zone.thermal_control.mean_heating_set_point
|
internal_temperature = thermal_zone.thermal_control.mean_heating_set_point
|
||||||
heating_ventilation_load += self._get_load_ventilation(thermal_zone, internal_temperature, ambient_temperature)
|
heating_ventilation_load += self._get_load_ventilation(thermal_zone, internal_temperature, ambient_temperature)
|
||||||
return heating_ventilation_load
|
return heating_ventilation_load
|
||||||
@ -103,7 +103,7 @@ class LoadsCalculation:
|
|||||||
"""
|
"""
|
||||||
cooling_ventilation_load = 0
|
cooling_ventilation_load = 0
|
||||||
for internal_zone in self._building.internal_zones:
|
for internal_zone in self._building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
internal_temperature = thermal_zone.thermal_control.mean_cooling_set_point
|
internal_temperature = thermal_zone.thermal_control.mean_cooling_set_point
|
||||||
cooling_ventilation_load += self._get_load_ventilation(thermal_zone, internal_temperature, ambient_temperature)
|
cooling_ventilation_load += self._get_load_ventilation(thermal_zone, internal_temperature, ambient_temperature)
|
||||||
return cooling_ventilation_load
|
return cooling_ventilation_load
|
||||||
@ -117,7 +117,7 @@ class LoadsCalculation:
|
|||||||
cooling_load_lighting = 0
|
cooling_load_lighting = 0
|
||||||
cooling_load_equipment_sensible = 0
|
cooling_load_equipment_sensible = 0
|
||||||
for internal_zone in self._building.internal_zones:
|
for internal_zone in self._building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
cooling_load_occupancy_sensible += (thermal_zone.occupancy.sensible_convective_internal_gain
|
cooling_load_occupancy_sensible += (thermal_zone.occupancy.sensible_convective_internal_gain
|
||||||
+ thermal_zone.occupancy.sensible_radiative_internal_gain) \
|
+ thermal_zone.occupancy.sensible_radiative_internal_gain) \
|
||||||
* thermal_zone.footprint_area
|
* thermal_zone.footprint_area
|
||||||
@ -139,7 +139,7 @@ class LoadsCalculation:
|
|||||||
"""
|
"""
|
||||||
cooling_load_radiation = 0
|
cooling_load_radiation = 0
|
||||||
for internal_zone in self._building.internal_zones:
|
for internal_zone in self._building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
for thermal_opening in thermal_boundary.thermal_openings:
|
for thermal_opening in thermal_boundary.thermal_openings:
|
||||||
radiation = thermal_boundary.parent_surface.global_irradiance[cte.HOUR][irradiance_format][hour]
|
radiation = thermal_boundary.parent_surface.global_irradiance[cte.HOUR][irradiance_format][hour]
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
"""
|
|
||||||
Thermal zones creation 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
|
|
||||||
"""
|
|
||||||
|
|
||||||
from hub.imports.construction.helpers.storeys_generation import StoreysGeneration
|
|
||||||
|
|
||||||
|
|
||||||
class ThermalZonesCreation:
|
|
||||||
"""
|
|
||||||
PeakLoads class
|
|
||||||
"""
|
|
||||||
def __init__(self, building=None):
|
|
||||||
self._building = building
|
|
||||||
|
|
||||||
# todo: ATTENTION!!
|
|
||||||
# try:
|
|
||||||
# thermal_boundary.window_ratio = catalog_construction.window_ratio
|
|
||||||
# except ValueError:
|
|
||||||
# # This is the normal operation way when the windows are defined in the geometry
|
|
||||||
# continue
|
|
||||||
|
|
||||||
# # The agreement is that the layers are defined from outside to inside
|
|
||||||
# external_layer = catalog_construction.layers[0]
|
|
||||||
# external_surface = thermal_boundary.parent_surface
|
|
||||||
# external_surface.short_wave_reflectance = 1 - external_layer.material.solar_absorptance
|
|
||||||
# external_surface.long_wave_emittance = 1 - external_layer.material.solar_absorptance
|
|
||||||
# internal_layer = catalog_construction.layers[len(catalog_construction.layers) - 1]
|
|
||||||
# internal_surface = thermal_boundary.internal_surface
|
|
||||||
# internal_surface.short_wave_reflectance = 1 - internal_layer.material.solar_absorptance
|
|
||||||
# internal_surface.long_wave_emittance = 1 - internal_layer.material.solar_absorptance
|
|
||||||
|
|
||||||
# if thermal_boundary.type in (cte.WALL, cte.ROOF):
|
|
||||||
# if catalog_construction.window is not None:
|
|
||||||
# if -math.sqrt(2) / 2 < math.sin(thermal_boundary.parent_surface.azimuth) < math.sqrt(2) / 2:
|
|
||||||
# if 0 < math.cos(thermal_boundary.parent_surface.azimuth):
|
|
||||||
# thermal_boundary.window_ratio = \
|
|
||||||
# float(catalog_construction.window_ratio['north']) / 100
|
|
||||||
# else:
|
|
||||||
# thermal_boundary.window_ratio = \
|
|
||||||
# float(catalog_construction.window_ratio['south']) / 100
|
|
||||||
# elif math.sqrt(2) / 2 <= math.sin(thermal_boundary.parent_surface.azimuth):
|
|
||||||
# thermal_boundary.window_ratio = \
|
|
||||||
# float(catalog_construction.window_ratio['east']) / 100
|
|
||||||
# else:
|
|
||||||
# thermal_boundary.window_ratio = \
|
|
||||||
# float(catalog_construction.window_ratio['west']) / 100
|
|
||||||
|
|
||||||
@property
|
|
||||||
def thermal_zones_from_storeys(self):
|
|
||||||
"""
|
|
||||||
Create and get thermal zones as 1 per each storey
|
|
||||||
:return: [ThermalZone]
|
|
||||||
"""
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _create_storeys(building, archetype, divide_in_storeys):
|
|
||||||
building.average_storey_height = archetype.average_storey_height
|
|
||||||
thermal_zones = StoreysGeneration(building, building.internal_zones[0],
|
|
||||||
divide_in_storeys=divide_in_storeys).thermal_zones
|
|
||||||
building.internal_zones[0].thermal_zones_from_internal_zones = thermal_zones
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _search_construction_in_archetype(archetype, construction_type):
|
|
||||||
construction_archetypes = archetype.constructions
|
|
||||||
for construction_archetype in construction_archetypes:
|
|
||||||
if str(construction_type) == str(construction_archetype.type):
|
|
||||||
return construction_archetype
|
|
||||||
return None
|
|
@ -6,13 +6,15 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import math
|
||||||
|
|
||||||
|
import hub.helpers.constants as cte
|
||||||
from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
|
from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
|
||||||
from hub.city_model_structure.building_demand.thermal_archetype import ThermalArchetype
|
|
||||||
from hub.city_model_structure.building_demand.construction import Construction
|
|
||||||
from hub.city_model_structure.building_demand.layer import Layer
|
from hub.city_model_structure.building_demand.layer import Layer
|
||||||
|
from hub.city_model_structure.building_demand.material import Material
|
||||||
from hub.helpers.dictionaries import Dictionaries
|
from hub.helpers.dictionaries import Dictionaries
|
||||||
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
|
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
|
||||||
|
from hub.imports.construction.helpers.storeys_generation import StoreysGeneration
|
||||||
|
|
||||||
|
|
||||||
class EilatPhysicsParameters:
|
class EilatPhysicsParameters:
|
||||||
@ -33,7 +35,7 @@ class EilatPhysicsParameters:
|
|||||||
eilat_catalog = ConstructionCatalogFactory('eilat').catalog
|
eilat_catalog = ConstructionCatalogFactory('eilat').catalog
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
if building.function not in Dictionaries().hub_function_to_eilat_construction_function.keys():
|
if building.function not in Dictionaries().hub_function_to_eilat_construction_function.keys():
|
||||||
logging.error(f'Building %s has an unknown building function %s', building.name, building.function)
|
logging.error(f'Building %s has an unknown building function %s', building.name, building.function )
|
||||||
continue
|
continue
|
||||||
function = Dictionaries().hub_function_to_eilat_construction_function[building.function]
|
function = Dictionaries().hub_function_to_eilat_construction_function[building.function]
|
||||||
try:
|
try:
|
||||||
@ -44,8 +46,29 @@ class EilatPhysicsParameters:
|
|||||||
f'[%s], building year of construction: %s and climate zone %s', building.name, function,
|
f'[%s], building year of construction: %s and climate zone %s', building.name, function,
|
||||||
building.function, building.year_of_construction, self._climate_zone)
|
building.function, building.year_of_construction, self._climate_zone)
|
||||||
continue
|
continue
|
||||||
thermal_archetype = ThermalArchetype()
|
|
||||||
self._assign_values(thermal_archetype, archetype)
|
# if building has no thermal zones defined from geometry, and the building will be divided in storeys,
|
||||||
|
# one thermal zone per storey is assigned
|
||||||
|
|
||||||
|
if len(building.internal_zones) == 1:
|
||||||
|
if building.internal_zones[0].thermal_zones is None:
|
||||||
|
self._create_storeys(building, archetype, self._divide_in_storeys)
|
||||||
|
if self._divide_in_storeys:
|
||||||
|
for internal_zone in building.internal_zones:
|
||||||
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
|
thermal_zone.total_floor_area = thermal_zone.footprint_area
|
||||||
|
else:
|
||||||
|
number_of_storeys = int(building.eave_height / building.average_storey_height)
|
||||||
|
thermal_zone = building.internal_zones[0].thermal_zones[0]
|
||||||
|
thermal_zone.total_floor_area = thermal_zone.footprint_area * number_of_storeys
|
||||||
|
else:
|
||||||
|
for internal_zone in building.internal_zones:
|
||||||
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
|
thermal_zone.total_floor_area = thermal_zone.footprint_area
|
||||||
|
for internal_zone in building.internal_zones:
|
||||||
|
self._assign_values(internal_zone.thermal_zones, archetype)
|
||||||
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
|
self._calculate_view_factors(thermal_zone)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _search_archetype(nrcan_catalog, function, year_of_construction, climate_zone):
|
def _search_archetype(nrcan_catalog, function, year_of_construction, climate_zone):
|
||||||
@ -58,43 +81,133 @@ class EilatPhysicsParameters:
|
|||||||
raise KeyError('archetype not found')
|
raise KeyError('archetype not found')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _assign_values(thermal_archetype, catalog_archetype):
|
def _search_construction_in_archetype(archetype, construction_type):
|
||||||
thermal_archetype.extra_loses_due_to_thermal_bridges = catalog_archetype.extra_loses_due_to_thermal_bridges
|
construction_archetypes = archetype.constructions
|
||||||
thermal_archetype.indirect_heated_ratio = 0
|
for construction_archetype in construction_archetypes:
|
||||||
thermal_archetype.infiltration_rate_for_ventilation_system_on = catalog_archetype.infiltration_rate_for_ventilation_system_on
|
if str(construction_type) == str(construction_archetype.type):
|
||||||
thermal_archetype.infiltration_rate_for_ventilation_system_off = catalog_archetype.infiltration_rate_for_ventilation_system_off
|
return construction_archetype
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _assign_values(self, thermal_zones, archetype):
|
||||||
|
for thermal_zone in thermal_zones:
|
||||||
|
thermal_zone.additional_thermal_bridge_u_value = archetype.extra_loses_due_to_thermal_bridges
|
||||||
effective_thermal_capacity = 0
|
effective_thermal_capacity = 0
|
||||||
for catalog_construction in catalog_archetype.constructions:
|
thermal_zone.indirectly_heated_area_ratio = 0
|
||||||
construction = Construction()
|
thermal_zone.infiltration_rate_system_on = archetype.infiltration_rate_for_ventilation_system_on
|
||||||
construction.window_ratio = catalog_construction.window_ratio
|
thermal_zone.infiltration_rate_system_off = archetype.infiltration_rate_for_ventilation_system_off
|
||||||
_layers = []
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
|
construction_archetype = self._search_construction_in_archetype(archetype, thermal_boundary.type)
|
||||||
|
thermal_boundary.construction_name = construction_archetype.name
|
||||||
|
try:
|
||||||
|
thermal_boundary.window_ratio = 0
|
||||||
|
if thermal_boundary.type in (cte.WALL, cte.ROOF):
|
||||||
|
if construction_archetype.window is not None:
|
||||||
|
if -math.sqrt(2) / 2 < math.sin(thermal_boundary.parent_surface.azimuth) < math.sqrt(2) / 2:
|
||||||
|
if 0 < math.cos(thermal_boundary.parent_surface.azimuth):
|
||||||
|
thermal_boundary.window_ratio = \
|
||||||
|
float(construction_archetype.window_ratio['north']) / 100
|
||||||
|
else:
|
||||||
|
thermal_boundary.window_ratio = \
|
||||||
|
float(construction_archetype.window_ratio['south']) / 100
|
||||||
|
elif math.sqrt(2) / 2 <= math.sin(thermal_boundary.parent_surface.azimuth):
|
||||||
|
thermal_boundary.window_ratio = \
|
||||||
|
float(construction_archetype.window_ratio['east']) / 100
|
||||||
|
else:
|
||||||
|
thermal_boundary.window_ratio = \
|
||||||
|
float(construction_archetype.window_ratio['west']) / 100
|
||||||
|
except ValueError:
|
||||||
|
# This is the normal operation way when the windows are defined in the geometry
|
||||||
|
continue
|
||||||
|
thermal_boundary.layers = []
|
||||||
total_thickness = 0
|
total_thickness = 0
|
||||||
for layer_archetype in catalog_construction.layers:
|
for layer_archetype in construction_archetype.layers:
|
||||||
layer = Layer()
|
layer = Layer()
|
||||||
layer.thickness = layer_archetype.thickness
|
layer.thickness = layer_archetype.thickness
|
||||||
total_thickness += layer_archetype.thickness
|
total_thickness += layer_archetype.thickness
|
||||||
|
material = Material()
|
||||||
archetype_material = layer_archetype.material
|
archetype_material = layer_archetype.material
|
||||||
layer.name = archetype_material.name
|
material.name = archetype_material.name
|
||||||
layer.no_mass = archetype_material.no_mass
|
material.id = archetype_material.id
|
||||||
|
material.no_mass = archetype_material.no_mass
|
||||||
if archetype_material.no_mass:
|
if archetype_material.no_mass:
|
||||||
layer.thermal_resistance = archetype_material.thermal_resistance
|
material.thermal_resistance = archetype_material.thermal_resistance
|
||||||
else:
|
else:
|
||||||
layer.density = archetype_material.density
|
material.density = archetype_material.density
|
||||||
layer.conductivity = archetype_material.conductivity
|
material.conductivity = archetype_material.conductivity
|
||||||
layer.specific_heat = archetype_material.specific_heat
|
material.specific_heat = archetype_material.specific_heat
|
||||||
effective_thermal_capacity += archetype_material.specific_heat \
|
effective_thermal_capacity += archetype_material.specific_heat \
|
||||||
* archetype_material.density * layer_archetype.thickness
|
* archetype_material.density * layer_archetype.thickness
|
||||||
layer.solar_absorptance = archetype_material.solar_absorptance
|
material.solar_absorptance = archetype_material.solar_absorptance
|
||||||
layer.thermal_absorptance = archetype_material.thermal_absorptance
|
material.thermal_absorptance = archetype_material.thermal_absorptance
|
||||||
layer.visible_absorptance = archetype_material.visible_absorptance
|
material.visible_absorptance = archetype_material.visible_absorptance
|
||||||
_layers.append(layer)
|
layer.material = material
|
||||||
construction.layers = _layers
|
thermal_boundary.layers.append(layer)
|
||||||
|
|
||||||
effective_thermal_capacity = effective_thermal_capacity / total_thickness
|
effective_thermal_capacity = effective_thermal_capacity / total_thickness
|
||||||
|
# The agreement is that the layers are defined from outside to inside
|
||||||
|
external_layer = construction_archetype.layers[0]
|
||||||
|
external_surface = thermal_boundary.parent_surface
|
||||||
|
external_surface.short_wave_reflectance = 1 - external_layer.material.solar_absorptance
|
||||||
|
external_surface.long_wave_emittance = 1 - external_layer.material.solar_absorptance
|
||||||
|
internal_layer = construction_archetype.layers[len(construction_archetype.layers) - 1]
|
||||||
|
internal_surface = thermal_boundary.internal_surface
|
||||||
|
internal_surface.short_wave_reflectance = 1 - internal_layer.material.solar_absorptance
|
||||||
|
internal_surface.long_wave_emittance = 1 - internal_layer.material.solar_absorptance
|
||||||
|
|
||||||
if catalog_construction.window is not None:
|
for thermal_opening in thermal_boundary.thermal_openings:
|
||||||
window_archetype = catalog_construction.window
|
if construction_archetype.window is not None:
|
||||||
construction.window_frame_ratio = window_archetype.frame_ratio
|
window_archetype = construction_archetype.window
|
||||||
construction.window_g_value = window_archetype.g_value
|
thermal_opening.construction_name = window_archetype.name
|
||||||
construction.window_overall_u_value = window_archetype.overall_u_value
|
thermal_opening.frame_ratio = window_archetype.frame_ratio
|
||||||
|
thermal_opening.g_value = window_archetype.g_value
|
||||||
|
thermal_opening.overall_u_value = window_archetype.overall_u_value
|
||||||
|
|
||||||
thermal_archetype.thermal_capacity = effective_thermal_capacity
|
thermal_zone.effective_thermal_capacity = effective_thermal_capacity
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _calculate_view_factors(thermal_zone):
|
||||||
|
"""
|
||||||
|
Get thermal zone view factors matrix
|
||||||
|
:return: [[float]]
|
||||||
|
"""
|
||||||
|
total_area = 0
|
||||||
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
|
total_area += thermal_boundary.opaque_area
|
||||||
|
for thermal_opening in thermal_boundary.thermal_openings:
|
||||||
|
total_area += thermal_opening.area
|
||||||
|
|
||||||
|
view_factors_matrix = []
|
||||||
|
for thermal_boundary_1 in thermal_zone.thermal_boundaries:
|
||||||
|
values = []
|
||||||
|
for thermal_boundary_2 in thermal_zone.thermal_boundaries:
|
||||||
|
value = 0
|
||||||
|
if thermal_boundary_1.id != thermal_boundary_2.id:
|
||||||
|
value = thermal_boundary_2.opaque_area / (total_area - thermal_boundary_1.opaque_area)
|
||||||
|
values.append(value)
|
||||||
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
|
for thermal_opening in thermal_boundary.thermal_openings:
|
||||||
|
value = thermal_opening.area / (total_area - thermal_boundary_1.opaque_area)
|
||||||
|
values.append(value)
|
||||||
|
view_factors_matrix.append(values)
|
||||||
|
|
||||||
|
for thermal_boundary_1 in thermal_zone.thermal_boundaries:
|
||||||
|
values = []
|
||||||
|
for thermal_opening_1 in thermal_boundary_1.thermal_openings:
|
||||||
|
for thermal_boundary_2 in thermal_zone.thermal_boundaries:
|
||||||
|
value = thermal_boundary_2.opaque_area / (total_area - thermal_opening_1.area)
|
||||||
|
values.append(value)
|
||||||
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
|
for thermal_opening_2 in thermal_boundary.thermal_openings:
|
||||||
|
value = 0
|
||||||
|
if thermal_opening_1.id != thermal_opening_2.id:
|
||||||
|
value = thermal_opening_2.area / (total_area - thermal_opening_1.area)
|
||||||
|
values.append(value)
|
||||||
|
view_factors_matrix.append(values)
|
||||||
|
thermal_zone.view_factors_matrix = view_factors_matrix
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _create_storeys(building, archetype, divide_in_storeys):
|
||||||
|
building.average_storey_height = archetype.average_storey_height
|
||||||
|
thermal_zones = StoreysGeneration(building, building.internal_zones[0],
|
||||||
|
divide_in_storeys=divide_in_storeys).thermal_zones
|
||||||
|
building.internal_zones[0].thermal_zones = thermal_zones
|
||||||
|
@ -6,13 +6,15 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import math
|
||||||
|
|
||||||
|
import hub.helpers.constants as cte
|
||||||
from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
|
from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
|
||||||
from hub.city_model_structure.building_demand.thermal_archetype import ThermalArchetype
|
|
||||||
from hub.city_model_structure.building_demand.construction import Construction
|
|
||||||
from hub.city_model_structure.building_demand.layer import Layer
|
from hub.city_model_structure.building_demand.layer import Layer
|
||||||
|
from hub.city_model_structure.building_demand.material import Material
|
||||||
from hub.helpers.dictionaries import Dictionaries
|
from hub.helpers.dictionaries import Dictionaries
|
||||||
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
|
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
|
||||||
|
from hub.imports.construction.helpers.storeys_generation import StoreysGeneration
|
||||||
|
|
||||||
|
|
||||||
class NrcanPhysicsParameters:
|
class NrcanPhysicsParameters:
|
||||||
@ -33,7 +35,7 @@ class NrcanPhysicsParameters:
|
|||||||
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
|
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
if building.function not in Dictionaries().hub_function_to_nrcan_construction_function.keys():
|
if building.function not in Dictionaries().hub_function_to_nrcan_construction_function.keys():
|
||||||
logging.error(f'Building %s has an unknown building function %s', building.name, building.function)
|
logging.error(f'Building %s has an unknown building function %s', building.name, building.function )
|
||||||
continue
|
continue
|
||||||
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
|
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
|
||||||
try:
|
try:
|
||||||
@ -44,8 +46,29 @@ class NrcanPhysicsParameters:
|
|||||||
f'[%s], building year of construction: %s and climate zone %s', building.name, function,
|
f'[%s], building year of construction: %s and climate zone %s', building.name, function,
|
||||||
building.function, building.year_of_construction, self._climate_zone)
|
building.function, building.year_of_construction, self._climate_zone)
|
||||||
continue
|
continue
|
||||||
thermal_archetype = ThermalArchetype()
|
|
||||||
self._assign_values(thermal_archetype, archetype)
|
# if building has no thermal zones defined from geometry, and the building will be divided in storeys,
|
||||||
|
# one thermal zone per storey is assigned
|
||||||
|
|
||||||
|
if len(building.internal_zones) == 1:
|
||||||
|
if building.internal_zones[0].thermal_zones is None:
|
||||||
|
self._create_storeys(building, archetype, self._divide_in_storeys)
|
||||||
|
if self._divide_in_storeys:
|
||||||
|
for internal_zone in building.internal_zones:
|
||||||
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
|
thermal_zone.total_floor_area = thermal_zone.footprint_area
|
||||||
|
else:
|
||||||
|
number_of_storeys = int(building.eave_height / building.average_storey_height)
|
||||||
|
thermal_zone = building.internal_zones[0].thermal_zones[0]
|
||||||
|
thermal_zone.total_floor_area = thermal_zone.footprint_area * number_of_storeys
|
||||||
|
else:
|
||||||
|
for internal_zone in building.internal_zones:
|
||||||
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
|
thermal_zone.total_floor_area = thermal_zone.footprint_area
|
||||||
|
for internal_zone in building.internal_zones:
|
||||||
|
self._assign_values(internal_zone.thermal_zones, archetype)
|
||||||
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
|
self._calculate_view_factors(thermal_zone)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _search_archetype(nrcan_catalog, function, year_of_construction, climate_zone):
|
def _search_archetype(nrcan_catalog, function, year_of_construction, climate_zone):
|
||||||
@ -58,36 +81,126 @@ class NrcanPhysicsParameters:
|
|||||||
raise KeyError('archetype not found')
|
raise KeyError('archetype not found')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _assign_values(thermal_archetype, catalog_archetype):
|
def _search_construction_in_archetype(archetype, construction_type):
|
||||||
thermal_archetype.extra_loses_due_to_thermal_bridges = catalog_archetype.extra_loses_due_to_thermal_bridges
|
construction_archetypes = archetype.constructions
|
||||||
thermal_archetype.thermal_capacity = catalog_archetype.thermal_capacity
|
for construction_archetype in construction_archetypes:
|
||||||
thermal_archetype.indirect_heated_ratio = 0
|
if str(construction_type) == str(construction_archetype.type):
|
||||||
thermal_archetype.infiltration_rate_for_ventilation_system_on = catalog_archetype.infiltration_rate_for_ventilation_system_on
|
return construction_archetype
|
||||||
thermal_archetype.infiltration_rate_for_ventilation_system_off = catalog_archetype.infiltration_rate_for_ventilation_system_off
|
return None
|
||||||
for catalog_construction in catalog_archetype.constructions:
|
|
||||||
construction = Construction()
|
def _assign_values(self, thermal_zones, archetype):
|
||||||
construction.window_ratio = catalog_construction.window_ratio
|
for thermal_zone in thermal_zones:
|
||||||
_layers = []
|
thermal_zone.additional_thermal_bridge_u_value = archetype.extra_loses_due_to_thermal_bridges
|
||||||
for layer_archetype in catalog_construction.layers:
|
thermal_zone.effective_thermal_capacity = archetype.thermal_capacity
|
||||||
|
thermal_zone.indirectly_heated_area_ratio = 0
|
||||||
|
thermal_zone.infiltration_rate_system_on = archetype.infiltration_rate_for_ventilation_system_on
|
||||||
|
thermal_zone.infiltration_rate_system_off = archetype.infiltration_rate_for_ventilation_system_off
|
||||||
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
|
construction_archetype = self._search_construction_in_archetype(archetype, thermal_boundary.type)
|
||||||
|
thermal_boundary.construction_name = construction_archetype.name
|
||||||
|
try:
|
||||||
|
thermal_boundary.window_ratio = 0
|
||||||
|
if thermal_boundary.type in ( cte.WALL, cte.ROOF):
|
||||||
|
if construction_archetype.window is not None:
|
||||||
|
if -math.sqrt(2) / 2 < math.sin(thermal_boundary.parent_surface.azimuth) < math.sqrt(2) / 2:
|
||||||
|
if 0 < math.cos(thermal_boundary.parent_surface.azimuth):
|
||||||
|
thermal_boundary.window_ratio = \
|
||||||
|
float(construction_archetype.window_ratio['north']) / 100
|
||||||
|
else:
|
||||||
|
thermal_boundary.window_ratio = \
|
||||||
|
float(construction_archetype.window_ratio['south']) / 100
|
||||||
|
elif math.sqrt(2) / 2 <= math.sin(thermal_boundary.parent_surface.azimuth):
|
||||||
|
thermal_boundary.window_ratio = \
|
||||||
|
float(construction_archetype.window_ratio['east']) / 100
|
||||||
|
else:
|
||||||
|
thermal_boundary.window_ratio = \
|
||||||
|
float(construction_archetype.window_ratio['west']) / 100
|
||||||
|
except ValueError:
|
||||||
|
# This is the normal operation way when the windows are defined in the geometry
|
||||||
|
continue
|
||||||
|
thermal_boundary.layers = []
|
||||||
|
for layer_archetype in construction_archetype.layers:
|
||||||
layer = Layer()
|
layer = Layer()
|
||||||
layer.thickness = layer_archetype.thickness
|
layer.thickness = layer_archetype.thickness
|
||||||
|
material = Material()
|
||||||
archetype_material = layer_archetype.material
|
archetype_material = layer_archetype.material
|
||||||
layer.name = archetype_material.name
|
material.name = archetype_material.name
|
||||||
layer.no_mass = archetype_material.no_mass
|
material.id = archetype_material.id
|
||||||
|
material.no_mass = archetype_material.no_mass
|
||||||
if archetype_material.no_mass:
|
if archetype_material.no_mass:
|
||||||
layer.thermal_resistance = archetype_material.thermal_resistance
|
material.thermal_resistance = archetype_material.thermal_resistance
|
||||||
else:
|
else:
|
||||||
layer.density = archetype_material.density
|
material.density = archetype_material.density
|
||||||
layer.conductivity = archetype_material.conductivity
|
material.conductivity = archetype_material.conductivity
|
||||||
layer.specific_heat = archetype_material.specific_heat
|
material.specific_heat = archetype_material.specific_heat
|
||||||
layer.solar_absorptance = archetype_material.solar_absorptance
|
material.solar_absorptance = archetype_material.solar_absorptance
|
||||||
layer.thermal_absorptance = archetype_material.thermal_absorptance
|
material.thermal_absorptance = archetype_material.thermal_absorptance
|
||||||
layer.visible_absorptance = archetype_material.visible_absorptance
|
material.visible_absorptance = archetype_material.visible_absorptance
|
||||||
_layers.append(layer)
|
layer.material = material
|
||||||
construction.layers = _layers
|
thermal_boundary.layers.append(layer)
|
||||||
|
# The agreement is that the layers are defined from outside to inside
|
||||||
|
external_layer = construction_archetype.layers[0]
|
||||||
|
external_surface = thermal_boundary.parent_surface
|
||||||
|
external_surface.short_wave_reflectance = 1 - external_layer.material.solar_absorptance
|
||||||
|
external_surface.long_wave_emittance = 1 - external_layer.material.solar_absorptance
|
||||||
|
internal_layer = construction_archetype.layers[len(construction_archetype.layers) - 1]
|
||||||
|
internal_surface = thermal_boundary.internal_surface
|
||||||
|
internal_surface.short_wave_reflectance = 1 - internal_layer.material.solar_absorptance
|
||||||
|
internal_surface.long_wave_emittance = 1 - internal_layer.material.solar_absorptance
|
||||||
|
|
||||||
if catalog_construction.window is not None:
|
for thermal_opening in thermal_boundary.thermal_openings:
|
||||||
window_archetype = catalog_construction.window
|
if construction_archetype.window is not None:
|
||||||
construction.window_frame_ratio = window_archetype.frame_ratio
|
window_archetype = construction_archetype.window
|
||||||
construction.window_g_value = window_archetype.g_value
|
thermal_opening.construction_name = window_archetype.name
|
||||||
construction.window_overall_u_value = window_archetype.overall_u_value
|
thermal_opening.frame_ratio = window_archetype.frame_ratio
|
||||||
|
thermal_opening.g_value = window_archetype.g_value
|
||||||
|
thermal_opening.overall_u_value = window_archetype.overall_u_value
|
||||||
|
|
||||||
|
# todo: verify windows
|
||||||
|
@staticmethod
|
||||||
|
def _calculate_view_factors(thermal_zone):
|
||||||
|
"""
|
||||||
|
Get thermal zone view factors matrix
|
||||||
|
:return: [[float]]
|
||||||
|
"""
|
||||||
|
total_area = 0
|
||||||
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
|
total_area += thermal_boundary.opaque_area
|
||||||
|
for thermal_opening in thermal_boundary.thermal_openings:
|
||||||
|
total_area += thermal_opening.area
|
||||||
|
|
||||||
|
view_factors_matrix = []
|
||||||
|
for thermal_boundary_1 in thermal_zone.thermal_boundaries:
|
||||||
|
values = []
|
||||||
|
for thermal_boundary_2 in thermal_zone.thermal_boundaries:
|
||||||
|
value = 0
|
||||||
|
if thermal_boundary_1.id != thermal_boundary_2.id:
|
||||||
|
value = thermal_boundary_2.opaque_area / (total_area - thermal_boundary_1.opaque_area)
|
||||||
|
values.append(value)
|
||||||
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
|
for thermal_opening in thermal_boundary.thermal_openings:
|
||||||
|
value = thermal_opening.area / (total_area - thermal_boundary_1.opaque_area)
|
||||||
|
values.append(value)
|
||||||
|
view_factors_matrix.append(values)
|
||||||
|
|
||||||
|
for thermal_boundary_1 in thermal_zone.thermal_boundaries:
|
||||||
|
values = []
|
||||||
|
for thermal_opening_1 in thermal_boundary_1.thermal_openings:
|
||||||
|
for thermal_boundary_2 in thermal_zone.thermal_boundaries:
|
||||||
|
value = thermal_boundary_2.opaque_area / (total_area - thermal_opening_1.area)
|
||||||
|
values.append(value)
|
||||||
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
|
for thermal_opening_2 in thermal_boundary.thermal_openings:
|
||||||
|
value = 0
|
||||||
|
if thermal_opening_1.id != thermal_opening_2.id:
|
||||||
|
value = thermal_opening_2.area / (total_area - thermal_opening_1.area)
|
||||||
|
values.append(value)
|
||||||
|
view_factors_matrix.append(values)
|
||||||
|
thermal_zone.view_factors_matrix = view_factors_matrix
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _create_storeys(building, archetype, divide_in_storeys):
|
||||||
|
building.average_storey_height = archetype.average_storey_height
|
||||||
|
thermal_zones = StoreysGeneration(building, building.internal_zones[0],
|
||||||
|
divide_in_storeys=divide_in_storeys).thermal_zones
|
||||||
|
building.internal_zones[0].thermal_zones = thermal_zones
|
||||||
|
@ -8,11 +8,11 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
|
from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
|
||||||
from hub.city_model_structure.building_demand.thermal_archetype import ThermalArchetype
|
|
||||||
from hub.city_model_structure.building_demand.construction import Construction
|
|
||||||
from hub.city_model_structure.building_demand.layer import Layer
|
from hub.city_model_structure.building_demand.layer import Layer
|
||||||
|
from hub.city_model_structure.building_demand.material import Material
|
||||||
from hub.helpers.dictionaries import Dictionaries
|
from hub.helpers.dictionaries import Dictionaries
|
||||||
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
|
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
|
||||||
|
from hub.imports.construction.helpers.storeys_generation import StoreysGeneration
|
||||||
|
|
||||||
|
|
||||||
class NrelPhysicsParameters:
|
class NrelPhysicsParameters:
|
||||||
@ -44,8 +44,28 @@ class NrelPhysicsParameters:
|
|||||||
f' and climate zone {self._climate_zone}\n')
|
f' and climate zone {self._climate_zone}\n')
|
||||||
|
|
||||||
continue
|
continue
|
||||||
thermal_archetype = ThermalArchetype()
|
# if building has no thermal zones defined from geometry, and the building will be divided in storeys,
|
||||||
self._assign_values(thermal_archetype, archetype)
|
# one thermal zone per storey is assigned
|
||||||
|
if len(building.internal_zones) == 1:
|
||||||
|
if building.internal_zones[0].thermal_zones is None:
|
||||||
|
self._create_storeys(building, archetype, self._divide_in_storeys)
|
||||||
|
if self._divide_in_storeys:
|
||||||
|
for internal_zone in building.internal_zones:
|
||||||
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
|
thermal_zone.total_floor_area = thermal_zone.footprint_area
|
||||||
|
else:
|
||||||
|
number_of_storeys = int(building.eave_height / building.average_storey_height)
|
||||||
|
thermal_zone = building.internal_zones[0].thermal_zones[0]
|
||||||
|
thermal_zone.total_floor_area = thermal_zone.footprint_area * number_of_storeys
|
||||||
|
else:
|
||||||
|
for internal_zone in building.internal_zones:
|
||||||
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
|
thermal_zone.total_floor_area = thermal_zone.footprint_area
|
||||||
|
|
||||||
|
for internal_zone in building.internal_zones:
|
||||||
|
self._assign_values(internal_zone.thermal_zones, archetype)
|
||||||
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
|
self._calculate_view_factors(thermal_zone)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _search_archetype(nrel_catalog, function, year_of_construction, climate_zone):
|
def _search_archetype(nrel_catalog, function, year_of_construction, climate_zone):
|
||||||
@ -60,36 +80,111 @@ class NrelPhysicsParameters:
|
|||||||
raise KeyError('archetype not found')
|
raise KeyError('archetype not found')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _assign_values(thermal_archetype, catalog_archetype):
|
def _search_construction_in_archetype(archetype, construction_type):
|
||||||
thermal_archetype.extra_loses_due_to_thermal_bridges = catalog_archetype.extra_loses_due_to_thermal_bridges
|
construction_archetypes = archetype.constructions
|
||||||
thermal_archetype.thermal_capacity = catalog_archetype.thermal_capacity
|
for construction_archetype in construction_archetypes:
|
||||||
thermal_archetype.indirect_heated_ratio = catalog_archetype.indirect_heated_ratio
|
if str(construction_type) == str(construction_archetype.type):
|
||||||
thermal_archetype.infiltration_rate_for_ventilation_system_on = catalog_archetype.infiltration_rate_for_ventilation_system_on
|
return construction_archetype
|
||||||
thermal_archetype.infiltration_rate_for_ventilation_system_off = catalog_archetype.infiltration_rate_for_ventilation_system_off
|
return None
|
||||||
for catalog_construction in catalog_archetype.constructions:
|
|
||||||
construction = Construction()
|
def _assign_values(self, thermal_zones, archetype):
|
||||||
construction.window_ratio = catalog_construction.window_ratio
|
for thermal_zone in thermal_zones:
|
||||||
_layers = []
|
thermal_zone.additional_thermal_bridge_u_value = archetype.extra_loses_due_to_thermal_bridges
|
||||||
for layer_archetype in catalog_construction.layers:
|
thermal_zone.effective_thermal_capacity = archetype.thermal_capacity
|
||||||
|
thermal_zone.indirectly_heated_area_ratio = archetype.indirect_heated_ratio
|
||||||
|
thermal_zone.infiltration_rate_system_on = archetype.infiltration_rate_for_ventilation_system_on
|
||||||
|
thermal_zone.infiltration_rate_system_off = archetype.infiltration_rate_for_ventilation_system_off
|
||||||
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
|
construction_archetype = self._search_construction_in_archetype(archetype, thermal_boundary.type)
|
||||||
|
thermal_boundary.construction_name = construction_archetype.name
|
||||||
|
try:
|
||||||
|
thermal_boundary.window_ratio = construction_archetype.window_ratio
|
||||||
|
except ValueError:
|
||||||
|
# This is the normal operation way when the windows are defined in the geometry
|
||||||
|
continue
|
||||||
|
thermal_boundary.layers = []
|
||||||
|
for layer_archetype in construction_archetype.layers:
|
||||||
layer = Layer()
|
layer = Layer()
|
||||||
layer.thickness = layer_archetype.thickness
|
layer.thickness = layer_archetype.thickness
|
||||||
|
material = Material()
|
||||||
archetype_material = layer_archetype.material
|
archetype_material = layer_archetype.material
|
||||||
layer.name = archetype_material.name
|
material.name = archetype_material.name
|
||||||
layer.no_mass = archetype_material.no_mass
|
material.id = archetype_material.id
|
||||||
|
material.no_mass = archetype_material.no_mass
|
||||||
if archetype_material.no_mass:
|
if archetype_material.no_mass:
|
||||||
layer.thermal_resistance = archetype_material.thermal_resistance
|
material.thermal_resistance = archetype_material.thermal_resistance
|
||||||
else:
|
else:
|
||||||
layer.density = archetype_material.density
|
material.density = archetype_material.density
|
||||||
layer.conductivity = archetype_material.conductivity
|
material.conductivity = archetype_material.conductivity
|
||||||
layer.specific_heat = archetype_material.specific_heat
|
material.specific_heat = archetype_material.specific_heat
|
||||||
layer.solar_absorptance = archetype_material.solar_absorptance
|
material.solar_absorptance = archetype_material.solar_absorptance
|
||||||
layer.thermal_absorptance = archetype_material.thermal_absorptance
|
material.thermal_absorptance = archetype_material.thermal_absorptance
|
||||||
layer.visible_absorptance = archetype_material.visible_absorptance
|
material.visible_absorptance = archetype_material.visible_absorptance
|
||||||
_layers.append(layer)
|
layer.material = material
|
||||||
construction.layers = _layers
|
thermal_boundary.layers.append(layer)
|
||||||
|
# The agreement is that the layers are defined from outside to inside
|
||||||
|
external_layer = construction_archetype.layers[0]
|
||||||
|
external_surface = thermal_boundary.parent_surface
|
||||||
|
external_surface.short_wave_reflectance = 1 - external_layer.material.solar_absorptance
|
||||||
|
external_surface.long_wave_emittance = 1 - external_layer.material.solar_absorptance
|
||||||
|
internal_layer = construction_archetype.layers[len(construction_archetype.layers) - 1]
|
||||||
|
internal_surface = thermal_boundary.internal_surface
|
||||||
|
internal_surface.short_wave_reflectance = 1 - internal_layer.material.solar_absorptance
|
||||||
|
internal_surface.long_wave_emittance = 1 - internal_layer.material.solar_absorptance
|
||||||
|
|
||||||
if catalog_construction.window is not None:
|
for thermal_opening in thermal_boundary.thermal_openings:
|
||||||
window_archetype = catalog_construction.window
|
if construction_archetype.window is not None:
|
||||||
construction.window_frame_ratio = window_archetype.frame_ratio
|
window_archetype = construction_archetype.window
|
||||||
construction.window_g_value = window_archetype.g_value
|
thermal_opening.construction_name = window_archetype.name
|
||||||
construction.window_overall_u_value = window_archetype.overall_u_value
|
thermal_opening.frame_ratio = window_archetype.frame_ratio
|
||||||
|
thermal_opening.g_value = window_archetype.g_value
|
||||||
|
thermal_opening.overall_u_value = window_archetype.overall_u_value
|
||||||
|
|
||||||
|
# todo: verify windows
|
||||||
|
@staticmethod
|
||||||
|
def _calculate_view_factors(thermal_zone):
|
||||||
|
"""
|
||||||
|
Get thermal zone view factors matrix
|
||||||
|
:return: [[float]]
|
||||||
|
"""
|
||||||
|
total_area = 0
|
||||||
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
|
total_area += thermal_boundary.opaque_area
|
||||||
|
for thermal_opening in thermal_boundary.thermal_openings:
|
||||||
|
total_area += thermal_opening.area
|
||||||
|
|
||||||
|
view_factors_matrix = []
|
||||||
|
for thermal_boundary_1 in thermal_zone.thermal_boundaries:
|
||||||
|
values = []
|
||||||
|
for thermal_boundary_2 in thermal_zone.thermal_boundaries:
|
||||||
|
value = 0
|
||||||
|
if thermal_boundary_1.id != thermal_boundary_2.id:
|
||||||
|
value = thermal_boundary_2.opaque_area / (total_area - thermal_boundary_1.opaque_area)
|
||||||
|
values.append(value)
|
||||||
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
|
for thermal_opening in thermal_boundary.thermal_openings:
|
||||||
|
value = thermal_opening.area / (total_area - thermal_boundary_1.opaque_area)
|
||||||
|
values.append(value)
|
||||||
|
view_factors_matrix.append(values)
|
||||||
|
|
||||||
|
for thermal_boundary_1 in thermal_zone.thermal_boundaries:
|
||||||
|
values = []
|
||||||
|
for thermal_opening_1 in thermal_boundary_1.thermal_openings:
|
||||||
|
for thermal_boundary_2 in thermal_zone.thermal_boundaries:
|
||||||
|
value = thermal_boundary_2.opaque_area / (total_area - thermal_opening_1.area)
|
||||||
|
values.append(value)
|
||||||
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
|
for thermal_opening_2 in thermal_boundary.thermal_openings:
|
||||||
|
value = 0
|
||||||
|
if thermal_opening_1.id != thermal_opening_2.id:
|
||||||
|
value = thermal_opening_2.area / (total_area - thermal_opening_1.area)
|
||||||
|
values.append(value)
|
||||||
|
view_factors_matrix.append(values)
|
||||||
|
thermal_zone.view_factors_matrix = view_factors_matrix
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _create_storeys(building, archetype, divide_in_storeys):
|
||||||
|
building.average_storey_height = archetype.average_storey_height
|
||||||
|
thermal_zones = StoreysGeneration(building, building.internal_zones[0],
|
||||||
|
divide_in_storeys=divide_in_storeys).thermal_zones
|
||||||
|
building.internal_zones[0].thermal_zones = thermal_zones
|
||||||
|
@ -45,12 +45,12 @@ class InselMonthlyEnergyBalance:
|
|||||||
domestic_hot_water_demand = []
|
domestic_hot_water_demand = []
|
||||||
lighting_demand = []
|
lighting_demand = []
|
||||||
appliances_demand = []
|
appliances_demand = []
|
||||||
if building.internal_zones[0].thermal_zones_from_internal_zones is None:
|
if building.internal_zones[0].thermal_zones is None:
|
||||||
domestic_hot_water_demand = [0] * 12
|
domestic_hot_water_demand = [0] * 12
|
||||||
lighting_demand = [0] * 12
|
lighting_demand = [0] * 12
|
||||||
appliances_demand = [0] * 12
|
appliances_demand = [0] * 12
|
||||||
else:
|
else:
|
||||||
thermal_zone = building.internal_zones[0].thermal_zones_from_internal_zones[0]
|
thermal_zone = building.internal_zones[0].thermal_zones[0]
|
||||||
area = thermal_zone.total_floor_area
|
area = thermal_zone.total_floor_area
|
||||||
cold_water = building.cold_water_temperature[cte.MONTH]['epw']
|
cold_water = building.cold_water_temperature[cte.MONTH]['epw']
|
||||||
peak_flow = thermal_zone.domestic_hot_water.peak_flow
|
peak_flow = thermal_zone.domestic_hot_water.peak_flow
|
||||||
|
@ -58,7 +58,7 @@ class CityObject(Models):
|
|||||||
self.wall_area = wall_area
|
self.wall_area = wall_area
|
||||||
window_ratio = 0
|
window_ratio = 0
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
window_ratio = thermal_boundary.window_ratio
|
window_ratio = thermal_boundary.window_ratio
|
||||||
break
|
break
|
||||||
|
@ -106,7 +106,7 @@ class TestConstructionFactory(TestCase):
|
|||||||
self.assertIsNotNone(building.shell, 'building shell is none')
|
self.assertIsNotNone(building.shell, 'building shell is none')
|
||||||
|
|
||||||
def _check_thermal_zones(self, internal_zone):
|
def _check_thermal_zones(self, internal_zone):
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self.assertIsNotNone(thermal_zone.id, 'thermal_zone id is none')
|
self.assertIsNotNone(thermal_zone.id, 'thermal_zone id is none')
|
||||||
self.assertIsNotNone(thermal_zone.footprint_area, 'thermal_zone floor area is none')
|
self.assertIsNotNone(thermal_zone.footprint_area, 'thermal_zone floor area is none')
|
||||||
self.assertTrue(len(thermal_zone.thermal_boundaries) > 0, 'thermal_zone thermal_boundaries not defined')
|
self.assertTrue(len(thermal_zone.thermal_boundaries) > 0, 'thermal_zone thermal_boundaries not defined')
|
||||||
@ -133,7 +133,7 @@ class TestConstructionFactory(TestCase):
|
|||||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
self.assertIsNotNone(thermal_boundary.id, 'thermal_boundary id is none')
|
self.assertIsNotNone(thermal_boundary.id, 'thermal_boundary id is none')
|
||||||
self.assertIsNotNone(thermal_boundary.parent_surface, 'thermal_boundary surface is none')
|
self.assertIsNotNone(thermal_boundary.parent_surface, 'thermal_boundary surface is none')
|
||||||
self.assertIsNotNone(thermal_boundary.thermal_zones_from_internal_zones, 'thermal_boundary delimits no thermal zone')
|
self.assertIsNotNone(thermal_boundary.thermal_zones, 'thermal_boundary delimits no thermal zone')
|
||||||
self.assertIsNotNone(thermal_boundary.opaque_area, 'thermal_boundary area is none')
|
self.assertIsNotNone(thermal_boundary.opaque_area, 'thermal_boundary area is none')
|
||||||
self.assertIsNotNone(thermal_boundary.thickness, 'thermal_boundary thickness is none')
|
self.assertIsNotNone(thermal_boundary.thickness, 'thermal_boundary thickness is none')
|
||||||
self.assertIsNotNone(thermal_boundary.type, 'thermal_boundary type is none')
|
self.assertIsNotNone(thermal_boundary.type, 'thermal_boundary type is none')
|
||||||
@ -184,7 +184,7 @@ class TestConstructionFactory(TestCase):
|
|||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
self._check_thermal_zones(internal_zone)
|
self._check_thermal_zones(internal_zone)
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self._check_thermal_boundaries(thermal_zone)
|
self._check_thermal_boundaries(thermal_zone)
|
||||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
||||||
@ -202,7 +202,7 @@ class TestConstructionFactory(TestCase):
|
|||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
self._check_thermal_zones(internal_zone)
|
self._check_thermal_zones(internal_zone)
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self._check_thermal_boundaries(thermal_zone)
|
self._check_thermal_boundaries(thermal_zone)
|
||||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
||||||
@ -220,7 +220,7 @@ class TestConstructionFactory(TestCase):
|
|||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
self._check_thermal_zones(internal_zone)
|
self._check_thermal_zones(internal_zone)
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self._check_thermal_boundaries(thermal_zone)
|
self._check_thermal_boundaries(thermal_zone)
|
||||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
||||||
@ -238,7 +238,7 @@ class TestConstructionFactory(TestCase):
|
|||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
self._check_thermal_zones(internal_zone)
|
self._check_thermal_zones(internal_zone)
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self._check_thermal_boundaries(thermal_zone)
|
self._check_thermal_boundaries(thermal_zone)
|
||||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
||||||
@ -256,7 +256,7 @@ class TestConstructionFactory(TestCase):
|
|||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
self._check_thermal_zones(internal_zone)
|
self._check_thermal_zones(internal_zone)
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self._check_thermal_boundaries(thermal_zone)
|
self._check_thermal_boundaries(thermal_zone)
|
||||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
||||||
@ -277,7 +277,7 @@ class TestConstructionFactory(TestCase):
|
|||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
self._check_thermal_zones(internal_zone)
|
self._check_thermal_zones(internal_zone)
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self._check_thermal_boundaries(thermal_zone)
|
self._check_thermal_boundaries(thermal_zone)
|
||||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
||||||
@ -299,7 +299,7 @@ class TestConstructionFactory(TestCase):
|
|||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
self._check_thermal_zones(internal_zone)
|
self._check_thermal_zones(internal_zone)
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self._check_thermal_boundaries(thermal_zone)
|
self._check_thermal_boundaries(thermal_zone)
|
||||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
||||||
@ -321,7 +321,7 @@ class TestConstructionFactory(TestCase):
|
|||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
self._check_thermal_zones(internal_zone)
|
self._check_thermal_zones(internal_zone)
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self._check_thermal_boundaries(thermal_zone)
|
self._check_thermal_boundaries(thermal_zone)
|
||||||
for thermal_boundary in thermal_zone.thermal_boundaries:
|
for thermal_boundary in thermal_zone.thermal_boundaries:
|
||||||
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
|
||||||
|
@ -115,7 +115,7 @@ class TestExports(TestCase):
|
|||||||
self.assertIsNotNone(building.basement_heated, f'building {building.name} basement_heated is none')
|
self.assertIsNotNone(building.basement_heated, f'building {building.name} basement_heated is none')
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
self.assertIsNotNone(internal_zone.area, f'internal zone {internal_zone.id} area is none')
|
self.assertIsNotNone(internal_zone.area, f'internal zone {internal_zone.id} area is none')
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self.assertIsNotNone(thermal_zone.indirectly_heated_area_ratio, f'thermal zone {thermal_zone.id} '
|
self.assertIsNotNone(thermal_zone.indirectly_heated_area_ratio, f'thermal zone {thermal_zone.id} '
|
||||||
f'indirectly_heated_area_ratio is none')
|
f'indirectly_heated_area_ratio is none')
|
||||||
self.assertIsNotNone(thermal_zone.effective_thermal_capacity, f'thermal zone {thermal_zone.id} '
|
self.assertIsNotNone(thermal_zone.effective_thermal_capacity, f'thermal zone {thermal_zone.id} '
|
||||||
|
@ -38,7 +38,7 @@ class TestGeometryFactory(TestCase):
|
|||||||
self.assertIsNot(len(internal_zone.usages), 0, 'no building usages defined')
|
self.assertIsNot(len(internal_zone.usages), 0, 'no building usages defined')
|
||||||
for usage in internal_zone.usages:
|
for usage in internal_zone.usages:
|
||||||
self.assertIsNotNone(usage.id, 'usage id is none')
|
self.assertIsNotNone(usage.id, 'usage id is none')
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self._check_thermal_zone(thermal_zone)
|
self._check_thermal_zone(thermal_zone)
|
||||||
|
|
||||||
def _check_buildings(self, city):
|
def _check_buildings(self, city):
|
||||||
@ -46,7 +46,7 @@ class TestGeometryFactory(TestCase):
|
|||||||
self.assertIsNotNone(building.internal_zones, 'no internal zones created')
|
self.assertIsNotNone(building.internal_zones, 'no internal zones created')
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
self.assertIsNotNone(internal_zone.usages, 'usage zones are not defined')
|
self.assertIsNotNone(internal_zone.usages, 'usage zones are not defined')
|
||||||
self.assertIsNotNone(internal_zone.thermal_zones_from_internal_zones, 'thermal zones are not defined')
|
self.assertIsNotNone(internal_zone.thermal_zones, 'thermal zones are not defined')
|
||||||
self.assertIsNone(building.basement_heated, 'building basement_heated is not none')
|
self.assertIsNone(building.basement_heated, 'building basement_heated is not none')
|
||||||
self.assertIsNone(building.attic_heated, 'building attic_heated is not none')
|
self.assertIsNone(building.attic_heated, 'building attic_heated is not none')
|
||||||
self.assertIsNotNone(building.average_storey_height, 'building average_storey_height is none')
|
self.assertIsNotNone(building.average_storey_height, 'building average_storey_height is none')
|
||||||
@ -105,7 +105,7 @@ class TestGeometryFactory(TestCase):
|
|||||||
if usage_key == 'comnet':
|
if usage_key == 'comnet':
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self._check_extra_thermal_zone(thermal_zone)
|
self._check_extra_thermal_zone(thermal_zone)
|
||||||
# usage factory called first
|
# usage factory called first
|
||||||
city = self._get_citygml(file)
|
city = self._get_citygml(file)
|
||||||
@ -117,7 +117,7 @@ class TestGeometryFactory(TestCase):
|
|||||||
if usage_key == 'comnet':
|
if usage_key == 'comnet':
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self._check_extra_thermal_zone(thermal_zone)
|
self._check_extra_thermal_zone(thermal_zone)
|
||||||
|
|
||||||
def _test_pluto(self, file):
|
def _test_pluto(self, file):
|
||||||
@ -135,7 +135,7 @@ class TestGeometryFactory(TestCase):
|
|||||||
if usage_key == 'comnet':
|
if usage_key == 'comnet':
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self._check_extra_thermal_zone(thermal_zone)
|
self._check_extra_thermal_zone(thermal_zone)
|
||||||
# usage factory called first
|
# usage factory called first
|
||||||
city = self._get_citygml(file)
|
city = self._get_citygml(file)
|
||||||
@ -147,7 +147,7 @@ class TestGeometryFactory(TestCase):
|
|||||||
if usage_key == 'comnet':
|
if usage_key == 'comnet':
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self._check_extra_thermal_zone(thermal_zone)
|
self._check_extra_thermal_zone(thermal_zone)
|
||||||
|
|
||||||
def test_enrichment(self):
|
def test_enrichment(self):
|
||||||
|
@ -120,7 +120,6 @@ class TestExports(TestCase):
|
|||||||
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
|
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
|
||||||
UsageFactory('nrcan', city).enrich()
|
UsageFactory('nrcan', city).enrich()
|
||||||
WeatherFactory('epw', city).enrich()
|
WeatherFactory('epw', city).enrich()
|
||||||
print(self._output_path)
|
|
||||||
try:
|
try:
|
||||||
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
|
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -62,7 +62,7 @@ class TestGeometryFactory(TestCase):
|
|||||||
self.assertIsNotNone(building.internal_zones, 'building internal zones is none')
|
self.assertIsNotNone(building.internal_zones, 'building internal zones is none')
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
self.assertIsNone(internal_zone.usages, 'usage zones are defined')
|
self.assertIsNone(internal_zone.usages, 'usage zones are defined')
|
||||||
self.assertIsNone(internal_zone.thermal_zones_from_internal_zones, 'thermal zones are defined')
|
self.assertIsNone(internal_zone.thermal_zones, 'thermal zones are defined')
|
||||||
self.assertIsNone(building.basement_heated, 'building basement_heated is not none')
|
self.assertIsNone(building.basement_heated, 'building basement_heated is not none')
|
||||||
self.assertIsNone(building.attic_heated, 'building attic_heated is not none')
|
self.assertIsNone(building.attic_heated, 'building attic_heated is not none')
|
||||||
self.assertIsNone(building.terrains, 'building terrains is not none')
|
self.assertIsNone(building.terrains, 'building terrains is not none')
|
||||||
|
@ -115,7 +115,7 @@ class TestExports(TestCase):
|
|||||||
self.assertIsNotNone(building.basement_heated, f'building {building.name} basement_heated is none')
|
self.assertIsNotNone(building.basement_heated, f'building {building.name} basement_heated is none')
|
||||||
for internal_zone in building.internal_zones:
|
for internal_zone in building.internal_zones:
|
||||||
self.assertIsNotNone(internal_zone.area, f'internal zone {internal_zone.id} area is none')
|
self.assertIsNotNone(internal_zone.area, f'internal zone {internal_zone.id} area is none')
|
||||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
for thermal_zone in internal_zone.thermal_zones:
|
||||||
self.assertIsNotNone(thermal_zone.indirectly_heated_area_ratio, f'thermal zone {thermal_zone.id} '
|
self.assertIsNotNone(thermal_zone.indirectly_heated_area_ratio, f'thermal zone {thermal_zone.id} '
|
||||||
f'indirectly_heated_area_ratio is none')
|
f'indirectly_heated_area_ratio is none')
|
||||||
self.assertIsNotNone(thermal_zone.effective_thermal_capacity, f'thermal zone {thermal_zone.id} '
|
self.assertIsNotNone(thermal_zone.effective_thermal_capacity, f'thermal zone {thermal_zone.id} '
|
||||||
|
Loading…
Reference in New Issue
Block a user