From eea12cf89e5d875f0dbfeea407169a0c92446460 Mon Sep 17 00:00:00 2001 From: Bart Date: Sat, 22 Aug 2026 11:26:12 +0200 Subject: [PATCH] Take the billow axis from the section pair, not a global projection Billowing rotates each section's trailing edge about the leading-edge span vector, and the sign of that vector decided whether the panel billows up or down. It came from projecting on `spanwise_direction`, which is near-degenerate where the span vector is not spanwise: on a C-shaped kite's tip panels the alignment is 0.033, 11 mm of span between the outermost sections, so a deforming tip could flip one panel's billow while its neighbours kept theirs. Sections run +y to -y, so the pair itself fixes the sign with no projection and no degeneracy. On a wing whose tips are not near-vertical the two agree, so the refined mesh is unchanged there. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 9 +++++++++ src/wing_geometry.jl | 10 +++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c06c68a0..fe2ceee3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## Unreleased + +### Fixed +- Billowing now takes its rotation axis from the section pair itself instead of + projecting the leading-edge span vector on `spanwise_direction`. Sections run + `+y` to `-y`, so the pair already fixes the sign. The projection was decided by + 3 % of the vector on a C-shaped kite's tip panels — 11 mm of span between the + outermost sections — so a deforming tip could flip that one panel's billow. + ## VortexStepMethod v4.1.1 2026-08-19 ### Fixed diff --git a/src/wing_geometry.jl b/src/wing_geometry.jl index 6abc004c..f64b01b8 100644 --- a/src/wing_geometry.jl +++ b/src/wing_geometry.jl @@ -1535,18 +1535,14 @@ function refine_mesh_by_splitting_provided_sections!( # Apply billowing by rotating chords around LE. if billowing_percentage > 0 && idx > start_idx s_l = sections[li]; s_r = sections[li + 1] - if dot(s_l.LE_point - s_r.LE_point, wing.spanwise_direction) >= 0 - le_neg, le_pos = s_r.LE_point, s_l.LE_point - else - le_neg, le_pos = s_l.LE_point, s_r.LE_point - end - diff_vec = le_pos - le_neg + # Sections run +y to -y, so the pair fixes the axis sign on its own. + diff_vec = s_l.LE_point - s_r.LE_point span_len = norm(diff_vec) y_hat = diff_vec / span_len apply_billowing_to_pair!( wing.refined_sections, start_idx, idx - 1, - y_hat, span_len, le_neg, + y_hat, span_len, s_r.LE_point, s_l.TE_point, s_r.TE_point, billowing_percentage) end