diff --git a/hub/imports/construction/nrcan_physics_parameters.py b/hub/imports/construction/nrcan_physics_parameters.py index c65bd2da..35f5382a 100644 --- a/hub/imports/construction/nrcan_physics_parameters.py +++ b/hub/imports/construction/nrcan_physics_parameters.py @@ -3,6 +3,7 @@ NrcanPhysicsParameters import the construction and material information defined SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2022 Concordia CERC group Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +Project Collaborator Saeed Ranjbar saeed.ranjbar@concordia.ca """ import logging @@ -32,10 +33,21 @@ class NrcanPhysicsParameters: city = self._city nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog for building in city.buildings: - if building.function not in Dictionaries().hub_function_to_nrcan_construction_function: - logging.error('Building %s has an unknown building function %s', building.name, building.function) + main_function = None + functions = building.function.split('_') + if len(functions) > 1: + maximum_percentage = 0 + for function in functions: + percentage_and_function = function.split('-') + if float(percentage_and_function[0]) > maximum_percentage: + maximum_percentage = float(percentage_and_function[0]) + main_function = percentage_and_function[-1] + else: + main_function = functions[-1] + if main_function not in Dictionaries().hub_function_to_nrcan_construction_function: + logging.error('Building %s has an unknown building function %s', building.name, main_function) continue - function = Dictionaries().hub_function_to_nrcan_construction_function[building.function] + function = Dictionaries().hub_function_to_nrcan_construction_function[main_function] try: archetype = self._search_archetype(nrcan_catalog, function, building.year_of_construction, self._climate_zone) diff --git a/hub/imports/geometry/geojson.py b/hub/imports/geometry/geojson.py index b07a6a7b..888045ad 100644 --- a/hub/imports/geometry/geojson.py +++ b/hub/imports/geometry/geojson.py @@ -3,6 +3,7 @@ Geojson module parses geojson files and import the geometry into the city model SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2022 Concordia CERC group Project Coder Guillermo Gutierrez Guillermo.GutierrezMorote@concordia.ca +Project Collaborator Saeed Ranjbar saeed.ranjbar@concordia.ca """ import uuid @@ -127,6 +128,19 @@ class Geojson: function = None if self._function_field is not None: function = str(feature['properties'][self._function_field]) + if function == 'Mixed use' or function == 'mixed use': + function_parts = [] + for key, value in feature['properties'].items(): + if key.startswith("mixed_type_") and not key.endswith("_percentage"): + type_key = key + percentage_key = f"{key}_percentage" + if percentage_key in feature['properties']: + if self._function_to_hub is not None and feature['properties'][type_key] in self._function_to_hub: + usage_function = self._function_to_hub[feature['properties'][type_key]] + function_parts.append(f"{feature['properties'][percentage_key]}-{usage_function}") + else: + function_parts.append(f"{feature['properties'][percentage_key]}-{feature['properties'][type_key]}") + function = "_".join(function_parts) if self._function_to_hub is not None: # use the transformation dictionary to retrieve the proper function if function in self._function_to_hub: diff --git a/hub/imports/usage/comnet_usage_parameters.py b/hub/imports/usage/comnet_usage_parameters.py index 02f9b77e..a48089fd 100644 --- a/hub/imports/usage/comnet_usage_parameters.py +++ b/hub/imports/usage/comnet_usage_parameters.py @@ -3,6 +3,7 @@ ComnetUsageParameters extracts the usage properties from Comnet catalog and assi SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2022 Concordia CERC group Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +Project Collaborator Saeed Ranjbar saeed.ranjbar@concordia.ca """ import copy import logging @@ -35,29 +36,60 @@ class ComnetUsageParameters: city = self._city comnet_catalog = UsageCatalogFactory('comnet').catalog for building in city.buildings: - usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function] - try: - archetype_usage = self._search_archetypes(comnet_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] + usages = [] + comnet_archetype_usages = [] + building_functions = building.function.split('_') + for function in building_functions: + usages.append(function.split('-')) + for usage in usages: + comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage[-1]] + try: + comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name) + comnet_archetype_usages.append(comnet_archetype_usage) + except KeyError: + logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name) + continue + for (i, internal_zone) in enumerate(building.internal_zones): + internal_zone_usages = [] + if len(building.internal_zones) > 1: + volume_per_area = 0 + if internal_zone.area is None: + logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s', + building.name, usages[i][-1]) + continue + if internal_zone.volume is None: + logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s', + building.name, usages[i][-1]) + continue + if internal_zone.area <= 0: + logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s', + building.name, usages[i][-1]) + continue + volume_per_area += internal_zone.volume / internal_zone.area + usage = Usage() + usage.name = usages[i][-1] + self._assign_values(usage, comnet_archetype_usages[i], volume_per_area, building.cold_water_temperature) + usage.percentage = 1 + self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[i]) + internal_zone_usages.append(usage) + else: + if building.storeys_above_ground is None: + logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s', + building.name, usages) + continue + volume_per_area = building.volume / building.floor_area / building.storeys_above_ground + for (j, mixed_usage) in enumerate(usages): + usage = Usage() + usage.name = mixed_usage[-1] + if len(usages) > 1: + usage.percentage = float(mixed_usage[0]) / 100 + else: + usage.percentage = 1 + self._assign_values(usage, comnet_archetype_usages[j], volume_per_area, building.cold_water_temperature) + self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[j]) + internal_zone_usages.append(usage) + internal_zone.usages = internal_zone_usages @staticmethod def _search_archetypes(comnet_catalog, usage_name): comnet_archetypes = comnet_catalog.entries('archetypes').usages diff --git a/hub/imports/usage/nrcan_usage_parameters.py b/hub/imports/usage/nrcan_usage_parameters.py index 9d718d33..9c88bc05 100644 --- a/hub/imports/usage/nrcan_usage_parameters.py +++ b/hub/imports/usage/nrcan_usage_parameters.py @@ -3,6 +3,7 @@ NrcanUsageParameters extracts the usage properties from NRCAN catalog and assign SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2022 Concordia CERC group Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +Project Collaborator Saeed Ranjbar saeed.ranjbar@concordia.ca """ import logging @@ -33,53 +34,72 @@ class NrcanUsageParameters: city = self._city nrcan_catalog = UsageCatalogFactory('nrcan').catalog comnet_catalog = UsageCatalogFactory('comnet').catalog - for building in city.buildings: - usage_name = Dictionaries().hub_usage_to_nrcan_usage[building.function] - try: - archetype_usage = self._search_archetypes(nrcan_catalog, usage_name) - except KeyError: - logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name) - continue + usages = [] + nrcan_archetype_usages = [] + comnet_archetype_usages = [] + building_functions = building.function.split('_') + for function in building_functions: + usages.append(function.split('-')) + for usage in usages: + usage_name = Dictionaries().hub_usage_to_nrcan_usage[usage[-1]] + try: + archetype_usage = self._search_archetypes(nrcan_catalog, usage_name) + nrcan_archetype_usages.append(archetype_usage) + except KeyError: + logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name) + continue + comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage[-1]] + try: + comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name) + comnet_archetype_usages.append(comnet_archetype_usage) + except KeyError: + logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name) + continue - comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function] - try: - comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name) - except KeyError: - logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name) - continue - - for internal_zone in building.internal_zones: + for (i, internal_zone) in enumerate(building.internal_zones): + internal_zone_usages = [] if len(building.internal_zones) > 1: volume_per_area = 0 if internal_zone.area is None: logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s', - building.name, usage_name) + building.name, usages[i][-1]) continue if internal_zone.volume is None: logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s', - building.name, usage_name) + building.name, usages[i][-1]) continue if internal_zone.area <= 0: logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s', - building.name, usage_name) + building.name, usages[i][-1]) continue volume_per_area += internal_zone.volume / internal_zone.area + usage = Usage() + usage.name = usages[i][-1] + self._assign_values(usage, nrcan_archetype_usages[i], volume_per_area, building.cold_water_temperature) + self._assign_comnet_extra_values(usage, comnet_archetype_usages[i], nrcan_archetype_usages[i].occupancy.occupancy_density) + usage.percentage = 1 + self._calculate_reduced_values_from_extended_library(usage, nrcan_archetype_usages[i]) + internal_zone_usages.append(usage) else: if building.storeys_above_ground is None: logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s', - building.name, usage_name) + building.name, usages) continue volume_per_area = building.volume / building.floor_area / building.storeys_above_ground + for (j, mixed_usage) in enumerate(usages): + usage = Usage() + usage.name = mixed_usage[-1] + if len(usages) > 1: + usage.percentage = float(mixed_usage[0]) / 100 + else: + usage.percentage = 1 + self._assign_values(usage, nrcan_archetype_usages[j], volume_per_area, building.cold_water_temperature) + self._assign_comnet_extra_values(usage, comnet_archetype_usages[j], nrcan_archetype_usages[j].occupancy.occupancy_density) + self._calculate_reduced_values_from_extended_library(usage, nrcan_archetype_usages[j]) + internal_zone_usages.append(usage) - usage = Usage() - usage.name = usage_name - self._assign_values(usage, archetype_usage, volume_per_area, building.cold_water_temperature) - self._assign_comnet_extra_values(usage, comnet_archetype_usage, archetype_usage.occupancy.occupancy_density) - usage.percentage = 1 - self._calculate_reduced_values_from_extended_library(usage, archetype_usage) - - internal_zone.usages = [usage] + internal_zone.usages = internal_zone_usages @staticmethod def _search_archetypes(catalog, usage_name):