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']