diff --git a/city_model_structure/building_demand/thermal_control.py b/city_model_structure/building_demand/thermal_control.py index 41f88bb6..77ef928e 100644 --- a/city_model_structure/building_demand/thermal_control.py +++ b/city_model_structure/building_demand/thermal_control.py @@ -54,7 +54,7 @@ class ThermalControl: Set heating set point defined for a thermal zone in Celsius :param value: float """ - self._mean_heating_set_point = value + self._mean_heating_set_point = float(value) @property def heating_set_back(self) -> Union[None, float]: @@ -93,7 +93,7 @@ class ThermalControl: Set cooling set point defined for a thermal zone in Celsius :param value: float """ - self._mean_cooling_set_point = value + self._mean_cooling_set_point = float(value) @property def hvac_availability_schedules(self) -> Union[None, List[Schedule]]: diff --git a/city_model_structure/building_demand/thermal_zone.py b/city_model_structure/building_demand/thermal_zone.py index 2b4b016e..079fa3b1 100644 --- a/city_model_structure/building_demand/thermal_zone.py +++ b/city_model_structure/building_demand/thermal_zone.py @@ -4,7 +4,7 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2020 Project Author Guille Gutierrez guillermo.gutierrezmorote@concordia.ca Contributors Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ -import uuid +import uuid, sys import copy from typing import List, Union, TypeVar from city_model_structure.building_demand.occupancy import Occupancy @@ -238,8 +238,7 @@ class ThermalZone: for day_type in schedule.day_types: if day_type == requested_day_type: return schedule - else: - return None + return None @property def not_detailed_source_mean_annual_internal_gains(self) -> Union[None, List[InternalGains]]: @@ -257,9 +256,9 @@ class ThermalZone: _radiative_part = 0 _latent_part = 0 for _usage_zone in self._parent_internal_zone.usage_zones: - if _usage_zone.internal_gains is None: + if _usage_zone.not_detailed_source_mean_annual_internal_gains is None: return None - for _internal_gain in _usage_zone.internal_gains: + for _internal_gain in _usage_zone.not_detailed_source_mean_annual_internal_gains: _average_internal_gain += _internal_gain.average_internal_gain _convective_part += _internal_gain.average_internal_gain * _internal_gain.convective_fraction _radiative_part += _internal_gain.average_internal_gain * _internal_gain.radiative_fraction @@ -270,24 +269,35 @@ class ThermalZone: _grouped_internal_gain.convective_fraction = _convective_part / _average_internal_gain _grouped_internal_gain.radiative_fraction = _radiative_part / _average_internal_gain _grouped_internal_gain.latent_fraction = _latent_part / _average_internal_gain - _internal_gains_reference = self._parent_internal_zone.usage_zones[0].internal_gains[0] - day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY, cte.SATURDAY, cte.SUNDAY] - schedule_of_days = [] - for i_day in range(0, 7): - schedule_of_day = \ - copy.deepcopy(self._get_schedule_of_day(day_types[i_day], _internal_gains_reference.schedules)) - schedule_of_day.day_types = [day_types[i_day]] - new_values = [] - for i_value in range(0, len(_internal_gains_reference.schedules[0].values)): - _new_value = 0 - for _usage_zone in self._parent_internal_zone.usage_zones: - for _internal_gain in _usage_zone.internal_gains: - _value = self._get_schedule_of_day(day_types[i_day], _internal_gain.schedules)[i_value] - _new_value += _usage_zone.percentage * _value / len(_usage_zone.internal_gains) - new_values.append(_new_value) - schedule_of_day.values = new_values - schedule_of_days.append(schedule_of_day) - _grouped_internal_gain.schedules = schedule_of_days + + _internal_gains_reference = \ + self._parent_internal_zone.usage_zones[0].not_detailed_source_mean_annual_internal_gains[0] + if _internal_gains_reference.schedules is not None: + day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY, cte.SATURDAY, cte.SUNDAY] + schedule_of_days = [] + for i_day in range(0, 7): + schedule_of_day = \ + copy.deepcopy(self._get_schedule_of_day(day_types[i_day], _internal_gains_reference.schedules)) + if schedule_of_day is None: + sys.stderr.write(f'Error. Not found requested day type when generating internal gains schedules ' + f'in thermal_zone.\n') + schedule_of_day.day_types = [day_types[i_day]] + new_values = [] + for i_value in range(0, len(_internal_gains_reference.schedules[0].values)): + _new_value = 0 + for _usage_zone in self._parent_internal_zone.usage_zones: + for _internal_gain in _usage_zone.not_detailed_source_mean_annual_internal_gains: + _value = self._get_schedule_of_day(day_types[i_day], _internal_gain.schedules) + if _value is None: + sys.stderr.write(f'Error. Not found requested day type when generating internal gains schedules ' + f'in thermal_zone.\n') + _value = _value.values[i_value] + _new_value += _usage_zone.percentage * _value \ + / len(_usage_zone.not_detailed_source_mean_annual_internal_gains) + new_values.append(_new_value) + schedule_of_day.values = new_values + schedule_of_days.append(schedule_of_day) + _grouped_internal_gain.schedules = schedule_of_days else: _grouped_internal_gain.convective_fraction = 0 _grouped_internal_gain.radiative_fraction = 0 @@ -361,6 +371,8 @@ class ThermalZone: if self._mechanical_air_change is None: self._mechanical_air_change = 0 for usage_zone in self._parent_internal_zone.usage_zones: + if usage_zone.mechanical_air_change is None: + return None self._mechanical_air_change += usage_zone.percentage * usage_zone.mechanical_air_change return self._mechanical_air_change @@ -391,27 +403,29 @@ class ThermalZone: if usage_zone.occupancy is None: return None _occupancy_density += usage_zone.percentage * usage_zone.occupancy.occupancy_density - _convective_part += usage_zone.percentage * usage_zone.occupancy.sensible_convective_internal_gain - _radiative_part += usage_zone.percentage * usage_zone.occupancy.sensible_radiative_internal_gain - _latent_part += usage_zone.percentage * usage_zone.occupancy.latent_internal_gain + if usage_zone.occupancy.sensible_convective_internal_gain is not None: + _convective_part += usage_zone.percentage * usage_zone.occupancy.sensible_convective_internal_gain + _radiative_part += usage_zone.percentage * usage_zone.occupancy.sensible_radiative_internal_gain + _latent_part += usage_zone.percentage * usage_zone.occupancy.latent_internal_gain self._occupancy.occupancy_density = _occupancy_density self._occupancy.sensible_convective_internal_gain = _convective_part self._occupancy.sensible_radiative_internal_gain = _radiative_part self._occupancy.latent_internal_gain = _latent_part _occupancy_reference = self._parent_internal_zone.usage_zones[0].occupancy - _schedules = [] - for i_schedule in range(0, len(_occupancy_reference.occupancy_schedules)): - schedule = copy.deepcopy(_occupancy_reference.occupancy_schedules[i_schedule]) - new_values = [] - for i_value in range(0, len(_occupancy_reference.occupancy_schedules[i_schedule].values)): - _new_value = 0 - for usage_zone in self._parent_internal_zone.usage_zones: - _new_value += usage_zone.percentage * usage_zone.occupancy.occupancy_schedules[i_schedule].values[i_value] - new_values.append(_new_value) - schedule.values = new_values - _schedules.append(schedule) - self._occupancy.occupancy_schedules = _schedules + if _occupancy_reference.occupancy_schedules is not None: + _schedules = [] + for i_schedule in range(0, len(_occupancy_reference.occupancy_schedules)): + schedule = copy.deepcopy(_occupancy_reference.occupancy_schedules[i_schedule]) + new_values = [] + for i_value in range(0, len(_occupancy_reference.occupancy_schedules[i_schedule].values)): + _new_value = 0 + for usage_zone in self._parent_internal_zone.usage_zones: + _new_value += usage_zone.percentage * usage_zone.occupancy.occupancy_schedules[i_schedule].values[i_value] + new_values.append(_new_value) + schedule.values = new_values + _schedules.append(schedule) + self._occupancy.occupancy_schedules = _schedules return self._occupancy @occupancy.setter @@ -440,12 +454,13 @@ class ThermalZone: if usage_zone.lighting is None: return None _lighting_density += usage_zone.percentage * usage_zone.lighting.density - _convective_part += usage_zone.percentage * usage_zone.lighting.density \ - * usage_zone.lighting.convective_fraction - _radiative_part += usage_zone.percentage * usage_zone.lighting.density \ - * usage_zone.lighting.radiative_fraction - _latent_part += usage_zone.percentage * usage_zone.lighting.density \ - * usage_zone.lighting.latent_fraction + if usage_zone.lighting.convective_fraction is not None: + _convective_part += usage_zone.percentage * usage_zone.lighting.density \ + * usage_zone.lighting.convective_fraction + _radiative_part += usage_zone.percentage * usage_zone.lighting.density \ + * usage_zone.lighting.radiative_fraction + _latent_part += usage_zone.percentage * usage_zone.lighting.density \ + * usage_zone.lighting.latent_fraction self._lighting.density = _lighting_density if _lighting_density > 0: self._lighting.convective_fraction = _convective_part / _lighting_density @@ -457,18 +472,19 @@ class ThermalZone: self._lighting.latent_fraction = 0 _lighting_reference = self._parent_internal_zone.usage_zones[0].lighting - _schedules = [] - for i_schedule in range(0, len(_lighting_reference.schedules)): - schedule = copy.deepcopy(_lighting_reference.schedules[i_schedule]) - new_values = [] - for i_value in range(0, len(_lighting_reference.schedules[i_schedule].values)): - _new_value = 0 - for usage_zone in self._parent_internal_zone.usage_zones: - _new_value += usage_zone.percentage * usage_zone.lighting.schedules[i_schedule].values[i_value] - new_values.append(_new_value) - schedule.values = new_values - _schedules.append(schedule) - self._lighting.schedules = _schedules + if _lighting_reference.schedules is not None: + _schedules = [] + for i_schedule in range(0, len(_lighting_reference.schedules)): + schedule = copy.deepcopy(_lighting_reference.schedules[i_schedule]) + new_values = [] + for i_value in range(0, len(_lighting_reference.schedules[i_schedule].values)): + _new_value = 0 + for usage_zone in self._parent_internal_zone.usage_zones: + _new_value += usage_zone.percentage * usage_zone.lighting.schedules[i_schedule].values[i_value] + new_values.append(_new_value) + schedule.values = new_values + _schedules.append(schedule) + self._lighting.schedules = _schedules return self._lighting @lighting.setter @@ -497,12 +513,13 @@ class ThermalZone: if usage_zone.appliances is None: return None _appliances_density += usage_zone.percentage * usage_zone.appliances.density - _convective_part += usage_zone.percentage * usage_zone.appliances.density \ - * usage_zone.appliances.convective_fraction - _radiative_part += usage_zone.percentage * usage_zone.appliances.density \ - * usage_zone.appliances.radiative_fraction - _latent_part += usage_zone.percentage * usage_zone.appliances.density \ - * usage_zone.appliances.latent_fraction + if usage_zone.appliances.convective_fraction is not None: + _convective_part += usage_zone.percentage * usage_zone.appliances.density \ + * usage_zone.appliances.convective_fraction + _radiative_part += usage_zone.percentage * usage_zone.appliances.density \ + * usage_zone.appliances.radiative_fraction + _latent_part += usage_zone.percentage * usage_zone.appliances.density \ + * usage_zone.appliances.latent_fraction self._appliances.density = _appliances_density if _appliances_density > 0: self._appliances.convective_fraction = _convective_part / _appliances_density @@ -514,18 +531,19 @@ class ThermalZone: self._appliances.latent_fraction = 0 _appliances_reference = self._parent_internal_zone.usage_zones[0].appliances - _schedules = [] - for i_schedule in range(0, len(_appliances_reference.schedules)): - schedule = copy.deepcopy(_appliances_reference.schedules[i_schedule]) - new_values = [] - for i_value in range(0, len(_appliances_reference.schedules[i_schedule].values)): - _new_value = 0 - for usage_zone in self._parent_internal_zone.usage_zones: - _new_value += usage_zone.percentage * usage_zone.appliances.schedules[i_schedule].values[i_value] - new_values.append(_new_value) - schedule.values = new_values - _schedules.append(schedule) - self._appliances.schedules = _schedules + if _appliances_reference.schedules is not None: + _schedules = [] + for i_schedule in range(0, len(_appliances_reference.schedules)): + schedule = copy.deepcopy(_appliances_reference.schedules[i_schedule]) + new_values = [] + for i_value in range(0, len(_appliances_reference.schedules[i_schedule].values)): + _new_value = 0 + for usage_zone in self._parent_internal_zone.usage_zones: + _new_value += usage_zone.percentage * usage_zone.appliances.schedules[i_schedule].values[i_value] + new_values.append(_new_value) + schedule.values = new_values + _schedules.append(schedule) + self._appliances.schedules = _schedules return self._appliances @appliances.setter @@ -562,9 +580,14 @@ class ThermalZone: + self.occupancy.sensible_radiative_internal_gain + self.occupancy.latent_internal_gain) _internal_gain.average_internal_gain = _total_heat_gain - _internal_gain.latent_fraction = self.occupancy.latent_internal_gain / _total_heat_gain - _internal_gain.radiative_fraction = self.occupancy.sensible_radiative_internal_gain / _total_heat_gain - _internal_gain.convective_fraction = self.occupancy.sensible_convective_internal_gain / _total_heat_gain + if _total_heat_gain > 0: + _internal_gain.latent_fraction = self.occupancy.latent_internal_gain / _total_heat_gain + _internal_gain.radiative_fraction = self.occupancy.sensible_radiative_internal_gain / _total_heat_gain + _internal_gain.convective_fraction = self.occupancy.sensible_convective_internal_gain / _total_heat_gain + else: + _internal_gain.latent_fraction = 0 + _internal_gain.radiative_fraction = 0 + _internal_gain.convective_fraction = 0 _internal_gain.schedules = self.occupancy.occupancy_schedules if self._internal_gains is not None: self._internal_gains.append(_internal_gain) @@ -613,25 +636,30 @@ class ThermalZone: self._thermal_control.mean_cooling_set_point = _mean_cooling_set_point _thermal_control_reference = self._parent_internal_zone.usage_zones[0].thermal_control - _types_reference = [_thermal_control_reference.hvac_availability_schedules, - _thermal_control_reference.heating_set_point_schedules, - _thermal_control_reference.cooling_set_point_schedules] + _types_reference = [] + if _thermal_control_reference.hvac_availability_schedules is not None: + _types_reference.append([cte.HVAC_AVAILABILITY, _thermal_control_reference.hvac_availability_schedules]) + if _thermal_control_reference.heating_set_point_schedules is not None: + _types_reference.append([cte.HEATING_SET_POINT, _thermal_control_reference.heating_set_point_schedules]) + if _thermal_control_reference.cooling_set_point_schedules is not None: + _types_reference.append([cte.COOLING_SET_POINT, _thermal_control_reference.cooling_set_point_schedules]) + for i_type in range(0, len(_types_reference)): _schedules = [] - _schedule_type = _types_reference[i_type] + _schedule_type = _types_reference[i_type][1] for i_schedule in range(0, len(_schedule_type)): schedule = copy.deepcopy(_schedule_type[i_schedule]) new_values = [] for i_value in range(0, len(_schedule_type[i_schedule].values)): _new_value = 0 for usage_zone in self._parent_internal_zone.usage_zones: - if i_type == 0: + if _types_reference[i_type][0] == cte.HVAC_AVAILABILITY: _new_value += usage_zone.percentage * \ usage_zone.thermal_control.hvac_availability_schedules[i_schedule].values[i_value] - elif i_type == 1: + elif _types_reference[i_type][0] == cte.HEATING_SET_POINT: _new_value += usage_zone.percentage * \ usage_zone.thermal_control.heating_set_point_schedules[i_schedule].values[i_value] - elif i_type == 2: + elif _types_reference[i_type][0] == cte.COOLING_SET_POINT: _new_value += usage_zone.percentage * \ usage_zone.thermal_control.cooling_set_point_schedules[i_schedule].values[i_value] new_values.append(_new_value) diff --git a/imports/usage/hft_usage_interface.py b/imports/usage/hft_usage_interface.py index d3605ce1..0524785a 100644 --- a/imports/usage/hft_usage_interface.py +++ b/imports/usage/hft_usage_interface.py @@ -59,11 +59,16 @@ class HftUsageInterface: _schedule.time_range = cte.DAY _schedule.time_step = cte.HOUR _schedule.data_type = cte.ANY_NUMBER - _schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY] + _schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY, cte.SATURDAY, + cte.SUNDAY] _values = zone_usage_type['occupancy']['internGains']['load']['weekDayProfile']['values'] while ' ' in _values: _values = _values.replace(' ', ' ') - _schedule.values = _values.split() + _values = _values.split() + _values_float = [] + for _value in _values: + _values_float.append(float(_value)) + _schedule.values = _values_float _internal_gain.schedules = [_schedule] usage_zone_archetype.not_detailed_source_mean_annual_internal_gains = [_internal_gain] @@ -80,11 +85,16 @@ class HftUsageInterface: _schedule.time_range = cte.DAY _schedule.time_step = cte.HOUR _schedule.data_type = cte.TEMPERATURE - _schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY] + _schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY, cte.SATURDAY, + cte.SUNDAY] _values = zone_usage_type['endUses']['space_heating']['schedule']['weekDayProfile']['values'] while ' ' in _values: _values = _values.replace(' ', ' ') - _schedule.values = _values.split() + _values = _values.split() + _values_float = [] + for _value in _values: + _values_float.append(float(_value)) + _schedule.values = _values_float _thermal_control.heating_set_point_schedules = [_schedule] if 'space_cooling' in zone_usage_type['endUses']: @@ -96,11 +106,16 @@ class HftUsageInterface: _schedule.time_range = cte.DAY _schedule.time_step = cte.HOUR _schedule.data_type = cte.TEMPERATURE - _schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY] + _schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY, cte.SATURDAY, + cte.SUNDAY] _values = zone_usage_type['endUses']['space_cooling']['schedule']['weekDayProfile']['values'] while ' ' in _values: _values = _values.replace(' ', ' ') - _schedule.values = _values.split() + _values = _values.split() + _values_float = [] + for _value in _values: + _values_float.append(float(_value)) + _schedule.values = _values_float _thermal_control.cooling_set_point_schedules = [_schedule] usage_zone_archetype.thermal_control = _thermal_control @@ -164,11 +179,16 @@ class HftUsageInterface: _schedule.time_range = cte.DAY _schedule.time_step = cte.HOUR _schedule.data_type = cte.ANY_NUMBER - _schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY] + _schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY, cte.SATURDAY, + cte.SUNDAY] _values = usage_zone_variant['occupancy']['internGains']['load']['weekDayProfile']['values'] while ' ' in _values: _values = _values.replace(' ', ' ') - _schedule.values = _values.split() + _values = _values.split() + _values_float = [] + for _value in _values: + _values_float.append(float(_value)) + _schedule.values = _values_float _internal_gain.schedules = [_schedule] usage_zone_archetype.not_detailed_source_mean_annual_internal_gains = [_internal_gain] @@ -187,11 +207,16 @@ class HftUsageInterface: _schedule.time_range = cte.DAY _schedule.time_step = cte.HOUR _schedule.data_type = cte.TEMPERATURE - _schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY] + _schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY, cte.SATURDAY, + cte.SUNDAY] _values = usage_zone_variant['endUses']['space_heating']['schedule']['weekDayProfile']['values'] while ' ' in _values: _values = _values.replace(' ', ' ') - _schedule.values = _values.split() + _values = _values.split() + _values_float = [] + for _value in _values: + _values_float.append(float(_value)) + _schedule.values = _values_float _thermal_control.heating_set_point_schedules = [_schedule] if 'space_cooling' in usage_zone_variant['endUses'] and \ @@ -205,11 +230,16 @@ class HftUsageInterface: _schedule.time_range = cte.DAY _schedule.time_step = cte.HOUR _schedule.data_type = cte.TEMPERATURE - _schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY] + _schedule.day_types = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY, cte.SATURDAY, + cte.SUNDAY] _values = usage_zone_variant['endUses']['space_cooling']['schedule']['weekDayProfile']['values'] while ' ' in _values: _values = _values.replace(' ', ' ') - _schedule.values = _values.split() + _values = _values.split() + _values_float = [] + for _value in _values: + _values_float.append(float(_value)) + _schedule.values = _values_float _thermal_control.cooling_set_point_schedules = [_schedule] usage_zone_archetype.thermal_control = _thermal_control diff --git a/unittests/test_construction_factory.py b/unittests/test_construction_factory.py index 9348e8d3..7ddd129b 100644 --- a/unittests/test_construction_factory.py +++ b/unittests/test_construction_factory.py @@ -84,9 +84,18 @@ class TestConstructionFactory(TestCase): 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.usage_zones, 'thermal_zone usage_zones is not none') - self.assertIsNone(thermal_zone.thermal_control, 'thermal_zone thermal_control is not 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.not_detailed_source_mean_annual_internal_gains, + 'thermal_zone not detailed source internal gains 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.get_internal_gains(), 'thermal_zone internal gains not returns none') def _check_thermal_boundaries(self, thermal_zone): for thermal_boundary in thermal_zone.thermal_boundaries: diff --git a/unittests/test_enrichement.py b/unittests/test_enrichement.py index 95861429..804ba697 100644 --- a/unittests/test_enrichement.py +++ b/unittests/test_enrichement.py @@ -30,6 +30,16 @@ class TestGeometryFactory(TestCase): self.assertIsNotNone(self._city, 'city is none') return self._city + def _check_result(self, city): + self._check_buildings(city) + for building in city.buildings: + for internal_zone in building.internal_zones: + self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined') + for usage_zone in internal_zone.usage_zones: + self.assertIsNotNone(usage_zone.id, 'usage id is none') + for thermal_zone in internal_zone.thermal_zones: + self._check_thermal_zone(thermal_zone) + def _check_buildings(self, city): for building in city.buildings: self.assertIsNotNone(building.internal_zones, 'no internal zones created') @@ -42,13 +52,19 @@ class TestGeometryFactory(TestCase): self.assertIsNotNone(building.storeys_above_ground, 'building storeys_above_ground is none') self.assertTrue(building.is_conditioned, 'building is_conditioned is not conditioned') - def _check_usage_zone(self, usage_zone): - self.assertIsNotNone(usage_zone.id, 'usage id is none') - - def _check_thermal_zones(self, thermal_zone): + def _check_thermal_zone(self, thermal_zone): self.assertIsNotNone(thermal_zone.id, 'thermal_zone id is none') - self.assertIsNone(thermal_zone.usage_zones, 'thermal_zone usage_zones is not none') - self.assertIsNone(thermal_zone.thermal_control, 'thermal_zone thermal_control is not none') + self.assertIsNotNone(thermal_zone.usage, 'thermal_zone usage is not none') + self.assertIsNotNone(thermal_zone.hours_day, 'thermal_zone hours a day is none') + self.assertIsNotNone(thermal_zone.days_year, 'thermal_zone days a year is none') + self.assertIsNotNone(thermal_zone.occupancy, 'thermal_zone occupancy is none') + self.assertIsNotNone(thermal_zone.thermal_control, 'thermal_zone thermal control is none') + self.assertIsNotNone(thermal_zone.get_internal_gains(), 'thermal_zone internal gains returns none') + + def _check_extra_thermal_zone(self, thermal_zone): + self.assertIsNotNone(thermal_zone.lighting, 'thermal_zone lighting is none') + self.assertIsNotNone(thermal_zone.appliances, 'thermal_zone appliances is none') + self.assertIsNotNone(thermal_zone.mechanical_air_change, 'thermal_zone mechanical air change is none') @staticmethod def _prepare_case_usage_first(city, input_key, construction_key, usage_key): @@ -72,92 +88,69 @@ class TestGeometryFactory(TestCase): ConstructionFactory(construction_key, city).enrich() UsageFactory(usage_key, city).enrich() + def _test_hft(self, file): + _construction_keys = ['nrel', 'nrcan'] + _usage_keys = ['ca', 'comnet', 'hft'] + for construction_key in _construction_keys: + for usage_key in _usage_keys: + # construction factory called first + city = self._get_citygml(file) + self.assertTrue(len(city.buildings) > 0) + self._prepare_case_construction_first(city, 'hft', construction_key, usage_key) + self._check_result(city) + if usage_key == 'comnet': + for building in city.buildings: + for internal_zone in building.internal_zones: + for thermal_zone in internal_zone.thermal_zones: + self._check_extra_thermal_zone(thermal_zone) + # usage factory called first + city = self._get_citygml(file) + self.assertTrue(len(city.buildings) > 0) + self._prepare_case_usage_first(city, 'hft', construction_key, usage_key) + self._check_result(city) + if usage_key == 'comnet': + for building in city.buildings: + for internal_zone in building.internal_zones: + for thermal_zone in internal_zone.thermal_zones: + self._check_extra_thermal_zone(thermal_zone) + + def _test_pluto(self, file): + _construction_keys = ['nrel'] + _usage_keys = ['comnet', 'hft'] + for construction_key in _construction_keys: + for usage_key in _usage_keys: + # construction factory called first + city = self._get_citygml(file) + self.assertTrue(len(city.buildings) > 0) + self._prepare_case_construction_first(city, 'pluto', construction_key, usage_key) + self._check_result(city) + if usage_key == 'comnet': + for building in city.buildings: + for internal_zone in building.internal_zones: + for thermal_zone in internal_zone.thermal_zones: + self._check_extra_thermal_zone(thermal_zone) + # usage factory called first + city = self._get_citygml(file) + self.assertTrue(len(city.buildings) > 0) + self._prepare_case_usage_first(city, 'pluto', construction_key, usage_key) + self._check_result(city) + if usage_key == 'comnet': + for building in city.buildings: + for internal_zone in building.internal_zones: + for thermal_zone in internal_zone.thermal_zones: + self._check_extra_thermal_zone(thermal_zone) + def test_enrichment(self): """ Test enrichment of the city with different order and all possible combinations :return: None """ file_1 = 'one_building_in_kelowna.gml' + print('file 1') + self._test_hft(file_1) file_2 = 'pluto_building.gml' + print('file 2') + self._test_pluto(file_2) file_3 = 'C40_Final.gml' - _construction_keys = ['nrel', 'nrcan'] - _usage_keys = ['ca', 'comnet'] # todo: add 'hft' - - for construction_key in _construction_keys: - for usage_key in _usage_keys: - city = self._get_citygml(file_1) - self.assertTrue(len(city.buildings) == 1) - self._prepare_case_construction_first(city, 'hft', construction_key, usage_key) - self._check_buildings(city) - for building in city.buildings: - for internal_zone in building.internal_zones: - self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined') - for usage_zone in internal_zone.usage_zones: - self._check_usage_zone(usage_zone) - for thermal_zone in internal_zone.thermal_zones: - self._check_thermal_zones(thermal_zone) - - for construction_key in _construction_keys: - for usage_key in _usage_keys: - city = self._get_citygml(file_1) - self.assertTrue(len(city.buildings) == 1) - self._prepare_case_usage_first(city, 'hft', construction_key, usage_key) - self._check_buildings(city) - for building in city.buildings: - for internal_zone in building.internal_zones: - self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined') - for usage_zone in internal_zone.usage_zones: - self._check_usage_zone(usage_zone) - for thermal_zone in internal_zone.thermal_zones: - self._check_thermal_zones(thermal_zone) - - for construction_key in _construction_keys: - if construction_key != 'nrcan': - for usage_key in _usage_keys: - if usage_key != 'ca': - city = self._get_citygml(file_2) - self.assertTrue(len(city.buildings) == 1) - self._prepare_case_construction_first(city, 'pluto', construction_key, usage_key) - self._check_buildings(city) - for building in city.buildings: - for internal_zone in building.internal_zones: - self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined') - for usage_zone in internal_zone.usage_zones: - self._check_usage_zone(usage_zone) - for thermal_zone in internal_zone.thermal_zones: - self._check_thermal_zones(thermal_zone) - - for construction_key in _construction_keys: - if construction_key != 'nrcan': - for usage_key in _usage_keys: - if usage_key != 'ca': - city = self._get_citygml(file_2) - self.assertTrue(len(city.buildings) == 1) - self._prepare_case_usage_first(city, 'pluto', construction_key, usage_key) - self._check_buildings(city) - for building in city.buildings: - for internal_zone in building.internal_zones: - self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined') - for usage_zone in internal_zone.usage_zones: - self._check_usage_zone(usage_zone) - for thermal_zone in internal_zone.thermal_zones: - self._check_thermal_zones(thermal_zone) - - city = self._get_citygml(file_3) - self.assertTrue(len(city.buildings) == 10) - - for construction_key in _construction_keys: - if construction_key != 'nrcan': - for usage_key in _usage_keys: - if usage_key != 'ca': - city = self._get_citygml(file_2) - self.assertTrue(len(city.buildings) == 1) - self._prepare_case_construction_first(city, 'pluto', construction_key, usage_key) - self._check_buildings(city) - for building in city.buildings: - for internal_zone in building.internal_zones: - self.assertIsNot(len(internal_zone.usage_zones), 0, 'no building usage_zones defined') - for usage_zone in internal_zone.usage_zones: - self._check_usage_zone(usage_zone) - for thermal_zone in internal_zone.thermal_zones: - self._check_thermal_zones(thermal_zone) + print('file 3') + self._test_hft(file_3) diff --git a/unittests/test_usage_factory.py b/unittests/test_usage_factory.py index 92c47ba5..7d2dada1 100644 --- a/unittests/test_usage_factory.py +++ b/unittests/test_usage_factory.py @@ -71,7 +71,6 @@ class TestUsageFactory(TestCase): def _check_usage_zone(self, usage_zone): self.assertIsNotNone(usage_zone.usage, 'usage is none') self.assertIsNotNone(usage_zone.percentage, 'usage percentage is none') - self.assertIsNotNone(usage_zone.get_internal_gains, 'internal gains is none') self.assertIsNotNone(usage_zone.hours_day, 'hours per day is none') self.assertIsNotNone(usage_zone.days_year, 'days per year is none') self.assertIsNotNone(usage_zone.thermal_control, 'thermal control is none') @@ -177,4 +176,3 @@ class TestUsageFactory(TestCase): self.assertIsNone(occupancy.occupants, 'occupancy density is not none') self.assertIsNone(usage_zone.lighting, 'lighting is not none') self.assertIsNone(usage_zone.appliances, 'appliances is not none') -