Skip to content

Continuous wrapping method - #262

Open
1-Bart-1 wants to merge 2 commits into
mainfrom
wrap/rolling-ball
Open

Continuous wrapping method#262
1-Bart-1 wants to merge 2 commits into
mainfrom
wrap/rolling-ball

Conversation

@1-Bart-1

@1-Bart-1 1-Bart-1 commented Aug 17, 2026

Copy link
Copy Markdown
Member

Split out of #258, which carried this rewrite alongside unrelated section-order work and failed CI because of it.

What changes

shrink_wrap was a distance field: threshold at the ball radius, flood fill, erode back to clearance, trace the level set with marching squares, fair the result. Every step was bounded by the grid, so cell_size set the fidelity of the wrap and padding the field for min_concave_radius cost time in both directions.

pivot_contour now rolls the ball around the cloud and emits what its contact side sweeps: an arc of radius clearance about each point it touches, joined by an arc of the ball radius across each gap it cannot enter. Those arcs are the wrap boundary, so there is no resolution to choose.

  • ShrinkWrap's cell_size becomes min_clearance — a floor on clearance rather than a grid pitch. Still accepted under the old name.
  • The wrap sits at exactly clearance from the cloud instead of a cell over it: a V3 canopy's aft strip is 2 * clearance thick where the grid gave 3.5 * cell_size.
  • min_concave_radius stops costing anything. One V3 slice at radius 0.4 drops from 173 ms to 10 ms; at the default radius, 15 ms to 3 ms.

Resampling had to follow

push_arc! steps each arc to a chord tolerance, so its segments scale as sqrt(radius) and the trace's node spacing alternates by a factor of several between the two arc families. Diffusing the turning per node carried that alternation into the sampling measure, leaving resampled panel lengths oscillating by up to 5.7x between neighbours.

  • smoothed_curvature averages the turning over a fixed arclength band instead, which is independent of how the arcs happen to be stepped. Neighbour ratio drops to the 3.0 of a plain cosine-clustered .dat.
  • enforce_min_spacing! keeps cosine clustering — which thins as the square of the station count — from putting leading-edge panels a fraction of a percent of chord long.

Known limitation — not ready to merge

XFoil's viscous solver still fails to converge on the wrapped NACA0012 in test/solver/test_backend_comparison.jl, where the distance-field wrap succeeded, so that test errors in interpolate_matrix_nans! with nothing to interpolate from.

What is established so far:

  • XFoil reports no LEFIND warning, so the contour is well formed; it is the viscous march that fails, returning an alpha-independent cl (~-0.484 at -4, 0 and +4 deg alike).
  • repanel=true converges 6/6, so XFoil's own repaneling repairs whatever it dislikes.
  • Convergence is non-monotone in the panel size floor: 0.1 gives 6/6, 0.2-0.5 gives 0/6, 0.7 gives 6/6. So neither grading nor absolute panel size is the discriminator, and tuning a constant until it passes would not be a fix.
  • Current suspect: the round trailing-edge cap of radius clearance. The contour both starts and ends inside it, so each surface turns ~90 deg around the cap before the boundary layer can start. A sharp-TE airfoil has no such cap in the distance-field wrap.

Next step is to confirm that mechanism and, per the validation bar this repo needs, check any fix through a written .dat roundtrip plus ~1e-7 coordinate noise over several sections rather than a single in-memory pass.

🤖 Generated with Claude Code

1-Bart-1 and others added 2 commits August 17, 2026 12:16
The wrap was a distance field: threshold at the ball radius, flood fill, erode
back to clearance, trace the level set with marching squares, then fair the
result. Every one of those steps was bounded by the grid, so cell_size set the
fidelity of the wrap and padding the field for min_concave_radius cost time in
both directions.

pivot_contour rolls the ball around the cloud and emits what its contact side
sweeps: an arc of radius clearance about each point it touches, joined by an arc
of the ball radius across each gap it cannot enter. Those arcs are the wrap
boundary, so there is no resolution to choose. cell_size becomes min_clearance,
a floor on clearance rather than a grid pitch, and is still accepted under the
old name.

The wrap now sits at exactly clearance from the cloud rather than a cell over it,
so a V3 canopy's aft strip is 2*clearance thick where the grid gave
3.5*cell_size. One V3 slice at min_concave_radius 0.4 drops from 173 ms to 10 ms,
and at the default radius from 15 ms to 3 ms.

The resampling had to follow. push_arc! steps each arc to a chord tolerance, so
its segments scale as sqrt(radius) and the trace's node spacing alternates by a
factor of several between the two arc families. Diffusing the turning per node
carried that alternation into the sampling measure and left the resampled panel
lengths oscillating by up to 5.7x between neighbours; smoothed_curvature averages
the turning over a fixed arclength band instead, which brings that down to the
3.0 of a plain cosine-clustered .dat. enforce_min_spacing! then keeps cosine
clustering, which thins as the square of the station count, from putting
leading-edge panels a fraction of a percent of chord long.

Known limitation: XFoil's viscous solver still fails to converge on the wrapped
NACA0012 of test/solver/test_backend_comparison.jl, where the distance-field wrap
succeeded, and does so non-monotonically in the panel size. XFoil reports no
LEFIND warning, so the contour is well formed; the suspect is the round trailing
edge cap, which the contour both starts and ends inside. That is why this is a
branch of its own and not part of #258.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant