diff --git a/crates/specialized/rtx-cfd/src/mesh/patch_mesh.rs b/crates/specialized/rtx-cfd/src/mesh/patch_mesh.rs index 235ae29..80fe1b0 100644 --- a/crates/specialized/rtx-cfd/src/mesh/patch_mesh.rs +++ b/crates/specialized/rtx-cfd/src/mesh/patch_mesh.rs @@ -173,6 +173,23 @@ impl PatchMesh { k * (self.ns + 1) + i } /// Node coordinates. + /// `[x_min, x_max, y_min, y_max]` over the nodes. + pub fn bounding_box(&self) -> [f64; 4] { + let (mut b, mut first) = ([0.0; 4], true); + for (&x, &y) in self.x.iter().zip(&self.y) { + if first { + b = [x, x, y, y]; + first = false; + } else { + b[0] = b[0].min(x); + b[1] = b[1].max(x); + b[2] = b[2].min(y); + b[3] = b[3].max(y); + } + } + b + } + pub fn node_xy(&self, n: usize) -> [f64; 2] { [self.x[n], self.y[n]] } diff --git a/crates/specialized/rtx-cfd/src/solvers/incompressible/overset/overlap.rs b/crates/specialized/rtx-cfd/src/solvers/incompressible/overset/overlap.rs index 2e208c6..a20ca16 100644 --- a/crates/specialized/rtx-cfd/src/solvers/incompressible/overset/overlap.rs +++ b/crates/specialized/rtx-cfd/src/solvers/incompressible/overset/overlap.rs @@ -162,13 +162,20 @@ impl OverlapMap { let primal = QuadIndex::primal(patch); let body = body_polygon(patch); - // 1. Cells. + // 1. Cells. A centre outside the patch's node bounding box lies in + // no patch cell and outside the body (which the patch encloses): + // Active without a point location (PERF-2 P1.2, the same class + // the search would return). + let bbox = patch.bounding_box(); let mut class = vec![CellClass::Active; nx * ny]; let mut hole_cells = 0; for j in 0..ny { for i in 0..nx { let x = (i as f64 + 0.5) * dx; let y = (j as f64 + 0.5) * dy; + if x < bbox[0] || x > bbox[1] || y < bbox[2] || y > bbox[3] { + continue; + } let in_hole = match primal.locate(patch, x, y) { Some(c) => patch.cell_ki(c).0 <= hole_row_max, None => body