add_retrofit_input_file

This commit is contained in:
Mohamed_Osman 2024-09-23 15:53:36 -04:00 committed by s_ranjbar
parent f9d27627e9
commit cbba9f30f1
3 changed files with 73 additions and 117 deletions

View File

@ -1,87 +1,54 @@
# from hub.city_model_structure.building import Building
# from hub.city_model_structure.city import City
# import hub.helpers.constants as cte
# import copy
# class RetrofitFactory:
# def __init__(self, retrofit_type, city):
# self._retrofit_type = retrofit_type
# self._city = city
# def apply_retrofit(self, wall_u_value=None, roof_u_value=None, ground_u_value=None):
# for building in self._city.buildings:
# self._apply_retrofit_to_building(building, wall_u_value, roof_u_value, ground_u_value)
# def _apply_retrofit_to_building(self, building: Building, wall_u_value, roof_u_value, ground_u_value):
# for thermal_zone in building.thermal_zones_from_internal_zones:
# for thermal_boundary in thermal_zone.thermal_boundaries:
# if wall_u_value is not None and thermal_boundary.type == cte.WALL and thermal_boundary.u_value > wall_u_value:
# self._change_thermal_resistance(thermal_boundary, wall_u_value)
# thermal_boundary.u_value = wall_u_value
# elif roof_u_value is not None and thermal_boundary.type == cte.ROOF:
# self._change_thermal_resistance(thermal_boundary, roof_u_value)
# thermal_boundary.u_value = roof_u_value
# elif ground_u_value is not None and thermal_boundary.type == cte.GROUND:
# self._change_thermal_resistance(thermal_boundary, ground_u_value)
# thermal_boundary.u_value = ground_u_value
# print("thermal_boundary.u_value",thermal_boundary.u_value, thermal_boundary.type)
# def _change_thermal_resistance(self, thermal_boundary, new_u_value):
# old_u_value = thermal_boundary.u_value
# new_u_value = new_u_value
# if new_u_value < old_u_value:
# delta_r = (1 / new_u_value) - (1 / old_u_value)
# for layer in thermal_boundary.layers:
# if "virtual_no_mass" in layer.material_name.lower():
# new_thermal_resistance = layer.thermal_resistance + delta_r
# layer.thermal_resistance = new_thermal_resistance
# else:
# print("New U-value:", new_u_value, "is not less than old U-value:", old_u_value, "for thermal boundary type:", thermal_boundary.type)
# def enrich(self, wall_u_value=None, roof_u_value=None, ground_u_value=None):
# # This method can be expanded to include different retrofit strategies
# if self._retrofit_type == 'basic':
# self.apply_retrofit(wall_u_value=0.247, roof_u_value=0.138, ground_u_value=0.156)
# elif self._retrofit_type == 'advanced':
# self.apply_retrofit(wall_u_value=0.11, roof_u_value=0.08, ground_u_value=0.1)
# #add option for custom wall only, roof only, ground only, the user choose the values
# elif self._retrofit_type == 'custom':
# # Use user-defined custom values (if provided)
# self.apply_retrofit(wall_u_value=wall_u_value, roof_u_value=roof_u_value, ground_u_value=ground_u_value)
# else:
# print("Invalid retrofit type:", self._retrofit_type)
from hub.city_model_structure.building import Building from hub.city_model_structure.building import Building
from hub.city_model_structure.city import City from hub.city_model_structure.city import City
import hub.helpers.constants as cte import hub.helpers.constants as cte
import copy
class RetrofitFactory: class RetrofitFactory:
def __init__(self, retrofit_types, city): def __init__(self, retrofit_data, city):
""" """
:param retrofit_types: List of retrofit types to apply. Options are 'construction', 'windows', 'infiltration'. :param retrofit_data: Dictionary mapping building IDs to their retrofit data.
:param city: The City object containing the buildings to retrofit. :param city: The City object containing the buildings to retrofit.
""" """
self._retrofit_types = retrofit_types self._retrofit_data = retrofit_data
self._city = city self._city = city
def apply_construction_retrofit(self, wall_u_value=None, roof_u_value=None, ground_u_value=None): def enrich(self):
for building in self._city.buildings: for building in self._city.buildings:
self._apply_construction_retrofit_to_building(building, wall_u_value, roof_u_value, ground_u_value) building_id = str(building.name) # Convert ID to string to match JSON keys
if building_id in self._retrofit_data:
print(f"Applying retrofits to building ID {building_id}")
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)
else:
print(f"No retrofit data for building ID {building_id}")
def _apply_retrofits_to_building(self, building, retrofit_types, retrofit_params):
if 'construction' in retrofit_types:
self._apply_construction_retrofit_to_building(building, retrofit_params)
if 'infiltration' in retrofit_types:
self._reduce_infiltration_rate_by_percentage(building, retrofit_params)
if 'windows' in retrofit_types:
self._apply_window_retrofit_to_building(building, retrofit_params)
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')
def _apply_construction_retrofit_to_building(self, building: Building, wall_u_value, roof_u_value, ground_u_value):
for thermal_zone in building.thermal_zones_from_internal_zones: for thermal_zone in building.thermal_zones_from_internal_zones:
for thermal_boundary in thermal_zone.thermal_boundaries: for thermal_boundary in thermal_zone.thermal_boundaries:
if wall_u_value is not None and thermal_boundary.type == cte.WALL and thermal_boundary.u_value > wall_u_value: if wall_u_value is not None and thermal_boundary.type == cte.WALL and thermal_boundary.u_value > wall_u_value:
self._change_thermal_resistance(thermal_boundary, wall_u_value) self._change_thermal_resistance(thermal_boundary, wall_u_value)
thermal_boundary.u_value = wall_u_value thermal_boundary.u_value = wall_u_value
print(f"Updated wall U-value to {wall_u_value} in building {building.name}")
elif roof_u_value is not None and thermal_boundary.type == cte.ROOF and thermal_boundary.u_value > roof_u_value: elif roof_u_value is not None and thermal_boundary.type == cte.ROOF and thermal_boundary.u_value > roof_u_value:
self._change_thermal_resistance(thermal_boundary, roof_u_value) self._change_thermal_resistance(thermal_boundary, roof_u_value)
thermal_boundary.u_value = roof_u_value thermal_boundary.u_value = roof_u_value
print(f"Updated roof U-value to {roof_u_value} in building {building.name}")
elif ground_u_value is not None and thermal_boundary.type == cte.GROUND and thermal_boundary.u_value > ground_u_value: elif ground_u_value is not None and thermal_boundary.type == cte.GROUND and thermal_boundary.u_value > ground_u_value:
self._change_thermal_resistance(thermal_boundary, ground_u_value) self._change_thermal_resistance(thermal_boundary, ground_u_value)
thermal_boundary.u_value = ground_u_value thermal_boundary.u_value = ground_u_value
print("thermal_boundary.u_value", thermal_boundary.u_value, thermal_boundary.type) print(f"Updated ground U-value to {ground_u_value} in building {building.name}")
def _change_thermal_resistance(self, thermal_boundary, new_u_value): def _change_thermal_resistance(self, thermal_boundary, new_u_value):
old_u_value = thermal_boundary.u_value old_u_value = thermal_boundary.u_value
@ -91,57 +58,46 @@ class RetrofitFactory:
if "virtual_no_mass" in layer.material_name.lower(): if "virtual_no_mass" in layer.material_name.lower():
new_thermal_resistance = layer.thermal_resistance + delta_r new_thermal_resistance = layer.thermal_resistance + delta_r
layer.thermal_resistance = new_thermal_resistance layer.thermal_resistance = new_thermal_resistance
print(f"Increased thermal resistance by {delta_r} in layer {layer.material_name}")
else: else:
print("New U-value:", new_u_value, "is not less than old U-value:", old_u_value, "for thermal boundary type:", thermal_boundary.type) print(f"New U-value {new_u_value} is not less than old U-value {old_u_value} for thermal boundary type {thermal_boundary.type}")
def reduce_infiltration_rate_by_percentage(self, percentage): def _reduce_infiltration_rate_by_percentage(self, building: Building, retrofit_params):
""" percentage = retrofit_params.get('infiltration_reduction')
Reduce the infiltration_rate_system_off of each thermal zone by the given percentage. if percentage is None:
:param percentage: Percentage by which to reduce the infiltration rate (e.g., 20 for 20%) return
""" for thermal_zone in building.thermal_zones_from_internal_zones:
for building in self._city.buildings: thermal_archetype = thermal_zone.parent_internal_zone.thermal_archetype
for thermal_zone in building.thermal_zones_from_internal_zones: old_rate = thermal_archetype.infiltration_rate_for_ventilation_system_off
old_rate = thermal_zone.infiltration_rate_system_off new_rate = old_rate * (1 - percentage / 100)
new_rate = old_rate * (1 - percentage / 100) thermal_archetype.infiltration_rate_for_ventilation_system_off = new_rate
thermal_zone.infiltration_rate_system_off = new_rate print(f"Reduced infiltration rate from {old_rate} to {new_rate} in building {building.name}")
print(f"Reduced infiltration rate from {old_rate} to {new_rate} in thermal zone {thermal_zone}")
def apply_window_retrofit(self, overall_u_value=None, g_value=None):
""" def _apply_window_retrofit_to_building(self, building: Building, retrofit_params):
Apply window retrofit by changing window overall U-value and g-value. overall_u_value = retrofit_params.get('window_u_value')
:param overall_u_value: New overall U-value for the windows (if not None). g_value = retrofit_params.get('window_g_value')
:param g_value: New g-value (solar heat gain coefficient) for the windows (if not None).
""" for thermal_zone in building.thermal_zones_from_internal_zones:
for building in self._city.buildings: for thermal_boundary in thermal_zone.thermal_boundaries:
for thermal_zone in building.thermal_zones_from_internal_zones: if thermal_boundary.type == cte.WALL:
for thermal_boundary in thermal_zone.thermal_boundaries: construction_archetype = thermal_boundary._construction_archetype
# Only apply to walls (and roofs if skylights are considered) construction_archetype.window_overall_u_value = overall_u_value
if thermal_boundary.type in [cte.WALL]: # Add cte.ROOF if skylights are present construction_archetype.window_g_value = g_value
if hasattr(thermal_boundary, 'thermal_openings') and thermal_boundary.thermal_openings:
for opening in thermal_boundary.thermal_openings: if hasattr(thermal_boundary, 'thermal_openings') and thermal_boundary.thermal_openings:
if overall_u_value is not None and overall_u_value != 0: for opening in thermal_boundary.thermal_openings:
old_u_value = opening.overall_u_value if overall_u_value is not None and overall_u_value != 0:
opening.overall_u_value = overall_u_value old_u_value = opening.overall_u_value
print(f"Changed window overall_u_value from {old_u_value} to {opening.overall_u_value} in opening {opening}") opening.overall_u_value = overall_u_value
if g_value is not None and g_value != 0: print(f"Changed window U-value from {old_u_value} to {opening.overall_u_value} in building {building.name}")
old_g_value = opening.g_value if g_value is not None and g_value != 0:
opening.g_value = g_value old_g_value = opening.g_value
print(f"Changed window g_value from {old_g_value} to {opening.g_value} in opening {opening}") opening.g_value = g_value
else: print(f"Changed window g-value from {old_g_value} to {opening.g_value} in building {building.name}")
print(f"No thermal openings in thermal boundary {thermal_boundary} of type {thermal_boundary.type}")
else: else:
# Skip thermal boundaries that are not walls or roofs print(f"No thermal openings in thermal boundary {thermal_boundary} of type {thermal_boundary.type} in building {building.name}")
continue else:
# Skip thermal boundaries that are not walls
def enrich(self, wall_u_value=None, roof_u_value=None, ground_u_value=None, continue
infiltration_rate_percentage_reduction=None,
window_overall_u_value=None, window_g_value=None):
"""
Apply selected retrofits to the city.
"""
if 'construction' in self._retrofit_types:
self.apply_construction_retrofit(wall_u_value, roof_u_value, ground_u_value)
if 'infiltration' in self._retrofit_types and infiltration_rate_percentage_reduction is not None:
self.reduce_infiltration_rate_by_percentage(infiltration_rate_percentage_reduction)
if 'windows' in self._retrofit_types:
self.apply_window_retrofit(overall_u_value=window_overall_u_value, g_value=window_g_value)

View File

@ -8,12 +8,12 @@
"window_u_value": 1.1, "window_u_value": 1.1,
"window_g_value": 0.6 "window_g_value": 0.6
}, },
"175786": { "176293": {
"retrofit_types": ["windows"], "retrofit_types": ["windows"],
"window_u_value": 1.3, "window_u_value": 1.3,
"window_g_value": 0.5 "window_g_value": 0.5
}, },
"175787": { "182393": {
"retrofit_types": ["infiltration"], "retrofit_types": ["infiltration"],
"infiltration_reduction": 25 "infiltration_reduction": 25
} }

View File

@ -6,13 +6,13 @@ from hub.helpers.dictionaries import Dictionaries
from hub.imports.construction_factory import ConstructionFactory from hub.imports.construction_factory import ConstructionFactory
from hub.imports.usage_factory import UsageFactory from hub.imports.usage_factory import UsageFactory
from hub.imports.weather_factory import WeatherFactory from hub.imports.weather_factory import WeatherFactory
from hub.imports.retrofit_factory_virtual import RetrofitFactory from hub.imports.retrofit_factory import RetrofitFactory
import json import json
# Specify the GeoJSON file path # Specify the GeoJSON file path
input_files_path = (Path(__file__).parent / 'input_files') input_files_path = (Path(__file__).parent / 'input_files')
input_files_path.mkdir(parents=True, exist_ok=True) input_files_path.mkdir(parents=True, exist_ok=True)
geojson_file = process_geojson(x=-73.5681295982132, y=45.49218262677643, diff=0.0001) geojson_file = process_geojson(x=-73.5681295982132, y=45.49218262677643, diff=0.0001)
geojson_file_path = input_files_path / 'input_one_buildings.geojson' geojson_file_path = input_files_path / 'input_buildings.geojson'
retrofit_json_file_path = input_files_path / 'retrofit_scenarios.json' retrofit_json_file_path = input_files_path / 'retrofit_scenarios.json'
with open(retrofit_json_file_path, 'r') as f: with open(retrofit_json_file_path, 'r') as f:
@ -29,7 +29,7 @@ city = GeometryFactory('geojson',
# Enrich city data # Enrich city data
ConstructionFactory('cerc', city).enrich() ConstructionFactory('cerc', city).enrich()
UsageFactory('cerc', city).enrich() UsageFactory('cerc', city).enrich()
# Apply retrofits based on JSON data using building IDs
RetrofitFactory(retrofit_data, city).enrich() RetrofitFactory(retrofit_data, city).enrich()
WeatherFactory('epw', city).enrich() WeatherFactory('epw', city).enrich()