You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every query point on a convex curved boundary is extrapolated rather than
located, at every rank count including serial, and the caller is not told.
This came out of the #604 / #602 discussion about whether points on the domain
boundary are findable. The answer is that they are not, and that it is not a
parallel defect.
Measured
Annulus, radiusInner=0.5, radiusOuter=1.0, cellSize=0.15. A P2 MeshVariable carrying x^2 + 2 y^2, which P2 represents exactly, sampled at 36
angles chosen to fall BETWEEN boundary nodes. check_extrapolated=True reports
per point whether the value was located or extrapolated.
ring
extrapolated
max abs error
outer, r = R exactly
36/36
5.97e-02
outer, r = R(1 - 1e-9)
36/36
5.97e-02
outer, r = R(1 + 1e-9)
36/36
5.97e-02
inner, r = R exactly
0/36
2.8e-16
mid-annulus
0/36
6.7e-16
Identical at np=1, np=2 and np=4 — the numbers above do not change with rank
count.
Why, and why the two boundaries differ
The mesh is a polygon. On the OUTER boundary its chords sag inside the true
circle, so a point on the true circle between two boundary nodes is outside the
meshed domain by about the sagitta. On the INNER boundary the chords lie closer
to the centre than the true circle, so the meshed domain extends slightly further
in and a point at r = R_in is inside it. Which side the domain is on decides
whether "on the boundary" means inside or outside.
A point a nanometre inside the nominal outer radius is still outside the mesh,
which is why tightening the query radius does not help.
The error converges at O(h), not O(sagitta)
cellSize
extrapolated
max abs error
sagitta ~ h^2/8
0.300
36/36
1.095e-01
1.13e-02
0.150
36/36
5.970e-02
2.81e-03
0.075
36/36
2.668e-02
7.03e-04
The miss distance falls as h^2 but the error falls as h, so this is the
extrapolant's own error over a stencil of size h rather than the distance
travelled. Refinement helps, slowly: still 2.7% at cellSize=0.075.
Why it matters
evaluate and global_evaluate return return_value alone unless the caller
asks for check_extrapolated=True. So sampling a field on the outer boundary of
an annulus or a spherical shell — surface velocity, dynamic topography, a
boundary profile for a benchmark — silently returns an extrapolated value with a
first-order error, and nothing in the call says so.
Directly relevant to #320 (free-slip methods compared on Kramer annulus and
spherical benchmarks) and to anything reading a field on the outer surface of a
shell.
What the fix might be
Not obvious, and it is a contract decision rather than a bug fix:
Snap query points to the mesh. Pull a point that misses by less than a
cell inward to the nearest facet, and interpolate there. Cheap, and it makes r = R mean "on the meshed boundary" rather than "on the ideal circle".
Leave it and document it, with the guidance that boundary sampling should
use the mesh's own boundary nodes.
Option 2 is worth doing whatever else is decided.
Not a parallel problem
Worth stating plainly, because that is where the suspicion started: the parallel
best-claim fallback is working. Serial and parallel agree to the digit on every
row above, so the machinery that recovers unlocatable points is doing its job.
What is wrong is that a point on a curved boundary is genuinely outside the
domain we meshed.
Related: #604 (a located point interpolating to NaN — a different mechanism), #551 (the locator umbrella), #320.
Underworld development team with AI support from Claude Code
Every query point on a convex curved boundary is extrapolated rather than
located, at every rank count including serial, and the caller is not told.
This came out of the #604 / #602 discussion about whether points on the domain
boundary are findable. The answer is that they are not, and that it is not a
parallel defect.
Measured
Annulus,
radiusInner=0.5,radiusOuter=1.0,cellSize=0.15. A P2MeshVariablecarryingx^2 + 2 y^2, which P2 represents exactly, sampled at 36angles chosen to fall BETWEEN boundary nodes.
check_extrapolated=Truereportsper point whether the value was located or extrapolated.
r = Rexactlyr = R(1 - 1e-9)r = R(1 + 1e-9)r = RexactlyIdentical at np=1, np=2 and np=4 — the numbers above do not change with rank
count.
Why, and why the two boundaries differ
The mesh is a polygon. On the OUTER boundary its chords sag inside the true
circle, so a point on the true circle between two boundary nodes is outside the
meshed domain by about the sagitta. On the INNER boundary the chords lie closer
to the centre than the true circle, so the meshed domain extends slightly further
in and a point at
r = R_inis inside it. Which side the domain is on decideswhether "on the boundary" means inside or outside.
A point a nanometre inside the nominal outer radius is still outside the mesh,
which is why tightening the query radius does not help.
The error converges at O(h), not O(sagitta)
cellSizeThe miss distance falls as
h^2but the error falls ash, so this is theextrapolant's own error over a stencil of size
hrather than the distancetravelled. Refinement helps, slowly: still 2.7% at
cellSize=0.075.Why it matters
evaluateandglobal_evaluatereturnreturn_valuealone unless the callerasks for
check_extrapolated=True. So sampling a field on the outer boundary ofan annulus or a spherical shell — surface velocity, dynamic topography, a
boundary profile for a benchmark — silently returns an extrapolated value with a
first-order error, and nothing in the call says so.
Directly relevant to #320 (free-slip methods compared on Kramer annulus and
spherical benchmarks) and to anything reading a field on the outer surface of a
shell.
What the fix might be
Not obvious, and it is a contract decision rather than a bug fix:
cell inward to the nearest facet, and interpolate there. Cheap, and it makes
r = Rmean "on the meshed boundary" rather than "on the ideal circle".Does not fix the number, but it stops the error being invisible — and it is
the same request as A located point can interpolate to NaN, and #602 makes that invisible #604's.
use the mesh's own boundary nodes.
Option 2 is worth doing whatever else is decided.
Not a parallel problem
Worth stating plainly, because that is where the suspicion started: the parallel
best-claim fallback is working. Serial and parallel agree to the digit on every
row above, so the machinery that recovers unlocatable points is doing its job.
What is wrong is that a point on a curved boundary is genuinely outside the
domain we meshed.
Related: #604 (a located point interpolating to NaN — a different mechanism),
#551 (the locator umbrella), #320.
Underworld development team with AI support from Claude Code