diff --git a/fdsreader/bndf/obstruction.py b/fdsreader/bndf/obstruction.py index d9ba6a4..1082df8 100644 --- a/fdsreader/bndf/obstruction.py +++ b/fdsreader/bndf/obstruction.py @@ -574,7 +574,7 @@ def get_nearest_patch(self, x: float = None, y: float = None, z: float = None): """ if self.has_boundary_data: d_min = np.finfo(float).max - patches_min = list() + patches_with_dist = list() for subobst in self._subobstructions.values(): for patch in subobst.get_data(self.quantities[0])._patches: @@ -582,16 +582,23 @@ def get_nearest_patch(self, x: float = None, y: float = None, z: float = None): dy = max(patch.extent.y_start - y, 0, y - patch.extent.y_end) if y is not None else 0 dz = max(patch.extent.z_start - z, 0, z - patch.extent.z_end) if z is not None else 0 d = np.sqrt(dx * dx + dy * dy + dz * dz) - if d <= d_min: + if d < d_min: d_min = d - patches_min.append(patch) - - if x is not None: - patches_min.sort(key=lambda patch: (patch.extent.x_end - patch.extent.x_start)) - if y is not None: - patches_min.sort(key=lambda patch: (patch.extent.y_end - patch.extent.y_start)) - if z is not None: - patches_min.sort(key=lambda patch: (patch.extent.z_end - patch.extent.z_start)) + patches_with_dist = [(patch, dx, dy, dz)] + elif math.isclose(d, d_min, rel_tol=1e-9, abs_tol=0.0): + patches_with_dist.append((patch, dx, dy, dz)) + + patches_min = [p[0] for p in patches_with_dist] + + if x is not None and len(patches_with_dist) > 1: + patches_with_dist.sort(key=lambda p: p[1]) + patches_min = [p[0] for p in patches_with_dist] + elif y is not None and len(patches_with_dist) > 1: + patches_with_dist.sort(key=lambda p: p[2]) + patches_min = [p[0] for p in patches_with_dist] + elif z is not None and len(patches_with_dist) > 1: + patches_with_dist.sort(key=lambda p: p[3]) + patches_min = [p[0] for p in patches_with_dist] if len(patches_min) > 0: return patches_min[0] diff --git a/tests/acceptance_tests/test_bndf.py b/tests/acceptance_tests/test_bndf.py index 1513649..1dabfdb 100644 --- a/tests/acceptance_tests/test_bndf.py +++ b/tests/acceptance_tests/test_bndf.py @@ -1,9 +1,36 @@ +import os from fdsreader import Simulation +TEST_DIR = os.path.dirname(os.path.abspath(__file__)) + def test_bndf(): - sim = Simulation("./bndf_data") + sim = Simulation(os.path.join(TEST_DIR, "../cases/bndf_data")) obst = sim.obstructions.get_nearest(-0.8, 1, 1) face = obst.get_global_boundary_data_arrays("Wall Temperature")[1] assert len(face[-1]) == 68 + + +def test_get_nearest_patch(): + """Test that get_nearest_patch returns correct face based on distance.""" + sim = Simulation(os.path.join(TEST_DIR, "../cases/bndf_data")) + obst = sim.obstructions[0] + + # Get patches for different points around the obstruction + # Bounding box: x=[-1, 2], y=[-1.2, 2.4], z=[-0.1, 0] + # Use z slightly inside the obstruction for side faces to avoid edge/face ties. + patch_x_plus = obst.get_nearest_patch(3, 0.5, -0.05) + patch_x_minus = obst.get_nearest_patch(-2, 0.5, -0.05) + patch_y_plus = obst.get_nearest_patch(0.5, 3, -0.05) + patch_y_minus = obst.get_nearest_patch(0.5, -2, -0.05) + patch_z_plus = obst.get_nearest_patch(0.5, 0.5, 1) + + # Orientations: 1=X+, 2=Y+, 3=Z+, -1=X-, -2=Y-, -3=Z- + assert patch_x_plus.orientation == 1 + assert patch_x_minus.orientation == -1 + assert patch_y_plus.orientation == 2 + assert patch_y_minus.orientation == -2 + assert patch_z_plus.orientation == 3 + + # Note: no -3 (z-minus) patch exists in this test data, so -z is not tested