Skip to content

Default correct_aoa to true, with the aero-centre flow leaving out only the section's own bound vortex - #400

Draft
1-Bort-1 wants to merge 10 commits into
agent/94-remove-results-dictfrom
agent/318-correct-aoa-defaults-to-false-so-the-sol
Draft

1-Bort-1 wants to merge 10 commits into
agent/94-remove-results-dictfrom
agent/318-correct-aoa-defaults-to-false-so-the-sol

Conversation

@1-Bort-1

@1-Bort-1 1-Bort-1 commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Do not merge ahead of #415: this pull request closes when #415 merges. #415 makes the default solve agree with the Python VSM v2.3.0, and that also turns this correction on. It takes the quarter-chord flow by Python's rule, which conflicts with the rule here, and only one of the two can stand.

With the old default, one velocity both read the polars and turned the force, which keeps lift but loses induced drag: the straight elliptic AR 4 wing reached an Oswald efficiency of 0.73 against a theoretical 1. This branch turns the force by the flow at the quarter chord (Gaunaa, Li & Pirrung 2026) and reaches 0.998. In that flow it leaves out only the section's own bound vortex, where the existing code left out every section's.

Oswald efficiency error against the paper's VLM at 120 sections, for the paper's own lifting-line model, this branch and #415, on five wings from its appendix

Against the paper's vortex-lattice reference, this rule is the closer one on wings that are only curved: within 0.8 %, where #415 is off by 2.3–2.5 %. It is no better once the wing is swept, as a kite is. On the 15 % swept wing and the swept, anhedral wing it overshoots by 13.5 % and 7.8 %, where #415 undershoots by 8.2 % and 8.0 %. The paper's own model stays within 5.6 % and 0.5 % there. On the 25 % swept wing this branch gives NaN, and #415 stays finite but does not converge.

I judge that #415 should win: the project has asked for agreement with Python, this rule also moves the LLT model away from Python, and it has no accuracy advantage on a swept wing. What that costs is about 2 % of Oswald efficiency on a purely curved wing. Whoever wants this rule instead should say so on #415 before it merges.

On the TU Delft V3 kite the default change keeps CL and the 14° stall, and lowers drag at 10° from 0.0998 to 0.0742. Anyone calibrated to the old drag sees about 25 % less of it, and #415 moves that drag again.

The vortex-segment changes here exist because this rule evaluates bound filaments on their own axes, which the Python rule never does, so nothing needs them once this closes. #408 is built on this branch and has been told to move.

Verification

  • Rule comparison: every wing from the paper's appendix, inviscid, 120 sections, α = 10° by constant twist, force on the chordwise legs on, run on this branch and on The default solve now gives the same results as the Python VSM v2.3.0 #415's head 242880a.
  • The appendix does not fully state the geometry. I took the reading that brings CL closest to the reference: chord elliptic in projected span, twist about the local tangent, CL on blade area. That gives CL within 1.5 % on the dihedral, anhedral and combined wings. On the swept wings the chord direction stays an assumption, and The default solve now gives the same results as the Python VSM v2.3.0 #415's CL is 3.0 % low at 15 % sweep.
  • Neither branch reproduces the paper's 12 % effect of the chordwise-leg force on the swept, anhedral wing: it moves e by 0.2 % here and 0.1 % on The default solve now gives the same results as the Python VSM v2.3.0 #415.
  • Straight elliptic AR 4, old default: e = 0.7283. test/verification/test_verification.jl red with the old default (22/23), green now (24/24), including a pin of the old setting below 0.8.
  • Local full suite on 602fcd5: PASS (9 min, Julia 1.13.0, one matrix cell). GitHub CI: docs PASS; the test matrix is skipped while this is a draft.
  • Docs build: not run locally. No new public symbols.
  • Benchmark: inconclusive; the box was saturated. Allocations on the V3 kite: 6 allocations, 208 B per solve with either setting.
  • Risk: the swept-wing ranking rests on an assumed chord direction.

Opened by 1-Bort-1, an AI agent working for @1-Bart-1.
Closes #318 · task VortexStepMethod.jl-318

1-Bort-1 and others added 7 commits September 30, 2026 10:07
…vortex at the aero centre

Bart decided on #318 to default correct_aoa to true. The aero-centre
matrix used for the force directions now keeps every other panel's bound
filament (Gaunaa, Li & Pirrung 2026, Eq. 2) instead of zeroing all of them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… bound filaments

Also list correct_aoa in the Solver docstring.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ite on its own axis

The correct_aoa default now calls calculate_AIC_matrices! from calc_forces!
on every solve, so its temporaries come from the body's buffers. With a
near-zero core, a point on a filament's line fell through the colinearity
test on rounding noise and came back NaN.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the axis

With the aero-centre matrix keeping neighbouring bound filaments, an aero
centre on a refined straight segment lies on its neighbours' axes. The core
branch normalised the radial vector there and the old guard returned a hard
zero, so ForwardDiff lost the slope FiniteDiff sees. The closed form is the
same velocity (2e-11 relative) and linear through the axis.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… bound

cl_dist is read at alpha_uncorrected, which equals alpha_dist only without
correct_aoa. trim_angle's default alpha_tol bounds |CMy| by 3.3e-5 on the
trimmable wing, so the 1e-5 check passed by where the bisection landed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drop comments that restate code, name the kernels' work-vector slots
correctly, share the uniform-inflow AIC call across the matrix tests and
hoist the ForwardDiff probe out of its testset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@1-Bort-1 1-Bort-1 added agent:running Agent task state agent:ci Agent task state and removed agent:running Agent task state labels Sep 30, 2026

@1-Bort-1 1-Bort-1 left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent review (advisory)

Verdict: APPROVE WITH COMMENTS · 2 inline, 0 off the diff

Good

  • Matches the plan: the default flips in both SolverSettings and Solver, and the Eq. 2 fix is the one-line model == LLT && icp == jring change at body_aerodynamics.jl:480, as the card says
  • Closed-form core is correct: I derived Γ/(4π ε² ℓ²)·d_sum·(r1×r0) from the core-boundary velocity scaled by h/ε, and the sign matches, since r1×r2 = −r1×r0
  • Slot reuse is safe: work_vectors[8:9] are only otherwise used by induced_velocity_at, which is never nested in calculate_AIC_matrices!, and the filament kernels only touch slots 1–5
  • body_aero.cache[5:6] are otherwise unused in src, so the allocation fix does not overwrite any buffer
  • Bug-fix tests fail before the fix, as the card reports: the curved-wing LLT matrix test checks norm(velocity) > 1e-3 for i≠j, so it separates Eq. 2 from zeroing every bound filament; the ForwardDiff slope test gave 0 before
  • The test_polar_vectors.jl and test_stability.jl edits tighten or correct the tests and loosen nothing: the 1e-5 CMy assertion is kept and the bisection tolerance now bounds CMy below it
  • Comment trims and the uniform_AIC! helper are behaviour-preserving cleanup around the change, and the card names them

Not good

  • src/settings.jl:202 — With true as the default, every VSM solve! (and every perturbation inside linearize) now builds a second N×N×3 aero-centre AIC, but the card gives no timing and only shows the change stays allocation-free. Simulators calling solve! every step will pay a cost nobody measured.
  • src/filament.jl:115 — The zero-core cutoff scales with norm3(r1), the distance to the filament start, not with the filament length or epsilon. A point far along the extended axis therefore gets a looser 'on axis' band than one near x1, and neither the docstring nor a test pins down which is intended.
  • velocity_induced and U_2D are still zeros(MVector) while their siblings moved to work_vectors; the zero-alloc result depends on escape analysis, and the code does not show why two moved and two did not
  • The card's table says 'default core radius', but the new verification test goes through lift_drag_polar, which fixes core_radius_fraction=1e-20; the tested case is not the one tabulated
  • vsm_settings_coarse.yaml changes its live value from false to true; the card calls this collapsing a duplicate, not a behaviour flip for users of that file
  • Now that false is no longer the default, no test pins the correct_aoa=false path (LL-3/4); anyone who sets it back to get the old drag has no regression guard
  • The 'LLT matrix leaves out only…' test rebuilds the AIC from the filament kernels, which is close to the parity-test pattern §2 warns about; a hand-computed expectation for one off-diagonal entry would be independent of the kernels
  • The swept-wing no-core test only asserts isfinite; it would also pass if the fallback zeroed entries it should not

claude, rubric CLEAN_CODE.md. A different lab from the implementer
on purpose: a reviewer sharing its blind spots would not flag its mistakes.

Comment thread src/settings.jl Resolved
Comment thread src/filament.jl Resolved
@1-Bort-1 1-Bort-1 added agent:queued Agent task state agent:running Agent task state and removed agent:ci Agent task state agent:queued Agent task state labels Sep 30, 2026
…e zero-core fallback

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@1-Bort-1

1-Bort-1 commented Sep 30, 2026 •

Copy link
Copy Markdown
Member Author

Local full suite: PASS (26 min, Julia 1.13.3, one cell of the matrix)

@1-Bort-1 1-Bort-1 added agent:queued Agent task state agent:running Agent task state agent:ci Agent task state agent:review Agent task state and removed agent:running Agent task state agent:queued Agent task state agent:ci Agent task state agent:review Agent task state labels Sep 30, 2026
@1-Bort-1 1-Bort-1 added agent:queued Agent task state agent:running Agent task state and removed agent:queued Agent task state labels Sep 30, 2026
1-Bort-1 and others added 2 commits September 30, 2026 14:01
Takes #393's inflow_angle in update_effective_angle_of_attack! and keeps this
branch's own-bound-only aero-centre matrix; BodyAerodynamics.cache holds the
three buffers still read (induced velocity, panel areas, AIC inflow).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plotting changes only; no overlap with this branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@1-Bort-1 1-Bort-1 added agent:queued Agent task state agent:running Agent task state agent:ci Agent task state agent:review Agent task state and removed agent:running Agent task state agent:queued Agent task state agent:ci Agent task state labels Sep 30, 2026
@1-Bort-1 1-Bort-1 added agent:queued Agent task state agent:running Agent task state and removed agent:review Agent task state agent:queued Agent task state labels Nov 5, 2026
@1-Bort-1 1-Bort-1 added agent:ci Agent task state and removed agent:running Agent task state labels Nov 5, 2026
@1-Bort-1 1-Bort-1 added agent:queued Agent task state agent:review Agent task state and removed agent:ci Agent task state agent:queued Agent task state labels Nov 8, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent:review Agent task state

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant