diff --git a/.gitignore b/.gitignore index de610241..c46d9b4c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ cerc_hub.egg-info /out_files /input_files /CitRetrofitEnv +/cityretrofit_env +/.eggs \ No newline at end of file diff --git a/hub/imports/retrofit_factory.py b/hub/imports/retrofit_factory.py index f1b20ef6..3f12a032 100644 --- a/hub/imports/retrofit_factory.py +++ b/hub/imports/retrofit_factory.py @@ -9,27 +9,40 @@ class RetrofitFactory: def apply_retrofit(self, wall_u_value=None, roof_u_value=None, ground_u_value=None): for building in self._city.buildings: + print("building", building.name) 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 internal_zone in building.internal_zones: - # print(internal_zone.id) - for thermal_zone in building.thermal_zones_from_internal_zones: for thermal_boundary in thermal_zone.thermal_boundaries: if wall_u_value and thermal_boundary.type == cte.WALL: - print(thermal_boundary.u_value) + print("old_u_value", thermal_boundary.u_value) + self._change_thermal_resistance(thermal_boundary, wall_u_value) thermal_boundary.u_value = wall_u_value - print(thermal_boundary.u_value) elif roof_u_value and thermal_boundary.type == cte.ROOF: - print("roof", thermal_boundary.u_value) + self._change_thermal_resistance(thermal_boundary, roof_u_value) thermal_boundary.u_value = roof_u_value - print("roof", thermal_boundary.u_value) elif ground_u_value and thermal_boundary.type == cte.GROUND: + self._change_thermal_resistance(thermal_boundary, ground_u_value) thermal_boundary.u_value = ground_u_value - print("ground", thermal_boundary.u_value) + + + def _change_thermal_resistance(self, thermal_boundary, u_value): + old_u_value =thermal_boundary.u_value + new_u_value = u_value + if new_u_value < old_u_value: + delta_r = 1/(old_u_value - new_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: + pass + def enrich(self): # This method can be expanded to include different retrofit strategies if self._retrofit_type == 'basic': - self.apply_retrofit(wall_u_value=0.85, roof_u_value=0.95, ground_u_value=0.95) \ No newline at end of file + 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.15, roof_u_value=0.08, ground_u_value=0.1) diff --git a/hub/imports/retrofit_factory_virtual.py b/hub/imports/retrofit_factory_virtual.py new file mode 100644 index 00000000..d344a2ef --- /dev/null +++ b/hub/imports/retrofit_factory_virtual.py @@ -0,0 +1,63 @@ +from hub.city_model_structure.city import City +from hub.city_model_structure.building_demand.thermal_archetype import ThermalArchetype +from hub.city_model_structure.building_demand.construction import Construction +from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory + +class RetrofitFactoryVirtual: + def __init__(self, retrofit_type, city): + self._retrofit_type = retrofit_type + self._city = city + self._cerc_catalog = ConstructionCatalogFactory('cerc').catalog + + def apply_retrofit(self, **u_values): + for building in self._city.buildings: + for internal_zone in building.internal_zones: + self._apply_retrofit_to_thermal_archetype(internal_zone.thermal_archetype, u_values) + + def _apply_retrofit_to_thermal_archetype(self, thermal_archetype: ThermalArchetype, u_values): + for construction in thermal_archetype.constructions: + if construction.type in u_values and any(surface in construction.type.lower() for surface in ['wall', 'roof', 'ground']): + self._update_construction_u_value(construction, u_values[construction.type]) + + def _update_construction_u_value(self, construction: Construction, new_u_value): + virtual_no_mass_layer = next((layer for layer in construction.layers if "virtual_no_mass" in layer.material_name.lower()), None) + + if virtual_no_mass_layer: + old_r_value = 1 / construction.u_value + new_r_value = 1 / new_u_value + delta_r = new_r_value - old_r_value + + virtual_no_mass_layer.thermal_resistance += delta_r + print(f"Updated {construction.type} - New thermal resistance: {virtual_no_mass_layer.thermal_resistance}") + construction.u_value = new_u_value + + def modify_thermal_resistance(self, new_thermal_resistance): + import sys + + for building in self._city.buildings: + for zone in building.thermal_zones_from_internal_zones: + for boundary in zone.thermal_boundaries: + if any(surface in boundary.type.lower() for surface in ['wall', 'roof', 'ground']): + layers = getattr(boundary, 'get_layers', lambda: [])() + sys.stderr.write(f"Checking boundary type: {boundary.type}, found {len(layers)} layers\n") + for layer in layers: + if layer and hasattr(layer, 'material_name'): + sys.stderr.write(f"Checking layer: {layer.material_name}\n") + if "virtual_no_mass" in layer.material_name.lower(): + layer.thermal_resistance = new_thermal_resistance + sys.stderr.write(f"Set thermal resistance to {new_thermal_resistance} for {layer.material_name} in {boundary.type}\n") + sys.stderr.flush() + + def enrich(self): + if self._retrofit_type == 'basic': + self.apply_retrofit( + OutdoorsWall=0.85, + GroundWall=0.85, + OutdoorsRoofCeiling=0.95, + GroundRoofCeiling=0.95, + OutdoorsFloor=0.95, + GroundFloor=0.95 + ) + # After applying the retrofit, set a specific thermal resistance + self.modify_thermal_resistance(2.0) + # Add more retrofit types as needed \ No newline at end of file diff --git a/main.py b/main.py index ec7e1b1d..b4b45b91 100644 --- a/main.py +++ b/main.py @@ -7,6 +7,7 @@ from hub.imports.construction_factory import ConstructionFactory from hub.imports.usage_factory import UsageFactory from hub.imports.weather_factory import WeatherFactory from hub.imports.retrofit_factory import RetrofitFactory + # Specify the GeoJSON file path input_files_path = (Path(__file__).parent / 'input_files') input_files_path.mkdir(parents=True, exist_ok=True) @@ -22,9 +23,9 @@ city = GeometryFactory('geojson', function_field='function', function_to_hub=Dictionaries().montreal_function_to_hub_function).city # Enrich city data -ConstructionFactory('cerc', city).enrich() -UsageFactory('cerc', city).enrich() -RetrofitFactory('basic', city).enrich() +ConstructionFactory('nrcan', city).enrich() +UsageFactory('nrcan', city).enrich() +RetrofitFactory('advanced', city).enrich() WeatherFactory('epw', city).enrich() energy_plus_workflow(city)