diff --git a/RetrofitFactory_Documentation.txt b/RetrofitFactory_Documentation.txt new file mode 100644 index 00000000..57f87d66 --- /dev/null +++ b/RetrofitFactory_Documentation.txt @@ -0,0 +1,187 @@ + +RetrofitFactory Documentation + +Overview +RetrofitFactory is a tool designed to apply energy efficiency retrofits to buildings within a city model. It supports multiple retrofit types, including construction improvements, infiltration reduction, and window upgrades. + +Usage + +Basic Implementation +```python +from hub.imports.retrofit_factory import RetrofitFactory + +# Load retrofit data from JSON file +with open('retrofit_scenarios.json', 'r') as f: + retrofit_data = json.load(f) + +# Apply retrofits to a city +retrofit_factory = RetrofitFactory(retrofit_data, city) +retrofit_factory.enrich() +``` + +Retrofit Data Structure +The retrofit data is stored as a JSON object where building IDs serve as keys and retrofit specifications as values: +```json +{ + "building_id": { + "retrofit_types": ["construction", "infiltration", "windows"], + "wall_u_value": 0.3, + "roof_u_value": 0.2, + "ground_u_value": 0.25, + "infiltration_reduction": 30, + "window_u_value": 1.5, + "window_g_value": 0.6 + } +} +``` + +Supported Retrofit Types +RetrofitFactory supports the following types of retrofits: + +1. Construction Retrofits +Modifies U-values for walls, roofs, and ground surfaces, but only if the new U-value is lower than the existing one. The retrofit improves thermal resistance of building materials. + +Parameters: +- wall_u_value: Target U-value for walls (W/m²K) +- roof_u_value: Target U-value for roofs (W/m²K) +- ground_u_value: Target U-value for ground surfaces (W/m²K) + +2. Infiltration Retrofits +Reduces air infiltration rate as a percentage, applied to the ventilation system when off. + +Parameters: +- infiltration_reduction: Percentage reduction in infiltration rate (0-100) + +3. Window Retrofits +Updates window thermal properties by modifying the U-value and solar heat gain coefficient (g-value). + +Parameters: +- window_u_value: Target U-value for windows (W/m²K) +- window_g_value: Target solar heat gain coefficient (0-1) + +Implementation Details + +Class Structure +```python +class RetrofitFactory: + def __init__(self, retrofit_data: dict, city: City): + self._retrofit_data = retrofit_data + self._city = city +``` + +Main Methods + +1. enrich() +Applies retrofits to all buildings in the city. It iterates over each building, retrieves its corresponding retrofit data, and applies the specified retrofits. + +```python +def enrich(self): + for building in self._city.buildings: + building_id = str(building.name) + if building_id in self._retrofit_data: + building_retrofit_data = self._retrofit_data[building_id] + retrofit_types = building_retrofit_data.get('retrofit_types', []) + self._apply_retrofits_to_building(building, retrofit_types, building_retrofit_data) +``` + +2. _apply_retrofits_to_building() +Handles applying the specified retrofits to an individual building based on its retrofit data. + +3. _apply_construction_retrofit_to_building() +Applies construction retrofits by modifying U-values for walls, roofs, and ground surfaces. Only updates if the new U-value is lower than the existing value. + +```python +def _apply_construction_retrofit_to_building(self, building: Building, retrofit_params): + wall_u_value = retrofit_params.get('wall_u_value') + roof_u_value = retrofit_params.get('roof_u_value') + ground_u_value = retrofit_params.get('ground_u_value') +``` + +Thermal resistance is calculated as: +ΔR = (1 / U_new) - (1 / U_old) + +```python +def _change_thermal_resistance(self, thermal_boundary, new_u_value): + old_u_value = thermal_boundary.u_value + if new_u_value < old_u_value: + delta_r = (1 / new_u_value) - (1 / old_u_value) +``` + +4. _reduce_infiltration_rate_by_percentage() +Reduces the infiltration rate by the specified percentage. + +```python +def _reduce_infiltration_rate_by_percentage(self, building: Building, retrofit_params): + percentage = retrofit_params.get('infiltration_reduction') + if percentage is not None: + new_rate = old_rate * (1 - percentage / 100) +``` + +5. _apply_window_retrofit_to_building() +Updates the overall U-value and g-value of windows. + +```python +def _apply_window_retrofit_to_building(self, building: Building, retrofit_params): + overall_u_value = retrofit_params.get('window_u_value') + g_value = retrofit_params.get('window_g_value') +``` + +Error Handling +RetrofitFactory includes various error prevention mechanisms: +- Building ID Validation: Logs missing retrofit data for buildings not found in the input. +- U-value Validation: Only applies if the new U-value is lower than the old one. +- Null Checks: Ensures that parameters like infiltration_reduction are not null. +- Type Validation: Checks for required attributes, such as thermal boundaries and openings. + +Data Validation + +1. Building ID Validation +```python +building_id = str(building.name) +if building_id in self._retrofit_data: + # Process building +else: + print(f"No retrofit data for building ID {building_id}") +``` + +2. U-value and Window Value Validation +```python +if new_u_value < old_u_value: + # Apply change +else: + print(f"New U-value {new_u_value} is not less than old U-value {old_u_value}") + +if overall_u_value is not None and overall_u_value != 0: + # Apply change +``` + +Building Model Integration +RetrofitFactory relies on the city model to access thermal zones, boundaries, and construction properties of buildings. For example: +- Thermal Zone Access: +```python +for thermal_zone in building.thermal_zones_from_internal_zones: + thermal_archetype = thermal_zone.parent_internal_zone.thermal_archetype +``` + +- Construction Properties Access: +```python +construction_archetype = thermal_boundary._construction_archetype +construction_archetype.window_overall_u_value = overall_u_value +construction_archetype.window_g_value = g_value +``` + +Logging and Debugging +RetrofitFactory includes detailed logging for tracking the progress and results of retrofits: +- Logs retrofit application: print(f"Applying retrofits to building ID {building_id}") +- Logs property updates: print(f"Updated wall U-value to {wall_u_value} in building {building.name}") +- Logs missing data: print(f"No retrofit data for building ID {building_id}") + +Performance Considerations +- Memory Efficiency: Directly modifies existing objects instead of creating new copies. +- Computational Efficiency: Only processes buildings with available retrofit data and skips unnecessary thermal boundaries. + +Integration Requirements +To function correctly, the city model must provide: +- Unique building names convertible to strings. +- Buildings with thermal zones and boundaries that contain layers for construction retrofits. +- Access to thermal zone properties and boundary layers. diff --git a/hub/catalog_factories/construction/cerc_catalog.py b/hub/catalog_factories/construction/cerc_catalog.py index 728c3943..93544fe8 100644 --- a/hub/catalog_factories/construction/cerc_catalog.py +++ b/hub/catalog_factories/construction/cerc_catalog.py @@ -1,8 +1,6 @@ """ Cerc construction catalog (Copy of Nrcan 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 +Catlog Coder Mohamed Osman mohamed.osman@mail.concordia.ca """ import json @@ -24,7 +22,7 @@ class CercCatalog(Catalog): """ def __init__(self, path): _path_archetypes = Path(path / 'cerc_archetypes.json').resolve() - _path_constructions = (path / 'cerc_constructions.json').resolve() + _path_constructions = Path(path / 'cerc_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: diff --git a/hub/imports/retrofit_factory.py b/hub/imports/retrofit_factory.py index 54675d8d..d63d2862 100644 --- a/hub/imports/retrofit_factory.py +++ b/hub/imports/retrofit_factory.py @@ -1,7 +1,14 @@ +""" +RetrofitFactory retrieve the specific construction module for the given region +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2024 Concordia CERC group +Project Coder mohamed Osman mohamed.osman@mail.concordia.ca +""" + from hub.city_model_structure.building import Building from hub.city_model_structure.city import City import hub.helpers.constants as cte - +# from hub.data.retrofit_data import retrofit_data class RetrofitFactory: def __init__(self, retrofit_data, city): """ diff --git a/input_files/retrofit_scenarios.json b/input_files/retrofit_scenarios.json index dc26bdfb..aea1403b 100644 --- a/input_files/retrofit_scenarios.json +++ b/input_files/retrofit_scenarios.json @@ -5,8 +5,8 @@ "roof_u_value": 0.15, "ground_u_value": 0.18, "infiltration_reduction": 30, - "window_u_value": 1.1, - "window_g_value": 0.6 + "window_u_value": 0.8, + "window_g_value": 0.4 }, "176293": { "retrofit_types": ["windows"], diff --git a/main.py b/main.py index 60ae2e54..ecac641b 100644 --- a/main.py +++ b/main.py @@ -27,8 +27,8 @@ city = GeometryFactory('geojson', function_field='function', function_to_hub=Dictionaries().montreal_function_to_hub_function).city # Enrich city data -ConstructionFactory('nrcan', city).enrich() -UsageFactory('nrcan', city).enrich() +ConstructionFactory('cerc', city).enrich() +UsageFactory('cerc', city).enrich() RetrofitFactory(retrofit_data, city).enrich()