From bca68f33fff005fee5b9f938a317489882948d81 Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Fri, 7 Jul 2023 15:31:32 -0400 Subject: [PATCH 1/6] solved a bug assigning the energy systems to the buildings --- .../montreal_custom_energy_system_parameters.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py b/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py index f80f66e9..f7349d3d 100644 --- a/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py +++ b/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py @@ -56,7 +56,6 @@ class MontrealCustomEnergySystemParameters: _energy_systems_connection_table, _generic_energy_systems \ = self._create_generic_systems(archetype, building, _energy_systems_connection_table, _generic_energy_systems) - city.energy_systems_connection_table = _energy_systems_connection_table city.generic_energy_systems = _generic_energy_systems @@ -123,9 +122,8 @@ class MontrealCustomEnergySystemParameters: energy_systems_connection = city.energy_systems_connection_table for building in city.buildings: _building_energy_systems = [] - energy_systems = energy_systems_connection['Energy System Type'].where( - energy_systems_connection['Building'] == building.name - ) + energy_systems = energy_systems_connection['Energy System Type'][ + energy_systems_connection['Building'] == building.name] for energy_system in energy_systems: if str(energy_system) == 'nan': break From f146cf32817b53ae9db79dd6e9a8bdb33d65aafb Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Mon, 10 Jul 2023 16:32:22 -0400 Subject: [PATCH 2/6] added 2 more regions to the _epw_file dictionary --- hub/imports/weather/helpers/weather.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hub/imports/weather/helpers/weather.py b/hub/imports/weather/helpers/weather.py index 0af8826d..18364beb 100644 --- a/hub/imports/weather/helpers/weather.py +++ b/hub/imports/weather/helpers/weather.py @@ -24,7 +24,9 @@ class Weather: 'CA.10.14': 'https://energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/CAN/PQ/CAN_PQ_Montreal.Intl.AP.716270_CWEC/CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw', 'CA.10.16': 'https://energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/CAN/PQ/CAN_PQ_Montreal.Intl.AP.716270_CWEC/CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw', 'DE.01.082': 'https://energyplus-weather.s3.amazonaws.com/europe_wmo_region_6/DEU/DEU_Stuttgart.107380_IWEC/DEU_Stuttgart.107380_IWEC.epw', - 'US.NY.047': 'https://energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/USA/NY/USA_NY_New.York.City-Central.Park.94728_TMY/USA_NY_New.York.City-Central.Park.94728_TMY.epw' + 'US.NY.047': 'https://energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/USA/NY/USA_NY_New.York.City-Central.Park.94728_TMY/USA_NY_New.York.City-Central.Park.94728_TMY.epw', + 'CA.10.12': 'https://energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/CAN/PQ/CAN_PQ_Quebec.717140_CWEC/CAN_PQ_Quebec.717140_CWEC.epw', + 'IL.01.': 'https://energyplus-weather.s3.amazonaws.com/europe_wmo_region_6/ISR/ISR_Eilat.401990_MSI/ISR_Eilat.401990_MSI.epw' } # todo: this dictionary need to be completed, a data science student task? From 5247eda305427506cfe4f1d81a90b4c64a2bb113 Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Tue, 11 Jul 2023 16:34:11 -0400 Subject: [PATCH 3/6] added eilat usage to catalog and imports --- hub/RECOGNIZED_FUNTIONS_AND_USAGES.md | 1 + hub/catalog_factories/usage/comnet_catalog.py | 1 - hub/catalog_factories/usage/eilat_catalog.py | 234 ++++++++++++++++++ hub/catalog_factories/usage/usage_helper.py | 13 + .../usage_catalog_factory.py | 8 + hub/data/usage/eilat_archetypes.xlsx | Bin 0 -> 15170 bytes .../usage/eilat_schedules_archetypes.xlsx | Bin 0 -> 78312 bytes .../data/eilat_function_to_hub_function.py | 28 +++ hub/helpers/data/hub_usage_to_eilat_usage.py | 29 +++ hub/helpers/dictionaries.py | 17 ++ hub/imports/usage/eilat_usage_parameters.py | 232 +++++++++++++++++ hub/imports/usage_factory.py | 12 + 12 files changed, 574 insertions(+), 1 deletion(-) create mode 100644 hub/catalog_factories/usage/eilat_catalog.py create mode 100644 hub/data/usage/eilat_archetypes.xlsx create mode 100644 hub/data/usage/eilat_schedules_archetypes.xlsx create mode 100644 hub/helpers/data/eilat_function_to_hub_function.py create mode 100644 hub/helpers/data/hub_usage_to_eilat_usage.py create mode 100644 hub/imports/usage/eilat_usage_parameters.py diff --git a/hub/RECOGNIZED_FUNTIONS_AND_USAGES.md b/hub/RECOGNIZED_FUNTIONS_AND_USAGES.md index b3439b5f..107ba6f2 100644 --- a/hub/RECOGNIZED_FUNTIONS_AND_USAGES.md +++ b/hub/RECOGNIZED_FUNTIONS_AND_USAGES.md @@ -15,6 +15,7 @@ Output formats accepted: * ca * hft * comnet + * Eilat Libs_functions: * single family house diff --git a/hub/catalog_factories/usage/comnet_catalog.py b/hub/catalog_factories/usage/comnet_catalog.py index 1d527573..e78fed67 100644 --- a/hub/catalog_factories/usage/comnet_catalog.py +++ b/hub/catalog_factories/usage/comnet_catalog.py @@ -33,7 +33,6 @@ class ComnetCatalog(Catalog): self._archetypes = self._read_archetype_file() self._schedules = self._read_schedules_file() - # todo: comment with @Guille, this hypotheses should go in the import factory? sensible_convective = ch().comnet_occupancy_sensible_convective sensible_radiative = ch().comnet_occupancy_sensible_radiant lighting_convective = ch().comnet_lighting_convective diff --git a/hub/catalog_factories/usage/eilat_catalog.py b/hub/catalog_factories/usage/eilat_catalog.py new file mode 100644 index 00000000..4b70c47c --- /dev/null +++ b/hub/catalog_factories/usage/eilat_catalog.py @@ -0,0 +1,234 @@ +""" +Eilat usage catalog +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2022 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" +import io +from typing import Dict + +import pandas as pd + +import hub.helpers.constants as cte +from hub.catalog_factories.catalog import Catalog +from hub.catalog_factories.data_models.usages.appliances import Appliances +from hub.catalog_factories.data_models.usages.content import Content +from hub.catalog_factories.data_models.usages.lighting import Lighting +from hub.catalog_factories.data_models.usages.occupancy import Occupancy +from hub.catalog_factories.data_models.usages.domestic_hot_water import DomesticHotWater +from hub.catalog_factories.data_models.usages.schedule import Schedule +from hub.catalog_factories.data_models.usages.thermal_control import ThermalControl +from hub.catalog_factories.data_models.usages.usage import Usage +from hub.catalog_factories.usage.usage_helper import UsageHelper +from hub.helpers.configuration_helper import ConfigurationHelper as ch + + +class EilatCatalog(Catalog): + """ + Eilat catalog class + """ + def __init__(self, path): + self._eilat_archetypes_path = str(path / 'eilat_archetypes.xlsx') + self._eilat_schedules_path = str(path / 'eilat_schedules_archetypes.xlsx') + self._archetypes = self._read_archetype_file() + self._schedules = self._read_schedules_file() + + sensible_convective = ch().comnet_occupancy_sensible_convective + sensible_radiative = ch().comnet_occupancy_sensible_radiant + lighting_convective = ch().comnet_lighting_convective + lighting_radiative = ch().comnet_lighting_radiant + lighting_latent = ch().comnet_lighting_latent + appliances_convective = ch().comnet_plugs_convective + appliances_radiative = ch().comnet_plugs_radiant + appliances_latent = ch().comnet_plugs_latent + + usages = [] + for schedule_key in self._archetypes['schedules_key']: + eilat_usage = schedule_key + schedule_name = self._archetypes['schedules_key'][schedule_key] + hours_day = None + days_year = None + occupancy_archetype = self._archetypes['occupancy'][eilat_usage] + lighting_archetype = self._archetypes['lighting'][eilat_usage] + appliances_archetype = self._archetypes['plug loads'][eilat_usage] + mechanical_air_change = None # eilat provides ventilation rate only + ventilation_rate = self._archetypes['ventilation rate'][eilat_usage] + # convert cfm/ft2 to m3/m2.s + ventilation_rate = ventilation_rate / (cte.METERS_TO_FEET * cte.MINUTES_TO_SECONDS) + domestic_hot_water_archetype = self._archetypes['water heating'][eilat_usage] + + # get occupancy + occupancy_density = occupancy_archetype[0] / pow(cte.METERS_TO_FEET, 2) + sensible_heat_gain = occupancy_archetype[1] * cte.BTU_H_TO_WATTS + latent_heat_gain = occupancy_archetype[1] * cte.BTU_H_TO_WATTS + if occupancy_density != 0: + occupancy_density = 1 / occupancy_density + sensible_convective_internal_gain = occupancy_density * sensible_heat_gain * sensible_convective + sensible_radiative_internal_gain = occupancy_density * sensible_heat_gain * sensible_radiative + latent_internal_gain = occupancy_density * latent_heat_gain + occupancy = Occupancy(occupancy_density, + sensible_convective_internal_gain, + sensible_radiative_internal_gain, + latent_internal_gain, + self._schedules[schedule_name]['Occupancy']) + + # get lighting + density = lighting_archetype[4] * pow(cte.METERS_TO_FEET, 2) + lighting = Lighting(density, + lighting_convective, + lighting_radiative, + lighting_latent, + self._schedules[schedule_name]['Lights']) + + # get appliances + density = appliances_archetype[0] + if density == 'n.a.': + density = 0 + # convert W/ft2 to W/m2 + density = float(density) * pow(cte.METERS_TO_FEET, 2) + appliances = Appliances(density, + appliances_convective, + appliances_radiative, + appliances_latent, + self._schedules[schedule_name]['Receptacle']) + + # get thermal control + thermal_control = ThermalControl(None, + None, + None, + self._schedules[schedule_name]['HVAC Avail'], + self._schedules[schedule_name]['HtgSetPt'], + self._schedules[schedule_name]['ClgSetPt'] + ) + + # get domestic hot water + density = domestic_hot_water_archetype + # convert Btu/h/occ to W/m2 + density = float(density) * cte.BTU_H_TO_WATTS * occupancy_density + domestic_hot_water_service_temperature = self._schedules[schedule_name]['WtrHtrSetPt'][0].values[0] + domestic_hot_water = DomesticHotWater(density, + None, + domestic_hot_water_service_temperature, + self._schedules[schedule_name]['Service Hot Water'] + ) + usages.append(Usage(eilat_usage, + hours_day, + days_year, + mechanical_air_change, + ventilation_rate, + occupancy, + lighting, + appliances, + thermal_control, + domestic_hot_water)) + + self._content = Content(usages) + + def _read_schedules_file(self) -> Dict: + dictionary = {} + eilat_usages = UsageHelper().eilat_schedules_key_to_eilat_schedules + eilat_days = UsageHelper().comnet_days + eilat_data_types = UsageHelper().comnet_data_type_to_hub_data_type + for usage_name in eilat_usages: + with open(self._eilat_schedules_path, 'rb') as xls: + _extracted_data = pd.read_excel( + io.BytesIO(xls.read()), + sheet_name=eilat_usages[usage_name], + skiprows=[0, 1, 2, 3], nrows=39, usecols="A:AA" + ) + _schedules = {} + for row in range(0, 39, 3): + _schedule_values = {} + schedule_name = _extracted_data.loc[row:row, 'Description'].item() + schedule_data_type = eilat_data_types[_extracted_data.loc[row:row, 'Type'].item()] + for day in eilat_days: + # Monday to Friday + start = row + end = row + 1 + if day == cte.FRIDAY: + start = start + 1 + end = end + 1 + elif day in (cte.SATURDAY, cte.HOLIDAY): + start = start + 2 + end = end + 2 + _schedule_values[day] = _extracted_data.iloc[start:end, 3:27].to_numpy().tolist()[0] + _schedule = [] + for day in _schedule_values: + if schedule_name in ('ClgSetPt', 'HtgSetPt', 'WtrHtrSetPt'): + # to celsius + if 'n.a.' in _schedule_values[day]: + _schedule_values[day] = None + else: + _schedule_values[day] = [(float(value)-32)*5/9 for value in _schedule_values[day]] + _schedule.append(Schedule(schedule_name, _schedule_values[day], schedule_data_type, cte.HOUR, cte.DAY, [day])) + _schedules[schedule_name] = _schedule + dictionary[usage_name] = _schedules + return dictionary + + def _read_archetype_file(self) -> Dict: + """ + reads xlsx files containing usage information into a dictionary + :return : Dict + """ + number_usage_types = 3 + with open(self._eilat_archetypes_path, 'rb') as xls: + _extracted_data = pd.read_excel( + io.BytesIO(xls.read()), + sheet_name="Modeling Data", + skiprows=[0, 1, 2], + nrows=number_usage_types + 1, usecols="A:AB" + ) + + lighting_data = {} + plug_loads_data = {} + occupancy_data = {} + ventilation_rate = {} + water_heating = {} + process_data = {} + schedules_key = {} + for j in range(0, number_usage_types): + usage_parameters = _extracted_data.iloc[j] + usage_type = usage_parameters[0] + lighting_data[usage_type] = usage_parameters[1:6].values.tolist() + plug_loads_data[usage_type] = usage_parameters[8:13].values.tolist() + occupancy_data[usage_type] = usage_parameters[17:20].values.tolist() + ventilation_rate[usage_type] = usage_parameters[20:21].item() + water_heating[usage_type] = usage_parameters[23:24].item() + process_data[usage_type] = usage_parameters[24:26].values.tolist() + schedules_key[usage_type] = usage_parameters[27:28].item() + + return {'lighting': lighting_data, + 'plug loads': plug_loads_data, + 'occupancy': occupancy_data, + 'ventilation rate': ventilation_rate, + 'water heating': water_heating, + 'process': process_data, + 'schedules_key': schedules_key + } + + def names(self, category=None): + """ + Get the catalog elements names + :parm: for usage catalog category filter does nothing as there is only one category (usages) + """ + _names = {'usages': []} + for usage in self._content.usages: + _names['usages'].append(usage.name) + return _names + + def entries(self, category=None): + """ + Get the catalog elements + :parm: for usage catalog category filter does nothing as there is only one category (usages) + """ + return self._content + + def get_entry(self, name): + """ + Get one catalog element by names + :parm: entry name + """ + for usage in self._content.usages: + if usage.name.lower() == name.lower(): + return usage + raise IndexError(f"{name} doesn't exists in the catalog") diff --git a/hub/catalog_factories/usage/usage_helper.py b/hub/catalog_factories/usage/usage_helper.py index 26677505..cd761d63 100644 --- a/hub/catalog_factories/usage/usage_helper.py +++ b/hub/catalog_factories/usage/usage_helper.py @@ -90,6 +90,12 @@ class UsageHelper: 'C-14 Gymnasium': 'C-14 Gymnasium' } + _eilat_schedules_key_to_eilat_schedules = { + 'C-12 Residential': 'C-12 Residential', + 'C-15 Dormitory': 'C-15 Dormitory', + 'C-16 Hotel employees': 'C-16 Hotel employees' + } + @property def nrcan_day_type_to_hub_days(self): """ @@ -138,3 +144,10 @@ class UsageHelper: Get the list of days used in comnet """ return self._comnet_days + + @property + def eilat_schedules_key_to_eilat_schedules(self) -> [str]: + """ + Get a dictionary to convert hub schedules to eilat schedules + """ + return self._eilat_schedules_key_to_eilat_schedules diff --git a/hub/catalog_factories/usage_catalog_factory.py b/hub/catalog_factories/usage_catalog_factory.py index 8e826cad..ce015a35 100644 --- a/hub/catalog_factories/usage_catalog_factory.py +++ b/hub/catalog_factories/usage_catalog_factory.py @@ -10,6 +10,7 @@ from typing import TypeVar from hub.catalog_factories.usage.comnet_catalog import ComnetCatalog from hub.catalog_factories.usage.nrcan_catalog import NrcanCatalog +from hub.catalog_factories.usage.eilat_catalog import EilatCatalog from hub.helpers.utils import validate_import_export_type Catalog = TypeVar('Catalog') @@ -41,6 +42,13 @@ class UsageCatalogFactory: # nrcan retrieves the data directly from github return NrcanCatalog(self._path) + @property + def _eilat(self): + """ + Retrieve Eilat catalog + """ + return EilatCatalog(self._path) + @property def catalog(self) -> Catalog: """ diff --git a/hub/data/usage/eilat_archetypes.xlsx b/hub/data/usage/eilat_archetypes.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..35ad7288803c7a700c4e22713de6486bff4c31aa GIT binary patch literal 15170 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 literal 0 HcmV?d00001 diff --git a/hub/data/usage/eilat_schedules_archetypes.xlsx b/hub/data/usage/eilat_schedules_archetypes.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..2f3a29568c6bdb49852d4beb48a10d77cab6b119 GIT binary patch literal 78312 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 dict: + """ + Get the dictionary + :return: {} + """ + return self._dictionary diff --git a/hub/helpers/data/hub_usage_to_eilat_usage.py b/hub/helpers/data/hub_usage_to_eilat_usage.py new file mode 100644 index 00000000..e4d8a4cc --- /dev/null +++ b/hub/helpers/data/hub_usage_to_eilat_usage.py @@ -0,0 +1,29 @@ +""" +Dictionaries module for hub usage to Eilat usage +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" + +import hub.helpers.constants as cte + + +class HubUsageToEilatUsage: + """ + Hub usage to Eilat usage class + """ + + def __init__(self): + self._dictionary = { + cte.RESIDENTIAL: 'Residential', + cte.HOTEL: 'Hotel employees', + cte.DORMITORY: 'Dormitory' + } + + @property + def dictionary(self) -> dict: + """ + Get the dictionary + :return: {} + """ + return self._dictionary diff --git a/hub/helpers/dictionaries.py b/hub/helpers/dictionaries.py index 5630c484..c2b766ef 100644 --- a/hub/helpers/dictionaries.py +++ b/hub/helpers/dictionaries.py @@ -7,6 +7,7 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca from hub.helpers.data.hft_function_to_hub_function import HftFunctionToHubFunction from hub.helpers.data.montreal_function_to_hub_function import MontrealFunctionToHubFunction +from hub.helpers.data.eilat_function_to_hub_function import EilatFunctionToHubFunction from hub.helpers.data.alkis_function_to_hub_function import AlkisFunctionToHubFunction from hub.helpers.data.pluto_function_to_hub_function import PlutoFunctionToHubFunction from hub.helpers.data.hub_function_to_nrel_construction_function import HubFunctionToNrelConstructionFunction @@ -14,6 +15,7 @@ from hub.helpers.data.hub_function_to_nrcan_construction_function import HubFunc from hub.helpers.data.hub_usage_to_comnet_usage import HubUsageToComnetUsage from hub.helpers.data.hub_usage_to_hft_usage import HubUsageToHftUsage from hub.helpers.data.hub_usage_to_nrcan_usage import HubUsageToNrcanUsage +from hub.helpers.data.hub_usage_to_eilat_usage import HubUsageToEilatUsage from hub.helpers.data.montreal_system_to_hub_energy_generation_system import MontrealSystemToHubEnergyGenerationSystem from hub.helpers.data.montreal_demand_type_to_hub_energy_demand_type import MontrealDemandTypeToHubEnergyDemandType from hub.helpers.data.hub_function_to_montreal_custom_costs_function import HubFunctionToMontrealCustomCostsFunction @@ -48,6 +50,14 @@ class Dictionaries: """ return HubUsageToNrcanUsage().dictionary + @property + def hub_usage_to_eilat_usage(self) -> dict: + """ + Hub usage to Eilat usage, transformation dictionary + :return: dict + """ + return HubUsageToEilatUsage().dictionary + @property def hub_function_to_nrcan_construction_function(self) -> dict: """ @@ -115,3 +125,10 @@ class Dictionaries: :return: dict """ return HubFunctionToMontrealCustomCostsFunction().dictionary + + @property + def eilat_function_to_hub_function(self) -> dict: + """ + Get Eilat's function to hub function, transformation dictionary + """ + return EilatFunctionToHubFunction().dictionary diff --git a/hub/imports/usage/eilat_usage_parameters.py b/hub/imports/usage/eilat_usage_parameters.py new file mode 100644 index 00000000..43fd9066 --- /dev/null +++ b/hub/imports/usage/eilat_usage_parameters.py @@ -0,0 +1,232 @@ +""" +EilatUsageParameters extracts the usage properties from Eilat catalog and assigns to each building +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" +import copy +import logging +import numpy +import hub.helpers.constants as cte +from hub.helpers.dictionaries import Dictionaries +from hub.city_model_structure.building_demand.usage import Usage +from hub.city_model_structure.building_demand.lighting import Lighting +from hub.city_model_structure.building_demand.occupancy import Occupancy +from hub.city_model_structure.building_demand.appliances import Appliances +from hub.city_model_structure.building_demand.thermal_control import ThermalControl +from hub.city_model_structure.building_demand.domestic_hot_water import DomesticHotWater +from hub.city_model_structure.attributes.schedule import Schedule +from hub.city_model_structure.building_demand.internal_gain import InternalGain +from hub.catalog_factories.usage_catalog_factory import UsageCatalogFactory + + +class EilatUsageParameters: + """ + EilatUsageParameters class + """ + def __init__(self, city): + self._city = city + + def enrich_buildings(self): + """ + Returns the city with the usage parameters assigned to the buildings + :return: + """ + city = self._city + eilat_catalog = UsageCatalogFactory('eilat').catalog + for building in city.buildings: + usage_name = Dictionaries().hub_usage_to_eilat_usage[building.function] + try: + archetype_usage = self._search_archetypes(eilat_catalog, usage_name) + except KeyError: + logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name) + continue + + for internal_zone in building.internal_zones: + if internal_zone.area is None: + raise TypeError('Internal zone area not defined, ACH cannot be calculated') + if internal_zone.volume is None: + raise TypeError('Internal zone volume not defined, ACH cannot be calculated') + if internal_zone.area <= 0: + raise TypeError('Internal zone area is zero, ACH cannot be calculated') + volume_per_area = internal_zone.volume / internal_zone.area + usage = Usage() + usage.name = usage_name + self._assign_values(usage, archetype_usage, volume_per_area, building.cold_water_temperature) + usage.percentage = 1 + self._calculate_reduced_values_from_extended_library(usage, archetype_usage) + + internal_zone.usages = [usage] + + @staticmethod + def _search_archetypes(eilat_catalog, usage_name): + eilat_archetypes = eilat_catalog.entries('archetypes').usages + for building_archetype in eilat_archetypes: + if str(usage_name) == str(building_archetype.name): + return building_archetype + raise KeyError('archetype not found') + + @staticmethod + def _assign_values(usage, archetype, volume_per_area, cold_water_temperature): + # Due to the fact that python is not a typed language, the wrong object type is assigned to + # usage.occupancy when writing usage.occupancy = archetype.occupancy. + # Same happens for lighting and appliances. Therefore, this walk around has been done. + usage.mechanical_air_change = archetype.ventilation_rate / volume_per_area \ + * cte.HOUR_TO_SECONDS + _occupancy = Occupancy() + _occupancy.occupancy_density = archetype.occupancy.occupancy_density + _occupancy.sensible_radiative_internal_gain = archetype.occupancy.sensible_radiative_internal_gain + _occupancy.latent_internal_gain = archetype.occupancy.latent_internal_gain + _occupancy.sensible_convective_internal_gain = archetype.occupancy.sensible_convective_internal_gain + _occupancy.occupancy_schedules = archetype.occupancy.schedules + usage.occupancy = _occupancy + _lighting = Lighting() + _lighting.density = archetype.lighting.density + _lighting.convective_fraction = archetype.lighting.convective_fraction + _lighting.radiative_fraction = archetype.lighting.radiative_fraction + _lighting.latent_fraction = archetype.lighting.latent_fraction + _lighting.schedules = archetype.lighting.schedules + usage.lighting = _lighting + _appliances = Appliances() + _appliances.density = archetype.appliances.density + _appliances.convective_fraction = archetype.appliances.convective_fraction + _appliances.radiative_fraction = archetype.appliances.radiative_fraction + _appliances.latent_fraction = archetype.appliances.latent_fraction + _appliances.schedules = archetype.appliances.schedules + usage.appliances = _appliances + _control = ThermalControl() + _control.cooling_set_point_schedules = archetype.thermal_control.cooling_set_point_schedules + _control.heating_set_point_schedules = archetype.thermal_control.heating_set_point_schedules + _control.hvac_availability_schedules = archetype.thermal_control.hvac_availability_schedules + usage.thermal_control = _control + _domestic_hot_water = DomesticHotWater() + _domestic_hot_water.density = archetype.domestic_hot_water.density + _domestic_hot_water.service_temperature = archetype.domestic_hot_water.service_temperature + peak_flow = None + if len(cold_water_temperature) > 0: + cold_temperature = cold_water_temperature[cte.YEAR]['epw'] + peak_flow = 0 + if (archetype.domestic_hot_water.service_temperature - cold_temperature) > 0: + peak_flow = archetype.domestic_hot_water.density / cte.WATER_DENSITY / cte.WATER_HEAT_CAPACITY \ + / (archetype.domestic_hot_water.service_temperature - cold_temperature) + _domestic_hot_water.peak_flow = peak_flow + _domestic_hot_water.schedules = archetype.domestic_hot_water.schedules + usage.domestic_hot_water = _domestic_hot_water + + @staticmethod + def _calculate_reduced_values_from_extended_library(usage, archetype): + number_of_days_per_type = {'WD': 231, 'Fri': 52, 'Sat': 82} + total = 0 + for schedule in archetype.thermal_control.hvac_availability_schedules: + if schedule.day_types[0] == cte.SATURDAY: + for value in schedule.values: + total += value * number_of_days_per_type['Fri'] + elif schedule.day_types[0] == cte.SUNDAY: + for value in schedule.values: + total += value * number_of_days_per_type['Sat'] + else: + for value in schedule.values: + total += value * number_of_days_per_type['WD'] + + usage.hours_day = total / 365 + usage.days_year = 365 + + max_heating_setpoint = cte.MIN_FLOAT + min_heating_setpoint = cte.MAX_FLOAT + + for schedule in archetype.thermal_control.heating_set_point_schedules: + if schedule.values is None: + max_heating_setpoint = None + min_heating_setpoint = None + break + if max(schedule.values) > max_heating_setpoint: + max_heating_setpoint = max(schedule.values) + if min(schedule.values) < min_heating_setpoint: + min_heating_setpoint = min(schedule.values) + + min_cooling_setpoint = cte.MAX_FLOAT + for schedule in archetype.thermal_control.cooling_set_point_schedules: + if schedule.values is None: + min_cooling_setpoint = None + break + if min(schedule.values) < min_cooling_setpoint: + min_cooling_setpoint = min(schedule.values) + + usage.thermal_control.mean_heating_set_point = max_heating_setpoint + usage.thermal_control.heating_set_back = min_heating_setpoint + usage.thermal_control.mean_cooling_set_point = min_cooling_setpoint + + @staticmethod + def _calculate_internal_gains(archetype): + + _days = [cte.MONDAY, cte.TUESDAY, cte.WEDNESDAY, cte.THURSDAY, cte.FRIDAY, cte.SATURDAY, cte.SUNDAY, cte.HOLIDAY] + _number_of_days_per_type = [51, 50, 50, 50, 50, 52, 52, 10] + + _mean_internal_gain = InternalGain() + _mean_internal_gain.type = 'mean_value_of_internal_gains' + _base_schedule = Schedule() + _base_schedule.type = cte.INTERNAL_GAINS + _base_schedule.time_range = cte.DAY + _base_schedule.time_step = cte.HOUR + _base_schedule.data_type = cte.FRACTION + + _latent_heat_gain = archetype.occupancy.latent_internal_gain + _convective_heat_gain = archetype.occupancy.sensible_convective_internal_gain + _radiative_heat_gain = archetype.occupancy.sensible_radiative_internal_gain + _total_heat_gain = _latent_heat_gain + _convective_heat_gain + _radiative_heat_gain + + _schedule_values = numpy.zeros([24, 8]) + _sum = 0 + for day, _schedule in enumerate(archetype.occupancy.schedules): + for v_index, value in enumerate(_schedule.values): + _schedule_values[v_index, day] = value * _total_heat_gain + _sum += value * _total_heat_gain * _number_of_days_per_type[day] + + _total_heat_gain += archetype.lighting.density + archetype.appliances.density + _latent_heat_gain += ( + archetype.lighting.latent_fraction * archetype.lighting.density + archetype.appliances.latent_fraction * + archetype.appliances.density + ) + _radiative_heat_gain = ( + archetype.lighting.radiative_fraction * archetype.lighting.density + archetype.appliances.radiative_fraction * + archetype.appliances.density + ) + _convective_heat_gain = ( + archetype.lighting.convective_fraction * archetype.lighting.density + archetype.appliances.convective_fraction * + archetype.appliances.density + ) + + for day, _schedule in enumerate(archetype.lighting.schedules): + for v_index, value in enumerate(_schedule.values): + _schedule_values[v_index, day] += value * archetype.lighting.density + _sum += value * archetype.lighting.density * _number_of_days_per_type[day] + + for day, _schedule in enumerate(archetype.appliances.schedules): + for v_index, value in enumerate(_schedule.values): + _schedule_values[v_index, day] += value * archetype.appliances.density + _sum += value * archetype.appliances.density * _number_of_days_per_type[day] + + _latent_fraction = 0 + _radiative_fraction = 0 + _convective_fraction = 0 + _average_internal_gain = 0 + if _total_heat_gain != 0: + _latent_fraction = _latent_heat_gain / _total_heat_gain + _radiative_fraction = _radiative_heat_gain / _total_heat_gain + _convective_fraction = _convective_heat_gain / _total_heat_gain + _average_internal_gain = _sum / _total_heat_gain + + _schedules = [] + for day, current_day in enumerate(_days): + _schedule = copy.deepcopy(_base_schedule) + _schedule.day_types = [current_day] + _schedule.values = _schedule_values[:day] + _schedules.append(_schedule) + + _mean_internal_gain.average_internal_gain = _average_internal_gain + _mean_internal_gain.latent_fraction = _latent_fraction + _mean_internal_gain.convective_fraction = _convective_fraction + _mean_internal_gain.radiative_fraction = _radiative_fraction + _mean_internal_gain.schedules = _schedules + + return [_mean_internal_gain] diff --git a/hub/imports/usage_factory.py b/hub/imports/usage_factory.py index 138a7e9f..8af57364 100644 --- a/hub/imports/usage_factory.py +++ b/hub/imports/usage_factory.py @@ -9,6 +9,7 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord from hub.helpers.utils import validate_import_export_type from hub.imports.usage.comnet_usage_parameters import ComnetUsageParameters from hub.imports.usage.nrcan_usage_parameters import NrcanUsageParameters +from hub.imports.usage.eilat_usage_parameters import EilatUsageParameters class UsageFactory: @@ -38,9 +39,20 @@ class UsageFactory: for building in self._city.buildings: building.level_of_detail.usage = 2 + def _eilat(self): + """ + Enrich the city with Eilat usage library + """ + EilatUsageParameters(self._city).enrich_buildings() + self._city.level_of_detail.usage = 2 + for building in self._city.buildings: + building.level_of_detail.usage = 2 + def enrich(self): """ Enrich the city given to the class using the usage factory given handler :return: None """ getattr(self, self._handler, lambda: None)() + + From ae157a924398a9a829a977210c5f4f10e7534a43 Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Wed, 12 Jul 2023 11:36:35 -0400 Subject: [PATCH 4/6] added eilat construction to catalog and imports and erased unused city_to_climate_reference_city in construction_helper.py --- .../construction/eilat_catalog.py | 232 ++ .../construction_catalog_factory.py | 10 +- hub/data/construction/eilat_archetypes.json | 106 + .../construction/eilat_constructions.json | 3501 +++++++++++++++++ ...function_to_eilat_construction_function.py | 28 + hub/helpers/dictionaries.py | 11 +- .../construction/eilat_physics_parameters.py | 213 + .../helpers/construction_helper.py | 40 +- .../construction/nrcan_physics_parameters.py | 2 +- .../construction/nrel_physics_parameters.py | 2 +- hub/imports/construction_factory.py | 10 + tests/test_construction_catalog.py | 20 + tests/test_construction_factory.py | 44 + tests/tests_data/eilat.geojson | 177 + tests/tests_data/levis.geojson | 73 + 15 files changed, 4445 insertions(+), 24 deletions(-) create mode 100644 hub/catalog_factories/construction/eilat_catalog.py create mode 100644 hub/data/construction/eilat_archetypes.json create mode 100644 hub/data/construction/eilat_constructions.json create mode 100644 hub/helpers/data/hub_function_to_eilat_construction_function.py create mode 100644 hub/imports/construction/eilat_physics_parameters.py create mode 100644 tests/tests_data/eilat.geojson create mode 100644 tests/tests_data/levis.geojson diff --git a/hub/catalog_factories/construction/eilat_catalog.py b/hub/catalog_factories/construction/eilat_catalog.py new file mode 100644 index 00000000..e33f5960 --- /dev/null +++ b/hub/catalog_factories/construction/eilat_catalog.py @@ -0,0 +1,232 @@ +""" +Eilat construction catalog +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" + +import json +from pathlib import Path +from hub.catalog_factories.catalog import Catalog +from hub.catalog_factories.data_models.construction.content import Content +from hub.catalog_factories.construction.construction_helper import ConstructionHelper +from hub.catalog_factories.data_models.construction.construction import Construction +from hub.catalog_factories.data_models.construction.archetype import Archetype +from hub.catalog_factories.data_models.construction.window import Window +from hub.catalog_factories.data_models.construction.material import Material +from hub.catalog_factories.data_models.construction.layer import Layer + + +class EilatCatalog(Catalog): + """ + Eilat catalog class + """ + def __init__(self, path): + _path_archetypes = Path(path / 'eilat_archetypes.json').resolve() + _path_constructions = (path / 'eilat_constructions.json').resolve() + with open(_path_archetypes, 'r', encoding='utf-8') as file: + self._archetypes = json.load(file) + with open(_path_constructions, 'r', encoding='utf-8') as file: + self._constructions = json.load(file) + + self._catalog_windows = self._load_windows() + self._catalog_materials = self._load_materials() + self._catalog_constructions = self._load_constructions() + self._catalog_archetypes = self._load_archetypes() + + # store the full catalog data model in self._content + self._content = Content(self._catalog_archetypes, + self._catalog_constructions, + self._catalog_materials, + self._catalog_windows) + + def _load_windows(self): + _catalog_windows = [] + windows = self._constructions['transparent_surfaces'] + for window in windows: + name = list(window.keys())[0] + window_id = name + g_value = window[name]['shgc'] + window_type = window[name]['type'] + frame_ratio = window[name]['frame_ratio'] + overall_u_value = window[name]['u_value'] + _catalog_windows.append(Window(window_id, frame_ratio, g_value, overall_u_value, name, window_type)) + return _catalog_windows + + def _load_materials(self): + _catalog_materials = [] + materials = self._constructions['materials'] + for material in materials: + name = list(material.keys())[0] + material_id = name + no_mass = material[name]['no_mass'] + thermal_resistance = None + conductivity = None + density = None + specific_heat = None + solar_absorptance = None + thermal_absorptance = None + visible_absorptance = None + if no_mass: + thermal_resistance = material[name]['thermal_resistance'] + else: + solar_absorptance = material[name]['solar_absorptance'] + thermal_absorptance = str(1 - float(material[name]['thermal_emittance'])) + visible_absorptance = material[name]['visible_absorptance'] + conductivity = material[name]['conductivity'] + density = material[name]['density'] + specific_heat = material[name]['specific_heat'] + _material = Material(material_id, + name, + solar_absorptance, + thermal_absorptance, + visible_absorptance, + no_mass, + thermal_resistance, + conductivity, + density, + specific_heat) + _catalog_materials.append(_material) + return _catalog_materials + + def _load_constructions(self): + _catalog_constructions = [] + constructions = self._constructions['opaque_surfaces'] + for construction in constructions: + name = list(construction.keys())[0] + construction_id = name + construction_type = ConstructionHelper().nrcan_surfaces_types_to_hub_types[construction[name]['type']] + layers = [] + for layer in construction[name]['layers']: + layer_id = layer + layer_name = layer + material_id = layer + thickness = construction[name]['layers'][layer] + for material in self._catalog_materials: + if str(material_id) == str(material.id): + layers.append(Layer(layer_id, layer_name, material, thickness)) + break + _catalog_constructions.append(Construction(construction_id, construction_type, name, layers)) + return _catalog_constructions + + def _load_archetypes(self): + _catalog_archetypes = [] + archetypes = self._archetypes['archetypes'] + for archetype in archetypes: + archetype_id = f'{archetype["function"]}_{archetype["period_of_construction"]}_{archetype["climate_zone"]}' + function = archetype['function'] + name = archetype_id + climate_zone = archetype['climate_zone'] + construction_period = archetype['period_of_construction'] + average_storey_height = archetype['average_storey_height'] + extra_loses_due_to_thermal_bridges = archetype['extra_loses_due_thermal_bridges'] + infiltration_rate_for_ventilation_system_off = archetype['infiltration_rate_for_ventilation_system_off'] + infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on'] + + archetype_constructions = [] + for archetype_construction in archetype['constructions']: + archetype_construction_type = ConstructionHelper().nrcan_surfaces_types_to_hub_types[archetype_construction] + archetype_construction_name = archetype['constructions'][archetype_construction]['opaque_surface_name'] + for construction in self._catalog_constructions: + if archetype_construction_type == construction.type and construction.name == archetype_construction_name: + _construction = None + _window = None + _window_ratio = None + if 'transparent_surface_name' in archetype['constructions'][archetype_construction].keys(): + _window_ratio = archetype['constructions'][archetype_construction]['transparent_ratio'] + _window_id = archetype['constructions'][archetype_construction]['transparent_surface_name'] + for window in self._catalog_windows: + if _window_id == window.id: + _window = window + break + _construction = Construction(construction.id, + construction.type, + construction.name, + construction.layers, + _window_ratio, + _window) + archetype_constructions.append(_construction) + break + + _catalog_archetypes.append(Archetype(archetype_id, + name, + function, + climate_zone, + construction_period, + archetype_constructions, + average_storey_height, + None, + extra_loses_due_to_thermal_bridges, + None, + infiltration_rate_for_ventilation_system_off, + infiltration_rate_for_ventilation_system_on)) + return _catalog_archetypes + + def names(self, category=None): + """ + Get the catalog elements names + :parm: optional category filter + """ + if category is None: + _names = {'archetypes': [], 'constructions': [], 'materials': [], 'windows': []} + for archetype in self._content.archetypes: + _names['archetypes'].append(archetype.name) + for construction in self._content.constructions: + _names['constructions'].append(construction.name) + for material in self._content.materials: + _names['materials'].append(material.name) + for window in self._content.windows: + _names['windows'].append(window.name) + else: + _names = {category: []} + if category.lower() == 'archetypes': + for archetype in self._content.archetypes: + _names[category].append(archetype.name) + elif category.lower() == 'constructions': + for construction in self._content.constructions: + _names[category].append(construction.name) + elif category.lower() == 'materials': + for material in self._content.materials: + _names[category].append(material.name) + elif category.lower() == 'windows': + for window in self._content.windows: + _names[category].append(window.name) + else: + raise ValueError(f'Unknown category [{category}]') + return _names + + def entries(self, category=None): + """ + Get the catalog elements + :parm: optional category filter + """ + if category is None: + return self._content + if category.lower() == 'archetypes': + return self._content.archetypes + if category.lower() == 'constructions': + return self._content.constructions + if category.lower() == 'materials': + return self._content.materials + if category.lower() == 'windows': + return self._content.windows + raise ValueError(f'Unknown category [{category}]') + + def get_entry(self, name): + """ + Get one catalog element by names + :parm: entry name + """ + for entry in self._content.archetypes: + if entry.name.lower() == name.lower(): + return entry + for entry in self._content.constructions: + if entry.name.lower() == name.lower(): + return entry + for entry in self._content.materials: + if entry.name.lower() == name.lower(): + return entry + for entry in self._content.windows: + if entry.name.lower() == name.lower(): + return entry + raise IndexError(f"{name} doesn't exists in the catalog") diff --git a/hub/catalog_factories/construction_catalog_factory.py b/hub/catalog_factories/construction_catalog_factory.py index a41e0aed..b1c8a45b 100644 --- a/hub/catalog_factories/construction_catalog_factory.py +++ b/hub/catalog_factories/construction_catalog_factory.py @@ -10,6 +10,7 @@ from typing import TypeVar from hub.catalog_factories.construction.nrcan_catalog import NrcanCatalog from hub.catalog_factories.construction.nrel_catalog import NrelCatalog +from hub.catalog_factories.construction.eilat_catalog import EilatCatalog from hub.helpers.utils import validate_import_export_type Catalog = TypeVar('Catalog') @@ -36,10 +37,17 @@ class ConstructionCatalogFactory: @property def _nrcan(self): """ - Retrieve NREL catalog + Retrieve NRCAN catalog """ return NrcanCatalog(self._path) + @property + def _eilat(self): + """ + Retrieve Eilat catalog + """ + return EilatCatalog(self._path) + @property def catalog(self) -> Catalog: """ diff --git a/hub/data/construction/eilat_archetypes.json b/hub/data/construction/eilat_archetypes.json new file mode 100644 index 00000000..35c8a26c --- /dev/null +++ b/hub/data/construction/eilat_archetypes.json @@ -0,0 +1,106 @@ +{ + "archetypes": [ + { + "function": "Residential", + "period_of_construction": "1000_1980", + "climate_zone": "BWh", + "average_storey_height": 1, + "extra_loses_due_thermal_bridges": 0.1, + "infiltration_rate_for_ventilation_system_on": 1, + "infiltration_rate_for_ventilation_system_off": 1, + "constructions": { + "OutdoorsWall": { + "opaque_surface_name": "residential_1000_1980_BWh", + "transparent_surface_name": "Window_residential_1000_1980_BWh", + "transparent_ratio": { + "north": "18.0", + "east": "0.0", + "south": "9.0", + "west": "0.0" + } + }, + "OutdoorsRoofCeiling": { + "opaque_surface_name": "residential_1000_1980_BWh", + "transparent_surface_name": null, + "transparent_ratio": { + "north": null, + "east": null, + "south": null, + "west": null + } + }, + "GroundFloor": { + "opaque_surface_name": "residential_1000_1980_BWh" + } + } + }, + { + "function": "Dormitory", + "period_of_construction": "2011_3000", + "climate_zone": "BWh", + "average_storey_height": 1, + "extra_loses_due_thermal_bridges": 0.1, + "infiltration_rate_for_ventilation_system_on": 1, + "infiltration_rate_for_ventilation_system_off": 1, + "constructions": { + "OutdoorsWall": { + "opaque_surface_name": "dormitory_2011_3000_BWh", + "transparent_surface_name": "Window_dormitory_2011_3000_BWh", + "transparent_ratio": { + "north": "14.0", + "east": "6.0", + "south": "14.0", + "west": "6.0" + } + }, + "OutdoorsRoofCeiling": { + "opaque_surface_name": "dormitory_2011_3000_BWh", + "transparent_surface_name": null, + "transparent_ratio": { + "north": null, + "east": null, + "south": null, + "west": null + } + }, + "GroundFloor": { + "opaque_surface_name": "dormitory_2011_3000_BWh" + } + } + }, + { + "function": "Hotel_employees", + "period_of_construction": "1981_2010", + "climate_zone": "BWh", + "average_storey_height": 1, + "extra_loses_due_thermal_bridges": 0.09, + "infiltration_rate_for_ventilation_system_on": 1, + "infiltration_rate_for_ventilation_system_off": 1, + "constructions": { + "OutdoorsWall": { + "opaque_surface_name": "hotel_employees_1981_2010_BWh", + "transparent_surface_name": "Window_hotel_employees_1981_2010_BWh", + "transparent_ratio": { + "north": "5.0", + "east": "21.0", + "south": "5.0", + "west": "26.0" + } + }, + "OutdoorsRoofCeiling": { + "opaque_surface_name": "hotel_employees_1981_2010_BWh", + "transparent_surface_name": null, + "transparent_ratio": { + "north": null, + "east": null, + "south": null, + "west": null + } + }, + "GroundFloor": { + "opaque_surface_name": "hotel_employees_1981_2010_BWh" + } + } + } + ] +} \ No newline at end of file diff --git a/hub/data/construction/eilat_constructions.json b/hub/data/construction/eilat_constructions.json new file mode 100644 index 00000000..c0bd4c1c --- /dev/null +++ b/hub/data/construction/eilat_constructions.json @@ -0,0 +1,3501 @@ +{ + "opaque_surfaces": [ + { + "residential_1000_1980_BWh": { + "type": "OutdoorsWall", + "layers": { + "Concrete Block (Medium)": 0.2, + "Gypsum Plastering": 0.02 + } + } + }, + { + "residential_1000_1980_BWh": { + "type": "OutdoorsRoofCeiling", + "layers": { + "Cast Concrete": 0.2, + "Plasterboard": 0.005 + } + } + }, + { + "residential_1000_1980_BWh": { + "type": "GroundFloor", + "layers": { + "Cast Concrete": 0.2 + } + } + }, + { + "dormitory_2011_3000_BWh": { + "type": "OutdoorsWall", + "layers": { + "Concrete Block (Medium)": 0.2, + "XPS Extruded Polystyrene- CO2 Blowing": 0.05, + "Cast Concrete": 0.05, + "Gypsum Plastering": 0.05 + } + } + }, + { + "dormitory_2011_3000_BWh": { + "type": "OutdoorsRoofCeiling", + "layers": { + "Cast Concrete": 0.2, + "XPS Extruded Polystyrene- CO2 Blowing": 0.06, + "Concrete Slopes": 0.05, + "Plasterboard": 0.005 + } + } + }, + { + "dormitory_2011_3000_BWh": { + "type": "GroundFloor", + "layers": { + "Cast Concrete": 0.1 + } + } + } +, + { + "hotel_employees_1981_2010_BWh": { + "type": "OutdoorsWall", + "layers": { + "Concrete Block (Medium)": 0.2, + "XPS Extruded Polystyrene- CO2 Blowing": 0.02, + "Gypsum Plastering": 0.02 + } + } + }, + { + "hotel_employees_1981_2010_BWh": { + "type": "OutdoorsRoofCeiling", + "layers": { + "Cast Concrete": 0.2, + "XPS Extruded Polystyrene- CO2 Blowing": 0.02, + "Concrete Slopes": 0.05, + "Plasterboard": 0.005 + } + } + }, + { + "hotel_employees_1981_2010_BWh": { + "type": "GroundFloor", + "layers": { + "Cast Concrete": 0.1 + } + } + } + ], + "transparent_surfaces": [ + { + "Window_residential_1000_1980_BWh": { + "shgc": 0.49, + "type": "Window", + "frame_ratio": 0, + "u_value": 10.09 + } + }, + { + "Window_dormitory_2011_3000_BWh": { + "shgc": 0.35, + "type": "Window", + "frame_ratio": 0, + "u_value": 2.38 + } + }, + { + "Window_hotel_employees_1981_2010_BWh": { + "shgc": 0.35, + "type": "Window", + "frame_ratio": 0, + "u_value": 2.38 + } + } + ], + "materials": [ + { + "Urea Formaldehyde Foam": { + "no_mass": false, + "conductivity": 0.04, + "density": 10, + "specific_heat": 1400, + "thermal_emittance": 0.9, + "solar_absorptance": 0.6, + "visible_absorptance": 0.6 + } + }, + { + "Cast Concrete": { + "no_mass": false, + "conductivity": 1.13, + "density": 2000, + "specific_heat": 1000, + "thermal_emittance": 0.9, + "solar_absorptance": 0.6, + "visible_absorptance": 0.6 + } + }, + { + "Concrete Slopes": { + "no_mass": false, + "conductivity": 1.13, + "density": 2000, + "specific_heat": 1000, + "thermal_emittance": 0.9, + "solar_absorptance": 0.6, + "visible_absorptance": 0.6 + } + }, + { + "Floor/Roof Screed": { + "no_mass": false, + "conductivity": 0.41, + "density": 1200, + "specific_heat": 840, + "thermal_emittance": 0.9, + "solar_absorptance": 0.73, + "visible_absorptance": 0.73 + } + }, + { + "Timber Flooring": { + "no_mass": false, + "conductivity": 0.14, + "density": 650, + "specific_heat": 1200, + "thermal_emittance": 0.9, + "solar_absorptance": 0.78, + "visible_absorptance": 0.78 + } + }, + { + "Asphalt 1": { + "no_mass": false, + "conductivity": 0.7, + "density": 2100, + "specific_heat": 1000, + "thermal_emittance": 0.9, + "solar_absorptance": 0.85, + "visible_absorptance": 0.9 + } + }, + { + "MW Glass Wool (rolls)": { + "no_mass": false, + "conductivity": 0.04, + "density": 12, + "specific_heat": 840, + "thermal_emittance": 0.9, + "solar_absorptance": 0.6, + "visible_absorptance": 0.6 + } + }, + { + "Plasterboard": { + "no_mass": false, + "conductivity": 0.25, + "density": 2800, + "specific_heat": 896, + "thermal_emittance": 0.9, + "solar_absorptance": 0.5, + "visible_absorptance": 0.5 + } + }, + { + "Brickwork Outer": { + "no_mass": false, + "conductivity": 0.84, + "density": 1700, + "specific_heat": 800, + "thermal_emittance": 0.9, + "solar_absorptance": 0.7, + "visible_absorptance": 0.7 + } + }, + { + "XPS Extruded Polystyrene- CO2 Blowing": { + "no_mass": false, + "conductivity": 0.034, + "density": 35, + "specific_heat": 1400, + "thermal_emittance": 0.9, + "solar_absorptance": 0.6, + "visible_absorptance": 0.6 + } + }, + { + "Concrete Block (Medium)": { + "no_mass": false, + "conductivity": 0.51, + "density": 1400, + "specific_heat": 1000, + "thermal_emittance": 0.9, + "solar_absorptance": 0.6, + "visible_absorptance": 0.6 + } + }, + { + "Gypsum Plastering": { + "no_mass": false, + "conductivity": 0.4, + "density": 1000, + "specific_heat": 1000, + "thermal_emittance": 0.9, + "solar_absorptance": 0.5, + "visible_absorptance": 0.5 + } + }, + { + "Lightweight Metallic Cladding": { + "no_mass": false, + "conductivity": 0.29, + "density": 1250, + "specific_heat": 1000, + "thermal_emittance": 0.9, + "solar_absorptance": 0.4, + "visible_absorptance": 0.4 + } + }, + { + "virtual_no_mass_0": { + "no_mass": true, + "thermal_resistance": 0.6584101668836548 + } + }, + { + "virtual_no_mass_1": { + "no_mass": true, + "thermal_resistance": 1.4385352223534045 + } + }, + { + "virtual_no_mass_2": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_3": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_4": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_5": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_6": { + "no_mass": true, + "thermal_resistance": 0.7634850606909431 + } + }, + { + "virtual_no_mass_7": { + "no_mass": true, + "thermal_resistance": 2.0620926640926642 + } + }, + { + "virtual_no_mass_8": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_9": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_10": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_11": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_12": { + "no_mass": true, + "thermal_resistance": 0.8674407782554092 + } + }, + { + "virtual_no_mass_13": { + "no_mass": true, + "thermal_resistance": 2.4290326377742106 + } + }, + { + "virtual_no_mass_14": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_15": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_16": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_17": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_18": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_19": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_20": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_21": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_22": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_23": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_24": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_25": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_26": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_27": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_28": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_29": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_30": { + "no_mass": true, + "thermal_resistance": 1.0608246538051842 + } + }, + { + "virtual_no_mass_31": { + "no_mass": true, + "thermal_resistance": 4.365532467532468 + } + }, + { + "virtual_no_mass_32": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_33": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_34": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_35": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_36": { + "no_mass": true, + "thermal_resistance": 0.6584101668836548 + } + }, + { + "virtual_no_mass_37": { + "no_mass": true, + "thermal_resistance": 1.4385352223534045 + } + }, + { + "virtual_no_mass_38": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_39": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_40": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_41": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_42": { + "no_mass": true, + "thermal_resistance": 0.7634850606909431 + } + }, + { + "virtual_no_mass_43": { + "no_mass": true, + "thermal_resistance": 2.0620926640926642 + } + }, + { + "virtual_no_mass_44": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_45": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_46": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_47": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_48": { + "no_mass": true, + "thermal_resistance": 0.8674407782554092 + } + }, + { + "virtual_no_mass_49": { + "no_mass": true, + "thermal_resistance": 2.4290326377742106 + } + }, + { + "virtual_no_mass_50": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_51": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_52": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_53": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_54": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_55": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_56": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_57": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_58": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_59": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_60": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_61": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_62": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_63": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_64": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_65": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_66": { + "no_mass": true, + "thermal_resistance": 1.0608246538051842 + } + }, + { + "virtual_no_mass_67": { + "no_mass": true, + "thermal_resistance": 4.365532467532468 + } + }, + { + "virtual_no_mass_68": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_69": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_70": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_71": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_72": { + "no_mass": true, + "thermal_resistance": 0.6584101668836548 + } + }, + { + "virtual_no_mass_73": { + "no_mass": true, + "thermal_resistance": 1.4385352223534045 + } + }, + { + "virtual_no_mass_74": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_75": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_76": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_77": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_78": { + "no_mass": true, + "thermal_resistance": 0.7634850606909431 + } + }, + { + "virtual_no_mass_79": { + "no_mass": true, + "thermal_resistance": 2.0620926640926642 + } + }, + { + "virtual_no_mass_80": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_81": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_82": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_83": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_84": { + "no_mass": true, + "thermal_resistance": 0.8674407782554092 + } + }, + { + "virtual_no_mass_85": { + "no_mass": true, + "thermal_resistance": 2.4290326377742106 + } + }, + { + "virtual_no_mass_86": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_87": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_88": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_89": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_90": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_91": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_92": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_93": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_94": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_95": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_96": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_97": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_98": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_99": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_100": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_101": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_102": { + "no_mass": true, + "thermal_resistance": 1.0608246538051842 + } + }, + { + "virtual_no_mass_103": { + "no_mass": true, + "thermal_resistance": 4.365532467532468 + } + }, + { + "virtual_no_mass_104": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_105": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_106": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_107": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_108": { + "no_mass": true, + "thermal_resistance": 0.6584101668836548 + } + }, + { + "virtual_no_mass_109": { + "no_mass": true, + "thermal_resistance": 1.4385352223534045 + } + }, + { + "virtual_no_mass_110": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_111": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_112": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_113": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_114": { + "no_mass": true, + "thermal_resistance": 0.7634850606909431 + } + }, + { + "virtual_no_mass_115": { + "no_mass": true, + "thermal_resistance": 2.0620926640926642 + } + }, + { + "virtual_no_mass_116": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_117": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_118": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_119": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_120": { + "no_mass": true, + "thermal_resistance": 0.8674407782554092 + } + }, + { + "virtual_no_mass_121": { + "no_mass": true, + "thermal_resistance": 2.4290326377742106 + } + }, + { + "virtual_no_mass_122": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_123": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_124": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_125": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_126": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_127": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_128": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_129": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_130": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_131": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_132": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_133": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_134": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_135": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_136": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_137": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_138": { + "no_mass": true, + "thermal_resistance": 1.0608246538051842 + } + }, + { + "virtual_no_mass_139": { + "no_mass": true, + "thermal_resistance": 4.365532467532468 + } + }, + { + "virtual_no_mass_140": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_141": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_142": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_143": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_144": { + "no_mass": true, + "thermal_resistance": 0.6584101668836548 + } + }, + { + "virtual_no_mass_145": { + "no_mass": true, + "thermal_resistance": 1.4385352223534045 + } + }, + { + "virtual_no_mass_146": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_147": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_148": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_149": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_150": { + "no_mass": true, + "thermal_resistance": 0.7634850606909431 + } + }, + { + "virtual_no_mass_151": { + "no_mass": true, + "thermal_resistance": 2.0620926640926642 + } + }, + { + "virtual_no_mass_152": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_153": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_154": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_155": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_156": { + "no_mass": true, + "thermal_resistance": 0.8674407782554092 + } + }, + { + "virtual_no_mass_157": { + "no_mass": true, + "thermal_resistance": 2.4290326377742106 + } + }, + { + "virtual_no_mass_158": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_159": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_160": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_161": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_162": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_163": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_164": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_165": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_166": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_167": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_168": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_169": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_170": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_171": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_172": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_173": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_174": { + "no_mass": true, + "thermal_resistance": 1.0608246538051842 + } + }, + { + "virtual_no_mass_175": { + "no_mass": true, + "thermal_resistance": 4.365532467532468 + } + }, + { + "virtual_no_mass_176": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_177": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_178": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_179": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_180": { + "no_mass": true, + "thermal_resistance": 0.6584101668836548 + } + }, + { + "virtual_no_mass_181": { + "no_mass": true, + "thermal_resistance": 1.4385352223534045 + } + }, + { + "virtual_no_mass_182": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_183": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_184": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_185": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_186": { + "no_mass": true, + "thermal_resistance": 0.7634850606909431 + } + }, + { + "virtual_no_mass_187": { + "no_mass": true, + "thermal_resistance": 2.0620926640926642 + } + }, + { + "virtual_no_mass_188": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_189": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_190": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_191": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_192": { + "no_mass": true, + "thermal_resistance": 0.8674407782554092 + } + }, + { + "virtual_no_mass_193": { + "no_mass": true, + "thermal_resistance": 2.4290326377742106 + } + }, + { + "virtual_no_mass_194": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_195": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_196": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_197": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_198": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_199": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_200": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_201": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_202": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_203": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_204": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_205": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_206": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_207": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_208": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_209": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_210": { + "no_mass": true, + "thermal_resistance": 1.0608246538051842 + } + }, + { + "virtual_no_mass_211": { + "no_mass": true, + "thermal_resistance": 4.365532467532468 + } + }, + { + "virtual_no_mass_212": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_213": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_214": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_215": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_216": { + "no_mass": true, + "thermal_resistance": 0.6584101668836548 + } + }, + { + "virtual_no_mass_217": { + "no_mass": true, + "thermal_resistance": 1.4385352223534045 + } + }, + { + "virtual_no_mass_218": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_219": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_220": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_221": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_222": { + "no_mass": true, + "thermal_resistance": 0.7634850606909431 + } + }, + { + "virtual_no_mass_223": { + "no_mass": true, + "thermal_resistance": 2.0620926640926642 + } + }, + { + "virtual_no_mass_224": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_225": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_226": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_227": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_228": { + "no_mass": true, + "thermal_resistance": 0.8674407782554092 + } + }, + { + "virtual_no_mass_229": { + "no_mass": true, + "thermal_resistance": 2.4290326377742106 + } + }, + { + "virtual_no_mass_230": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_231": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_232": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_233": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_234": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_235": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_236": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_237": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_238": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_239": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_240": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_241": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_242": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_243": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_244": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_245": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_246": { + "no_mass": true, + "thermal_resistance": 1.0608246538051842 + } + }, + { + "virtual_no_mass_247": { + "no_mass": true, + "thermal_resistance": 4.365532467532468 + } + }, + { + "virtual_no_mass_248": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_249": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_250": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_251": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_252": { + "no_mass": true, + "thermal_resistance": 0.6584101668836548 + } + }, + { + "virtual_no_mass_253": { + "no_mass": true, + "thermal_resistance": 1.4385352223534045 + } + }, + { + "virtual_no_mass_254": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_255": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_256": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_257": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_258": { + "no_mass": true, + "thermal_resistance": 0.7634850606909431 + } + }, + { + "virtual_no_mass_259": { + "no_mass": true, + "thermal_resistance": 2.0620926640926642 + } + }, + { + "virtual_no_mass_260": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_261": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_262": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_263": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_264": { + "no_mass": true, + "thermal_resistance": 0.8674407782554092 + } + }, + { + "virtual_no_mass_265": { + "no_mass": true, + "thermal_resistance": 2.4290326377742106 + } + }, + { + "virtual_no_mass_266": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_267": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_268": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_269": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_270": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_271": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_272": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_273": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_274": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_275": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_276": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_277": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_278": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_279": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_280": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_281": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_282": { + "no_mass": true, + "thermal_resistance": 1.0608246538051842 + } + }, + { + "virtual_no_mass_283": { + "no_mass": true, + "thermal_resistance": 4.365532467532468 + } + }, + { + "virtual_no_mass_284": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_285": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_286": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_287": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_288": { + "no_mass": true, + "thermal_resistance": 0.6584101668836548 + } + }, + { + "virtual_no_mass_289": { + "no_mass": true, + "thermal_resistance": 1.4385352223534045 + } + }, + { + "virtual_no_mass_290": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_291": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_292": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_293": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_294": { + "no_mass": true, + "thermal_resistance": 0.7634850606909431 + } + }, + { + "virtual_no_mass_295": { + "no_mass": true, + "thermal_resistance": 2.0620926640926642 + } + }, + { + "virtual_no_mass_296": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_297": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_298": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_299": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_300": { + "no_mass": true, + "thermal_resistance": 0.8674407782554092 + } + }, + { + "virtual_no_mass_301": { + "no_mass": true, + "thermal_resistance": 2.4290326377742106 + } + }, + { + "virtual_no_mass_302": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_303": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_304": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_305": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_306": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_307": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_308": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_309": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_310": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_311": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_312": { + "no_mass": true, + "thermal_resistance": 0.9477107371445987 + } + }, + { + "virtual_no_mass_313": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_314": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_315": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_316": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_317": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_318": { + "no_mass": true, + "thermal_resistance": 1.0608246538051842 + } + }, + { + "virtual_no_mass_319": { + "no_mass": true, + "thermal_resistance": 4.365532467532468 + } + }, + { + "virtual_no_mass_320": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_321": { + "no_mass": true, + "thermal_resistance": 1.1273002032671475 + } + }, + { + "virtual_no_mass_322": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_323": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_324": { + "no_mass": true, + "thermal_resistance": 1.7073737251092764 + } + }, + { + "virtual_no_mass_325": { + "no_mass": true, + "thermal_resistance": 1.4385352223534045 + } + }, + { + "virtual_no_mass_326": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_327": { + "no_mass": true, + "thermal_resistance": 1.5969753613292363 + } + }, + { + "virtual_no_mass_328": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_329": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_330": { + "no_mass": true, + "thermal_resistance": 1.413086004651633 + } + }, + { + "virtual_no_mass_331": { + "no_mass": true, + "thermal_resistance": 2.0620926640926642 + } + }, + { + "virtual_no_mass_332": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_333": { + "no_mass": true, + "thermal_resistance": 1.7749639097270375 + } + }, + { + "virtual_no_mass_334": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_335": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_336": { + "no_mass": true, + "thermal_resistance": 2.294228185203173 + } + }, + { + "virtual_no_mass_337": { + "no_mass": true, + "thermal_resistance": 2.4290326377742106 + } + }, + { + "virtual_no_mass_338": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_339": { + "no_mass": true, + "thermal_resistance": 2.125459582300353 + } + }, + { + "virtual_no_mass_340": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_341": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_342": { + "no_mass": true, + "thermal_resistance": 2.8369837552322106 + } + }, + { + "virtual_no_mass_343": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_344": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_345": { + "no_mass": true, + "thermal_resistance": 2.2997515212981745 + } + }, + { + "virtual_no_mass_346": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_347": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_348": { + "no_mass": true, + "thermal_resistance": 2.8369837552322106 + } + }, + { + "virtual_no_mass_349": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_350": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_351": { + "no_mass": true, + "thermal_resistance": 2.2997515212981745 + } + }, + { + "virtual_no_mass_352": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_353": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_354": { + "no_mass": true, + "thermal_resistance": 3.692128696887511 + } + }, + { + "virtual_no_mass_355": { + "no_mass": true, + "thermal_resistance": 4.365532467532468 + } + }, + { + "virtual_no_mass_356": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_357": { + "no_mass": true, + "thermal_resistance": 2.8286547252310448 + } + }, + { + "virtual_no_mass_358": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_359": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_360": { + "no_mass": true, + "thermal_resistance": 1.7073737251092764 + } + }, + { + "virtual_no_mass_361": { + "no_mass": true, + "thermal_resistance": 1.4385352223534045 + } + }, + { + "virtual_no_mass_362": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_363": { + "no_mass": true, + "thermal_resistance": 1.5969753613292363 + } + }, + { + "virtual_no_mass_364": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_365": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_366": { + "no_mass": true, + "thermal_resistance": 1.413086004651633 + } + }, + { + "virtual_no_mass_367": { + "no_mass": true, + "thermal_resistance": 2.0620926640926642 + } + }, + { + "virtual_no_mass_368": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_369": { + "no_mass": true, + "thermal_resistance": 1.7749639097270375 + } + }, + { + "virtual_no_mass_370": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_371": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_372": { + "no_mass": true, + "thermal_resistance": 2.294228185203173 + } + }, + { + "virtual_no_mass_373": { + "no_mass": true, + "thermal_resistance": 2.4290326377742106 + } + }, + { + "virtual_no_mass_374": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_375": { + "no_mass": true, + "thermal_resistance": 2.125459582300353 + } + }, + { + "virtual_no_mass_376": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_377": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_378": { + "no_mass": true, + "thermal_resistance": 2.8369837552322106 + } + }, + { + "virtual_no_mass_379": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_380": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_381": { + "no_mass": true, + "thermal_resistance": 2.2997515212981745 + } + }, + { + "virtual_no_mass_382": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_383": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_384": { + "no_mass": true, + "thermal_resistance": 2.8369837552322106 + } + }, + { + "virtual_no_mass_385": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_386": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_387": { + "no_mass": true, + "thermal_resistance": 2.2997515212981745 + } + }, + { + "virtual_no_mass_388": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_389": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_390": { + "no_mass": true, + "thermal_resistance": 3.692128696887511 + } + }, + { + "virtual_no_mass_391": { + "no_mass": true, + "thermal_resistance": 4.365532467532468 + } + }, + { + "virtual_no_mass_392": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_393": { + "no_mass": true, + "thermal_resistance": 2.8286547252310448 + } + }, + { + "virtual_no_mass_394": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_395": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_396": { + "no_mass": true, + "thermal_resistance": 1.7073737251092764 + } + }, + { + "virtual_no_mass_397": { + "no_mass": true, + "thermal_resistance": 1.4385352223534045 + } + }, + { + "virtual_no_mass_398": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_399": { + "no_mass": true, + "thermal_resistance": 1.5969753613292363 + } + }, + { + "virtual_no_mass_400": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_401": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_402": { + "no_mass": true, + "thermal_resistance": 1.413086004651633 + } + }, + { + "virtual_no_mass_403": { + "no_mass": true, + "thermal_resistance": 2.0620926640926642 + } + }, + { + "virtual_no_mass_404": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_405": { + "no_mass": true, + "thermal_resistance": 1.7749639097270375 + } + }, + { + "virtual_no_mass_406": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_407": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_408": { + "no_mass": true, + "thermal_resistance": 2.294228185203173 + } + }, + { + "virtual_no_mass_409": { + "no_mass": true, + "thermal_resistance": 2.4290326377742106 + } + }, + { + "virtual_no_mass_410": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_411": { + "no_mass": true, + "thermal_resistance": 2.125459582300353 + } + }, + { + "virtual_no_mass_412": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_413": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_414": { + "no_mass": true, + "thermal_resistance": 2.8369837552322106 + } + }, + { + "virtual_no_mass_415": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_416": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_417": { + "no_mass": true, + "thermal_resistance": 2.2997515212981745 + } + }, + { + "virtual_no_mass_418": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_419": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_420": { + "no_mass": true, + "thermal_resistance": 2.8369837552322106 + } + }, + { + "virtual_no_mass_421": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_422": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_423": { + "no_mass": true, + "thermal_resistance": 2.2997515212981745 + } + }, + { + "virtual_no_mass_424": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_425": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_426": { + "no_mass": true, + "thermal_resistance": 3.692128696887511 + } + }, + { + "virtual_no_mass_427": { + "no_mass": true, + "thermal_resistance": 4.365532467532468 + } + }, + { + "virtual_no_mass_428": { + "no_mass": true, + "thermal_resistance": 0.10171897213616554 + } + }, + { + "virtual_no_mass_429": { + "no_mass": true, + "thermal_resistance": 2.8286547252310448 + } + }, + { + "virtual_no_mass_430": { + "no_mass": true, + "thermal_resistance": 0.15864053940160128 + } + }, + { + "virtual_no_mass_431": { + "no_mass": true, + "thermal_resistance": 1.3150021070375053 + } + }, + { + "virtual_no_mass_432": { + "no_mass": true, + "thermal_resistance": 3.1214135194307606 + } + }, + { + "virtual_no_mass_433": { + "no_mass": true, + "thermal_resistance": 3.08900062932662 + } + }, + { + "virtual_no_mass_434": { + "no_mass": true, + "thermal_resistance": 4.245362196962524 + } + }, + { + "virtual_no_mass_435": { + "no_mass": true, + "thermal_resistance": 1.7073737251092764 + } + }, + { + "virtual_no_mass_436": { + "no_mass": true, + "thermal_resistance": 0.44427766599597596 + } + }, + { + "virtual_no_mass_437": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_438": { + "no_mass": true, + "thermal_resistance": 3.5439326469858594 + } + }, + { + "virtual_no_mass_439": { + "no_mass": true, + "thermal_resistance": 4.148195160031225 + } + }, + { + "virtual_no_mass_440": { + "no_mass": true, + "thermal_resistance": 5.304556727667129 + } + }, + { + "virtual_no_mass_441": { + "no_mass": true, + "thermal_resistance": 2.5853327722682193 + } + }, + { + "virtual_no_mass_442": { + "no_mass": true, + "thermal_resistance": 1.3222367131549189 + } + }, + { + "virtual_no_mass_443": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_444": { + "no_mass": true, + "thermal_resistance": 3.995393340779003 + } + }, + { + "virtual_no_mass_445": { + "no_mass": true, + "thermal_resistance": 4.148195160031225 + } + }, + { + "virtual_no_mass_446": { + "no_mass": true, + "thermal_resistance": 5.304556727667129 + } + }, + { + "virtual_no_mass_447": { + "no_mass": true, + "thermal_resistance": 3.4679371053909667 + } + }, + { + "virtual_no_mass_448": { + "no_mass": true, + "thermal_resistance": 2.204841046277666 + } + }, + { + "virtual_no_mass_449": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_450": { + "no_mass": true, + "thermal_resistance": 4.708715106732348 + } + }, + { + "virtual_no_mass_451": { + "no_mass": true, + "thermal_resistance": 4.856553791887125 + } + }, + { + "virtual_no_mass_452": { + "no_mass": true, + "thermal_resistance": 6.012915359523029 + } + }, + { + "virtual_no_mass_453": { + "no_mass": true, + "thermal_resistance": 3.4679371053909667 + } + }, + { + "virtual_no_mass_454": { + "no_mass": true, + "thermal_resistance": 2.204841046277666 + } + }, + { + "virtual_no_mass_455": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_456": { + "no_mass": true, + "thermal_resistance": 4.708715106732348 + } + }, + { + "virtual_no_mass_457": { + "no_mass": true, + "thermal_resistance": 4.856553791887125 + } + }, + { + "virtual_no_mass_458": { + "no_mass": true, + "thermal_resistance": 6.012915359523029 + } + }, + { + "virtual_no_mass_459": { + "no_mass": true, + "thermal_resistance": 3.4679371053909667 + } + }, + { + "virtual_no_mass_460": { + "no_mass": true, + "thermal_resistance": 2.204841046277666 + } + }, + { + "virtual_no_mass_461": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_462": { + "no_mass": true, + "thermal_resistance": 5.411291219144526 + } + }, + { + "virtual_no_mass_463": { + "no_mass": true, + "thermal_resistance": 5.725967806841046 + } + }, + { + "virtual_no_mass_464": { + "no_mass": true, + "thermal_resistance": 6.88232937447695 + } + }, + { + "virtual_no_mass_465": { + "no_mass": true, + "thermal_resistance": 4.708715106732348 + } + }, + { + "virtual_no_mass_466": { + "no_mass": true, + "thermal_resistance": 3.4456190476190476 + } + }, + { + "virtual_no_mass_467": { + "no_mass": true, + "thermal_resistance": 2.478598280790823 + } + }, + { + "virtual_no_mass_468": { + "no_mass": true, + "thermal_resistance": 3.1214135194307606 + } + }, + { + "virtual_no_mass_469": { + "no_mass": true, + "thermal_resistance": 3.865061435973353 + } + }, + { + "virtual_no_mass_470": { + "no_mass": true, + "thermal_resistance": 4.245362196962524 + } + }, + { + "virtual_no_mass_471": { + "no_mass": true, + "thermal_resistance": 1.7073737251092764 + } + }, + { + "virtual_no_mass_472": { + "no_mass": true, + "thermal_resistance": 0.44427766599597596 + } + }, + { + "virtual_no_mass_473": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_474": { + "no_mass": true, + "thermal_resistance": 3.5439326469858594 + } + }, + { + "virtual_no_mass_475": { + "no_mass": true, + "thermal_resistance": 5.093970695970697 + } + }, + { + "virtual_no_mass_476": { + "no_mass": true, + "thermal_resistance": 5.304556727667129 + } + }, + { + "virtual_no_mass_477": { + "no_mass": true, + "thermal_resistance": 2.5853327722682193 + } + }, + { + "virtual_no_mass_478": { + "no_mass": true, + "thermal_resistance": 1.3222367131549189 + } + }, + { + "virtual_no_mass_479": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_480": { + "no_mass": true, + "thermal_resistance": 3.995393340779003 + } + }, + { + "virtual_no_mass_481": { + "no_mass": true, + "thermal_resistance": 5.093970695970697 + } + }, + { + "virtual_no_mass_482": { + "no_mass": true, + "thermal_resistance": 5.304556727667129 + } + }, + { + "virtual_no_mass_483": { + "no_mass": true, + "thermal_resistance": 3.4679371053909667 + } + }, + { + "virtual_no_mass_484": { + "no_mass": true, + "thermal_resistance": 2.204841046277666 + } + }, + { + "virtual_no_mass_485": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_486": { + "no_mass": true, + "thermal_resistance": 4.708715106732348 + } + }, + { + "virtual_no_mass_487": { + "no_mass": true, + "thermal_resistance": 5.9300910973084875 + } + }, + { + "virtual_no_mass_488": { + "no_mass": true, + "thermal_resistance": 6.012915359523029 + } + }, + { + "virtual_no_mass_489": { + "no_mass": true, + "thermal_resistance": 3.4679371053909667 + } + }, + { + "virtual_no_mass_490": { + "no_mass": true, + "thermal_resistance": 2.204841046277666 + } + }, + { + "virtual_no_mass_491": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_492": { + "no_mass": true, + "thermal_resistance": 4.708715106732348 + } + }, + { + "virtual_no_mass_493": { + "no_mass": true, + "thermal_resistance": 5.9300910973084875 + } + }, + { + "virtual_no_mass_494": { + "no_mass": true, + "thermal_resistance": 6.012915359523029 + } + }, + { + "virtual_no_mass_495": { + "no_mass": true, + "thermal_resistance": 3.4679371053909667 + } + }, + { + "virtual_no_mass_496": { + "no_mass": true, + "thermal_resistance": 2.204841046277666 + } + }, + { + "virtual_no_mass_497": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_498": { + "no_mass": true, + "thermal_resistance": 5.411291219144526 + } + }, + { + "virtual_no_mass_499": { + "no_mass": true, + "thermal_resistance": 6.948177095631642 + } + }, + { + "virtual_no_mass_500": { + "no_mass": true, + "thermal_resistance": 6.88232937447695 + } + }, + { + "virtual_no_mass_501": { + "no_mass": true, + "thermal_resistance": 4.708715106732348 + } + }, + { + "virtual_no_mass_502": { + "no_mass": true, + "thermal_resistance": 3.4456190476190476 + } + }, + { + "virtual_no_mass_503": { + "no_mass": true, + "thermal_resistance": 2.478598280790823 + } + }, + { + "virtual_no_mass_504": { + "no_mass": true, + "thermal_resistance": 3.395086206896552 + } + }, + { + "virtual_no_mass_505": { + "no_mass": true, + "thermal_resistance": 4.781275261324042 + } + }, + { + "virtual_no_mass_506": { + "no_mass": true, + "thermal_resistance": 5.021423003609256 + } + }, + { + "virtual_no_mass_507": { + "no_mass": true, + "thermal_resistance": 1.7073737251092764 + } + }, + { + "virtual_no_mass_508": { + "no_mass": true, + "thermal_resistance": 0.44427766599597596 + } + }, + { + "virtual_no_mass_509": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_510": { + "no_mass": true, + "thermal_resistance": 3.720395250487963 + } + }, + { + "virtual_no_mass_511": { + "no_mass": true, + "thermal_resistance": 5.093970695970697 + } + }, + { + "virtual_no_mass_512": { + "no_mass": true, + "thermal_resistance": 5.554361567635904 + } + }, + { + "virtual_no_mass_513": { + "no_mass": true, + "thermal_resistance": 2.5853327722682193 + } + }, + { + "virtual_no_mass_514": { + "no_mass": true, + "thermal_resistance": 1.3222367131549189 + } + }, + { + "virtual_no_mass_515": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_516": { + "no_mass": true, + "thermal_resistance": 4.113477011494253 + } + }, + { + "virtual_no_mass_517": { + "no_mass": true, + "thermal_resistance": 5.9300910973084875 + } + }, + { + "virtual_no_mass_518": { + "no_mass": true, + "thermal_resistance": 6.2503322636066 + } + }, + { + "virtual_no_mass_519": { + "no_mass": true, + "thermal_resistance": 3.4679371053909667 + } + }, + { + "virtual_no_mass_520": { + "no_mass": true, + "thermal_resistance": 2.204841046277666 + } + }, + { + "virtual_no_mass_521": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_522": { + "no_mass": true, + "thermal_resistance": 4.597973135525261 + } + }, + { + "virtual_no_mass_523": { + "no_mass": true, + "thermal_resistance": 6.948177095631642 + } + }, + { + "virtual_no_mass_524": { + "no_mass": true, + "thermal_resistance": 7.0864526649443915 + } + }, + { + "virtual_no_mass_525": { + "no_mass": true, + "thermal_resistance": 3.4679371053909667 + } + }, + { + "virtual_no_mass_526": { + "no_mass": true, + "thermal_resistance": 2.204841046277666 + } + }, + { + "virtual_no_mass_527": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_528": { + "no_mass": true, + "thermal_resistance": 5.209968239564429 + } + }, + { + "virtual_no_mass_529": { + "no_mass": true, + "thermal_resistance": 7.230722832722833 + } + }, + { + "virtual_no_mass_530": { + "no_mass": true, + "thermal_resistance": 8.104538663267546 + } + }, + { + "virtual_no_mass_531": { + "no_mass": true, + "thermal_resistance": 3.4679371053909667 + } + }, + { + "virtual_no_mass_532": { + "no_mass": true, + "thermal_resistance": 2.204841046277666 + } + }, + { + "virtual_no_mass_533": { + "no_mass": true, + "thermal_resistance": 1.1610798163620788 + } + }, + { + "virtual_no_mass_534": { + "no_mass": true, + "thermal_resistance": 6.007416405433647 + } + }, + { + "virtual_no_mass_535": { + "no_mass": true, + "thermal_resistance": 7.774623376623378 + } + }, + { + "virtual_no_mass_536": { + "no_mass": true, + "thermal_resistance": 8.387084400358736 + } + }, + { + "virtual_no_mass_537": { + "no_mass": true, + "thermal_resistance": 4.708715106732348 + } + }, + { + "virtual_no_mass_538": { + "no_mass": true, + "thermal_resistance": 3.4456190476190476 + } + }, + { + "virtual_no_mass_539": { + "no_mass": true, + "thermal_resistance": 2.478598280790823 + } + } + ] +} \ No newline at end of file diff --git a/hub/helpers/data/hub_function_to_eilat_construction_function.py b/hub/helpers/data/hub_function_to_eilat_construction_function.py new file mode 100644 index 00000000..e4ecfe87 --- /dev/null +++ b/hub/helpers/data/hub_function_to_eilat_construction_function.py @@ -0,0 +1,28 @@ +""" +Dictionaries module for hub function to eilat construction function +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" + +import hub.helpers.constants as cte + + +class HubFunctionToEilatConstructionFunction: + """ + Hub function to Eilat construction function class + """ + def __init__(self): + self._dictionary = { + cte.RESIDENTIAL: 'Residential', + cte.HOTEL: 'Hotel_employees', + cte.DORMITORY: 'Dormitory' + } + + @property + def dictionary(self) -> dict: + """ + Get the dictionary + :return: {} + """ + return self._dictionary diff --git a/hub/helpers/dictionaries.py b/hub/helpers/dictionaries.py index c2b766ef..a6045975 100644 --- a/hub/helpers/dictionaries.py +++ b/hub/helpers/dictionaries.py @@ -1,7 +1,7 @@ """ Dictionaries module saves all transformations of functions and usages to access the catalogs SPDX - License - Identifier: LGPL - 3.0 - or -later -Copyright © 2022 Concordia CERC group +Copyright © 2023 Concordia CERC group Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ @@ -12,6 +12,7 @@ from hub.helpers.data.alkis_function_to_hub_function import AlkisFunctionToHubFu from hub.helpers.data.pluto_function_to_hub_function import PlutoFunctionToHubFunction from hub.helpers.data.hub_function_to_nrel_construction_function import HubFunctionToNrelConstructionFunction from hub.helpers.data.hub_function_to_nrcan_construction_function import HubFunctionToNrcanConstructionFunction +from hub.helpers.data.hub_function_to_eilat_construction_function import HubFunctionToEilatConstructionFunction from hub.helpers.data.hub_usage_to_comnet_usage import HubUsageToComnetUsage from hub.helpers.data.hub_usage_to_hft_usage import HubUsageToHftUsage from hub.helpers.data.hub_usage_to_nrcan_usage import HubUsageToNrcanUsage @@ -66,6 +67,14 @@ class Dictionaries: """ return HubFunctionToNrcanConstructionFunction().dictionary + @property + def hub_function_to_eilat_construction_function(self) -> dict: + """ + Get hub function to NRCAN construction function, transformation dictionary + :return: dict + """ + return HubFunctionToEilatConstructionFunction().dictionary + @property def hub_function_to_nrel_construction_function(self) -> dict: """ diff --git a/hub/imports/construction/eilat_physics_parameters.py b/hub/imports/construction/eilat_physics_parameters.py new file mode 100644 index 00000000..607af32b --- /dev/null +++ b/hub/imports/construction/eilat_physics_parameters.py @@ -0,0 +1,213 @@ +""" +EilatPhysicsParameters import the construction and material information defined for Eilat +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" + +import logging +import math + +import hub.helpers.constants as cte +from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory +from hub.city_model_structure.building_demand.layer import Layer +from hub.city_model_structure.building_demand.material import Material +from hub.helpers.dictionaries import Dictionaries +from hub.imports.construction.helpers.construction_helper import ConstructionHelper +from hub.imports.construction.helpers.storeys_generation import StoreysGeneration + + +class EilatPhysicsParameters: + """ + EilatPhysicsParameters class + """ + + def __init__(self, city, divide_in_storeys=False): + self._city = city + self._divide_in_storeys = divide_in_storeys + self._climate_zone = ConstructionHelper.city_to_israel_climate_zone(city.climate_reference_city) + + def enrich_buildings(self): + """ + Returns the city with the construction parameters assigned to the buildings + """ + city = self._city + eilat_catalog = ConstructionCatalogFactory('eilat').catalog + for building in city.buildings: + if building.function not in Dictionaries().hub_function_to_eilat_construction_function.keys(): + logging.error(f'Building %s has an unknown building function %s', building.name, building.function ) + continue + function = Dictionaries().hub_function_to_eilat_construction_function[building.function] + try: + archetype = self._search_archetype(eilat_catalog, function, building.year_of_construction, self._climate_zone) + + except KeyError: + logging.error(f'Building %s has unknown construction archetype for building function: %s ' + f'[%s], building year of construction: %s and climate zone %s', building.name, function, + building.function, building.year_of_construction, self._climate_zone) + continue + + # 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 building.internal_zones[0].thermal_zones is None: + self._create_storeys(building, archetype, self._divide_in_storeys) + if self._divide_in_storeys: + for internal_zone in building.internal_zones: + for thermal_zone in internal_zone.thermal_zones: + thermal_zone.total_floor_area = thermal_zone.footprint_area + else: + number_of_storeys = int(building.eave_height / building.average_storey_height) + thermal_zone = building.internal_zones[0].thermal_zones[0] + thermal_zone.total_floor_area = thermal_zone.footprint_area * number_of_storeys + else: + for internal_zone in building.internal_zones: + for thermal_zone in internal_zone.thermal_zones: + thermal_zone.total_floor_area = thermal_zone.footprint_area + for internal_zone in building.internal_zones: + self._assign_values(internal_zone.thermal_zones, archetype) + for thermal_zone in internal_zone.thermal_zones: + self._calculate_view_factors(thermal_zone) + + @staticmethod + def _search_archetype(nrcan_catalog, function, year_of_construction, climate_zone): + nrcan_archetypes = nrcan_catalog.entries('archetypes') + for building_archetype in nrcan_archetypes: + construction_period_limits = building_archetype.construction_period.split('_') + if int(construction_period_limits[0]) <= int(year_of_construction) <= int(construction_period_limits[1]): + if str(function) == str(building_archetype.function) and climate_zone == str(building_archetype.climate_zone): + return building_archetype + raise KeyError('archetype not found') + + @staticmethod + def _search_construction_in_archetype(archetype, construction_type): + construction_archetypes = archetype.constructions + for construction_archetype in construction_archetypes: + if str(construction_type) == str(construction_archetype.type): + return construction_archetype + return None + + def _assign_values(self, thermal_zones, archetype): + for thermal_zone in thermal_zones: + thermal_zone.additional_thermal_bridge_u_value = archetype.extra_loses_due_to_thermal_bridges + effective_thermal_capacity = 0 + thermal_zone.indirectly_heated_area_ratio = 0 + thermal_zone.infiltration_rate_system_on = archetype.infiltration_rate_for_ventilation_system_on + thermal_zone.infiltration_rate_system_off = archetype.infiltration_rate_for_ventilation_system_off + for thermal_boundary in thermal_zone.thermal_boundaries: + construction_archetype = self._search_construction_in_archetype(archetype, thermal_boundary.type) + thermal_boundary.construction_name = construction_archetype.name + try: + thermal_boundary.window_ratio = 0 + if thermal_boundary.type in (cte.WALL, cte.ROOF): + if construction_archetype.window is not None: + if -math.sqrt(2) / 2 < math.sin(thermal_boundary.parent_surface.azimuth) < math.sqrt(2) / 2: + if 0 < math.cos(thermal_boundary.parent_surface.azimuth): + thermal_boundary.window_ratio = \ + float(construction_archetype.window_ratio['north']) / 100 + else: + thermal_boundary.window_ratio = \ + float(construction_archetype.window_ratio['south']) / 100 + elif math.sqrt(2) / 2 <= math.sin(thermal_boundary.parent_surface.azimuth): + thermal_boundary.window_ratio = \ + float(construction_archetype.window_ratio['east']) / 100 + else: + thermal_boundary.window_ratio = \ + float(construction_archetype.window_ratio['west']) / 100 + except ValueError: + # This is the normal operation way when the windows are defined in the geometry + continue + thermal_boundary.layers = [] + total_thickness = 0 + for layer_archetype in construction_archetype.layers: + layer = Layer() + layer.thickness = layer_archetype.thickness + total_thickness += layer_archetype.thickness + material = Material() + archetype_material = layer_archetype.material + material.name = archetype_material.name + material.id = archetype_material.id + material.no_mass = archetype_material.no_mass + if archetype_material.no_mass: + material.thermal_resistance = archetype_material.thermal_resistance + else: + material.density = archetype_material.density + material.conductivity = archetype_material.conductivity + material.specific_heat = archetype_material.specific_heat + effective_thermal_capacity += archetype_material.specific_heat \ + * archetype_material.density * layer_archetype.thickness + material.solar_absorptance = archetype_material.solar_absorptance + material.thermal_absorptance = archetype_material.thermal_absorptance + material.visible_absorptance = archetype_material.visible_absorptance + layer.material = material + thermal_boundary.layers.append(layer) + + effective_thermal_capacity = effective_thermal_capacity / total_thickness + # The agreement is that the layers are defined from outside to inside + external_layer = construction_archetype.layers[0] + external_surface = thermal_boundary.parent_surface + external_surface.short_wave_reflectance = 1 - external_layer.material.solar_absorptance + external_surface.long_wave_emittance = 1 - 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 - internal_layer.material.solar_absorptance + internal_surface.long_wave_emittance = 1 - internal_layer.material.solar_absorptance + + for thermal_opening in thermal_boundary.thermal_openings: + if construction_archetype.window is not None: + window_archetype = construction_archetype.window + thermal_opening.construction_name = window_archetype.name + thermal_opening.frame_ratio = window_archetype.frame_ratio + thermal_opening.g_value = window_archetype.g_value + thermal_opening.overall_u_value = window_archetype.overall_u_value + + thermal_zone.effective_thermal_capacity = effective_thermal_capacity + + @staticmethod + def _calculate_view_factors(thermal_zone): + """ + Get thermal zone view factors matrix + :return: [[float]] + """ + total_area = 0 + for thermal_boundary in thermal_zone.thermal_boundaries: + total_area += thermal_boundary.opaque_area + for thermal_opening in thermal_boundary.thermal_openings: + total_area += thermal_opening.area + + view_factors_matrix = [] + for thermal_boundary_1 in thermal_zone.thermal_boundaries: + values = [] + for thermal_boundary_2 in thermal_zone.thermal_boundaries: + value = 0 + if thermal_boundary_1.id != thermal_boundary_2.id: + value = thermal_boundary_2.opaque_area / (total_area - thermal_boundary_1.opaque_area) + values.append(value) + for thermal_boundary in thermal_zone.thermal_boundaries: + for thermal_opening in thermal_boundary.thermal_openings: + value = thermal_opening.area / (total_area - thermal_boundary_1.opaque_area) + values.append(value) + view_factors_matrix.append(values) + + for thermal_boundary_1 in thermal_zone.thermal_boundaries: + values = [] + for thermal_opening_1 in thermal_boundary_1.thermal_openings: + for thermal_boundary_2 in thermal_zone.thermal_boundaries: + value = thermal_boundary_2.opaque_area / (total_area - thermal_opening_1.area) + values.append(value) + for thermal_boundary in thermal_zone.thermal_boundaries: + for thermal_opening_2 in thermal_boundary.thermal_openings: + value = 0 + if thermal_opening_1.id != thermal_opening_2.id: + value = thermal_opening_2.area / (total_area - thermal_opening_1.area) + values.append(value) + view_factors_matrix.append(values) + thermal_zone.view_factors_matrix = view_factors_matrix + + @staticmethod + def _create_storeys(building, archetype, divide_in_storeys): + building.average_storey_height = archetype.average_storey_height + thermal_zones = StoreysGeneration(building, building.internal_zones[0], + divide_in_storeys=divide_in_storeys).thermal_zones + building.internal_zones[0].thermal_zones = thermal_zones diff --git a/hub/imports/construction/helpers/construction_helper.py b/hub/imports/construction/helpers/construction_helper.py index d33f6c39..ae5cd95d 100644 --- a/hub/imports/construction/helpers/construction_helper.py +++ b/hub/imports/construction/helpers/construction_helper.py @@ -48,7 +48,12 @@ class ConstructionHelper: } _reference_city_to_nrcan_climate_zone = { - 'Montreal': '6' + 'Montreal': '6', + 'Levis': '7A' + } + + _reference_city_to_israel_climate_zone = { + 'Eilat': 'BWh' } @staticmethod @@ -65,36 +70,31 @@ class ConstructionHelper: return standard @staticmethod - def city_to_reference_city(city): - """ - City name to reference city - :param city: str - :return: str - """ - # todo: Dummy function that needs to be implemented - reference_city = 'Montreal' - if city is not None: - reference_city = 'Montreal' - return reference_city - - @staticmethod - def city_to_nrel_climate_zone(city): + def city_to_nrel_climate_zone(reference_city): """ City name to NREL climate zone - :param city: str + :param reference_city: str :return: str """ - reference_city = ConstructionHelper.city_to_reference_city(city) + # todo: finish dictionary implementation if reference_city not in ConstructionHelper._reference_city_to_nrel_climate_zone: reference_city = 'Baltimore' return ConstructionHelper._reference_city_to_nrel_climate_zone[reference_city] @staticmethod - def city_to_nrcan_climate_zone(city): + def city_to_nrcan_climate_zone(reference_city): """ City name to NRCAN climate zone - :param city: str + :param reference_city: str :return: str """ - reference_city = ConstructionHelper.city_to_reference_city(city) return ConstructionHelper._reference_city_to_nrcan_climate_zone[reference_city] + + @staticmethod + def city_to_israel_climate_zone(reference_city): + """ + City name to Israel climate zone + :param reference_city: str + :return: str + """ + return ConstructionHelper._reference_city_to_israel_climate_zone[reference_city] diff --git a/hub/imports/construction/nrcan_physics_parameters.py b/hub/imports/construction/nrcan_physics_parameters.py index 13cd231a..cf4debcf 100644 --- a/hub/imports/construction/nrcan_physics_parameters.py +++ b/hub/imports/construction/nrcan_physics_parameters.py @@ -25,7 +25,7 @@ class NrcanPhysicsParameters: def __init__(self, city, divide_in_storeys=False): self._city = city self._divide_in_storeys = divide_in_storeys - self._climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.name) + self._climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city) def enrich_buildings(self): """ diff --git a/hub/imports/construction/nrel_physics_parameters.py b/hub/imports/construction/nrel_physics_parameters.py index eec57bc2..e01e3cbf 100644 --- a/hub/imports/construction/nrel_physics_parameters.py +++ b/hub/imports/construction/nrel_physics_parameters.py @@ -23,7 +23,7 @@ class NrelPhysicsParameters: def __init__(self, city, divide_in_storeys=False): self._city = city self._divide_in_storeys = divide_in_storeys - self._climate_zone = ConstructionHelper.city_to_nrel_climate_zone(city.name) + self._climate_zone = ConstructionHelper.city_to_nrel_climate_zone(city.climate_reference_city) def enrich_buildings(self): """ diff --git a/hub/imports/construction_factory.py b/hub/imports/construction_factory.py index 81d10b76..38019b66 100644 --- a/hub/imports/construction_factory.py +++ b/hub/imports/construction_factory.py @@ -9,6 +9,7 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord from hub.helpers.utils import validate_import_export_type from hub.imports.construction.nrcan_physics_parameters import NrcanPhysicsParameters from hub.imports.construction.nrel_physics_parameters import NrelPhysicsParameters +from hub.imports.construction.eilat_physics_parameters import EilatPhysicsParameters class ConstructionFactory: @@ -38,6 +39,15 @@ class ConstructionFactory: for building in self._city.buildings: building.level_of_detail.construction = 2 + def _eilat(self): + """ + Enrich the city by using Eilat information + """ + EilatPhysicsParameters(self._city).enrich_buildings() + self._city.level_of_detail.construction = 2 + for building in self._city.buildings: + building.level_of_detail.construction = 2 + def enrich(self): """ Enrich the city given to the class using the class given handler diff --git a/tests/test_construction_catalog.py b/tests/test_construction_catalog.py index b9f17c7e..5c5a0e9d 100644 --- a/tests/test_construction_catalog.py +++ b/tests/test_construction_catalog.py @@ -51,3 +51,23 @@ class TestConstructionCatalog(TestCase): with self.assertRaises(IndexError): catalog.get_entry('unknown') + + def test_eilat_catalog(self): + catalog = ConstructionCatalogFactory('eilat').catalog + catalog_categories = catalog.names() + constructions = catalog.names('constructions') + windows = catalog.names('windows') + materials = catalog.names('materials') + self.assertEqual(9, len(constructions['constructions'])) + self.assertEqual(3, len(windows['windows'])) + self.assertEqual(553, len(materials['materials'])) + with self.assertRaises(ValueError): + catalog.names('unknown') + + # retrieving all the entries should not raise any exceptions + for category in catalog_categories: + for value in catalog_categories[category]: + catalog.get_entry(value) + + with self.assertRaises(IndexError): + catalog.get_entry('unknown') diff --git a/tests/test_construction_factory.py b/tests/test_construction_factory.py index a7b40de1..8a3fe556 100644 --- a/tests/test_construction_factory.py +++ b/tests/test_construction_factory.py @@ -283,3 +283,47 @@ class TestConstructionFactory(TestCase): self.assertIsNotNone(thermal_boundary.layers, 'layers is none') self._check_thermal_openings(thermal_boundary) self._check_surfaces(thermal_boundary) + + def test_nrcan_construction_factory(self): + file = 'test.geojson' + file_path = (self._example_path / file).resolve() + city = GeometryFactory('geojson', + path=file_path, + height_field='citygml_me', + year_of_construction_field='ANNEE_CONS', + function_field='CODE_UTILI', + function_to_hub=Dictionaries().montreal_function_to_hub_function).city + ConstructionFactory('nrcan', city).enrich() + + self._check_buildings(city) + for building in city.buildings: + for internal_zone in building.internal_zones: + self._check_thermal_zones(internal_zone) + for thermal_zone in internal_zone.thermal_zones: + self._check_thermal_boundaries(thermal_zone) + for thermal_boundary in thermal_zone.thermal_boundaries: + self.assertIsNotNone(thermal_boundary.layers, 'layers is none') + self._check_thermal_openings(thermal_boundary) + self._check_surfaces(thermal_boundary) + + def test_eilat_construction_factory(self): + file = 'eilat.geojson' + file_path = (self._example_path / file).resolve() + city = GeometryFactory('geojson', + path=file_path, + height_field='heightmax', + year_of_construction_field='ANNEE_CONS', + function_field='CODE_UTILI', + function_to_hub=Dictionaries().eilat_function_to_hub_function).city + ConstructionFactory('eilat', city).enrich() + + self._check_buildings(city) + for building in city.buildings: + for internal_zone in building.internal_zones: + self._check_thermal_zones(internal_zone) + for thermal_zone in internal_zone.thermal_zones: + self._check_thermal_boundaries(thermal_zone) + for thermal_boundary in thermal_zone.thermal_boundaries: + self.assertIsNotNone(thermal_boundary.layers, 'layers is none') + self._check_thermal_openings(thermal_boundary) + self._check_surfaces(thermal_boundary) \ No newline at end of file diff --git a/tests/tests_data/eilat.geojson b/tests/tests_data/eilat.geojson new file mode 100644 index 00000000..2e4efd36 --- /dev/null +++ b/tests/tests_data/eilat.geojson @@ -0,0 +1,177 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "id": 1, + "properties": { + "heightmax": 9, + "ANNEE_CONS": 1978, + "CODE_UTILI": "residential" + }, + "geometry": { + "coordinates": [ + [ + [ + 34.95217088371581, + 29.56694805860026 + ], + [ + 34.95262396587913, + 29.566952667742285 + ], + [ + 34.95261999147337, + 29.567024109421467 + ], + [ + 34.952169558914704, + 29.567019500282157 + ], + [ + 34.95217088371581, + 29.56694805860026 + ] + ] + ], + "type": "Polygon" + } + }, + { + "type": "Feature", + "id": 3, + "properties": { + "heightmax": 16, + "ANNEE_CONS": 2012, + "CODE_UTILI": "dormitory" + }, + "geometry": { + "coordinates": [ + [ + [ + 34.95176644317411, + 29.56827388702702 + ], + [ + 34.95176550020565, + 29.568180388329026 + ], + [ + 34.95179850408434, + 29.568180388329026 + ], + [ + 34.95179850408434, + 29.5681303582886 + ], + [ + 34.95176644317411, + 29.5681303582886 + ], + [ + 34.95176644317411, + 29.568038499789708 + ], + [ + 34.951874884488376, + 29.568038499789708 + ], + [ + 34.951874884488376, + 29.568058183760357 + ], + [ + 34.95192391882168, + 29.568058183760357 + ], + [ + 34.951922032885705, + 29.56804178045124 + ], + [ + 34.95205216246262, + 29.568042600617147 + ], + [ + 34.952051219494166, + 29.568129538124154 + ], + [ + 34.95201821561636, + 29.5681303582886 + ], + [ + 34.95201821561636, + 29.568176287507143 + ], + [ + 34.95204839059062, + 29.568176287507143 + ], + [ + 34.95205027652662, + 29.56827552735433 + ], + [ + 34.95195503676348, + 29.568274707190284 + ], + [ + 34.95195597973188, + 29.56825830391628 + ], + [ + 34.951849424353696, + 29.56825830391628 + ], + [ + 34.951849424353696, + 29.568274707190284 + ], + [ + 34.95176644317411, + 29.56827388702702 + ] + ] + ], + "type": "Polygon" + } + }, + { + "type": "Feature", + "id": 2, + "properties": { + "heightmax": 24, + "ANNEE_CONS": 2002, + "CODE_UTILI": "Hotel employ" + }, + "geometry": { + "coordinates": [ + [ + [ + 34.94972280674813, + 29.566224752287738 + ], + [ + 34.94974316291999, + 29.56597561012454 + ], + [ + 34.94989147217407, + 29.565980668855033 + ], + [ + 34.94987402402688, + 29.566233605043536 + ], + [ + 34.94972280674813, + 29.566224752287738 + ] + ] + ], + "type": "Polygon" + } + } + ] +} diff --git a/tests/tests_data/levis.geojson b/tests/tests_data/levis.geojson new file mode 100644 index 00000000..04ed34e7 --- /dev/null +++ b/tests/tests_data/levis.geojson @@ -0,0 +1,73 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "id": 1, + "properties": { + "OBJECTID_12": 1, + "gml_id": 1, + "citygml_me": 20, + "Z_Min": 46.1162, + "Z_Max": 66.1162, + "ANNEE_CONS": 2023, + "CODE_UTILI": 1000 + }, + "geometry": { + "coordinates": [ + [ + [ + -71.16553932594044, + 46.7895775031096 + ], + [ + -71.16535210635354, + 46.78972033813616 + ], + [ + -71.1654671126711, + 46.78979908036044 + ], + [ + -71.16525314742928, + 46.78995473325631 + ], + [ + -71.16480114585448, + 46.7896544143249 + ], + [ + -71.16486533542763, + 46.789394380725696 + ], + [ + -71.16467544127534, + 46.78927901330414 + ], + [ + -71.16454171299826, + 46.78930465053031 + ], + [ + -71.16445612690187, + 46.789766118513455 + ], + [ + -71.16519698155322, + 46.79023673853192 + ], + [ + -71.16583887727946, + 46.78976794972763 + ], + [ + -71.16553932594044, + 46.7895775031096 + ] + ] + ], + "type": "Polygon" + } + } + ] +} \ No newline at end of file From 8be6e3b3e83af58f1fc7402f181d443140bcc328 Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Wed, 12 Jul 2023 15:55:26 -0400 Subject: [PATCH 5/6] small update to eilat_archetypes.json --- hub/data/construction/eilat_archetypes.json | 18 +++++++++--------- .../helpers/construction_helper.py | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/hub/data/construction/eilat_archetypes.json b/hub/data/construction/eilat_archetypes.json index 35c8a26c..4a15e038 100644 --- a/hub/data/construction/eilat_archetypes.json +++ b/hub/data/construction/eilat_archetypes.json @@ -4,10 +4,10 @@ "function": "Residential", "period_of_construction": "1000_1980", "climate_zone": "BWh", - "average_storey_height": 1, + "average_storey_height": 3, "extra_loses_due_thermal_bridges": 0.1, - "infiltration_rate_for_ventilation_system_on": 1, - "infiltration_rate_for_ventilation_system_off": 1, + "infiltration_rate_for_ventilation_system_on": 0, + "infiltration_rate_for_ventilation_system_off": 0.9, "constructions": { "OutdoorsWall": { "opaque_surface_name": "residential_1000_1980_BWh", @@ -38,10 +38,10 @@ "function": "Dormitory", "period_of_construction": "2011_3000", "climate_zone": "BWh", - "average_storey_height": 1, + "average_storey_height": 3, "extra_loses_due_thermal_bridges": 0.1, - "infiltration_rate_for_ventilation_system_on": 1, - "infiltration_rate_for_ventilation_system_off": 1, + "infiltration_rate_for_ventilation_system_on": 0, + "infiltration_rate_for_ventilation_system_off": 0.31, "constructions": { "OutdoorsWall": { "opaque_surface_name": "dormitory_2011_3000_BWh", @@ -72,10 +72,10 @@ "function": "Hotel_employees", "period_of_construction": "1981_2010", "climate_zone": "BWh", - "average_storey_height": 1, + "average_storey_height": 3, "extra_loses_due_thermal_bridges": 0.09, - "infiltration_rate_for_ventilation_system_on": 1, - "infiltration_rate_for_ventilation_system_off": 1, + "infiltration_rate_for_ventilation_system_on": 0, + "infiltration_rate_for_ventilation_system_off": 0.65, "constructions": { "OutdoorsWall": { "opaque_surface_name": "hotel_employees_1981_2010_BWh", diff --git a/hub/imports/construction/helpers/construction_helper.py b/hub/imports/construction/helpers/construction_helper.py index ae5cd95d..7f34e853 100644 --- a/hub/imports/construction/helpers/construction_helper.py +++ b/hub/imports/construction/helpers/construction_helper.py @@ -49,6 +49,7 @@ class ConstructionHelper: _reference_city_to_nrcan_climate_zone = { 'Montreal': '6', + 'Repentigny': '6', 'Levis': '7A' } From 8434bdef04bd55490b1099af52cbf0ecff2955fb Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Wed, 12 Jul 2023 16:28:14 -0400 Subject: [PATCH 6/6] solved bug in idf --- hub/exports/building_energy/idf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hub/exports/building_energy/idf.py b/hub/exports/building_energy/idf.py index a8a465b8..898beb55 100644 --- a/hub/exports/building_energy/idf.py +++ b/hub/exports/building_energy/idf.py @@ -104,7 +104,8 @@ class Idf: else: for building_name in target_buildings: building = city.city_object(building_name) - self._adjacent_buildings += building.neighbours + if building.neighbours is not None: + self._adjacent_buildings += building.neighbours self._export() def _sanity_check(self):