Constraints and projection¶
A constraint says what a vertex may do. Every vertex gets one, resolved once; two shared operations then hold it at every step: remove the forbidden part of the move, and project back.
Choosing constraints¶
Frozen(points)What a constraint is¶
A constraint applies to vertices, not to the mesh: connectivity never changes. Read it as a boundary condition on the vertex’s motion:
constraint |
like |
removes from a move |
known geometry |
no geometry: fitted to the input |
|---|---|---|---|---|
|
Dirichlet: fixed |
all of it |
||
|
slip on a curve |
all but the curve’s tangent, then projects back |
|
a spline through the input boundary |
|
no penetration |
the normal part, then projects back |
|
the input faces, as a triangle surface |
|
slip, no target |
the part normal to the boundary; nothing projects back |
the boundary’s own tangent, every step |
|
free (nothing named) |
natural |
nothing |
With \(P\) the projection onto the target and \(n\), \(t\) its unit normal and tangent at \(P(x)\), the two operations are
\(\omega=1\) is the full projection; Laplace ramps it \(i/N\to1\).
One vertex of the jittered sphere, half a local edge along its shape gradient (the vertex whose gradient has the largest normal part): the raw step (red) is 88 % normal. constrain_direction removes that part with the sphere’s own normal and keeps the tangential step (blue); snap then removes the remaining distance to the sphere, 0.003 local edges here.
Targets¶
target |
what it is |
for |
|---|---|---|
|
exact surfaces |
a flat face, a ball |
|
a surface read off a tessellation: an approximation |
a CAD tessellation, a scanned wall |
|
your own closest-point and unit-normal functions |
an implicit surface, any other wall |
|
exact curves |
a straight edge, a round rim |
|
a cubic spline through ordered points |
a rim known only by its points; what |
|
your own |
any other edge |
Normals come from the target, so one folded quad cannot poison them; a tessellation is only as exact as its triangles.
Which vertices get which¶
One dimension below the element: a vertex sits on the boundary of whatever it belongs to.
mesh |
interior |
boundary |
corners |
|---|---|---|---|
planar quads |
free |
|
|
quads on a curved 3-D surface |
|
the open rim: |
|
hexes |
free |
faces: |
|
The hex smoother reuses the same objects: Smoothing a hex mesh (experimental).
Boundary settings¶
resolve(mesh, constraints, boundary=...) is only a shorthand: it states one constraint for every boundary vertex that
no constraint names.
|
states |
the vertex |
when |
|---|---|---|---|
|
|
stays as meshed |
the safest |
|
nothing |
moves as proposed: Laplace pulls a convex boundary in, the optimizer pushes it out |
its position does not matter |
|
|
slides along the boundary, never inward |
Laplace, Winslow; no geometry |
|
|
slides along, then is projected onto the fitted curve |
no geometry, any method |
Corners are frozen in every mode but "free". One vertex, proposed move to final position, under each:
the average of its quads' shrunk corners (rings), which lie on the chords
boundary="frozen", Frozen: the move is dropped
boundary="free": moves as proposed, 13.4 % of the edge inside the curve
boundary="tangent", Tangent: the normal part is removed; slides along, 6.1 % of the move off the curve
a curve fitted (slide) or given (OnCurve): tangent move, then projected onto it
turn 101°, its neighbours' 8°: a jump, frozen except under free
Tangent. Under it, Laplace and Winslow move a boundary vertex only tangentially: their shrink-and-average step would pull it
toward the chord between its neighbours, inside a convex boundary; the move (Laplace, Winslow) or the gradient
(optimizer) loses its component normal to the boundary, so the vertex slides along the boundary and never moves inward.
The tangent is that of the circle through the vertex and its two boundary neighbours, exact on a circle:
with \(a=x_{\text{prev}}-x\) and \(c=x_{\text{next}}-x\).
On a hex boundary a face vertex moves in its patch’s tangent plane and a patch-edge vertex along the edge’s tangent. Nothing pulls the vertex back, so a curved boundary is kept to second order, not exactly.
Slide and OnCurve are one behaviour, a tangent move then a projection onto a curve; only the curve’s origin differs:
|
|
|
|---|---|---|
the curve |
your own, exact |
a cubic spline through the input boundary vertices: periodic on a corner-free loop, 3-D on a surface mesh |
cut at |
your choice of |
corners, and vertices another constraint claims |
holds |
the true shape |
the input’s shape: a badly sampled boundary stays badly sampled |
hexes |
|
per patch a plane or its input faces; per patch edge a line or spline |
On a curve Laplace projects its proposed point directly; Winslow and the optimizer take the tangent step first. Both end on the curve.
Known geometry goes on the boundary as OnCurve; without it, "slide" fits one to the input and "tangent" only
slides along the input boundary. On the free disk below the optimizer reaches the same shape under both:
annulus
min J 0.238
min J 0.995 · area +25.8 %
min J 0.998 · area +0.0 %
min J 0.998 · area +0.0 %
free disk
min J 0.266
min J 0.856 · area +61.7 %
min J 0.857 · area +0.0 %
min J 0.856 · area +0.0 %
Both inputs of the comparison under optimize(iters=200), no constraint named. Annulus: its 52 boundary vertices move along the boundary and its 4 corners are frozen (dots); the 169 interior vertices are free. Free disk: a circle has no corner, so all 24 boundary vertices move. Under "tangent" the optimizer runs 200 iterations to min scaled J 0.857, as under "frozen" (0.857); under "slide" it reaches 0.856 with the area kept.
Corners¶
A boundary vertex is a corner when its turn is a jump: above corner_deg (30 degrees) and above three times
the mean turn of its two boundary neighbours. A vertex without exactly two boundary neighbours is one too.
boundary |
turn at a vertex |
its neighbours’ |
corner |
|---|---|---|---|
a square’s corner |
90° |
0° |
yes |
a circle sampled with 8 points |
45° |
45° |
no |
a 3:1 ellipse sampled with 12 points, at its tip |
78° |
33° |
no: ratio 2.4 |
On a surface mesh the turn is measured in the surface’s tangent plane, so the surface’s own bending is not a corner.
On hexes the patches split where faces meet at more than corner_deg; a vertex where three or more patches meet, or
where a patch edge turns by a jump, is a corner.
Precedence and conflicts¶
Frozen > OnCurve > OnSurface > Tangent > Free. A vertex on two surfaces or on two curves is frozen and listed in the report;
on one surface and one curve, the curve wins. A box mesh: face interiors OnSurface(plane), the 12 edges
OnCurve(line), the 8 corners Frozen. Name an edge vertex from both its faces and it freezes; a corner claimed by
two edges freezes.
Layers and columns¶
KeepLayer(seeds, rings) freezes every vertex within rings quad-rings of the seeds. SlideColumns(columns, direction)
ties a rigid column to one slide parameter; it is frozen whole if anything else claims a member. Details and
measurements: Boundary layers and grading.
Calls¶
call |
meaning |
|---|---|
|
never moves |
|
moves along the boundary only: the normal part of each move or gradient is removed; nothing projects it back |
|
stays on a |
|
the same along a |
|
freezes every vertex within |
|
rigid columns with one shared degree of freedom along |
|
resolves the claims once; |
|
distance of constrained vertices to their targets and the largest move of a frozen one, in local edge lengths |
References¶
K. Mittal, P. Fischer, “Mesh smoothing for the spectral element method”, J. Sci. Comput. 78(2), 1152-1173 (2019), doi:10.1007/s10915-018-0812-9. Used for: The approach this smoother follows for spectral-element meshes. Cited as a record; its method is not summarised here.
K. Mittal, “Spectral element mesh generation and improvement methods”, M.S. thesis, University of Illinois at Urbana-Champaign (2016), hdl:2142/95509. Used for: With the paper above, the mesh-improvement approach this smoother follows for spectral-element meshes.