starting the process of changing thermal_zones generation, NOT working version
This commit is contained in:
parent
1a8dbe7f87
commit
f3208f1735
|
@ -114,7 +114,7 @@ class Building(CityObject):
|
|||
:return: [InternalZone]
|
||||
"""
|
||||
if self._internal_zones is None:
|
||||
self._internal_zones = [InternalZone(self.surfaces, self.floor_area)]
|
||||
self._internal_zones = [InternalZone(self.surfaces, self.floor_area, self.volume)]
|
||||
return self._internal_zones
|
||||
|
||||
@property
|
||||
|
|
134
hub/city_model_structure/building_demand/construction.py
Normal file
134
hub/city_model_structure/building_demand/construction.py
Normal file
|
@ -0,0 +1,134 @@
|
|||
"""
|
||||
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
|
|
@ -11,17 +11,18 @@ 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.attributes.polyhedron import Polyhedron
|
||||
from hub.city_model_structure.energy_systems.hvac_system import HvacSystem
|
||||
from hub.helpers.thermal_zones_creation import ThermalZonesCreation
|
||||
|
||||
|
||||
class InternalZone:
|
||||
"""
|
||||
InternalZone class
|
||||
"""
|
||||
def __init__(self, surfaces, area):
|
||||
def __init__(self, surfaces, area, volume):
|
||||
self._surfaces = surfaces
|
||||
self._id = None
|
||||
self._geometry = None
|
||||
self._volume = None
|
||||
self._volume = volume
|
||||
self._area = area
|
||||
self._thermal_zones = None
|
||||
self._usages = None
|
||||
|
@ -64,7 +65,7 @@ class InternalZone:
|
|||
Get internal zone volume in cubic meters
|
||||
:return: float
|
||||
"""
|
||||
return self.geometry.volume
|
||||
return self._volume
|
||||
|
||||
@property
|
||||
def area(self):
|
||||
|
|
|
@ -4,9 +4,9 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
import uuid
|
||||
from typing import Union
|
||||
from hub.city_model_structure.building_demand.material import Material
|
||||
|
||||
|
||||
class Layer:
|
||||
|
@ -14,9 +14,17 @@ class Layer:
|
|||
Layer class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._material = None
|
||||
self._thickness = 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
|
||||
def id(self):
|
||||
|
@ -28,22 +36,6 @@ class Layer:
|
|||
self._id = uuid.uuid4()
|
||||
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
|
||||
def thickness(self) -> Union[None, float]:
|
||||
"""
|
||||
|
@ -60,3 +52,155 @@ class Layer:
|
|||
"""
|
||||
if value is not None:
|
||||
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)
|
||||
|
|
|
@ -1,193 +0,0 @@
|
|||
"""
|
||||
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)
|
126
hub/city_model_structure/building_demand/thermal_archetype.py
Normal file
126
hub/city_model_structure/building_demand/thermal_archetype.py
Normal file
|
@ -0,0 +1,126 @@
|
|||
"""
|
||||
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
|
138
hub/helpers/thermal_zones_creation.py
Normal file
138
hub/helpers/thermal_zones_creation.py
Normal file
|
@ -0,0 +1,138 @@
|
|||
"""
|
||||
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
|
||||
from hub.city_model_structure.building_demand.thermal_zone import ThermalZone
|
||||
from hub.city_model_structure.building_demand.thermal_boundary import ThermalBoundary
|
||||
|
||||
|
||||
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_internal_zones(self) -> [ThermalZone]:
|
||||
"""
|
||||
Create and get thermal zones as 1 per each internal zone
|
||||
:return: [ThermalZone]
|
||||
"""
|
||||
_thermal_zones = []
|
||||
_thermal_boundaries = []
|
||||
for internal_zone in self._building.internal_zones:
|
||||
for surface in internal_zone.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, internal_zone, internal_zone.volume, internal_zone.floor_area)
|
||||
_thermal_zones.append(_thermal_zone)
|
||||
return _thermal_zones
|
||||
|
||||
@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 = thermal_zones
|
||||
|
||||
# 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 _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,15 +6,13 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
|||
"""
|
||||
|
||||
import logging
|
||||
import math
|
||||
|
||||
import hub.helpers.constants as cte
|
||||
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.material import Material
|
||||
from hub.helpers.dictionaries import Dictionaries
|
||||
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
|
||||
from hub.imports.construction.helpers.storeys_generation import StoreysGeneration
|
||||
|
||||
|
||||
class EilatPhysicsParameters:
|
||||
|
@ -35,7 +33,7 @@ class EilatPhysicsParameters:
|
|||
eilat_catalog = ConstructionCatalogFactory('eilat').catalog
|
||||
for building in city.buildings:
|
||||
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
|
||||
function = Dictionaries().hub_function_to_eilat_construction_function[building.function]
|
||||
try:
|
||||
|
@ -46,29 +44,8 @@ class EilatPhysicsParameters:
|
|||
f'[%s], building year of construction: %s and climate zone %s', building.name, function,
|
||||
building.function, building.year_of_construction, self._climate_zone)
|
||||
continue
|
||||
|
||||
# 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)
|
||||
thermal_archetype = ThermalArchetype()
|
||||
self._assign_values(thermal_archetype, archetype)
|
||||
|
||||
@staticmethod
|
||||
def _search_archetype(nrcan_catalog, function, year_of_construction, climate_zone):
|
||||
|
@ -81,133 +58,43 @@ class EilatPhysicsParameters:
|
|||
raise KeyError('archetype not found')
|
||||
|
||||
@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
|
||||
|
||||
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
|
||||
def _assign_values(thermal_archetype, catalog_archetype):
|
||||
thermal_archetype.extra_loses_due_to_thermal_bridges = catalog_archetype.extra_loses_due_to_thermal_bridges
|
||||
thermal_archetype.indirect_heated_ratio = 0
|
||||
thermal_archetype.infiltration_rate_for_ventilation_system_on = catalog_archetype.infiltration_rate_for_ventilation_system_on
|
||||
thermal_archetype.infiltration_rate_for_ventilation_system_off = catalog_archetype.infiltration_rate_for_ventilation_system_off
|
||||
effective_thermal_capacity = 0
|
||||
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 catalog_construction in catalog_archetype.constructions:
|
||||
construction = Construction()
|
||||
construction.window_ratio = catalog_construction.window_ratio
|
||||
_layers = []
|
||||
total_thickness = 0
|
||||
for layer_archetype in construction_archetype.layers:
|
||||
for layer_archetype in catalog_construction.layers:
|
||||
layer = Layer()
|
||||
layer.thickness = layer_archetype.thickness
|
||||
total_thickness += layer_archetype.thickness
|
||||
material = Material()
|
||||
archetype_material = layer_archetype.material
|
||||
material.name = archetype_material.name
|
||||
material.id = archetype_material.id
|
||||
material.no_mass = archetype_material.no_mass
|
||||
layer.name = archetype_material.name
|
||||
layer.no_mass = archetype_material.no_mass
|
||||
if archetype_material.no_mass:
|
||||
material.thermal_resistance = archetype_material.thermal_resistance
|
||||
layer.thermal_resistance = archetype_material.thermal_resistance
|
||||
else:
|
||||
material.density = archetype_material.density
|
||||
material.conductivity = archetype_material.conductivity
|
||||
material.specific_heat = archetype_material.specific_heat
|
||||
layer.density = archetype_material.density
|
||||
layer.conductivity = archetype_material.conductivity
|
||||
layer.specific_heat = archetype_material.specific_heat
|
||||
effective_thermal_capacity += archetype_material.specific_heat \
|
||||
* archetype_material.density * layer_archetype.thickness
|
||||
material.solar_absorptance = archetype_material.solar_absorptance
|
||||
material.thermal_absorptance = archetype_material.thermal_absorptance
|
||||
material.visible_absorptance = archetype_material.visible_absorptance
|
||||
layer.material = material
|
||||
thermal_boundary.layers.append(layer)
|
||||
|
||||
layer.solar_absorptance = archetype_material.solar_absorptance
|
||||
layer.thermal_absorptance = archetype_material.thermal_absorptance
|
||||
layer.visible_absorptance = archetype_material.visible_absorptance
|
||||
_layers.append(layer)
|
||||
construction.layers = _layers
|
||||
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
|
||||
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
if construction_archetype.window is not None:
|
||||
window_archetype = construction_archetype.window
|
||||
thermal_opening.construction_name = window_archetype.name
|
||||
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
|
||||
if catalog_construction.window is not None:
|
||||
window_archetype = catalog_construction.window
|
||||
construction.window_frame_ratio = window_archetype.frame_ratio
|
||||
construction.window_g_value = window_archetype.g_value
|
||||
construction.window_overall_u_value = window_archetype.overall_u_value
|
||||
|
||||
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
|
||||
thermal_archetype.thermal_capacity = effective_thermal_capacity
|
||||
|
|
|
@ -6,15 +6,13 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
|||
"""
|
||||
|
||||
import logging
|
||||
import math
|
||||
|
||||
import hub.helpers.constants as cte
|
||||
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.material import Material
|
||||
from hub.helpers.dictionaries import Dictionaries
|
||||
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
|
||||
from hub.imports.construction.helpers.storeys_generation import StoreysGeneration
|
||||
|
||||
|
||||
class NrcanPhysicsParameters:
|
||||
|
@ -35,7 +33,7 @@ class NrcanPhysicsParameters:
|
|||
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
|
||||
for building in city.buildings:
|
||||
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
|
||||
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
|
||||
try:
|
||||
|
@ -46,29 +44,8 @@ class NrcanPhysicsParameters:
|
|||
f'[%s], building year of construction: %s and climate zone %s', building.name, function,
|
||||
building.function, building.year_of_construction, self._climate_zone)
|
||||
continue
|
||||
|
||||
# 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)
|
||||
thermal_archetype = ThermalArchetype()
|
||||
self._assign_values(thermal_archetype, archetype)
|
||||
|
||||
@staticmethod
|
||||
def _search_archetype(nrcan_catalog, function, year_of_construction, climate_zone):
|
||||
|
@ -81,126 +58,36 @@ class NrcanPhysicsParameters:
|
|||
raise KeyError('archetype not found')
|
||||
|
||||
@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
|
||||
|
||||
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
|
||||
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:
|
||||
def _assign_values(thermal_archetype, catalog_archetype):
|
||||
thermal_archetype.extra_loses_due_to_thermal_bridges = catalog_archetype.extra_loses_due_to_thermal_bridges
|
||||
thermal_archetype.thermal_capacity = catalog_archetype.thermal_capacity
|
||||
thermal_archetype.indirect_heated_ratio = 0
|
||||
thermal_archetype.infiltration_rate_for_ventilation_system_on = catalog_archetype.infiltration_rate_for_ventilation_system_on
|
||||
thermal_archetype.infiltration_rate_for_ventilation_system_off = catalog_archetype.infiltration_rate_for_ventilation_system_off
|
||||
for catalog_construction in catalog_archetype.constructions:
|
||||
construction = Construction()
|
||||
construction.window_ratio = catalog_construction.window_ratio
|
||||
_layers = []
|
||||
for layer_archetype in catalog_construction.layers:
|
||||
layer = Layer()
|
||||
layer.thickness = layer_archetype.thickness
|
||||
material = Material()
|
||||
archetype_material = layer_archetype.material
|
||||
material.name = archetype_material.name
|
||||
material.id = archetype_material.id
|
||||
material.no_mass = archetype_material.no_mass
|
||||
layer.name = archetype_material.name
|
||||
layer.no_mass = archetype_material.no_mass
|
||||
if archetype_material.no_mass:
|
||||
material.thermal_resistance = archetype_material.thermal_resistance
|
||||
layer.thermal_resistance = archetype_material.thermal_resistance
|
||||
else:
|
||||
material.density = archetype_material.density
|
||||
material.conductivity = archetype_material.conductivity
|
||||
material.specific_heat = archetype_material.specific_heat
|
||||
material.solar_absorptance = archetype_material.solar_absorptance
|
||||
material.thermal_absorptance = archetype_material.thermal_absorptance
|
||||
material.visible_absorptance = archetype_material.visible_absorptance
|
||||
layer.material = material
|
||||
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
|
||||
layer.density = archetype_material.density
|
||||
layer.conductivity = archetype_material.conductivity
|
||||
layer.specific_heat = archetype_material.specific_heat
|
||||
layer.solar_absorptance = archetype_material.solar_absorptance
|
||||
layer.thermal_absorptance = archetype_material.thermal_absorptance
|
||||
layer.visible_absorptance = archetype_material.visible_absorptance
|
||||
_layers.append(layer)
|
||||
construction.layers = _layers
|
||||
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
if construction_archetype.window is not None:
|
||||
window_archetype = construction_archetype.window
|
||||
thermal_opening.construction_name = window_archetype.name
|
||||
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
|
||||
if catalog_construction.window is not None:
|
||||
window_archetype = catalog_construction.window
|
||||
construction.window_frame_ratio = window_archetype.frame_ratio
|
||||
construction.window_g_value = window_archetype.g_value
|
||||
construction.window_overall_u_value = window_archetype.overall_u_value
|
||||
|
|
|
@ -8,11 +8,11 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord
|
|||
import logging
|
||||
|
||||
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.material import Material
|
||||
from hub.helpers.dictionaries import Dictionaries
|
||||
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
|
||||
from hub.imports.construction.helpers.storeys_generation import StoreysGeneration
|
||||
|
||||
|
||||
class NrelPhysicsParameters:
|
||||
|
@ -44,28 +44,8 @@ class NrelPhysicsParameters:
|
|||
f' and climate zone {self._climate_zone}\n')
|
||||
|
||||
continue
|
||||
# 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)
|
||||
thermal_archetype = ThermalArchetype()
|
||||
self._assign_values(thermal_archetype, archetype)
|
||||
|
||||
@staticmethod
|
||||
def _search_archetype(nrel_catalog, function, year_of_construction, climate_zone):
|
||||
|
@ -80,111 +60,36 @@ class NrelPhysicsParameters:
|
|||
raise KeyError('archetype not found')
|
||||
|
||||
@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
|
||||
|
||||
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
|
||||
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:
|
||||
def _assign_values(thermal_archetype, catalog_archetype):
|
||||
thermal_archetype.extra_loses_due_to_thermal_bridges = catalog_archetype.extra_loses_due_to_thermal_bridges
|
||||
thermal_archetype.thermal_capacity = catalog_archetype.thermal_capacity
|
||||
thermal_archetype.indirect_heated_ratio = catalog_archetype.indirect_heated_ratio
|
||||
thermal_archetype.infiltration_rate_for_ventilation_system_on = catalog_archetype.infiltration_rate_for_ventilation_system_on
|
||||
thermal_archetype.infiltration_rate_for_ventilation_system_off = catalog_archetype.infiltration_rate_for_ventilation_system_off
|
||||
for catalog_construction in catalog_archetype.constructions:
|
||||
construction = Construction()
|
||||
construction.window_ratio = catalog_construction.window_ratio
|
||||
_layers = []
|
||||
for layer_archetype in catalog_construction.layers:
|
||||
layer = Layer()
|
||||
layer.thickness = layer_archetype.thickness
|
||||
material = Material()
|
||||
archetype_material = layer_archetype.material
|
||||
material.name = archetype_material.name
|
||||
material.id = archetype_material.id
|
||||
material.no_mass = archetype_material.no_mass
|
||||
layer.name = archetype_material.name
|
||||
layer.no_mass = archetype_material.no_mass
|
||||
if archetype_material.no_mass:
|
||||
material.thermal_resistance = archetype_material.thermal_resistance
|
||||
layer.thermal_resistance = archetype_material.thermal_resistance
|
||||
else:
|
||||
material.density = archetype_material.density
|
||||
material.conductivity = archetype_material.conductivity
|
||||
material.specific_heat = archetype_material.specific_heat
|
||||
material.solar_absorptance = archetype_material.solar_absorptance
|
||||
material.thermal_absorptance = archetype_material.thermal_absorptance
|
||||
material.visible_absorptance = archetype_material.visible_absorptance
|
||||
layer.material = material
|
||||
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
|
||||
layer.density = archetype_material.density
|
||||
layer.conductivity = archetype_material.conductivity
|
||||
layer.specific_heat = archetype_material.specific_heat
|
||||
layer.solar_absorptance = archetype_material.solar_absorptance
|
||||
layer.thermal_absorptance = archetype_material.thermal_absorptance
|
||||
layer.visible_absorptance = archetype_material.visible_absorptance
|
||||
_layers.append(layer)
|
||||
construction.layers = _layers
|
||||
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
if construction_archetype.window is not None:
|
||||
window_archetype = construction_archetype.window
|
||||
thermal_opening.construction_name = window_archetype.name
|
||||
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
|
||||
if catalog_construction.window is not None:
|
||||
window_archetype = catalog_construction.window
|
||||
construction.window_frame_ratio = window_archetype.frame_ratio
|
||||
construction.window_g_value = window_archetype.g_value
|
||||
construction.window_overall_u_value = window_archetype.overall_u_value
|
||||
|
|
|
@ -120,6 +120,7 @@ class TestExports(TestCase):
|
|||
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
|
||||
UsageFactory('nrcan', city).enrich()
|
||||
WeatherFactory('epw', city).enrich()
|
||||
print(self._output_path)
|
||||
try:
|
||||
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
|
||||
except Exception:
|
||||
|
|
Loading…
Reference in New Issue
Block a user