Repository navigation
Test that a POLAR_VECTORS wing solves on its own polars - #384
Conversation
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
left a comment
There was a problem hiding this comment.
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, sodrag/lift ≈ cd/clholds by construction and adds nothing the cd_dist check does not already prove. Checkingsol_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_vectorshelper that builds POLAR_VECTORS tuples from degrees. The card's search list does not mention it, andlinear_polarcould have reused it or said why it doesn't. moment[1] > 0depends 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 defaultpolar_neg_y=polar_pos_ywould 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.
| 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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Agreed, it held by construction. Replaced with sol_polar.cd_dist ≈ fill(0.05, 3) in ccd2cd1.
… 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>
|
Local full suite: PASS (6 min, Julia 1.13.0, one cell of the matrix) |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
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_interpsinsrc/panel.jl), so the design lets that averaging show.cl = 4π·alpha,cd = 0.1,cm = -0.02, the -y sections2π·alpha,0.05,-0.01. Solvedcl_dist / alpha_distmust 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.cd = 0.05,cm = 0on 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, andcd_distis 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 fromalpha = -20:30, in degrees, where radians are expected. It now usesdeg2rad. Allocation counts are unchanged (6 allocs, 208 B for both models).Verification
build_interpstakeclfrom the first section only. The test failed atsol.cl_dist ≈ [4π, 3π, 2π] .* sol.alpha_dist(middle panel 0.4967 vs 0.3725), and passed again (10/10) oncesrc/panel.jlwas 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.main@ 1b72901. UsesSolver(n_panels, n_unrefined_sections), sinceSolver(body_aero)is now deprecated, with no warnings.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)main, so not re-syncedbin/reuse_lint.moment[1] > 0relies 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 intest/bench.jl. Nosrc/changes. Searchedtest/forPOLAR_VECTORS,POLAR_MATRICES,INVISCIDand2πfor an existing polar-vs-polar or polar-vs-inviscid solve check. There was none;test/panel/test_panel.jlchecks the averaging at panel level only.test_verification.jlhas apolar_vectors(alpha_deg, cl, cd, cm)helper;linear_polardoes not reuse it because the two share only thedeg2rad, and reusing it would mean moving it intotest_data_utils.jland editingtest_verification.jl, outside this diff.Closes #29 · task
VortexStepMethod.jl-29