From cd6f4395bb4f67a679c242e96051be2341937869 Mon Sep 17 00:00:00 2001 From: Chris Mackey Date: Mon, 22 Apr 2024 17:41:42 -0700 Subject: [PATCH 1/2] fix(model): Ensure Model.reset_ids can also repair Surface BCs --- honeybee/model.py | 57 +++++++++++++++++++++++++++++++++++++++------ tests/model_test.py | 12 ++++++++++ 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/honeybee/model.py b/honeybee/model.py index 7da5a132..154c7783 100644 --- a/honeybee/model.py +++ b/honeybee/model.py @@ -1310,41 +1310,84 @@ def add_prefix(self, prefix): for shade_mesh in self._shade_meshes: shade_mesh.add_prefix(prefix) - def reset_ids(self): + def reset_ids(self, repair_surface_bcs=True): """Reset the identifiers of all Model objects to be derived from display_names. In the event that duplicate identifiers are found, an integer will be automatically appended to the new ID to make it unique. This is similar to the routines that automatically assign unique names to OpenStudio SDK objects. + + Args: + repair_surface_bcs: A Boolean to note whether all Surface boundary + conditions across the model should be updated with the new + identifiers that were generated from the display names. (Default: True). """ - self.reset_room_ids() + # set up dictionaries to hold various pieces of information + room_map = self.reset_room_ids() face_dict, ap_dict, dr_dict, shd_dict, sm_dict = {}, {}, {}, {}, {} + face_map, ap_map, dr_map = {}, {}, {} + # loop through the objects and change their identifiers for face in self.faces: - face.identifier = clean_and_number_string( + new_id = clean_and_number_string( face.display_name, face_dict, 'Face identifier') + face_map[face.identifier] = new_id + face.identifier = new_id for ap in self.apertures: - ap.identifier = clean_and_number_string( + new_id = clean_and_number_string( ap.display_name, ap_dict, 'Aperture identifier') + ap_map[ap.identifier] = new_id + ap.identifier = new_id for dr in self.doors: - dr.identifier = clean_and_number_string( + new_id = clean_and_number_string( dr.display_name, dr_dict, 'Door identifier') + dr_map[dr.identifier] = new_id + dr.identifier =new_id for shade in self.shades: shade.identifier = clean_and_number_string( shade.display_name, shd_dict, 'Shade identifier') for shade_mesh in self.shade_meshes: shade_mesh.identifier = clean_and_number_string( shade_mesh.display_name, sm_dict, 'ShadeMesh identifier') + # reset all of the Surface boundary conditions if requested + if repair_surface_bcs: + for room in self.rooms: + for face in room.faces: + if isinstance(face.boundary_condition, Surface): + old_objs = face.boundary_condition.boundary_condition_objects + new_objs = (face_map[old_objs[0]], room_map[old_objs[1]]) + new_bc = Surface(new_objs) + face.boundary_condition = new_bc + for ap in face.apertures: + old_objs = ap.boundary_condition.boundary_condition_objects + new_objs = (ap_map[old_objs[0]], face_map[old_objs[1]], + room_map[old_objs[2]]) + new_bc = Surface(new_objs, True) + ap.boundary_condition = new_bc + for dr in face.doors: + old_objs = dr.boundary_condition.boundary_condition_objects + new_objs = (dr_map[old_objs[0]], face_map[old_objs[1]], + room_map[old_objs[2]]) + new_bc = Surface(new_objs, True) + dr.boundary_condition = new_bc def reset_room_ids(self): """Reset the identifiers of the Model Rooms to be derived from display_names. In the event that duplicate Room identifiers are found, an integer will be automatically appended to the new Room ID to make it unique. + + Returns: + A dictionary that relates the old identifiers (keys) to the new + identifiers (values). This can be used to map between old and new + objects and update things like Surface boundary conditions. """ - room_dict = {} + room_dict, room_map = {}, {} for room in self.rooms: - room.identifier = clean_and_number_string( + new_id = clean_and_number_string( room.display_name, room_dict, 'Room identifier') + room_map[room.identifier] = new_id + room.identifier = new_id + return room_map def solve_adjacency( self, merge_coplanar=False, intersect=False, overwrite=False, diff --git a/tests/model_test.py b/tests/model_test.py index 0de92f85..b6465bff 100644 --- a/tests/model_test.py +++ b/tests/model_test.py @@ -380,6 +380,18 @@ def test_reset_room_ids(): assert new_model.rooms[0].identifier != parsed_model.rooms[0].identifier +def test_reset_ids(): + """Test the reset_room_ids method.""" + model_json = './tests/json/model_with_adiabatic.hbjson' + parsed_model = Model.from_hbjson(model_json) + + new_model = parsed_model.duplicate() + new_model.reset_ids(True) + + assert new_model.rooms[0].identifier != parsed_model.rooms[0].identifier + assert new_model.check_missing_adjacencies() == '' + + def test_offset_aperture_edges(): """Test the Face offset_aperture_edges method.""" model_json = './tests/json/room_for_window_offset.hbjson' From a4626264d08d13bb57762a267d7b757118a8a3a9 Mon Sep 17 00:00:00 2001 From: Chris Mackey Date: Tue, 23 Apr 2024 06:44:42 -0700 Subject: [PATCH 2/2] ci(python): Remove Python 3.7 as GitHub does not support it on Mac --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index af5b1016..f36d0ac0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -9,7 +9,7 @@ jobs: name: Unit tests strategy: matrix: - python-version: ['3.7', '3.10'] + python-version: ['3.10'] os: [macos-latest, ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }}