Partial implementation of new concept surfaces vs. polygons, not a working version
This commit is contained in:
parent
090e70a3d0
commit
fa83e195c4
|
@ -1,5 +1,6 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="PROJECT_PROFILE" value="Default" />
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
|
|
154
city_model_structure/attributes/polygon.py
Normal file
154
city_model_structure/attributes/polygon.py
Normal file
|
@ -0,0 +1,154 @@
|
|||
"""
|
||||
Polygon module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Pilar Monsalvete Álvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
import sys
|
||||
import numpy as np
|
||||
|
||||
from helpers.geometry_helper import GeometryHelper as gh
|
||||
|
||||
|
||||
class Polygon:
|
||||
"""
|
||||
Polygon class
|
||||
"""
|
||||
|
||||
def __init__(self, vertices):
|
||||
self._vertices = vertices
|
||||
self._remove_last = True
|
||||
self._area = None
|
||||
self._points = None
|
||||
self._normal = None
|
||||
|
||||
@property
|
||||
def points(self) -> np.ndarray:
|
||||
"""
|
||||
Surface point matrix
|
||||
:return: np.ndarray
|
||||
"""
|
||||
if self._points is None:
|
||||
self._points = np.fromstring(self._vertices, dtype=float, sep=' ')
|
||||
self._points = gh.to_points_matrix(self._points, self._remove_last)
|
||||
return self._points
|
||||
|
||||
@property
|
||||
def area(self):
|
||||
"""
|
||||
Surface area in square meters
|
||||
:return: float
|
||||
"""
|
||||
# New method to calculate area
|
||||
if self._area is None:
|
||||
if len(self.points) < 3:
|
||||
sys.stderr.write('Warning: the area of a line or point cannot be calculated 1. Area = 0\n')
|
||||
return 0
|
||||
alpha = 0
|
||||
vec_1 = self.points[1] - self.points[0]
|
||||
for i in range(2, len(self.points)):
|
||||
vec_2 = self.points[i] - self.points[0]
|
||||
alpha += gh.angle_between_vectors(vec_1, vec_2)
|
||||
if alpha == 0:
|
||||
sys.stderr.write('Warning: the area of a line or point cannot be calculated 2. Area = 0\n')
|
||||
return 0
|
||||
horizontal_points = self.rotate_surface_to_horizontal
|
||||
area = 0
|
||||
for i in range(0, len(horizontal_points)-1):
|
||||
point = horizontal_points[i]
|
||||
next_point = horizontal_points[i+1]
|
||||
area += (next_point[1] + point[1]) / 2 * (next_point[0] - point[0])
|
||||
next_point = horizontal_points[0]
|
||||
point = horizontal_points[len(horizontal_points)-1]
|
||||
area += (next_point[1] + point[1]) / 2 * (next_point[0] - point[0])
|
||||
self._area = abs(area)
|
||||
return self._area
|
||||
|
||||
@property
|
||||
def rotate_surface_to_horizontal(self):
|
||||
z_vector = [0, 0, 1]
|
||||
normal_vector = self.normal
|
||||
horizontal_points = []
|
||||
x = normal_vector[0]
|
||||
y = normal_vector[1]
|
||||
|
||||
if x == 0 and y == 0:
|
||||
# Already horizontal
|
||||
for point in self.points:
|
||||
horizontal_points.append([point[0], point[1], 0])
|
||||
else:
|
||||
alpha = gh.angle_between_vectors(normal_vector, z_vector)
|
||||
rotation_line = np.cross(normal_vector, z_vector)
|
||||
third_axis = np.cross(normal_vector, rotation_line)
|
||||
w_1 = rotation_line / np.linalg.norm(rotation_line)
|
||||
w_2 = normal_vector
|
||||
w_3 = third_axis / np.linalg.norm(third_axis)
|
||||
rotation_matrix = np.array([[1, 0, 0],
|
||||
[0, np.cos(alpha), -np.sin(alpha)],
|
||||
[0, np.sin(alpha), np.cos(alpha)]])
|
||||
base_matrix = np.array([w_1, w_2, w_3])
|
||||
rotation_base_matrix = np.matmul(base_matrix.transpose(), rotation_matrix.transpose())
|
||||
rotation_base_matrix = np.matmul(rotation_base_matrix, base_matrix)
|
||||
|
||||
if rotation_base_matrix is None:
|
||||
sys.stderr.write('Warning: rotation base matrix returned None\n')
|
||||
else:
|
||||
for point in self.points:
|
||||
new_point = np.matmul(rotation_base_matrix, point)
|
||||
horizontal_points.append(new_point)
|
||||
return horizontal_points
|
||||
|
||||
@property
|
||||
def normal(self) -> np.ndarray:
|
||||
"""
|
||||
Surface normal vector
|
||||
:return: np.ndarray
|
||||
"""
|
||||
if self._normal is None:
|
||||
points = self.points
|
||||
# todo: IF THE FIRST ONE IS 0, START WITH THE NEXT
|
||||
point_origin = points[len(points)-2]
|
||||
vector_1 = points[len(points)-1] - point_origin
|
||||
vector_2 = points[0] - point_origin
|
||||
vector_3 = points[1] - point_origin
|
||||
cross_product = np.cross(vector_1, vector_2)
|
||||
if np.linalg.norm(cross_product) != 0:
|
||||
cross_product = cross_product / np.linalg.norm(cross_product)
|
||||
alpha = gh.angle_between_vectors(vector_1, vector_2)
|
||||
else:
|
||||
# todo modify here
|
||||
cross_product = [0, 0, 0]
|
||||
alpha = 0
|
||||
if len(points) == 3:
|
||||
return cross_product
|
||||
alpha += self._angle(vector_2, vector_3, cross_product)
|
||||
for i in range(0, len(points)-4):
|
||||
vector_1 = points[i+1] - point_origin
|
||||
vector_2 = points[i+2] - point_origin
|
||||
alpha += self._angle(vector_1, vector_2, cross_product)
|
||||
vector_1 = points[len(points) - 1] - point_origin
|
||||
vector_2 = points[0] - point_origin
|
||||
if alpha < 0:
|
||||
cross_product = np.cross(vector_2, vector_1)
|
||||
else:
|
||||
cross_product = np.cross(vector_1, vector_2)
|
||||
self._normal = cross_product / np.linalg.norm(cross_product)
|
||||
return self._normal
|
||||
|
||||
@staticmethod
|
||||
def _angle(vector_1, vector_2, cross_product):
|
||||
accepted_normal_difference = 0.01
|
||||
cross_product_next = np.cross(vector_1, vector_2)
|
||||
if np.linalg.norm(cross_product_next) != 0:
|
||||
cross_product_next = cross_product_next / np.linalg.norm(cross_product_next)
|
||||
alpha = gh.angle_between_vectors(vector_1, vector_2)
|
||||
else:
|
||||
cross_product_next = [0, 0, 0]
|
||||
alpha = 0
|
||||
delta_normals = 0
|
||||
for j in range(0, 3):
|
||||
delta_normals += cross_product[j] - cross_product_next[j]
|
||||
if np.abs(delta_normals) < accepted_normal_difference:
|
||||
return alpha
|
||||
else:
|
||||
return -alpha
|
|
@ -12,9 +12,12 @@ import numpy as np
|
|||
import pyny3d.geoms as pn
|
||||
import math
|
||||
|
||||
from helpers.geometry_helper import GeometryHelper
|
||||
from helpers.geometry_helper import GeometryHelper as gh
|
||||
from city_model_structure.attributes.polygon import Polygon
|
||||
|
||||
# todo: @Guille, review methods depending on pyny3d
|
||||
# todo: remove pyny3d, seems to not be supported and has some issues
|
||||
# todo substitute pyny3d.polygon with city_model_structure.attributes.polygon
|
||||
|
||||
|
||||
class Surface:
|
||||
|
@ -28,14 +31,11 @@ class Surface:
|
|||
self._swr = swr
|
||||
self._remove_last = remove_last
|
||||
self._is_projected = is_projected
|
||||
self._geometry_helper = GeometryHelper()
|
||||
self._polygon = None
|
||||
self._ground_polygon = None
|
||||
self._area = None
|
||||
self._points = None
|
||||
self._ground_points = None
|
||||
self._points_list = None
|
||||
self._normal = None
|
||||
self._azimuth = None
|
||||
self._inclination = None
|
||||
self._area_above_ground = None
|
||||
|
@ -50,6 +50,10 @@ class Surface:
|
|||
self._global_irradiance = dict()
|
||||
self._ground_coordinates = (self.min_x, self.min_y, self.min_z)
|
||||
self._is_planar = None
|
||||
self._perimeter = Polygon(self.perimeter_vertices)
|
||||
# todo: rethink how to do this
|
||||
self._holes = [Polygon(self.vertices)]
|
||||
self._opaque = Polygon(self.opaque_vertices)
|
||||
|
||||
def parent(self, parent, surface_id):
|
||||
"""
|
||||
|
@ -96,7 +100,7 @@ class Surface:
|
|||
"""
|
||||
if self._points is None:
|
||||
self._points = np.fromstring(self._coordinates, dtype=float, sep=' ')
|
||||
self._points = GeometryHelper.to_points_matrix(self._points, self._remove_last)
|
||||
self._points = gh.to_points_matrix(self._points, self._remove_last)
|
||||
return self._points
|
||||
|
||||
def _min_coord(self, axis):
|
||||
|
@ -160,7 +164,7 @@ class Surface:
|
|||
coordinates = coordinates + ' '
|
||||
coordinates = coordinates + str(x) + ' ' + str(y) + ' ' + str(z)
|
||||
self._ground_points = np.fromstring(coordinates, dtype=float, sep=' ')
|
||||
self._ground_points = GeometryHelper.to_points_matrix(self._ground_points, False)
|
||||
self._ground_points = gh.to_points_matrix(self._ground_points, False)
|
||||
return self._ground_points
|
||||
|
||||
@property
|
||||
|
@ -202,42 +206,12 @@ class Surface:
|
|||
self._ground_polygon = None
|
||||
return self._ground_polygon
|
||||
|
||||
@property
|
||||
def area(self):
|
||||
"""
|
||||
Surface area in square meters
|
||||
:return: float
|
||||
"""
|
||||
# New method to calculate area
|
||||
if self._area is None:
|
||||
if len(self.points) < 3:
|
||||
sys.stderr.write('Warning: the area of a line or point cannot be calculated 1. Area = 0\n')
|
||||
return 0
|
||||
alpha = 0
|
||||
vec_1 = self.points[1] - self.points[0]
|
||||
for i in range(2, len(self.points)):
|
||||
vec_2 = self.points[i] - self.points[0]
|
||||
alpha += GeometryHelper.angle_between_vectors(vec_1, vec_2)
|
||||
if alpha == 0:
|
||||
sys.stderr.write('Warning: the area of a line or point cannot be calculated 2. Area = 0\n')
|
||||
return 0
|
||||
horizontal_points = self.rotate_surface_to_horizontal
|
||||
area = 0
|
||||
for i in range(0, len(horizontal_points)-1):
|
||||
point = horizontal_points[i]
|
||||
next_point = horizontal_points[i+1]
|
||||
area += (next_point[1] + point[1]) / 2 * (next_point[0] - point[0])
|
||||
next_point = horizontal_points[0]
|
||||
point = horizontal_points[len(horizontal_points)-1]
|
||||
area += (next_point[1] + point[1]) / 2 * (next_point[0] - point[0])
|
||||
self._area = abs(area)
|
||||
return self._area
|
||||
|
||||
def _is_almost_same_terrain(self, terrain_points, ground_points):
|
||||
@staticmethod
|
||||
def _is_almost_same_terrain(terrain_points, ground_points):
|
||||
equal = 0
|
||||
for terrain_point in terrain_points:
|
||||
for ground_point in ground_points:
|
||||
if self._geometry_helper.almost_equal(terrain_point, ground_point):
|
||||
if gh().almost_equal(terrain_point, ground_point):
|
||||
equal += 1
|
||||
return equal == len(terrain_points)
|
||||
|
||||
|
@ -255,7 +229,7 @@ class Surface:
|
|||
:return: float
|
||||
"""
|
||||
if self._area_above_ground is None:
|
||||
self._area_above_ground = self.area - self.area_below_ground
|
||||
self._area_above_ground = self._perimeter.area - self.area_below_ground
|
||||
return self._area_above_ground
|
||||
|
||||
@property
|
||||
|
@ -267,64 +241,9 @@ class Surface:
|
|||
if self._area_below_ground is None:
|
||||
self._area_below_ground = 0.0
|
||||
if self._is_terrain:
|
||||
self._area_below_ground = self.area
|
||||
self._area_below_ground = self._perimeter.area
|
||||
return self._area_below_ground
|
||||
|
||||
@property
|
||||
def normal(self) -> np.ndarray:
|
||||
"""
|
||||
Surface normal vector
|
||||
:return: np.ndarray
|
||||
"""
|
||||
if self._normal is None:
|
||||
points = self.points
|
||||
# todo: IF THE FIRST ONE IS 0, START WITH THE NEXT
|
||||
point_origin = points[len(points)-2]
|
||||
vector_1 = points[len(points)-1] - point_origin
|
||||
vector_2 = points[0] - point_origin
|
||||
vector_3 = points[1] - point_origin
|
||||
cross_product = np.cross(vector_1, vector_2)
|
||||
if np.linalg.norm(cross_product) != 0:
|
||||
cross_product = cross_product / np.linalg.norm(cross_product)
|
||||
alpha = GeometryHelper.angle_between_vectors(vector_1, vector_2)
|
||||
else:
|
||||
# todo modify here
|
||||
cross_product = [0, 0, 0]
|
||||
alpha = 0
|
||||
if len(points) == 3:
|
||||
return cross_product
|
||||
alpha += self._angle(vector_2, vector_3, cross_product)
|
||||
for i in range(0, len(points)-4):
|
||||
vector_1 = points[i+1] - point_origin
|
||||
vector_2 = points[i+2] - point_origin
|
||||
alpha += self._angle(vector_1, vector_2, cross_product)
|
||||
vector_1 = points[len(points) - 1] - point_origin
|
||||
vector_2 = points[0] - point_origin
|
||||
if alpha < 0:
|
||||
cross_product = np.cross(vector_2, vector_1)
|
||||
else:
|
||||
cross_product = np.cross(vector_1, vector_2)
|
||||
self._normal = cross_product / np.linalg.norm(cross_product)
|
||||
return self._normal
|
||||
|
||||
@staticmethod
|
||||
def _angle(vector_1, vector_2, cross_product):
|
||||
accepted_normal_difference = 0.01
|
||||
cross_product_next = np.cross(vector_1, vector_2)
|
||||
if np.linalg.norm(cross_product_next) != 0:
|
||||
cross_product_next = cross_product_next / np.linalg.norm(cross_product_next)
|
||||
alpha = GeometryHelper.angle_between_vectors(vector_1, vector_2)
|
||||
else:
|
||||
cross_product_next = [0, 0, 0]
|
||||
alpha = 0
|
||||
delta_normals = 0
|
||||
for j in range(0, 3):
|
||||
delta_normals += cross_product[j] - cross_product_next[j]
|
||||
if np.abs(delta_normals) < accepted_normal_difference:
|
||||
return alpha
|
||||
else:
|
||||
return -alpha
|
||||
|
||||
@property
|
||||
def azimuth(self):
|
||||
"""
|
||||
|
@ -332,7 +251,7 @@ class Surface:
|
|||
:return: float
|
||||
"""
|
||||
if self._azimuth is None:
|
||||
normal = self.normal
|
||||
normal = self._perimeter.normal
|
||||
self._azimuth = np.arctan2(normal[1], normal[0])
|
||||
return self._azimuth
|
||||
|
||||
|
@ -343,7 +262,7 @@ class Surface:
|
|||
:return: float
|
||||
"""
|
||||
if self._inclination is None:
|
||||
self._inclination = np.arccos(self.normal[2])
|
||||
self._inclination = np.arccos(self._perimeter.normal[2])
|
||||
return self._inclination
|
||||
|
||||
@property
|
||||
|
@ -369,7 +288,7 @@ class Surface:
|
|||
:param intersection_area:
|
||||
:return:
|
||||
"""
|
||||
percent = intersection_area / self.area
|
||||
percent = intersection_area / self._perimeter.area
|
||||
self._shared_surfaces.append((percent, surface))
|
||||
|
||||
def shared(self, surface):
|
||||
|
@ -380,9 +299,9 @@ class Surface:
|
|||
"""
|
||||
if self.type != 'Wall' or surface.type != 'Wall':
|
||||
return
|
||||
if self._geometry_helper.is_almost_same_surface(self, surface):
|
||||
if gh().is_almost_same_surface(self, surface):
|
||||
try:
|
||||
intersection_area = self.intersect(surface).area
|
||||
intersection_area = self.intersect(surface)._perimeter.area
|
||||
except ValueError:
|
||||
intersection_area = 0
|
||||
self.add_shared(surface, intersection_area)
|
||||
|
@ -496,38 +415,3 @@ class Surface:
|
|||
self._is_planar = False
|
||||
break
|
||||
return self._is_planar
|
||||
|
||||
@property
|
||||
def rotate_surface_to_horizontal(self):
|
||||
z_vector = [0, 0, 1]
|
||||
normal_vector = self.normal
|
||||
horizontal_points = []
|
||||
x = normal_vector[0]
|
||||
y = normal_vector[1]
|
||||
|
||||
if x == 0 and y == 0:
|
||||
# Already horizontal
|
||||
for point in self.points:
|
||||
horizontal_points.append([point[0], point[1], 0])
|
||||
else:
|
||||
alpha = GeometryHelper.angle_between_vectors(normal_vector, z_vector)
|
||||
rotation_line = np.cross(normal_vector, z_vector)
|
||||
third_axis = np.cross(normal_vector, rotation_line)
|
||||
w_1 = rotation_line / np.linalg.norm(rotation_line)
|
||||
w_2 = normal_vector
|
||||
w_3 = third_axis / np.linalg.norm(third_axis)
|
||||
rotation_matrix = np.array([[1, 0, 0],
|
||||
[0, math.cos(alpha), -math.sin(alpha)],
|
||||
[0, math.sin(alpha), math.cos(alpha)]])
|
||||
base_matrix = np.array([w_1, w_2, w_3])
|
||||
rotation_base_matrix = np.matmul(base_matrix.transpose(), rotation_matrix.transpose())
|
||||
rotation_base_matrix = np.matmul(rotation_base_matrix, base_matrix)
|
||||
|
||||
if rotation_base_matrix is None:
|
||||
sys.stderr.write('Warning: rotation base matrix returned None\n')
|
||||
else:
|
||||
for point in self.points:
|
||||
new_point = np.matmul(rotation_base_matrix, point)
|
||||
horizontal_points.append(new_point)
|
||||
return horizontal_points
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
ThermalBoundary module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
Contributors Pilar Monsalvete pilar_monsalvete@yahoo.es
|
||||
Contributors Pilar Monsalvete Álvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import List
|
||||
from city_model_structure.attributes.layer import Layer
|
||||
|
@ -15,22 +15,34 @@ class ThermalBoundary:
|
|||
"""
|
||||
ThermalBoundary class
|
||||
"""
|
||||
def __init__(self, surface, delimits, hi, he):
|
||||
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(hi, he)]
|
||||
self._thermal_openings = [ThermalOpening]
|
||||
self._layers = None
|
||||
self._outside_solar_absorptance = None
|
||||
self._outside_thermal_absorptance = None
|
||||
self._outside_visible_absorptance = None
|
||||
self._window_ratio = None
|
||||
self._u_value = None
|
||||
# todo: no sense -> window area in thermal opening?? Check in geometry_factory -> due to the definition of
|
||||
# window as surface_area * window_ratio
|
||||
self._window_area = None
|
||||
self._shortwave_reflectance = None
|
||||
self._construction_name = None
|
||||
self._hi = hi
|
||||
self._he = he
|
||||
self._hi = None
|
||||
self._he = None
|
||||
|
||||
# todo: to discuss with @Guille
|
||||
self._azimuth = None
|
||||
self._inclination = None
|
||||
self._area = None
|
||||
self._refurbishment_measure = None
|
||||
|
||||
# todo: to discuss with @Guille: 1. emissivity is a function of absorptance
|
||||
# 2. pg 17: fraction and surface -> NO
|
||||
self._emissivity = None
|
||||
|
||||
@property
|
||||
def surface(self) -> Surface:
|
||||
|
@ -38,6 +50,7 @@ class ThermalBoundary:
|
|||
Get the surface that belongs to the thermal boundary
|
||||
:return: Surface
|
||||
"""
|
||||
# todo: in LoD4 this property will be a list of surfaces, not only one
|
||||
return self._surface
|
||||
|
||||
@property
|
||||
|
@ -233,8 +246,8 @@ class ThermalBoundary:
|
|||
:return: float
|
||||
"""
|
||||
if self._u_value is None:
|
||||
h_i = self._hi
|
||||
h_e = self._he
|
||||
h_i = self.hi
|
||||
h_e = self.he
|
||||
r_value = 1.0/h_i + 1.0/h_e
|
||||
try:
|
||||
for layer in self.layers:
|
||||
|
@ -272,3 +285,37 @@ class ThermalBoundary:
|
|||
"""
|
||||
self._shortwave_reflectance = value
|
||||
self._outside_solar_absorptance = 1.0 - float(value)
|
||||
|
||||
@property
|
||||
def hi(self):
|
||||
"""
|
||||
Get internal convective heat transfer coefficient (W/m2K)
|
||||
:return: float
|
||||
"""
|
||||
return self._hi
|
||||
|
||||
@hi.setter
|
||||
def hi(self, value):
|
||||
"""
|
||||
Set internal convective heat transfer coefficient (W/m2K)
|
||||
:param value: internal convective heat transfer coefficient (W/m2K)
|
||||
:return:
|
||||
"""
|
||||
self._hi = value
|
||||
|
||||
@property
|
||||
def he(self):
|
||||
"""
|
||||
Get external convective heat transfer coefficient (W/m2K)
|
||||
:return: float
|
||||
"""
|
||||
return self._he
|
||||
|
||||
@he.setter
|
||||
def he(self, value):
|
||||
"""
|
||||
Set external convective heat transfer coefficient (W/m2K)
|
||||
:param value: external convective heat transfer coefficient (W/m2K)
|
||||
:return:
|
||||
"""
|
||||
self._he = value
|
||||
|
|
|
@ -10,7 +10,8 @@ class ThermalOpening:
|
|||
"""
|
||||
ThermalOpening class
|
||||
"""
|
||||
def __init__(self, hi, he):
|
||||
def __init__(self):
|
||||
self._area = None
|
||||
self._openable_ratio = None
|
||||
self._conductivity = None
|
||||
self._frame_ratio = 0
|
||||
|
@ -19,8 +20,16 @@ class ThermalOpening:
|
|||
self._front_side_solar_transmittance_at_normal_incidence = None
|
||||
self._back_side_solar_transmittance_at_normal_incidence = None
|
||||
self._overall_u_value = None
|
||||
self._hi = hi
|
||||
self._he = he
|
||||
self._hi = None
|
||||
self._he = None
|
||||
|
||||
@property
|
||||
def area(self):
|
||||
"""
|
||||
Thermal opening area in square meters
|
||||
:return: float
|
||||
"""
|
||||
return self._area
|
||||
|
||||
@property
|
||||
def openable_ratio(self):
|
||||
|
@ -58,8 +67,8 @@ class ThermalOpening:
|
|||
# This ensures a more robust code that returns the overall_u_value regardless the order the parameters are read.
|
||||
self._conductivity = value
|
||||
if self._overall_u_value is None and self.thickness is not None:
|
||||
h_i = self._hi
|
||||
h_e = self._he
|
||||
h_i = self.hi
|
||||
h_e = self.he
|
||||
r_value = 1 / h_i + 1 / h_e + float(self.conductivity) / float(self.thickness)
|
||||
self._overall_u_value = 1 / r_value
|
||||
|
||||
|
@ -116,8 +125,8 @@ class ThermalOpening:
|
|||
# This ensures a more robust code that returns the overall_u_value regardless the order the parameters are read.
|
||||
self._thickness = value
|
||||
if self._overall_u_value is None and self.conductivity is not None:
|
||||
h_i = self._hi
|
||||
h_e = self._he
|
||||
h_i = self.hi
|
||||
h_e = self.he
|
||||
r_value = 1 / h_i + 1 / h_e + float(self.conductivity) / float(self.thickness)
|
||||
self._overall_u_value = 1 / r_value
|
||||
|
||||
|
@ -171,3 +180,38 @@ class ThermalOpening:
|
|||
:return: None
|
||||
"""
|
||||
self._overall_u_value = value
|
||||
|
||||
@property
|
||||
def hi(self):
|
||||
"""
|
||||
Get internal convective heat transfer coefficient (W/m2K)
|
||||
:return: float
|
||||
"""
|
||||
return self._hi
|
||||
|
||||
@hi.setter
|
||||
def hi(self, value):
|
||||
"""
|
||||
Set internal convective heat transfer coefficient (W/m2K)
|
||||
:param value: internal convective heat transfer coefficient (W/m2K)
|
||||
:return:
|
||||
"""
|
||||
self._hi = value
|
||||
|
||||
@property
|
||||
def he(self):
|
||||
"""
|
||||
Get external convective heat transfer coefficient (W/m2K)
|
||||
:return: float
|
||||
"""
|
||||
return self._he
|
||||
|
||||
@he.setter
|
||||
def he(self, value):
|
||||
"""
|
||||
Set external convective heat transfer coefficient (W/m2K)
|
||||
:param value: external convective heat transfer coefficient (W/m2K)
|
||||
:return:
|
||||
"""
|
||||
self._he = value
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
ThermalZone module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
Contributors Pilar Monsalvete Álvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from typing import List, TypeVar
|
||||
|
||||
|
@ -15,26 +16,28 @@ class ThermalZone:
|
|||
"""
|
||||
ThermalZone class
|
||||
"""
|
||||
def __init__(self, surfaces, heated, cooled):
|
||||
def __init__(self, surfaces, is_heated, is_cooled):
|
||||
self._surfaces = surfaces
|
||||
self._floor_area = None
|
||||
self._bounded = None
|
||||
self._heated = heated
|
||||
self._cooled = cooled
|
||||
self._additional_thermal_bridge_u_value = 0
|
||||
self._is_heated = is_heated
|
||||
self._is_cooled = is_cooled
|
||||
self._additional_thermal_bridge_u_value = None
|
||||
self._effective_thermal_capacity = None
|
||||
self._indirectly_heated_area_ratio = 0
|
||||
self._infiltration_rate_system_on = 0
|
||||
self._indirectly_heated_area_ratio = None
|
||||
self._infiltration_rate_system_on = None
|
||||
self._infiltration_rate_system_off = None
|
||||
self._usage_zones = None
|
||||
|
||||
self._volume = None
|
||||
|
||||
@property
|
||||
def heated(self):
|
||||
"""
|
||||
Get thermal zone heated flag
|
||||
:return: Boolean
|
||||
"""
|
||||
return self._heated
|
||||
return self._is_heated
|
||||
|
||||
@property
|
||||
def cooled(self):
|
||||
|
@ -42,7 +45,7 @@ class ThermalZone:
|
|||
Get thermal zone cooled flag
|
||||
:return: Boolean
|
||||
"""
|
||||
return self._cooled
|
||||
return self._is_cooled
|
||||
|
||||
@property
|
||||
def floor_area(self):
|
||||
|
|
|
@ -5,6 +5,7 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
contributors: Pilar Monsalvete pilar_monsalvete@yahoo.es
|
||||
"""
|
||||
|
||||
|
||||
from typing import List
|
||||
|
||||
import matplotlib.patches as patches
|
||||
|
@ -26,20 +27,18 @@ class Building(CityObject):
|
|||
"""
|
||||
Building(CityObject) class
|
||||
"""
|
||||
def __init__(self, name, lod, surfaces, terrains, year_of_construction, function, lower_corner, heated=True,
|
||||
cooled=True, hi=10, he=25, attic_heated=0, basement_heated=0):
|
||||
def __init__(self, name, lod, surfaces, terrains, year_of_construction, function, lower_corner):
|
||||
# todo: take the default values out of the classes!!
|
||||
super().__init__(lod, surfaces, name)
|
||||
self._basement_heated = basement_heated
|
||||
self._attic_heated = attic_heated
|
||||
self._basement_heated = None
|
||||
self._attic_heated = None
|
||||
self._terrains = terrains
|
||||
self._year_of_construction = year_of_construction
|
||||
self._function = function
|
||||
# todo: this name is not clear. Is it lower corner of the building or lower corner of te city??
|
||||
self._lower_corner = lower_corner
|
||||
self._heated = heated
|
||||
self._cooled = cooled
|
||||
self._hi = hi
|
||||
self._he = he
|
||||
self._heated = None
|
||||
self._cooled = None
|
||||
self._average_storey_height = None
|
||||
self._storeys_above_ground = None
|
||||
self._foot_print = None
|
||||
|
@ -60,7 +59,7 @@ class Building(CityObject):
|
|||
self._thermal_zones.append(ThermalZone(self.surfaces, self._heated, self._cooled))
|
||||
|
||||
for t_zones in self._thermal_zones:
|
||||
t_zones.bounded = [ThermalBoundary(s, [t_zones], hi, he) for s in t_zones.surfaces]
|
||||
t_zones.bounded = [ThermalBoundary(s, [t_zones]) for s in t_zones.surfaces]
|
||||
surface_id = 0
|
||||
for surface in self._surfaces:
|
||||
surface.lower_corner = self._lower_corner
|
||||
|
|
|
@ -5,8 +5,8 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
"""
|
||||
from city_model_structure.city import City
|
||||
from city_model_structure.city_object import CityObject
|
||||
from factories.geometry_feeders.city_gml import CityGml
|
||||
from factories.geometry_feeders.osm_subway import OsmSubway
|
||||
from imports.geometry_feeders.city_gml import CityGml
|
||||
from imports.geometry_feeders.osm_subway import OsmSubway
|
||||
|
||||
|
||||
class GeometryFactory:
|
|
@ -5,7 +5,7 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
contributors Pilar Monsalvete pilar_monsalvete@yahoo.es
|
||||
"""
|
||||
import pandas as pd
|
||||
from factories.occupancy_feeders.helpers.schedules_helper import SchedulesHelper
|
||||
from imports.occupancy_feeders.helpers.schedules_helper import SchedulesHelper
|
||||
|
||||
|
||||
class ComnetSchedules:
|
|
@ -3,9 +3,9 @@ PhysicsFactory retrieve the specific physics module for the given region
|
|||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
from factories.physics_feeders.us_new_york_city_physics_parameters import UsNewYorkCityPhysicsParameters
|
||||
from factories.physics_feeders.us_physics_parameters import UsPhysicsParameters
|
||||
from factories.physics_feeders.ca_physics_parameters import CaPhysicsParameters
|
||||
from imports.physics_feeders.us_new_york_city_physics_parameters import UsNewYorkCityPhysicsParameters
|
||||
from imports.physics_feeders.us_physics_parameters import UsPhysicsParameters
|
||||
from imports.physics_feeders.ca_physics_parameters import CaPhysicsParameters
|
||||
from pathlib import Path
|
||||
|
||||
|
|
@ -5,8 +5,8 @@ Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
|
|||
"""
|
||||
import sys
|
||||
|
||||
from factories.physics_feeders.nrel_physics_interface import NrelPhysicsInterface
|
||||
from factories.physics_feeders.helpers.ca_to_library_types import CaToLibraryTypes
|
||||
from imports.physics_feeders.nrel_physics_interface import NrelPhysicsInterface
|
||||
from imports.physics_feeders.helpers.ca_to_library_types import CaToLibraryTypes
|
||||
|
||||
|
||||
class CaPhysicsParameters(NrelPhysicsInterface):
|
|
@ -4,7 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
|
||||
"""
|
||||
from typing import List
|
||||
from factories.physics_feeders.data_classes.nrel_thermal_boundary_archetype import NrelThermalBoundaryArchetype
|
||||
from imports.physics_feeders.data_classes.nrel_thermal_boundary_archetype import NrelThermalBoundaryArchetype
|
||||
|
||||
|
||||
class NrelBuildingArchetype:
|
|
@ -5,8 +5,8 @@ Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
|
|||
"""
|
||||
from typing import List
|
||||
|
||||
from factories.physics_feeders.data_classes.nrel_layer_archetype import NrelLayerArchetype
|
||||
from factories.physics_feeders.data_classes.nrel_thermal_opening_archetype import NrelThermalOpeningArchetype
|
||||
from imports.physics_feeders.data_classes.nrel_layer_archetype import NrelLayerArchetype
|
||||
from imports.physics_feeders.data_classes.nrel_thermal_opening_archetype import NrelThermalOpeningArchetype
|
||||
|
||||
|
||||
class NrelThermalBoundaryArchetype:
|
|
@ -7,10 +7,10 @@ Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
|
|||
import sys
|
||||
import xmltodict
|
||||
|
||||
from factories.physics_feeders.data_classes.nrel_building_achetype import NrelBuildingArchetype as nba
|
||||
from factories.physics_feeders.data_classes.nrel_thermal_boundary_archetype import NrelThermalBoundaryArchetype as ntba
|
||||
from factories.physics_feeders.data_classes.nrel_thermal_opening_archetype import NrelThermalOpeningArchetype as ntoa
|
||||
from factories.physics_feeders.data_classes.nrel_layer_archetype import NrelLayerArchetype as nla
|
||||
from imports.physics_feeders.data_classes.nrel_building_achetype import NrelBuildingArchetype as nba
|
||||
from imports.physics_feeders.data_classes.nrel_thermal_boundary_archetype import NrelThermalBoundaryArchetype as ntba
|
||||
from imports.physics_feeders.data_classes.nrel_thermal_opening_archetype import NrelThermalOpeningArchetype as ntoa
|
||||
from imports.physics_feeders.data_classes.nrel_layer_archetype import NrelLayerArchetype as nla
|
||||
|
||||
|
||||
class NrelPhysicsInterface:
|
|
@ -6,9 +6,9 @@ Contributors Pilar Monsalvete pilar_monsalvete@yahoo.es
|
|||
"""
|
||||
import sys
|
||||
|
||||
from factories.physics_feeders.nrel_physics_interface import NrelPhysicsInterface
|
||||
from factories.physics_feeders.helpers.us_pluto_to_function import UsPlutoToFunction as pf
|
||||
from factories.physics_feeders.helpers.us_to_library_types import UsToLibraryTypes
|
||||
from imports.physics_feeders.nrel_physics_interface import NrelPhysicsInterface
|
||||
from imports.physics_feeders.helpers.us_pluto_to_function import UsPlutoToFunction as pf
|
||||
from imports.physics_feeders.helpers.us_to_library_types import UsToLibraryTypes
|
||||
from city_model_structure.attributes.layer import Layer
|
||||
from city_model_structure.attributes.material import Material
|
||||
|
|
@ -6,8 +6,8 @@ Contributors Pilar Monsalvete pilar_monsalvete@yahoo.es
|
|||
"""
|
||||
import sys
|
||||
|
||||
from factories.physics_feeders.nrel_physics_interface import NrelPhysicsInterface
|
||||
from factories.physics_feeders.helpers.us_to_library_types import UsToLibraryTypes
|
||||
from imports.physics_feeders.nrel_physics_interface import NrelPhysicsInterface
|
||||
from imports.physics_feeders.helpers.us_to_library_types import UsToLibraryTypes
|
||||
from city_model_structure.attributes.layer import Layer
|
||||
from city_model_structure.attributes.material import Material
|
||||
|
|
@ -5,7 +5,7 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from factories.occupancy_feeders.usage_schedules import ComnetSchedules
|
||||
from imports.occupancy_feeders.usage_schedules import ComnetSchedules
|
||||
|
||||
|
||||
class SchedulesFactory:
|
|
@ -4,9 +4,9 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
from pathlib import Path
|
||||
from factories.usage_feeders.de_usage_parameters import DeUsageParameters
|
||||
from factories.usage_feeders.us_new_york_city_usage_parameters import UsNewYorkCityUsageParameters
|
||||
from factories.usage_feeders.ca_usage_parameters import CaUsageParameters
|
||||
from imports.usage_feeders.de_usage_parameters import DeUsageParameters
|
||||
from imports.usage_feeders.us_new_york_city_usage_parameters import UsNewYorkCityUsageParameters
|
||||
from imports.usage_feeders.ca_usage_parameters import CaUsageParameters
|
||||
|
||||
|
||||
class UsageFactory:
|
|
@ -5,7 +5,7 @@ Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
|
|||
"""
|
||||
import sys
|
||||
|
||||
from factories.usage_feeders.hft_usage_interface import HftUsageInterface
|
||||
from imports.usage_feeders.hft_usage_interface import HftUsageInterface
|
||||
from city_model_structure.attributes.usage_zone import UsageZone
|
||||
|
||||
|
||||
|
@ -35,7 +35,7 @@ class CaUsageParameters(HftUsageInterface):
|
|||
mix_usage = False
|
||||
if not mix_usage:
|
||||
# just one usage_zone
|
||||
usage_zone = UsageZone(self._min_air_change)
|
||||
usage_zone = UsageZone()
|
||||
self._assign_values(usage_zone, archetype)
|
||||
building.usage_zones = [usage_zone]
|
||||
|
|
@ -4,7 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
|
||||
"""
|
||||
from typing import List
|
||||
from factories.usage_feeders.data_classes.hft_internal_gains_archetype import HftInternalGainsArchetype
|
||||
from imports.usage_feeders.data_classes.hft_internal_gains_archetype import HftInternalGainsArchetype
|
||||
|
||||
|
||||
class HftUsageZoneArchetype:
|
|
@ -6,8 +6,8 @@ Contributors Pilar Monsalvete pilar_monsalvete@yahoo.es
|
|||
"""
|
||||
import sys
|
||||
|
||||
from factories.usage_feeders.helpers.us_function_to_usage import UsFunctionToUsage as fu
|
||||
from factories.usage_feeders.hft_usage_interface import HftUsageInterface
|
||||
from imports.usage_feeders.helpers.us_function_to_usage import UsFunctionToUsage as fu
|
||||
from imports.usage_feeders.hft_usage_interface import HftUsageInterface
|
||||
from city_model_structure.attributes.usage_zone import UsageZone
|
||||
|
||||
|
|
@ -3,7 +3,7 @@ UsPlutoToUsage helper
|
|||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
from factories.usage_feeders.helpers.us_function_to_usage import UsFunctionToUsage
|
||||
from imports.usage_feeders.helpers.us_function_to_usage import UsFunctionToUsage
|
||||
|
||||
|
||||
class UsPlutoToUsage:
|
|
@ -5,8 +5,8 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
|
||||
"""
|
||||
import xmltodict
|
||||
from factories.usage_feeders.data_classes.hft_usage_zone_archetype import HftUsageZoneArchetype as huza
|
||||
from factories.usage_feeders.data_classes.hft_internal_gains_archetype import HftInternalGainsArchetype as higa
|
||||
from imports.usage_feeders.data_classes.hft_usage_zone_archetype import HftUsageZoneArchetype as huza
|
||||
from imports.usage_feeders.data_classes.hft_internal_gains_archetype import HftInternalGainsArchetype as higa
|
||||
|
||||
|
||||
class HftUsageInterface:
|
|
@ -6,8 +6,8 @@ Contributors Pilar Monsalvete pilar_monsalvete@yahoo.es
|
|||
"""
|
||||
import sys
|
||||
|
||||
from factories.usage_feeders.helpers.us_pluto_to_usage import UsPlutoToUsage as pu
|
||||
from factories.usage_feeders.hft_usage_interface import HftUsageInterface
|
||||
from imports.usage_feeders.helpers.us_pluto_to_usage import UsPlutoToUsage as pu
|
||||
from imports.usage_feeders.hft_usage_interface import HftUsageInterface
|
||||
from city_model_structure.attributes.usage_zone import UsageZone
|
||||
|
||||
|
|
@ -5,8 +5,8 @@ Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
|
|||
"""
|
||||
import sys
|
||||
|
||||
from factories.usage_feeders.helpers.us_function_to_usage import UsFunctionToUsage as fu
|
||||
from factories.usage_feeders.hft_usage_interface import HftUsageInterface
|
||||
from imports.usage_feeders.helpers.us_function_to_usage import UsFunctionToUsage as fu
|
||||
from imports.usage_feeders.hft_usage_interface import HftUsageInterface
|
||||
from city_model_structure.attributes.usage_zone import UsageZone
|
||||
|
||||
|
|
@ -4,8 +4,8 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
|
||||
"""
|
||||
from pathlib import Path
|
||||
from factories.weather_feeders.dat_weather_parameters import DatWeatherParameters
|
||||
from factories.weather_feeders.xls_weather_parameters import XlsWeatherParameters
|
||||
from imports.weather_feeders.dat_weather_parameters import DatWeatherParameters
|
||||
from imports.weather_feeders.xls_weather_parameters import XlsWeatherParameters
|
||||
|
||||
|
||||
class WeatherFactory:
|
|
@ -8,7 +8,7 @@ from pathlib import Path
|
|||
from unittest import TestCase
|
||||
import math
|
||||
from city_model_structure.city import City
|
||||
from factories.geometry_factory import GeometryFactory
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
|
||||
|
||||
class TestGeometryFactory(TestCase):
|
||||
|
|
|
@ -5,11 +5,11 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
"""
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from factories.geometry_factory import GeometryFactory
|
||||
from factories.physics_factory import PhysicsFactory
|
||||
from factories.usage_factory import UsageFactory
|
||||
from factories.schedules_factory import SchedulesFactory
|
||||
from helpers.idf_helper import IdfHelper
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.physics_factory import PhysicsFactory
|
||||
from imports.usage_factory import UsageFactory
|
||||
from imports.schedules_factory import SchedulesFactory
|
||||
from exports.idf_helper import IdfHelper
|
||||
import os
|
||||
import glob
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@conc
|
|||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
|
||||
from factories.geometry_factory import GeometryFactory
|
||||
from factories.physics_factory import PhysicsFactory
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.physics_factory import PhysicsFactory
|
||||
|
||||
|
||||
class TestPhysicsFactory(TestCase):
|
||||
|
|
|
@ -7,9 +7,9 @@ Contributors Pilar Monsalvete pilar_monsalvete@yahoo.es
|
|||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
|
||||
from factories.geometry_factory import GeometryFactory
|
||||
from factories.usage_factory import UsageFactory
|
||||
from factories.schedules_factory import SchedulesFactory
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.usage_factory import UsageFactory
|
||||
from imports.schedules_factory import SchedulesFactory
|
||||
|
||||
|
||||
class TestSchedulesFactory(TestCase):
|
||||
|
|
|
@ -6,8 +6,8 @@ Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
|
|||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
|
||||
from factories.geometry_factory import GeometryFactory
|
||||
from factories.usage_factory import UsageFactory
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.usage_factory import UsageFactory
|
||||
|
||||
|
||||
class TestUsageFactory(TestCase):
|
||||
|
|
|
@ -6,8 +6,8 @@ Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es
|
|||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
|
||||
from factories.geometry_factory import GeometryFactory
|
||||
from factories.weather_factory import WeatherFactory
|
||||
from imports.geometry_factory import GeometryFactory
|
||||
from imports.weather_factory import WeatherFactory
|
||||
|
||||
|
||||
class TestWeatherFactory(TestCase):
|
||||
|
|
Loading…
Reference in New Issue
Block a user