From 15e257ec0b92d85addc591f5adb84c98f54e031e Mon Sep 17 00:00:00 2001 From: lmoresi Date: Thu, 27 Aug 2026 12:26:25 +1000 Subject: [PATCH] Stop the mesh factories recommending a deprecated, broken API (#538) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ten comments across four meshing modules said # boundary_normals deprecated — use mesh.Gamma_P1 for boundary normals steering the reader from one deprecated API to another. `Gamma_P1` is itself deprecated, and its own docstring explains that off-kernel evaluation "falls back to a coordinate-based direction" rather than a normal. Measured on a unit box (#538), it returns the edge TANGENT on Left and Bottom -- (0,1) where the outward normal is (-1,0) -- and drifts up to 40 degrees along Right and Top. `mesh.boundary_normal(boundary)` is exact on all four edges to 1.6e-11. So the guidance pointed at the one thing that does not work. Comments only; no behaviour change. Found by sweeping for in-tree callers of APIs whose own docstrings mark them deprecated or back-compat-only, prompted by two bugs in a row turning out to be callers of documented-unsuitable APIs (#538 on Gamma_P1, #614 on boundary_flux at a constrained boundary). The rest of that sweep came back clean, which is worth recording so nobody repeats it: boundary_flux_to_field no internal callers (only its own alias + warning) swarm.points only the deprecation machinery itself; the ckdtree hits are its own unrelated self.points mesh/swarm.access() only inside commented-out code use_legacy_array no callers The one REAL internal dependency on Gamma_P1 is the mesh-smoothing path -- `_slip_normals` (meshing/smoothing/graph.py:547) evaluates it, with pre-touch plumbing in graph.py, api.py and mmpde.py. That is #538's actual defect and is left alone here: it needs the per-boundary normal threaded through, not a comment change. Underworld development team with AI support from Claude Code --- src/underworld3/meshing/annulus.py | 25 ++++++++++++++++++++----- src/underworld3/meshing/geographic.py | 10 ++++++++-- src/underworld3/meshing/segmented.py | 10 ++++++++-- src/underworld3/meshing/spherical.py | 5 ++++- 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/underworld3/meshing/annulus.py b/src/underworld3/meshing/annulus.py index bbc6b41c..5febbbcb 100644 --- a/src/underworld3/meshing/annulus.py +++ b/src/underworld3/meshing/annulus.py @@ -265,7 +265,10 @@ class boundary_normals(Enum): Right = new_mesh.CoordinateSystem.unit_e_1 Centre = None - # boundary_normals deprecated — use mesh.Gamma_P1 for boundary normals + # boundary_normals deprecated — use mesh.Gamma inside integrands and BCs, + # or mesh.boundary_normal(boundary) for a per-boundary P1 normal field. + # NOT mesh.Gamma_P1: it is deprecated too, and off-kernel it falls back to + # a coordinate direction rather than a normal (#538). return new_mesh @@ -537,7 +540,10 @@ class boundary_normals(Enum): Upper = new_mesh.CoordinateSystem.unit_e_0 Centre = None - # boundary_normals deprecated — use mesh.Gamma_P1 for boundary normals + # boundary_normals deprecated — use mesh.Gamma inside integrands and BCs, + # or mesh.boundary_normal(boundary) for a per-boundary P1 normal field. + # NOT mesh.Gamma_P1: it is deprecated too, and off-kernel it falls back to + # a coordinate direction rather than a normal (#538). # Full annulus: rigid rotation about z-axis x, y = new_mesh.X @@ -790,7 +796,10 @@ class boundary_normals(Enum): Upper = new_mesh.CoordinateSystem.unit_e_0 Centre = None - # boundary_normals deprecated — use mesh.Gamma_P1 for boundary normals + # boundary_normals deprecated — use mesh.Gamma inside integrands and BCs, + # or mesh.boundary_normal(boundary) for a per-boundary P1 normal field. + # NOT mesh.Gamma_P1: it is deprecated too, and off-kernel it falls back to + # a coordinate direction rather than a normal (#538). return new_mesh @@ -1120,7 +1129,10 @@ class boundary_normals(Enum): ) Centre = None - # boundary_normals deprecated — use mesh.Gamma_P1 for boundary normals + # boundary_normals deprecated — use mesh.Gamma inside integrands and BCs, + # or mesh.boundary_normal(boundary) for a per-boundary P1 normal field. + # NOT mesh.Gamma_P1: it is deprecated too, and off-kernel it falls back to + # a coordinate direction rather than a normal (#538). # Full annulus with spokes: rigid rotation about z-axis x, y = new_mesh.X @@ -1715,7 +1727,10 @@ class boundary_normals(Enum): Internal = new_mesh.CoordinateSystem.unit_e_0 Centre = None - # boundary_normals deprecated — use mesh.Gamma_P1 for boundary normals + # boundary_normals deprecated — use mesh.Gamma inside integrands and BCs, + # or mesh.boundary_normal(boundary) for a per-boundary P1 normal field. + # NOT mesh.Gamma_P1: it is deprecated too, and off-kernel it falls back to + # a coordinate direction rather than a normal (#538). # Full disc with internal boundaries: rigid rotation about z-axis x, y = new_mesh.X diff --git a/src/underworld3/meshing/geographic.py b/src/underworld3/meshing/geographic.py index 6a2aafba..fe7a6c97 100644 --- a/src/underworld3/meshing/geographic.py +++ b/src/underworld3/meshing/geographic.py @@ -402,7 +402,10 @@ class boundary_normals(Enum): sympy.Piecewise((1.0, new_mesh.CoordinateSystem.R[0] > 0.99 * radiusOuter), (0.0, True)) ) - # boundary_normals deprecated — use mesh.Gamma_P1 for boundary normals + # boundary_normals deprecated — use mesh.Gamma inside integrands and BCs, + # or mesh.boundary_normal(boundary) for a per-boundary P1 normal field. + # NOT mesh.Gamma_P1: it is deprecated too, and off-kernel it falls back to + # a coordinate direction rather than a normal (#538). return new_mesh @@ -840,6 +843,9 @@ class boundary_normals(Enum): East = new_mesh.CoordinateSystem.geo.unit_east # Eastward at east boundary West = new_mesh.CoordinateSystem.geo.unit_west # Westward at west boundary - # boundary_normals deprecated — use mesh.Gamma_P1 for boundary normals + # boundary_normals deprecated — use mesh.Gamma inside integrands and BCs, + # or mesh.boundary_normal(boundary) for a per-boundary P1 normal field. + # NOT mesh.Gamma_P1: it is deprecated too, and off-kernel it falls back to + # a coordinate direction rather than a normal (#538). return new_mesh diff --git a/src/underworld3/meshing/segmented.py b/src/underworld3/meshing/segmented.py index e71c86a8..f9e624e9 100644 --- a/src/underworld3/meshing/segmented.py +++ b/src/underworld3/meshing/segmented.py @@ -675,7 +675,10 @@ class boundary_normals(Enum): ) Centre = None - # boundary_normals deprecated — use mesh.Gamma_P1 for boundary normals + # boundary_normals deprecated — use mesh.Gamma inside integrands and BCs, + # or mesh.boundary_normal(boundary) for a per-boundary P1 normal field. + # NOT mesh.Gamma_P1: it is deprecated too, and off-kernel it falls back to + # a coordinate direction rather than a normal (#538). # Full segmented spherical shell: 3 rigid rotation modes x, y, z = new_mesh.X @@ -1094,7 +1097,10 @@ class boundary_normals(Enum): ) Centre = None - # boundary_normals deprecated — use mesh.Gamma_P1 for boundary normals + # boundary_normals deprecated — use mesh.Gamma inside integrands and BCs, + # or mesh.boundary_normal(boundary) for a per-boundary P1 normal field. + # NOT mesh.Gamma_P1: it is deprecated too, and off-kernel it falls back to + # a coordinate direction rather than a normal (#538). # Solid sphere: 3 rigid rotation modes x, y, z = new_mesh.X diff --git a/src/underworld3/meshing/spherical.py b/src/underworld3/meshing/spherical.py index 4f8c97a2..1e2a7618 100644 --- a/src/underworld3/meshing/spherical.py +++ b/src/underworld3/meshing/spherical.py @@ -1351,7 +1351,10 @@ class boundary_normals(Enum): Lower = new_mesh.CoordinateSystem.unit_e_0 Upper = new_mesh.CoordinateSystem.unit_e_0 - # boundary_normals deprecated — use mesh.Gamma_P1 for boundary normals + # boundary_normals deprecated — use mesh.Gamma inside integrands and BCs, + # or mesh.boundary_normal(boundary) for a per-boundary P1 normal field. + # NOT mesh.Gamma_P1: it is deprecated too, and off-kernel it falls back to + # a coordinate direction rather than a normal (#538). # Full cubed sphere: 3 rigid rotation modes x, y, z = new_mesh.X