Skip to content

Test that a POLAR_VECTORS wing solves on its own polars - #384

Merged
1-Bart-1 merged 2 commits into
mainfrom
agent/29-add-polar-data-test
Sep 28, 2026
Merged

1-Bart-1 merged 2 commits into
mainfrom
agent/29-add-polar-data-test

Conversation

@1-Bort-1

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

Copy link
Copy Markdown
Member

TL;DR

Adds test/solver/test_polar_vectors.jl, the first test that checks a polar-data wing's solution against its input polar. Other tests already solve such wings (test_verification.jl, test_moment_units.jl, test_wing_directions.jl), but they compare against reference data or frame conventions, not panel by panel against the polar each panel was given.

The test

A flat 3-panel wing, 1 m × 1 m panels at 5°, built from four sections so refine! keeps them one-to-one. Each panel's polar is the average of its two edge sections (build_interps in src/panel.jl), so the design lets that averaging show.

  • Each panel solves on its own polar. The +y sections carry cl = 4π·alpha, cd = 0.1, cm = -0.02, the -y sections 2π·alpha, 0.05, -0.01. Solved cl_dist / alpha_dist must be [4π, 3π, 2π], cd_dist [0.1, 0.075, 0.05], cm_dist [-0.02, -0.015, -0.01], and the stronger +y side must roll the wing positive about x (moment[1] > 0, in its own named testset). Every solved alpha falls between table knots, so the interpolation is exercised, not just the knot values.
  • A 2π·alpha polar is INVISCID plus profile drag. With cd = 0.05, cm = 0 on every section, circulation and lift match the INVISCID wing to 1e-12. Each panel's force differs from INVISCID by exactly its profile drag, |Δf_i| = drag_dist_i · width_i, and cd_dist is 0.05 on every panel. The symmetric wing has no rolling moment.

I compared per panel on purpose: the norm of the total force difference misses the sum of the panel drags by 6e-6 relative (20.635145 vs 20.635268), because each panel's drag lies along its own induced flow direction.

@ufechner7's suggestion on the thread (3 panels, outer 2π·alpha, cd = 0.05, cm = 0, one outer twice the other) is in there in spirit. A middle panel with a different model from the outer ones cannot be built, since both edge sections of a panel must share a model.

Also fixed

test/bench.jl's gamma-loop allocation test built its POLAR_VECTORS table from alpha = -20:30, in degrees, where radians are expected. It now uses deg2rad. Allocation counts are unchanged (6 allocs, 208 B for both models).

Verification

  • Reproduced first: n/a, new test on existing behaviour. To show it catches a defect, I made build_interps take cl from the first section only. The test failed at sol.cl_dist ≈ [4π, 3π, 2π] .* sol.alpha_dist (middle panel 0.4967 vs 0.3725), and passed again (10/10) once src/panel.jl was restored. I did this on the rebased tree.
  • test/solver/test_polar_vectors.jl: 10/10 pass on ccd2cd1 after the review round. test/bench.jl: 21/21 pass. Both run in juliaserver, Julia 1.13.0, test environment.
  • Rebased on main @ 1b72901. Uses Solver(n_panels, n_unrefined_sections), since Solver(body_aero) is now deprecated, with no warnings.
  • Local full suite (agent ci-local, Julia 1.13.0, one matrix cell) on ccd2cd1: PASS in 10 min, exit 0 · GitHub CI on ccd2cd1: PASS (Julia 1.12 ubuntu/macOS/windows, 1.13 ubuntu, docs, setup test)
  • Merges cleanly into current main, so not re-synced
  • Docs/changelog: n/a, test-only · REUSE: the repo has no bin/reuse_lint.
  • Risk: moment[1] > 0 relies on sections being sorted +y first. That holds now, and the cl/cd/cm assertions would fail too if it changed.

Scope

+62 / -1 across 3 files: the new 60-line test, one line registering it in test/runtests.jl, and the one-line unit fix in test/bench.jl. No src/ changes. Searched test/ for POLAR_VECTORS, POLAR_MATRICES, INVISCID and 2π for an existing polar-vs-polar or polar-vs-inviscid solve check. There was none; test/panel/test_panel.jl checks the averaging at panel level only. test_verification.jl has a polar_vectors(alpha_deg, cl, cd, cm) helper; linear_polar does not reuse it because the two share only the deg2rad, and reusing it would mean moving it into test_data_utils.jl and editing test_verification.jl, outside this diff.

Closes #29 · task VortexStepMethod.jl-29

A three-panel wing with different linear polars on each side checks that
every panel solves on the average of its two sections' polars, and that a
2π·alpha polar reproduces the INVISCID circulation plus its profile drag.
bench.jl's gamma_loop polar now takes its alphas in radians.

Co-Authored-By: Claude Opus 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 22, 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 · 1 inline, 0 off the diff

Good

  • Fills a real gap: I read test_verification, test_moment_units and test_wing_directions, which do solve polar wings but only against CFD, scaling or symmetry. None checks panel cl/cd/cm against the polar it was given.
  • The 4-section, 3-panel layout makes the middle panel's averaged polar show up as [4π, 3π, 2π] and [0.1, 0.075, 0.05]. The card's mutation test (cl taken from the first section only) shows the assertion catches a broken build_interps.
  • Comparing each panel's force against INVISCID is the right precision. The card gives the numbers showing a total-force comparison would be off by 6e-6.
  • The bench.jl degrees-to-radians fix is correct: with alphas in degrees the table ran cl up to 2π·30. The card names it under 'Also fixed' and says allocation counts did not change.
  • The helpers have docstrings, the testset names describe the behaviour they protect, the new file is registered in runtests.jl, and I read no line over 92 characters.
  • The tolerances are strict (rtol 1e-12 on gamma and lift, 1e-10 solver rtol), so nothing was loosened to make it pass.

Not good

  • test/solver/test_polar_vectors.jl:53 — drag_dist and lift_dist are each q·c times cd and cl, so drag/lift ≈ cd/cl holds by construction and adds nothing the cd_dist check does not already prove. Checking sol_polar.cd_dist ≈ fill(0.05, 3) would state the same thing directly, or the line could be dropped.
  • The card's TL;DR says this is 'the first test that solves a wing built from polar data'. test_verification.jl:113, test_moment_units.jl:16 and test_wing_directions.jl:17 already do. The accurate claim is 'the first to check the solution against the input polar'.
  • test_verification.jl:29 already has a polar_vectors helper that builds POLAR_VECTORS tuples from degrees. The card's search list does not mention it, and linear_polar could have reused it or said why it doesn't.
  • moment[1] > 0 depends on the +y-first section order and on the sign convention. The card calls this out as a risk; a short testset name like 'stronger +y side rolls positive' would make the intent clear without the card.
  • solve_three_panel_wing(INVISCID, nothing, nothing) passes two arguments that only exist to be ignored. A default polar_neg_y=polar_pos_y would shorten both of the second testset's calls, but this is a minor point.

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 test/solver/test_polar_vectors.jl Outdated
sol_inviscid = solve_three_panel_wing(INVISCID, nothing, nothing)
@test sol_polar.gamma_distribution ≈ sol_inviscid.gamma_distribution rtol=1e-12
@test sol_polar.lift_dist ≈ sol_inviscid.lift_dist rtol=1e-12
@test sol_polar.drag_dist ./ sol_polar.lift_dist ≈ 0.05 ./ sol_polar.cl_dist

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.

MINOR: drag_dist and lift_dist are each q·c times cd and cl, so drag/lift ≈ cd/cl holds by construction and adds nothing the cd_dist check does not already prove. Checking sol_polar.cd_dist ≈ fill(0.05, 3) would state the same thing directly, or the line could be dropped.

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.

Agreed, it held by construction. Replaced with sol_polar.cd_dist ≈ fill(0.05, 3) in ccd2cd1.

@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 22, 2026
… test

drag/lift = cd/cl held by construction; state cd_dist instead. Default the
-y polar to the +y one so the symmetric and INVISCID wings need no filler
arguments.

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

1-Bort-1 commented Sep 22, 2026 •

Copy link
Copy Markdown
Member Author

Local full suite: PASS (6 min, Julia 1.13.0, one cell of the matrix)

@codecov

codecov Bot commented Sep 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@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 22, 2026
@1-Bort-1
1-Bort-1 requested a review from 1-Bart-1 September 22, 2026 14:55
@1-Bart-1
1-Bart-1 merged commit 6f6c98c into main Sep 28, 2026
7 checks passed
@1-Bart-1
1-Bart-1 deleted the agent/29-add-polar-data-test branch September 28, 2026 16:04
@1-Bort-1 1-Bort-1 added agent:done Agent task state and removed agent:review Agent task state labels Sep 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent:done Agent task state

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add polar_data test

2 participants