city_retrofit/hub/helpers/thermal_zones_creation.py

139 lines
5.8 KiB
Python
Raw Normal View History

"""
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