finished the reorganization between thermal boundaries and surfaces

This commit is contained in:
Pilar 2022-11-09 14:22:26 -05:00
parent f5fe1fd4d9
commit e9559a8485
9 changed files with 203 additions and 422 deletions

View File

@ -8,6 +8,7 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord
from typing import List, Union from typing import List, Union
import numpy as np import numpy as np
import helpers.constants as cte
from city_model_structure.building_demand.surface import Surface from city_model_structure.building_demand.surface import Surface
from city_model_structure.city_object import CityObject from city_model_structure.city_object import CityObject
from city_model_structure.building_demand.household import Household from city_model_structure.building_demand.household import Household
@ -48,11 +49,11 @@ class Building(CityObject):
self._min_z = min(self._min_z, surface.lower_corner[2]) self._min_z = min(self._min_z, surface.lower_corner[2])
surface.id = surface_id surface.id = surface_id
# todo: consider all type of surfaces, not only these four # todo: consider all type of surfaces, not only these four
if surface.type == 'Ground': if surface.type == cte.GROUND:
self._grounds.append(surface) self._grounds.append(surface)
elif surface.type == 'Wall': elif surface.type == cte.WALL:
self._walls.append(surface) self._walls.append(surface)
elif surface.type == 'Roof': elif surface.type == cte.ROOF:
self._roofs.append(surface) self._roofs.append(surface)
else: else:
self._internal_walls.append(surface) self._internal_walls.append(surface)
@ -60,11 +61,18 @@ class Building(CityObject):
@property @property
def shell(self) -> Polyhedron: def shell(self) -> Polyhedron:
""" """
Get building shell Get building's external polyhedron
:return: [Polyhedron] :return: [Polyhedron]
""" """
polygons = []
for surface in self.surfaces:
if surface.type is not cte.INTERIOR_WALL:
polygons.append(surface.solid_polygon)
if surface.holes_polygons is not None:
for hole in surface.holes_polygons:
polygons.append(hole)
if self._shell is None: if self._shell is None:
self._shell = Polyhedron(self.surfaces) self._shell = Polyhedron(polygons)
return self._shell return self._shell
@property @property
@ -103,6 +111,14 @@ class Building(CityObject):
""" """
return self._walls return self._walls
@property
def internal_walls(self) -> List[Surface]:
"""
Get building internal wall surfaces
:return: [Surface]
"""
return self._internal_walls
@property @property
def terrains(self) -> Union[None, List[Surface]]: def terrains(self) -> Union[None, List[Surface]]:
""" """
@ -327,7 +343,7 @@ class Building(CityObject):
@property @property
def human_readable_name(self): def human_readable_name(self):
""" """
Get the human readable name for the building Get the human-readable name for the building
:return: str :return: str
""" """
return self._human_readable_name return self._human_readable_name
@ -335,6 +351,6 @@ class Building(CityObject):
@human_readable_name.setter @human_readable_name.setter
def human_readable_name(self, value): def human_readable_name(self, value):
""" """
Set the human readable name for the building Set the human-readable name for the building
""" """
self._human_readable_name = value self._human_readable_name = value

View File

@ -80,7 +80,7 @@ class Storey:
if self._virtual_surfaces is None: if self._virtual_surfaces is None:
self._virtual_surfaces = [] self._virtual_surfaces = []
for thermal_boundary in self.thermal_boundaries: for thermal_boundary in self.thermal_boundaries:
self._virtual_surfaces.append(thermal_boundary.virtual_internal_surface) self._virtual_surfaces.append(thermal_boundary.internal_surface)
return self._virtual_surfaces return self._virtual_surfaces
@property @property

View File

@ -23,9 +23,8 @@ class Surface:
Surface class Surface class
""" """
def __init__(self, solid_polygon, perimeter_polygon, holes_polygons=None, name=None, surface_type=None, swr=None): def __init__(self, solid_polygon, perimeter_polygon, holes_polygons=None, name=None, surface_type=None):
self._type = surface_type self._type = surface_type
self._swr = swr
self._name = name self._name = name
self._id = None self._id = None
self._azimuth = None self._azimuth = None
@ -38,12 +37,12 @@ class Surface:
self._perimeter_polygon = perimeter_polygon self._perimeter_polygon = perimeter_polygon
self._holes_polygons = holes_polygons self._holes_polygons = holes_polygons
self._solid_polygon = solid_polygon self._solid_polygon = solid_polygon
self._short_wave_reflectance = None
self._long_wave_emittance = None
self._inverse = None self._inverse = None
self._associated_thermal_boundaries = [] self._associated_thermal_boundaries = []
self._vegetation = None self._vegetation = None
# todo: create self._associated_thermal_boundaries and bring the vegetation here instead of in thermal_boundary
@property @property
def name(self): def name(self):
""" """
@ -81,23 +80,6 @@ class Surface:
""" """
raise NotImplementedError raise NotImplementedError
@property
def swr(self) -> Union[None, float]:
"""
Get surface short wave reflectance
:return: None or float
"""
return self._swr
@swr.setter
def swr(self, value):
"""
Set surface short wave reflectance
:param value: float
"""
if value is not None:
self._swr = float(value)
def _max_coord(self, axis): def _max_coord(self, axis):
if axis == 'x': if axis == 'x':
axis = 0 axis = 0
@ -255,6 +237,42 @@ class Surface:
""" """
self._holes_polygons = value self._holes_polygons = value
@property
def short_wave_reflectance(self):
"""
Get the short wave reflectance, this includes all solar spectrum, visible and not visible
The absorptance as an opaque surface, can be calculated as 1-short_wave_reflectance
:return: float
"""
return self._short_wave_reflectance
@short_wave_reflectance.setter
def short_wave_reflectance(self, value):
"""
Set the short wave reflectance, this includes all solar spectrum, visible and not visible
The absorptance as an opaque surface, can be calculated as 1-short_wave_reflectance
:param value: float
"""
self._short_wave_reflectance = value
@property
def long_wave_emittance(self):
"""
Get the long wave emittance af the surface
The thermal absorptance can be calculated as 1-long_wave_emittance
:return: float
"""
return self._long_wave_emittance
@long_wave_emittance.setter
def long_wave_emittance(self, value):
"""
Set the long wave emittance af the surface
The thermal absorptance can be calculated as 1-long_wave_emittance
:param value: float
"""
self._long_wave_emittance = value
@property @property
def inverse(self) -> Surface: def inverse(self) -> Surface:
""" """

View File

@ -28,19 +28,12 @@ class ThermalBoundary:
self._thermal_zones = None self._thermal_zones = None
self._thermal_openings = None self._thermal_openings = None
self._layers = None self._layers = None
self._outside_solar_absorptance = None
self._outside_thermal_absorptance = None
self._outside_visible_absorptance = None
self._u_value = None
self._outside_shortwave_reflectance = None
self._construction_name = None
self._hi = ch().convective_heat_transfer_coefficient_interior
self._he = ch().convective_heat_transfer_coefficient_exterior self._he = ch().convective_heat_transfer_coefficient_exterior
self._hi = ch().convective_heat_transfer_coefficient_interior
self._u_value = None
self._construction_name = None
self._thickness = None self._thickness = None
self._virtual_internal_surface = None self._internal_surface = None
self._inside_emissivity = None
self._alpha_coefficient = None
self._radiative_coefficient = None
self._window_ratio = None self._window_ratio = None
self._window_ratio_is_calculated = False self._window_ratio_is_calculated = False
@ -78,23 +71,6 @@ class ThermalBoundary:
""" """
self._thermal_zones = value self._thermal_zones = value
# todo: do I need these two??
@property
def azimuth(self):
"""
Get the thermal boundary azimuth in radians
:return: float
"""
return self.parent_surface.azimuth
@property
def inclination(self):
"""
Get the thermal boundary inclination in radians
:return: float
"""
return self.parent_surface.inclination
@property @property
def opaque_area(self): def opaque_area(self):
""" """
@ -117,58 +93,6 @@ class ThermalBoundary:
self._thickness += layer.thickness self._thickness += layer.thickness
return self._thickness return self._thickness
@property
def outside_solar_absorptance(self) -> Union[None, float]:
"""
Get thermal boundary outside solar absorptance
:return: None or float
"""
return self._outside_solar_absorptance
@outside_solar_absorptance.setter
def outside_solar_absorptance(self, value):
"""
Set thermal boundary outside solar absorptance
:param value: float
"""
if value is not None:
self._outside_solar_absorptance = float(value)
self._outside_shortwave_reflectance = 1.0 - float(value)
@property
def outside_thermal_absorptance(self) -> Union[None, float]:
"""
Get thermal boundary outside thermal absorptance
:return: float
"""
return self._outside_thermal_absorptance
@outside_thermal_absorptance.setter
def outside_thermal_absorptance(self, value):
"""
Set thermal boundary outside thermal absorptance
:param value: float
"""
if value is not None:
self._outside_thermal_absorptance = float(value)
@property
def outside_visible_absorptance(self) -> Union[None, float]:
"""
Get thermal boundary outside visible absorptance
:return: None or float
"""
return self._outside_visible_absorptance
@outside_visible_absorptance.setter
def outside_visible_absorptance(self, value):
"""
Set thermal boundary outside visible absorptance
:param value: float
"""
if value is not None:
self._outside_visible_absorptance = float(value)
@property @property
def thermal_openings(self) -> Union[None, List[ThermalOpening]]: def thermal_openings(self) -> Union[None, List[ThermalOpening]]:
""" """
@ -310,24 +234,6 @@ class ThermalBoundary:
if value is not None: if value is not None:
self._u_value = float(value) self._u_value = float(value)
@property
def outside_shortwave_reflectance(self) -> Union[None, float]:
"""
Get thermal boundary external shortwave reflectance
:return: None or float
"""
return self._outside_shortwave_reflectance
@outside_shortwave_reflectance.setter
def outside_shortwave_reflectance(self, value):
"""
Set thermal boundary external shortwave reflectance
:param value: float
"""
if value is not None:
self._outside_shortwave_reflectance = float(value)
self._outside_solar_absorptance = 1.0 - float(value)
@property @property
def hi(self) -> Union[None, float]: def hi(self) -> Union[None, float]:
""" """
@ -363,62 +269,11 @@ class ThermalBoundary:
self._he = value self._he = value
@property @property
def virtual_internal_surface(self) -> Surface: def internal_surface(self) -> Surface:
""" """
Get the internal surface of the thermal boundary Get the internal surface of the thermal boundary
:return: Surface :return: Surface
""" """
if self._virtual_internal_surface is None: if self._internal_surface is None:
self._virtual_internal_surface = self.parent_surface.inverse self._internal_surface = self.parent_surface.inverse
return self._virtual_internal_surface return self._internal_surface
@property
def inside_emissivity(self) -> Union[None, float]:
"""
Get the short wave emissivity factor of the thermal boundary's internal surface (-)
:return: None or float
"""
return self._inside_emissivity
@inside_emissivity.setter
def inside_emissivity(self, value):
"""
Set short wave emissivity factor of the thermal boundary's internal surface (-)
:param value: float
"""
if value is not None:
self._inside_emissivity = float(value)
@property
def alpha_coefficient(self) -> Union[None, float]:
"""
Get the long wave emissivity factor of the thermal boundary's internal surface (-)
:return: None or float
"""
return self._alpha_coefficient
@alpha_coefficient.setter
def alpha_coefficient(self, value):
"""
Set long wave emissivity factor of the thermal boundary's internal surface (-)
:param value: float
"""
if value is not None:
self._alpha_coefficient = float(value)
@property
def radiative_coefficient(self) -> Union[None, float]:
"""
Get the radiative coefficient of the thermal boundary's external surface (-)
:return: None or float
"""
return self._radiative_coefficient
@radiative_coefficient.setter
def radiative_coefficient(self, value):
"""
Set radiative coefficient of the thermal boundary's external surface (-)
:param value: float
"""
if value is not None:
self._radiative_coefficient = float(value)

View File

@ -19,19 +19,13 @@ class ThermalOpening:
def __init__(self): def __init__(self):
self._id = None self._id = None
self._area = None self._area = None
self._openable_ratio = None
self._conductivity = None self._conductivity = None
self._frame_ratio = None self._frame_ratio = None
self._g_value = None self._g_value = None
self._thickness = None self._thickness = None
self._front_side_solar_transmittance_at_normal_incidence = None
self._back_side_solar_transmittance_at_normal_incidence = None
self._overall_u_value = None self._overall_u_value = None
self._hi = ch().convective_heat_transfer_coefficient_interior self._hi = ch().convective_heat_transfer_coefficient_interior
self._he = ch().convective_heat_transfer_coefficient_exterior self._he = ch().convective_heat_transfer_coefficient_exterior
self._inside_emissivity = None
self._alpha_coefficient = None
self._radiative_coefficient = None
self._construction_name = None self._construction_name = None
@property @property
@ -61,20 +55,6 @@ class ThermalOpening:
if value is not None: if value is not None:
self._area = float(value) self._area = float(value)
@property
def openable_ratio(self):
"""
Raises not implemented error
"""
raise NotImplementedError
@openable_ratio.setter
def openable_ratio(self, value):
"""
Raises not implemented error
"""
raise NotImplementedError
@property @property
def conductivity(self) -> Union[None, float]: def conductivity(self) -> Union[None, float]:
""" """
@ -119,7 +99,7 @@ class ThermalOpening:
@property @property
def g_value(self) -> Union[None, float]: def g_value(self) -> Union[None, float]:
""" """
Get thermal opening g-value Get thermal opening transmittance at normal incidence
:return: None or float :return: None or float
""" """
return self._g_value return self._g_value
@ -127,7 +107,7 @@ class ThermalOpening:
@g_value.setter @g_value.setter
def g_value(self, value): def g_value(self, value):
""" """
Set thermal opening g-value Set thermal opening transmittance at normal incidence
:param value: float :param value: float
""" """
if value is not None: if value is not None:
@ -157,40 +137,6 @@ class ThermalOpening:
r_value = 1 / h_i + 1 / h_e + float(self.conductivity) / float(self._thickness) r_value = 1 / h_i + 1 / h_e + float(self.conductivity) / float(self._thickness)
self._overall_u_value = 1 / r_value self._overall_u_value = 1 / r_value
@property
def front_side_solar_transmittance_at_normal_incidence(self) -> Union[None, float]:
"""
Get thermal opening front side solar transmittance at normal incidence
:return: None or float
"""
return self._front_side_solar_transmittance_at_normal_incidence
@front_side_solar_transmittance_at_normal_incidence.setter
def front_side_solar_transmittance_at_normal_incidence(self, value):
"""
Set thermal opening front side solar transmittance at normal incidence
:param value: float
"""
if value is not None:
self._front_side_solar_transmittance_at_normal_incidence = float(value)
@property
def back_side_solar_transmittance_at_normal_incidence(self) -> Union[None, float]:
"""
Get thermal opening back side solar transmittance at normal incidence
:return: None or float
"""
return self._back_side_solar_transmittance_at_normal_incidence
@back_side_solar_transmittance_at_normal_incidence.setter
def back_side_solar_transmittance_at_normal_incidence(self, value):
"""
Set thermal opening back side solar transmittance at normal incidence
:param value: float
"""
if value is not None:
self._back_side_solar_transmittance_at_normal_incidence = float(value)
@property @property
def overall_u_value(self) -> Union[None, float]: def overall_u_value(self) -> Union[None, float]:
""" """
@ -242,57 +188,6 @@ class ThermalOpening:
if value is not None: if value is not None:
self._he = float(value) self._he = float(value)
@property
def inside_emissivity(self) -> Union[None, float]:
"""
Get the short wave emissivity factor of the thermal opening's internal surface (-)
:return: None or float
"""
return self._inside_emissivity
@inside_emissivity.setter
def inside_emissivity(self, value):
"""
Set short wave emissivity factor of the thermal opening's internal surface (-)
:param value: float
"""
if value is not None:
self._inside_emissivity = float(value)
@property
def alpha_coefficient(self) -> Union[None, float]:
"""
Get the long wave emissivity factor of the thermal opening's internal surface (-)
:return: None or float
"""
return self._alpha_coefficient
@alpha_coefficient.setter
def alpha_coefficient(self, value):
"""
Set long wave emissivity factor of the thermal opening's internal surface (-)
:param value: float
"""
if value is not None:
self._alpha_coefficient = float(value)
@property
def radiative_coefficient(self) -> Union[None, float]:
"""
Get the radiative coefficient of the thermal opening's external surface (-)
:return: None or float
"""
return self._radiative_coefficient
@radiative_coefficient.setter
def radiative_coefficient(self, value):
"""
Set radiative coefficient of the thermal opening's external surface (-)
:param value: float
"""
if value is not None:
self._radiative_coefficient = float(value)
@property @property
def construction_name(self): def construction_name(self):
""" """

View File

@ -15,7 +15,6 @@ from city_model_structure.building_demand.appliances import Appliances
from city_model_structure.building_demand.lighting import Lighting from city_model_structure.building_demand.lighting import Lighting
from city_model_structure.building_demand.internal_gain import InternalGain from city_model_structure.building_demand.internal_gain import InternalGain
from city_model_structure.building_demand.thermal_control import ThermalControl from city_model_structure.building_demand.thermal_control import ThermalControl
from city_model_structure.energy_systems.hvac_system import HvacSystem
from city_model_structure.attributes.schedule import Schedule from city_model_structure.attributes.schedule import Schedule
import helpers.constants as cte import helpers.constants as cte
@ -208,15 +207,6 @@ class ThermalZone:
if value is not None: if value is not None:
self._ordinate_number = int(value) self._ordinate_number = int(value)
@property
def hvac_system(self) -> Union[None, HvacSystem]:
"""
Get HVAC system installed for this thermal zone
From internal_zone
:return: None or HvacSystem
"""
return self._parent_internal_zone.hvac_system
@property @property
def view_factors_matrix(self): def view_factors_matrix(self):
""" """

View File

@ -29,7 +29,6 @@ class UsPhysicsParameters(NrelPhysicsInterface):
""" """
Returns the city with the construction parameters assigned to the buildings Returns the city with the construction parameters assigned to the buildings
""" """
# todo: erase
city = self._city city = self._city
for building in city.buildings: for building in city.buildings:
try: try:
@ -40,7 +39,8 @@ class UsPhysicsParameters(NrelPhysicsInterface):
f'and climate zone reference norm {self._climate_zone}\n') f'and climate zone reference norm {self._climate_zone}\n')
return return
# if building has no thermal zones defined from geometry, one thermal zone per storey is assigned # if building has no thermal zones defined from geometry, and the building will be divided in storeys,
# one thermal zone per storey is assigned
if len(building.internal_zones) == 1: if len(building.internal_zones) == 1:
if building.internal_zones[0].thermal_zones is None: if building.internal_zones[0].thermal_zones is None:
self._create_storeys(building, archetype, self._divide_in_storeys) self._create_storeys(building, archetype, self._divide_in_storeys)
@ -121,9 +121,13 @@ class UsPhysicsParameters(NrelPhysicsInterface):
thermal_boundary.layers.append(layer) thermal_boundary.layers.append(layer)
# The agreement is that the layers are defined from outside to inside # The agreement is that the layers are defined from outside to inside
external_layer = construction_archetype.layers[0] external_layer = construction_archetype.layers[0]
thermal_boundary.outside_solar_absorptance = external_layer.material.solar_absorptance external_surface = thermal_boundary.parent_surface
thermal_boundary.outside_thermal_absorptance = external_layer.material.thermal_absorptance external_surface.short_wave_reflectance = 1 - float(external_layer.material.solar_absorptance)
thermal_boundary.outside_visible_absorptance = external_layer.material.visible_absorptance external_surface.long_wave_emittance = 1 - float(external_layer.material.solar_absorptance)
internal_layer = construction_archetype.layers[len(construction_archetype.layers) - 1]
internal_surface = thermal_boundary.internal_surface
internal_surface.short_wave_reflectance = 1 - float(internal_layer.material.solar_absorptance)
internal_surface.long_wave_emittance = 1 - float(internal_layer.material.solar_absorptance)
for thermal_opening in thermal_boundary.thermal_openings: for thermal_opening in thermal_boundary.thermal_openings:
if construction_archetype.window is not None: if construction_archetype.window is not None:

View File

@ -30,110 +30,15 @@ class TestConstructionFactory(TestCase):
self.assertIsNotNone(self._city, 'city is none') self.assertIsNotNone(self._city, 'city is none')
return self._city return self._city
def _check_buildings(self, city): @staticmethod
for building in city.buildings: def _internal_function(function_format, original_function):
self.assertIsNotNone(building.name, 'building name is none') if function_format == 'hft':
self.assertIsNotNone(building.lod, 'building lod is none') new_function = GeometryHelper.libs_function_from_hft(original_function)
self.assertIsNotNone(building.type, 'building type is none') elif function_format == 'pluto':
self.assertIsNotNone(building.volume, 'building volume is none') new_function = GeometryHelper.libs_function_from_pluto(original_function)
self.assertIsNotNone(building.detailed_polyhedron, 'building detailed polyhedron is none') else:
self.assertIsNotNone(building.simplified_polyhedron, 'building simplified polyhedron is none') raise Exception('Function key not recognized. Implemented only "hft" and "pluto"')
self.assertIsNotNone(building.surfaces, 'building surfaces is none') return new_function
self.assertIsNotNone(building.centroid, 'building centroid is none')
self.assertIsNotNone(building.max_height, 'building max_height is none')
self.assertEqual(len(building.external_temperature), 0, 'building external temperature is calculated')
self.assertEqual(len(building.global_horizontal), 0, 'building global horizontal is calculated')
self.assertEqual(len(building.diffuse), 0, 'building diffuse is calculated')
self.assertEqual(len(building.beam), 0, 'building beam is calculated')
self.assertIsNotNone(building.lower_corner, 'building lower corner is none')
self.assertEqual(len(building.sensors), 0, 'building sensors are assigned')
self.assertIsNotNone(building.internal_zones, 'no internal zones created')
self.assertIsNotNone(building.grounds, 'building grounds is none')
self.assertIsNotNone(building.walls, 'building walls is none')
self.assertIsNotNone(building.roofs, 'building roofs is none')
for internal_zone in building.internal_zones:
self.assertIsNone(internal_zone.usage_zones, 'usage zones are defined')
self.assertTrue(len(internal_zone.thermal_zones) > 0, 'thermal zones are not defined')
self.assertIsNone(building.basement_heated, 'building basement_heated is not none')
self.assertIsNone(building.attic_heated, 'building attic_heated is not none')
self.assertIsNone(building.terrains, 'building terrains is not none')
self.assertIsNotNone(building.year_of_construction, 'building year_of_construction is none')
self.assertIsNotNone(building.function, 'building function is none')
self.assertIsNotNone(building.average_storey_height, 'building average_storey_height is none')
self.assertIsNotNone(building.storeys_above_ground, 'building storeys_above_ground is none')
self.assertEqual(len(building.heating), 0, 'building heating is not none')
self.assertEqual(len(building.cooling), 0, 'building cooling is not none')
self.assertIsNotNone(building.eave_height, 'building eave height is none')
self.assertIsNotNone(building.roof_type, 'building roof type is none')
self.assertIsNotNone(building.floor_area, 'building floor_area is none')
self.assertIsNone(building.households, 'building households is not none')
self.assertFalse(building.is_conditioned, 'building is conditioned')
def _check_thermal_zones(self, internal_zone):
for thermal_zone in internal_zone.thermal_zones:
self.assertIsNotNone(thermal_zone.id, 'thermal_zone id is none')
self.assertIsNotNone(thermal_zone.footprint_area, 'thermal_zone floor area is none')
self.assertTrue(len(thermal_zone.thermal_boundaries) > 0, 'thermal_zone thermal_boundaries not defined')
self.assertIsNotNone(thermal_zone.additional_thermal_bridge_u_value, 'additional_thermal_bridge_u_value is none')
self.assertIsNotNone(thermal_zone.effective_thermal_capacity, 'thermal_zone effective_thermal_capacity is none')
self.assertIsNotNone(thermal_zone.indirectly_heated_area_ratio,
'thermal_zone indirectly_heated_area_ratio is none')
self.assertIsNotNone(thermal_zone.infiltration_rate_system_off,
'thermal_zone infiltration_rate_system_off is none')
self.assertIsNotNone(thermal_zone.infiltration_rate_system_on, 'thermal_zone infiltration_rate_system_on is none')
self.assertIsNotNone(thermal_zone.volume, 'thermal_zone volume is none')
self.assertIsNone(thermal_zone.ordinate_number, 'thermal_zone ordinate number is not none')
self.assertIsNotNone(thermal_zone.view_factors_matrix, 'thermal_zone view factors matrix is none')
self.assertIsNone(thermal_zone.hvac_system, 'thermal_zone hvac_system is not none')
self.assertIsNone(thermal_zone.usage, 'thermal_zone usage is not none')
self.assertIsNone(thermal_zone.hours_day, 'thermal_zone hours a day is not none')
self.assertIsNone(thermal_zone.days_year, 'thermal_zone days a year is not none')
self.assertIsNone(thermal_zone.mechanical_air_change, 'thermal_zone mechanical air change is not none')
self.assertIsNone(thermal_zone.occupancy, 'thermal_zone occupancy is not none')
self.assertIsNone(thermal_zone.lighting, 'thermal_zone lighting is not none')
self.assertIsNone(thermal_zone.appliances, 'thermal_zone appliances is not none')
self.assertIsNone(thermal_zone.thermal_control, 'thermal_zone thermal control is not none')
self.assertIsNone(thermal_zone.internal_gains, 'thermal_zone internal gains not returns none')
def _check_thermal_boundaries(self, thermal_zone):
for thermal_boundary in thermal_zone.thermal_boundaries:
self.assertIsNotNone(thermal_boundary.id, 'thermal_boundary id is none')
self.assertIsNotNone(thermal_boundary.parent_surface, 'thermal_boundary surface is none')
self.assertIsNotNone(thermal_boundary.thermal_zones, 'thermal_boundary delimits no thermal zone')
self.assertIsNotNone(thermal_boundary.opaque_area, 'thermal_boundary area is none')
self.assertIsNotNone(thermal_boundary.azimuth, 'thermal_boundary azimuth is none')
self.assertIsNotNone(thermal_boundary.inclination, 'thermal_boundary inclination is none')
self.assertIsNotNone(thermal_boundary.thickness, 'thermal_boundary thickness is none')
self.assertIsNotNone(thermal_boundary.type, 'thermal_boundary type is none')
self.assertIsNotNone(thermal_boundary.outside_solar_absorptance, 'outside_solar_absorptance is none')
self.assertIsNotNone(thermal_boundary.outside_shortwave_reflectance, 'shortwave_reflectance is none')
self.assertIsNotNone(thermal_boundary.thermal_openings, 'thermal_openings is none')
self.assertIsNotNone(thermal_boundary.construction_name, 'construction_name is none')
self.assertIsNotNone(thermal_boundary.window_ratio, 'window_ratio is none')
self.assertIsNone(thermal_boundary.windows_areas, 'windows_areas is not none')
self.assertIsNotNone(thermal_boundary.u_value, 'u_value is none')
self.assertIsNotNone(thermal_boundary.hi, 'hi is none')
self.assertIsNotNone(thermal_boundary.he, 'he is none')
self.assertIsNotNone(thermal_boundary.virtual_internal_surface, 'virtual_internal_surface is none')
self.assertIsNone(thermal_boundary.inside_emissivity, 'inside_emissivity is not none')
self.assertIsNone(thermal_boundary.alpha_coefficient, 'alpha_coefficient is not none')
self.assertIsNone(thermal_boundary.radiative_coefficient, 'radiative_coefficient is not none')
def _check_thermal_openings(self, thermal_boundary):
for thermal_opening in thermal_boundary.thermal_openings:
self.assertIsNotNone(thermal_opening.id, 'thermal opening id is not none')
self.assertIsNotNone(thermal_opening.construction_name, 'thermal opening construction is not none')
self.assertIsNotNone(thermal_opening.area, 'thermal opening area is not none')
self.assertRaises(Exception, lambda: thermal_opening.openable_ratio,
'thermal_opening openable_ratio is not raising an exception')
self.assertIsNotNone(thermal_opening.frame_ratio, 'thermal opening frame_ratio is none')
self.assertIsNotNone(thermal_opening.g_value, 'thermal opening g_value is none')
self.assertIsNotNone(thermal_opening.overall_u_value, 'thermal opening overall_u_value is none')
self.assertIsNotNone(thermal_opening.hi, 'thermal opening hi is none')
self.assertIsNotNone(thermal_opening.he, 'thermal opening he is none')
self.assertIsNone(thermal_opening.inside_emissivity, 'thermal opening inside_emissivity is not none')
self.assertIsNone(thermal_opening.alpha_coefficient, 'thermal opening alpha_coefficient is not none')
self.assertIsNone(thermal_opening.radiative_coefficient, 'thermal opening radiative_coefficient is not none')
def test_citygml_function(self): def test_citygml_function(self):
""" """
@ -162,6 +67,111 @@ class TestConstructionFactory(TestCase):
for building in city.buildings: for building in city.buildings:
self.assertRaises(Exception, lambda: self._internal_function(function_format, building.function)) self.assertRaises(Exception, lambda: self._internal_function(function_format, building.function))
def _check_buildings(self, city):
for building in city.buildings:
self.assertIsNotNone(building.name, 'building name is none')
self.assertIsNotNone(building.lod, 'building lod is none')
self.assertIsNotNone(building.type, 'building type is none')
self.assertIsNotNone(building.volume, 'building volume is none')
self.assertIsNotNone(building.detailed_polyhedron, 'building detailed polyhedron is none')
self.assertIsNotNone(building.simplified_polyhedron, 'building simplified polyhedron is none')
self.assertIsNotNone(building.surfaces, 'building surfaces is none')
self.assertIsNotNone(building.centroid, 'building centroid is none')
self.assertIsNotNone(building.max_height, 'building max_height is none')
self.assertEqual(len(building.external_temperature), 0, 'building external temperature is calculated')
self.assertEqual(len(building.global_horizontal), 0, 'building global horizontal is calculated')
self.assertEqual(len(building.diffuse), 0, 'building diffuse is calculated')
self.assertEqual(len(building.beam), 0, 'building beam is calculated')
self.assertIsNotNone(building.lower_corner, 'building lower corner is none')
self.assertEqual(len(building.sensors), 0, 'building sensors are assigned')
self.assertIsNotNone(building.internal_zones, 'no internal zones created')
self.assertIsNotNone(building.grounds, 'building grounds is none')
self.assertIsNotNone(building.walls, 'building walls is none')
self.assertIsNotNone(building.roofs, 'building roofs is none')
self.assertIsNotNone(building.internal_walls, 'building internal walls is none')
self.assertIsNone(building.basement_heated, 'building basement_heated is not none')
self.assertIsNone(building.attic_heated, 'building attic_heated is not none')
self.assertIsNone(building.terrains, 'building terrains is not none')
self.assertIsNotNone(building.year_of_construction, 'building year_of_construction is none')
self.assertIsNotNone(building.function, 'building function is none')
self.assertIsNotNone(building.average_storey_height, 'building average_storey_height is none')
self.assertIsNotNone(building.storeys_above_ground, 'building storeys_above_ground is none')
self.assertEqual(len(building.heating), 0, 'building heating is not none')
self.assertEqual(len(building.cooling), 0, 'building cooling is not none')
self.assertIsNotNone(building.eave_height, 'building eave height is none')
self.assertIsNotNone(building.roof_type, 'building roof type is none')
self.assertIsNotNone(building.floor_area, 'building floor_area is none')
self.assertIsNone(building.households, 'building households is not none')
self.assertFalse(building.is_conditioned, 'building is conditioned')
self.assertIsNotNone(building.shell, 'building shell is none')
self.assertIsNone(building.human_readable_name, 'building human_readable_name is not none')
def _check_thermal_zones(self, internal_zone):
for thermal_zone in internal_zone.thermal_zones:
self.assertIsNotNone(thermal_zone.id, 'thermal_zone id is none')
self.assertIsNotNone(thermal_zone.footprint_area, 'thermal_zone floor area is none')
self.assertTrue(len(thermal_zone.thermal_boundaries) > 0, 'thermal_zone thermal_boundaries not defined')
self.assertIsNotNone(thermal_zone.additional_thermal_bridge_u_value, 'additional_thermal_bridge_u_value is none')
self.assertIsNotNone(thermal_zone.effective_thermal_capacity, 'thermal_zone effective_thermal_capacity is none')
self.assertIsNotNone(thermal_zone.indirectly_heated_area_ratio,
'thermal_zone indirectly_heated_area_ratio is none')
self.assertIsNotNone(thermal_zone.infiltration_rate_system_off,
'thermal_zone infiltration_rate_system_off is none')
self.assertIsNotNone(thermal_zone.infiltration_rate_system_on, 'thermal_zone infiltration_rate_system_on is none')
self.assertIsNotNone(thermal_zone.volume, 'thermal_zone volume is none')
self.assertIsNone(thermal_zone.ordinate_number, 'thermal_zone ordinate number is not none')
self.assertIsNotNone(thermal_zone.view_factors_matrix, 'thermal_zone view factors matrix is none')
self.assertIsNotNone(thermal_zone.total_floor_area, 'thermal zone total_floor_area is none')
self.assertIsNone(thermal_zone.usage, 'thermal_zone usage is not none')
self.assertIsNone(thermal_zone.hours_day, 'thermal_zone hours a day is not none')
self.assertIsNone(thermal_zone.days_year, 'thermal_zone days a year is not none')
self.assertIsNone(thermal_zone.mechanical_air_change, 'thermal_zone mechanical air change is not none')
self.assertIsNone(thermal_zone.occupancy, 'thermal_zone occupancy is not none')
self.assertIsNone(thermal_zone.lighting, 'thermal_zone lighting is not none')
self.assertIsNone(thermal_zone.appliances, 'thermal_zone appliances is not none')
self.assertIsNone(thermal_zone.thermal_control, 'thermal_zone thermal control is not none')
self.assertIsNone(thermal_zone.internal_gains, 'thermal_zone internal gains not returns none')
def _check_thermal_boundaries(self, thermal_zone):
for thermal_boundary in thermal_zone.thermal_boundaries:
self.assertIsNotNone(thermal_boundary.id, 'thermal_boundary id is none')
self.assertIsNotNone(thermal_boundary.parent_surface, 'thermal_boundary surface is none')
self.assertIsNotNone(thermal_boundary.thermal_zones, 'thermal_boundary delimits no thermal zone')
self.assertIsNotNone(thermal_boundary.opaque_area, 'thermal_boundary area is none')
self.assertIsNotNone(thermal_boundary.thickness, 'thermal_boundary thickness is none')
self.assertIsNotNone(thermal_boundary.type, 'thermal_boundary type is none')
self.assertIsNotNone(thermal_boundary.thermal_openings, 'thermal_openings is none')
self.assertIsNotNone(thermal_boundary.construction_name, 'construction_name is none')
self.assertIsNotNone(thermal_boundary.window_ratio, 'window_ratio is none')
self.assertIsNone(thermal_boundary.windows_areas, 'windows_areas is not none')
self.assertIsNotNone(thermal_boundary.u_value, 'u_value is none')
self.assertIsNotNone(thermal_boundary.hi, 'hi is none')
self.assertIsNotNone(thermal_boundary.he, 'he is none')
self.assertIsNotNone(thermal_boundary.internal_surface, 'virtual_internal_surface is none')
self.assertIsNotNone(thermal_boundary.layers, 'layers is not none')
def _check_thermal_openings(self, thermal_boundary):
for thermal_opening in thermal_boundary.thermal_openings:
self.assertIsNotNone(thermal_opening.id, 'thermal opening id is not none')
self.assertIsNotNone(thermal_opening.construction_name, 'thermal opening construction is not none')
self.assertIsNotNone(thermal_opening.area, 'thermal opening area is not none')
self.assertIsNotNone(thermal_opening.frame_ratio, 'thermal opening frame_ratio is none')
self.assertIsNotNone(thermal_opening.g_value, 'thermal opening g_value is none')
self.assertIsNotNone(thermal_opening.overall_u_value, 'thermal opening overall_u_value is none')
self.assertIsNotNone(thermal_opening.hi, 'thermal opening hi is none')
self.assertIsNotNone(thermal_opening.he, 'thermal opening he is none')
self.assertIsNotNone(thermal_opening.construction_name, 'thermal opening construction_name is none')
def _check_surfaces(self, thermal_boundary):
external_surface = thermal_boundary.parent_surface
internal_surface = thermal_boundary.internal_surface
self.assertIsNotNone(external_surface.short_wave_reflectance,
'external surface short_wave_reflectance id is not none')
self.assertIsNotNone(external_surface.long_wave_emittance, 'external surface long_wave_emittance id is not none')
self.assertIsNotNone(internal_surface.short_wave_reflectance,
'external surface short_wave_reflectance id is not none')
self.assertIsNotNone(internal_surface.long_wave_emittance, 'external surface long_wave_emittance id is not none')
def test_city_with_construction_extended_library(self): def test_city_with_construction_extended_library(self):
""" """
Enrich the city with the construction information and verify it Enrich the city with the construction information and verify it
@ -180,17 +190,6 @@ class TestConstructionFactory(TestCase):
for thermal_zone in internal_zone.thermal_zones: for thermal_zone in internal_zone.thermal_zones:
self._check_thermal_boundaries(thermal_zone) self._check_thermal_boundaries(thermal_zone)
for thermal_boundary in thermal_zone.thermal_boundaries: for thermal_boundary in thermal_zone.thermal_boundaries:
self.assertIsNotNone(thermal_boundary.outside_thermal_absorptance, 'outside_thermal_absorptance is none')
self.assertIsNotNone(thermal_boundary.outside_visible_absorptance, 'outside_visible_absorptance is none')
self.assertIsNotNone(thermal_boundary.layers, 'layers is none') self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
self._check_thermal_openings(thermal_boundary) self._check_thermal_openings(thermal_boundary)
self._check_surfaces(thermal_boundary)
@staticmethod
def _internal_function(function_format, original_function):
if function_format == 'hft':
new_function = GeometryHelper.libs_function_from_hft(original_function)
elif function_format == 'pluto':
new_function = GeometryHelper.libs_function_from_pluto(original_function)
else:
raise Exception('Function key not recognized. Implemented only "hft" and "pluto"')
return new_function

View File

@ -89,17 +89,21 @@ class TestGeometryFactory(TestCase):
for surface in building.surfaces: for surface in building.surfaces:
self.assertIsNotNone(surface.name, 'surface name is none') self.assertIsNotNone(surface.name, 'surface name is none')
self.assertIsNotNone(surface.id, 'surface id is none') self.assertIsNotNone(surface.id, 'surface id is none')
self.assertIsNone(surface.swr, 'surface swr is not none')
self.assertIsNotNone(surface.lower_corner, 'surface envelope_lower_corner is none') self.assertIsNotNone(surface.lower_corner, 'surface envelope_lower_corner is none')
self.assertIsNotNone(surface.upper_corner, 'surface envelope_upper_corner is none') self.assertIsNotNone(surface.upper_corner, 'surface envelope_upper_corner is none')
self.assertIsNotNone(surface.perimeter_area, 'surface area_above_ground is none') self.assertIsNotNone(surface.perimeter_area, 'surface area_above_ground is none')
self.assertIsNotNone(surface.azimuth, 'surface azimuth is none') self.assertIsNotNone(surface.azimuth, 'surface azimuth is none')
self.assertIsNotNone(surface.type, 'surface type is none')
self.assertIsNotNone(surface.inclination, 'surface inclination is none') self.assertIsNotNone(surface.inclination, 'surface inclination is none')
self.assertIsNotNone(surface.type, 'surface type is none')
self.assertEqual(len(surface.global_irradiance), 0, 'global irradiance is calculated') self.assertEqual(len(surface.global_irradiance), 0, 'global irradiance is calculated')
self.assertIsNotNone(surface.perimeter_polygon, 'surface perimeter_polygon is none') self.assertIsNotNone(surface.perimeter_polygon, 'surface perimeter_polygon is none')
self.assertIsNone(surface.holes_polygons, 'surface hole_polygons is not none') self.assertIsNone(surface.holes_polygons, 'surface hole_polygons is not none')
self.assertIsNotNone(surface.solid_polygon, 'surface solid_polygon is none') self.assertIsNotNone(surface.solid_polygon, 'surface solid_polygon is none')
self.assertIsNone(surface.short_wave_reflectance, 'surface short_wave_reflectance is not none')
self.assertIsNone(surface.long_wave_emittance, 'surface long_wave_emittance is not none')
self.assertIsNotNone(surface.inverse, 'surface inverse is none')
self.assertEqual(len(surface.associated_thermal_boundaries), 0, 'associated_thermal_boundaries are assigned')
self.assertIsNone(surface.vegetation, 'surface vegetation is not none')
# citygml_classes # citygml_classes
def test_import_citygml(self): def test_import_citygml(self):