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