Continuous wrapping method - #262
Open
1-Bart-1 wants to merge 2 commits into
Open
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Split out of #258, which carried this rewrite alongside unrelated section-order work and failed CI because of it.
What changes
shrink_wrapwas a distance field: threshold at the ball radius, flood fill, erode back toclearance, trace the level set with marching squares, fair the result. Every step was bounded by the grid, socell_sizeset the fidelity of the wrap and padding the field formin_concave_radiuscost time in both directions.pivot_contournow rolls the ball around the cloud and emits what its contact side sweeps: an arc of radiusclearanceabout 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'scell_sizebecomesmin_clearance— a floor onclearancerather than a grid pitch. Still accepted under the old name.clearancefrom the cloud instead of a cell over it: a V3 canopy's aft strip is2 * clearancethick where the grid gave3.5 * cell_size.min_concave_radiusstops 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 assqrt(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_curvatureaverages 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 ininterpolate_matrix_nans!with nothing to interpolate from.What is established so far:
LEFINDwarning, 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=trueconverges 6/6, so XFoil's own repaneling repairs whatever it dislikes.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
.datroundtrip plus ~1e-7 coordinate noise over several sections rather than a single in-memory pass.🤖 Generated with Claude Code