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/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/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/construction/eilat_archetypes.json b/hub/data/construction/eilat_archetypes.json new file mode 100644 index 00000000..4a15e038 --- /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": 3, + "extra_loses_due_thermal_bridges": 0.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", + "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": 3, + "extra_loses_due_thermal_bridges": 0.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", + "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": 3, + "extra_loses_due_thermal_bridges": 0.09, + "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", + "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/data/usage/eilat_archetypes.xlsx b/hub/data/usage/eilat_archetypes.xlsx new file mode 100644 index 00000000..35ad7288 Binary files /dev/null and b/hub/data/usage/eilat_archetypes.xlsx differ diff --git a/hub/data/usage/eilat_schedules_archetypes.xlsx b/hub/data/usage/eilat_schedules_archetypes.xlsx new file mode 100644 index 00000000..2f3a2956 Binary files /dev/null and b/hub/data/usage/eilat_schedules_archetypes.xlsx differ 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): diff --git a/hub/helpers/data/eilat_function_to_hub_function.py b/hub/helpers/data/eilat_function_to_hub_function.py new file mode 100644 index 00000000..71cd0d3f --- /dev/null +++ b/hub/helpers/data/eilat_function_to_hub_function.py @@ -0,0 +1,28 @@ +""" +Dictionaries module for Eilat function to hub 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 EilatFunctionToHubFunction: + """ + Eilat function to hub function class + """ + + def __init__(self): + self._dictionary = {'Residential': cte.RESIDENTIAL, + 'Dormitory': cte.DORMITORY, + 'Hotel employ': cte.HOTEL + } + + @property + def dictionary(self) -> dict: + """ + Get the dictionary + :return: {} + """ + return self._dictionary 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/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..a6045975 100644 --- a/hub/helpers/dictionaries.py +++ b/hub/helpers/dictionaries.py @@ -1,19 +1,22 @@ """ 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 """ 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 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 +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 +51,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: """ @@ -56,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: """ @@ -115,3 +134,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/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..7f34e853 100644 --- a/hub/imports/construction/helpers/construction_helper.py +++ b/hub/imports/construction/helpers/construction_helper.py @@ -48,7 +48,13 @@ class ConstructionHelper: } _reference_city_to_nrcan_climate_zone = { - 'Montreal': '6' + 'Montreal': '6', + 'Repentigny': '6', + 'Levis': '7A' + } + + _reference_city_to_israel_climate_zone = { + 'Eilat': 'BWh' } @staticmethod @@ -65,36 +71,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/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 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)() + + 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? 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