diff --git a/hub/city_model_structure/building_demand/construction.py b/hub/city_model_structure/building_demand/construction.py index ad82999d..e41d2981 100644 --- a/hub/city_model_structure/building_demand/construction.py +++ b/hub/city_model_structure/building_demand/construction.py @@ -14,6 +14,7 @@ class Construction: """ def __init__(self): self._type = None + self._name = None self._layers = None self._window_ratio = None self._window_frame_ratio = None @@ -37,6 +38,22 @@ class Construction: """ self._type = value + @property + def name(self): + """ + Get construction name + :return: str + """ + return self._name + + @name.setter + def name(self, value): + """ + Set construction name + :param value: str + """ + self._name = value + @property def layers(self) -> [Layer]: """ diff --git a/hub/city_model_structure/building_demand/internal_zone.py b/hub/city_model_structure/building_demand/internal_zone.py index c0494f0a..8bf2c98b 100644 --- a/hub/city_model_structure/building_demand/internal_zone.py +++ b/hub/city_model_structure/building_demand/internal_zone.py @@ -130,6 +130,7 @@ class InternalZone: for hole in surface.holes_polygons: windows_areas.append(hole.area) _thermal_boundary = ThermalBoundary(surface, surface.solid_polygon.area, windows_areas) + surface.associated_thermal_boundaries = [_thermal_boundary] _thermal_boundaries.append(_thermal_boundary) _number_of_storeys = int(self.volume / self.area / self.thermal_archetype.average_storey_height) _thermal_zone = ThermalZone(_thermal_boundaries, self, self.volume, self.area, _number_of_storeys) diff --git a/hub/city_model_structure/building_demand/thermal_boundary.py b/hub/city_model_structure/building_demand/thermal_boundary.py index 66746037..1ff00244 100644 --- a/hub/city_model_structure/building_demand/thermal_boundary.py +++ b/hub/city_model_structure/building_demand/thermal_boundary.py @@ -256,6 +256,19 @@ class ThermalBoundary: raise TypeError('Constructions layers are not initialized') from TypeError return self._u_value + @property + def construction_name(self): + """ + Get construction name + :return: str + """ + if self._construction_archetype is not None: + self._construction_name = self._construction_archetype.name + else: + logging.error('Construction name not defined\n') + raise ValueError('Construction name not defined') + return self._construction_name + @u_value.setter def u_value(self, value): """ diff --git a/hub/exports/building_energy/idf.py b/hub/exports/building_energy/idf.py index 02de155e..50f97849 100644 --- a/hub/exports/building_energy/idf.py +++ b/hub/exports/building_energy/idf.py @@ -148,28 +148,28 @@ class Idf: def _add_material(self, layer): for material in self._idf.idfobjects[self._MATERIAL]: - if material.Name == layer.material.name: + if material.Name == layer.name: return for material in self._idf.idfobjects[self._MATERIAL_NOMASS]: - if material.Name == layer.material.name: + if material.Name == layer.name: return - if layer.material.no_mass: + if layer.no_mass: self._idf.newidfobject(self._MATERIAL_NOMASS, - Name=layer.material.name, + Name=layer.name, Roughness=self._ROUGHNESS, - Thermal_Resistance=layer.material.thermal_resistance + Thermal_Resistance=layer.thermal_resistance ) else: self._idf.newidfobject(self._MATERIAL, - Name=layer.material.name, + Name=layer.name, Roughness=self._ROUGHNESS, Thickness=layer.thickness, - Conductivity=layer.material.conductivity, - Density=layer.material.density, - Specific_Heat=layer.material.specific_heat, - Thermal_Absorptance=layer.material.thermal_absorptance, - Solar_Absorptance=layer.material.solar_absorptance, - Visible_Absorptance=layer.material.visible_absorptance + Conductivity=layer.conductivity, + Density=layer.density, + Specific_Heat=layer.specific_heat, + Thermal_Absorptance=layer.thermal_absorptance, + Solar_Absorptance=layer.solar_absorptance, + Visible_Absorptance=layer.visible_absorptance ) @staticmethod @@ -338,11 +338,11 @@ class Idf: _kwargs = {'Name': vegetation_name, 'Outside_Layer': thermal_boundary.parent_surface.vegetation.name} for i in range(0, len(layers) - 1): - _kwargs[f'Layer_{i + 2}'] = layers[i].material.name + _kwargs[f'Layer_{i + 2}'] = layers[i].name else: - _kwargs = {'Name': thermal_boundary.construction_name, 'Outside_Layer': layers[0].material.name} + _kwargs = {'Name': thermal_boundary.construction_name, 'Outside_Layer': layers[0].name} for i in range(1, len(layers) - 1): - _kwargs[f'Layer_{i + 1}'] = layers[i].material.name + _kwargs[f'Layer_{i + 1}'] = layers[i].name self._idf.newidfobject(self._CONSTRUCTION, **_kwargs) def _add_window_construction_and_material(self, thermal_opening): @@ -512,12 +512,12 @@ class Idf: self._rename_building(self._city.name) self._lod = self._city.level_of_detail.geometry for building in self._city.buildings: - print('building name', building.name) for internal_zone in building.internal_zones: if internal_zone.thermal_zones_from_internal_zones is None: continue for thermal_zone in internal_zone.thermal_zones_from_internal_zones: for thermal_boundary in thermal_zone.thermal_boundaries: + self._add_construction(thermal_boundary) if thermal_boundary.parent_surface.vegetation is not None: self._add_vegetation_material(thermal_boundary.parent_surface.vegetation) @@ -560,7 +560,7 @@ class Idf: self._add_dhw(thermal_zone, building.name) if self._export_type == "Surfaces": 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.thermal_zones_from_internal_zones is not None: self._add_surfaces(building, building.name) else: self._add_pure_geometry(building, building.name) @@ -677,41 +677,40 @@ class Idf: self._idf.set_wwr(wwr) def _add_surfaces(self, building, zone_name): - for internal_zone in building.internal_zones: - for thermal_zone in internal_zone.thermal_zones_from_internal_zones: - for boundary in thermal_zone.thermal_boundaries: - idf_surface_type = self.idf_surfaces[boundary.parent_surface.type] - outside_boundary_condition = 'Outdoors' - sun_exposure = 'SunExposed' - wind_exposure = 'WindExposed' - _kwargs = {'Name': f'{boundary.parent_surface.name}', - 'Surface_Type': idf_surface_type, - 'Zone_Name': zone_name} - if boundary.parent_surface.type == cte.GROUND: - outside_boundary_condition = 'Ground' - sun_exposure = 'NoSun' - wind_exposure = 'NoWind' - if boundary.parent_surface.percentage_shared is not None and boundary.parent_surface.percentage_shared > 0.5: - outside_boundary_condition = 'Surface' - outside_boundary_condition_object = boundary.parent_surface.name - sun_exposure = 'NoSun' - wind_exposure = 'NoWind' - _kwargs['Outside_Boundary_Condition_Object'] = outside_boundary_condition_object - _kwargs['Outside_Boundary_Condition'] = outside_boundary_condition - _kwargs['Sun_Exposure'] = sun_exposure - _kwargs['Wind_Exposure'] = wind_exposure + for thermal_zone in building.thermal_zones_from_internal_zones: + for boundary in thermal_zone.thermal_boundaries: + idf_surface_type = self.idf_surfaces[boundary.parent_surface.type] + outside_boundary_condition = 'Outdoors' + sun_exposure = 'SunExposed' + wind_exposure = 'WindExposed' + _kwargs = {'Name': f'{boundary.parent_surface.name}', + 'Surface_Type': idf_surface_type, + 'Zone_Name': zone_name} + if boundary.parent_surface.type == cte.GROUND: + outside_boundary_condition = 'Ground' + sun_exposure = 'NoSun' + wind_exposure = 'NoWind' + if boundary.parent_surface.percentage_shared is not None and boundary.parent_surface.percentage_shared > 0.5: + outside_boundary_condition = 'Surface' + outside_boundary_condition_object = boundary.parent_surface.name + sun_exposure = 'NoSun' + wind_exposure = 'NoWind' + _kwargs['Outside_Boundary_Condition_Object'] = outside_boundary_condition_object + _kwargs['Outside_Boundary_Condition'] = outside_boundary_condition + _kwargs['Sun_Exposure'] = sun_exposure + _kwargs['Wind_Exposure'] = wind_exposure - if boundary.parent_surface.vegetation is not None: - construction_name = f'{boundary.construction_name}_{boundary.parent_surface.vegetation.name}' - else: - construction_name = boundary.construction_name - _kwargs['Construction_Name'] = construction_name + if boundary.parent_surface.vegetation is not None: + construction_name = f'{boundary.construction_name}_{boundary.parent_surface.vegetation.name}' + else: + construction_name = boundary.construction_name + _kwargs['Construction_Name'] = construction_name - surface = self._idf.newidfobject(self._SURFACE, **_kwargs) + surface = self._idf.newidfobject(self._SURFACE, **_kwargs) - coordinates = self._matrix_to_list(boundary.parent_surface.solid_polygon.coordinates, - self._city.lower_corner) - surface.setcoords(coordinates) + coordinates = self._matrix_to_list(boundary.parent_surface.solid_polygon.coordinates, + self._city.lower_corner) + surface.setcoords(coordinates) if self._lod >= 3: for internal_zone in building.internal_zones: diff --git a/hub/imports/construction/eilat_physics_parameters.py b/hub/imports/construction/eilat_physics_parameters.py index ea088178..c09db490 100644 --- a/hub/imports/construction/eilat_physics_parameters.py +++ b/hub/imports/construction/eilat_physics_parameters.py @@ -71,6 +71,7 @@ class EilatPhysicsParameters: for catalog_construction in catalog_archetype.constructions: construction = Construction() construction.type = catalog_construction.type + construction.name = catalog_construction.name if catalog_construction.window_ratio is not None: for _orientation in catalog_construction.window_ratio: if catalog_construction.window_ratio[_orientation] is None: diff --git a/hub/imports/construction/nrcan_physics_parameters.py b/hub/imports/construction/nrcan_physics_parameters.py index 9ab9964c..8caede23 100644 --- a/hub/imports/construction/nrcan_physics_parameters.py +++ b/hub/imports/construction/nrcan_physics_parameters.py @@ -71,6 +71,7 @@ class NrcanPhysicsParameters: for catalog_construction in catalog_archetype.constructions: construction = Construction() construction.type = catalog_construction.type + construction.name = catalog_construction.name if catalog_construction.window_ratio is not None: for _orientation in catalog_construction.window_ratio: if catalog_construction.window_ratio[_orientation] is None: diff --git a/hub/imports/construction/nrel_physics_parameters.py b/hub/imports/construction/nrel_physics_parameters.py index 55b4d3b7..6f61102a 100644 --- a/hub/imports/construction/nrel_physics_parameters.py +++ b/hub/imports/construction/nrel_physics_parameters.py @@ -73,6 +73,7 @@ class NrelPhysicsParameters: for catalog_construction in catalog_archetype.constructions: construction = Construction() construction.type = catalog_construction.type + construction.name = catalog_construction.name if catalog_construction.window_ratio is not None: construction.window_ratio = {'north': catalog_construction.window_ratio, 'east': catalog_construction.window_ratio,