diff --git a/city_model_structure/building.py b/city_model_structure/building.py index 73b6e763..1626ff75 100644 --- a/city_model_structure/building.py +++ b/city_model_structure/building.py @@ -52,6 +52,7 @@ class Building(CityObject): self._min_y = min(self._min_y, surface.lower_corner[1]) self._min_z = min(self._min_z, surface.lower_corner[2]) surface.id = surface_id + # todo: consider all type of surfaces, not only these four if surface.type == 'Ground': self._grounds.append(surface) elif surface.type == 'Wall': @@ -302,6 +303,8 @@ class Building(CityObject): """ number_of_storeys, height = self._calculate_number_storeys_and_height(self.average_storey_height, self.eave_height, self.storeys_above_ground) + + number_of_storeys = 1 if not self._divide_in_storeys or number_of_storeys == 1: return [Storey('storey_0', self.surfaces, [None, None], self.volume)] diff --git a/city_model_structure/building_demand/surface.py b/city_model_structure/building_demand/surface.py index cf892c46..b4467129 100644 --- a/city_model_structure/building_demand/surface.py +++ b/city_model_structure/building_demand/surface.py @@ -38,7 +38,8 @@ class Surface: self._solid_polygon = solid_polygon self._pv_system_installed = None self._inverse = None - self._thermal_boundary = None + # todo: do I need it??? + self._associated_thermal_boundary = None @property def name(self): diff --git a/city_model_structure/building_demand/thermal_boundary.py b/city_model_structure/building_demand/thermal_boundary.py index 7e992a30..25d7c26c 100644 --- a/city_model_structure/building_demand/thermal_boundary.py +++ b/city_model_structure/building_demand/thermal_boundary.py @@ -20,8 +20,9 @@ class ThermalBoundary: def __init__(self, surface, delimits): self._surface = surface self._delimits = delimits - # ToDo: up to at least LOD2 will be just one thermal opening per Thermal boundary, review for LOD3 and LOD4 - self._thermal_openings = [ThermalOpening()] + # ToDo: up to at least LOD2 will be just one thermal opening per Thermal boundary only if window_ratio > 0, + # review for LOD3 and LOD4 + self._thermal_openings = None self._layers = None self._outside_solar_absorptance = None self._outside_thermal_absorptance = None @@ -36,6 +37,9 @@ class ThermalBoundary: self._surface_geometry = None self._thickness = None self._virtual_internal_surface = None + self._inside_emissivity = None + self._alpha_coefficient = None + self._radiative_coefficient = None @property def surface(self) -> Surface: @@ -76,7 +80,20 @@ class ThermalBoundary: Thermal boundary area in square meters :return: float """ - return self._surface.solid_polygon.area + # to check the lod without depending on that parameter + if float(self.surface.solid_polygon.area) - float(self.surface.perimeter_polygon.area) < 1e-3: + area = float(self.surface.perimeter_polygon.area) * (1 - float(self.window_ratio)) + else: + area = self.surface.solid_polygon.area + return area + + @property + def _total_area_including_windows(self): + """ + Thermal boundary plus windows area in square meters + :return: float + """ + return self.surface.perimeter_polygon.area @property def thickness(self): @@ -146,6 +163,15 @@ class ThermalBoundary: Get thermal boundary thermal openings :return: [ThermalOpening] """ + if self._thermal_openings is None: + if float(self.window_ratio) > 0: + thermal_opening = ThermalOpening() + thermal_opening.area = float(self._total_area_including_windows) * float(self.window_ratio) + thermal_opening.hi = self.hi + thermal_opening.he = self.he + self._thermal_openings = [thermal_opening] + else: + self._thermal_openings = [] return self._thermal_openings @thermal_openings.setter @@ -309,3 +335,30 @@ class ThermalBoundary: if self._virtual_internal_surface is None: self._virtual_internal_surface = self.surface.inverse return self._virtual_internal_surface + + # todo: need to be documented and extract information from construction library + @property + def inside_emissivity(self): + return self._inside_emissivity + + @inside_emissivity.setter + def inside_emissivity(self, value): + self._inside_emissivity = value + + @property + def alpha_coefficient(self): + return self._alpha_coefficient + + @alpha_coefficient.setter + def alpha_coefficient(self, value): + self._alpha_coefficient = value + + @property + def radiative_coefficient(self): + return self._radiative_coefficient + + @radiative_coefficient.setter + def radiative_coefficient(self, value): + self._radiative_coefficient = value + + diff --git a/city_model_structure/building_demand/thermal_opening.py b/city_model_structure/building_demand/thermal_opening.py index 01aebd2d..c34bcf55 100644 --- a/city_model_structure/building_demand/thermal_opening.py +++ b/city_model_structure/building_demand/thermal_opening.py @@ -26,6 +26,9 @@ class ThermalOpening: self._hi = None self._he = None self._surface_geometry = None + self._inside_emissivity = None + self._alpha_coefficient = None + self._radiative_coefficient = None @property def area(self): @@ -35,6 +38,14 @@ class ThermalOpening: """ return self._area + @area.setter + def area(self, value): + """ + Thermal opening area in square meters setter + :param value: float + """ + self._area = value + @property def openable_ratio(self): """ @@ -127,8 +138,6 @@ class ThermalOpening: if self._overall_u_value is None and self.conductivity is not None: h_i = self.hi h_e = self.he - h_i = 1 - h_e = 1 r_value = 1 / h_i + 1 / h_e + float(self.conductivity) / float(self.thickness) self._overall_u_value = 1 / r_value @@ -219,3 +228,28 @@ class ThermalOpening: :return: Polygon """ return self._surface_geometry + + # todo: need to be documented and extract information from construction library + @property + def inside_emissivity(self): + return self._inside_emissivity + + @inside_emissivity.setter + def inside_emissivity(self, value): + self._inside_emissivity = value + + @property + def alpha_coefficient(self): + return self._alpha_coefficient + + @alpha_coefficient.setter + def alpha_coefficient(self, value): + self._alpha_coefficient = value + + @property + def radiative_coefficient(self): + return self._radiative_coefficient + + @radiative_coefficient.setter + def radiative_coefficient(self, value): + self._radiative_coefficient = value diff --git a/data/construction/us_constructions.xml b/data/construction/us_constructions.xml index c18ec613..b7a2ab51 100644 --- a/data/construction/us_constructions.xml +++ b/data/construction/us_constructions.xml @@ -133,13 +133,6 @@ 0.7 0.7 - - true - 0.36256 - 0.9 - 0.7 - 0.7 - 45.006 7680 @@ -163,13 +156,6 @@ 0.7 0.8 - - true - 0.36256 - 0.9 - 0.7 - 0.7 - true 0.21648 @@ -177,13 +163,6 @@ 0.7 0.8 - - true - 0.36256 - 0.9 - 0.7 - 0.7 - true 0.21648 @@ -345,7 +324,7 @@ 0.92 - 13 + 12 3 @@ -454,7 +433,7 @@ 0.92 - 17 + 12 3 @@ -525,7 +504,7 @@ 0.92 - 19 + 12 3 diff --git a/imports/construction/ca_physics_parameters.py b/imports/construction/ca_physics_parameters.py index 13cad8b7..59d76d20 100644 --- a/imports/construction/ca_physics_parameters.py +++ b/imports/construction/ca_physics_parameters.py @@ -63,9 +63,10 @@ class CaPhysicsParameters(NrelPhysicsInterface): thermal_boundary.outside_solar_absorptance = thermal_boundary_archetype.outside_solar_absorptance thermal_boundary.construction_name = thermal_boundary_archetype.construction_name thermal_boundary.window_ratio = thermal_boundary_archetype.window_ratio - for thermal_opening in thermal_boundary.thermal_openings: - if thermal_boundary_archetype.thermal_opening is not None: - thermal_opening_archetype = thermal_boundary_archetype.thermal_opening - thermal_opening.frame_ratio = thermal_opening_archetype.frame_ratio - thermal_opening.g_value = thermal_opening_archetype.g_value - thermal_opening.overall_u_value = thermal_opening_archetype.overall_u_value + if thermal_boundary.thermal_openings is not None: + for thermal_opening in thermal_boundary.thermal_openings: + if thermal_boundary_archetype.thermal_opening is not None: + thermal_opening_archetype = thermal_boundary_archetype.thermal_opening + thermal_opening.frame_ratio = thermal_opening_archetype.frame_ratio + thermal_opening.g_value = thermal_opening_archetype.g_value + thermal_opening.overall_u_value = thermal_opening_archetype.overall_u_value diff --git a/imports/geometry/citygml.py b/imports/geometry/citygml.py index cbc23a6d..a244db1a 100644 --- a/imports/geometry/citygml.py +++ b/imports/geometry/citygml.py @@ -83,7 +83,8 @@ class CityGml: surfaces = CityGmlLod2(city_object).surfaces else: raise NotImplementedError("Not supported level of detail") - return Building(name, lod, surfaces, year_of_construction, function, self._lower_corner, []) + return Building(name, lod, surfaces, year_of_construction, function, self._lower_corner, [], + divide_in_storeys=True) def _create_parts_consisting_building(self, city_object): name = city_object['@id']