Repository navigation
Test the solver against the references in the Python verification cases - #334
Conversation
Port the checks from ocayon/Vortex-Step-Method tests/verification_cases that compare against an outside reference: elliptic wing vs lifting-line theory, curved Clark Y wing vs RANS, rectangular AR 12 wing vs CFD, V3 kite vs RANS, and three horseshoe vortices vs Biot-Savart. Same geometry, flow, solver settings and tolerances; reference CSVs copied in. 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 · 2 inline, 0 off the diff
Good
- This is what #93 asked for: the five Python cases that check against theory, CFD, RANS or Biot-Savart, and no Python-vs-Python checks; I compared the diff with the card and every testset maps to a card row
- Geometry comes from the existing
generate_coordinates_*andflip_created_coord_in_pairsintest/utils.jl; the new helper names (read_columns,polar_vectors,max_error, …) collide with nothing else intest/, which I checked with grep - The card's margins match its table: kite CL at 9° is 0.9391−0.8605=0.079 and elliptic VSM CD is 0.01418−0.01281=0.00137
- The card shows the tests can fail: a 10 % stronger semi-infinite vortex turned 4 of the 22 checks red
- Reusing
left_velocity/right_velocityin the finite-trailing check is safe:velocity_3D_trailing_vortex!overwritesvelin both branches (src/filament.jl) - No line in
test_verification.jlis over 92 characters (checked by grep); theDelimitedFilesandInterpolationsdependencies are already intest/Project.toml - The card explains each departure from Python (the sweep-0 name, the tripled Clark Y block, the direct CD interpolation) with its size against the tolerance
Not good
test/verification/test_verification.jl:39—wing_from_coordinatesis the same flip →Wing(n; UNCHANGED)→add_section!pairs →refine!loop written out twice intest/body_aerodynamics/test_body_aerodynamics.jl(lines ~32 and ~172), which includes the sameutils.jl. Adding it only here makes a third copy; it belongs intest/utils.jl, with the body-aero copies switched to it now or in acleanup:PR.test/verification/test_verification.jl:201— In all three horseshoes the evaluation point lies on the bound filament's line, sobound_velocityis exactly zero and the change sold as 'adds all three filaments' checks nothing Python did not. Either assertbound_velocity == zeros(3)so the claim is tested, or drop the call and say in the card that the case only covers the trailing legs.- The card does not say what was searched for before the new helpers were added (§2), and the duplication below suggests the search missed test_body_aerodynamics.jl
- The local full suite and GitHub CI were still unticked when the card was written, so the only green result is from the verification file plus body_aerodynamics
- Kite CL at 9° has 0.021 of headroom; the card rightly says to revisit the reference rather than widen the tolerance, and that should hold when #317/#318 land
max_erroris the only helper without a docstring; its name is clear, but the file is otherwise consistent about docstrings
claude, rubric CLEAN_CODE.md. A different lab from the implementer
on purpose: a reviewer sharing its blind spots would not flag its mistakes.
| Refined wing with one section per leading/trailing-edge row pair of the 2N×3 | ||
| `coordinates`, which run from -y to +y. | ||
| """ | ||
| function wing_from_coordinates(coordinates, aero_model, aero_data=nothing; |
There was a problem hiding this comment.
MINOR: wing_from_coordinates is the same flip → Wing(n; UNCHANGED) → add_section! pairs → refine! loop written out twice in test/body_aerodynamics/test_body_aerodynamics.jl (lines ~32 and ~172), which includes the same utils.jl. Adding it only here makes a third copy; it belongs in test/utils.jl, with the body-aero copies switched to it now or in a cleanup: PR.
| ) | ||
| for (gamma, left, right, velocity) in horseshoes | ||
| bound_velocity = zeros(3) | ||
| velocity_3D_bound_vortex!(bound_velocity, bound_filament(right, left), |
There was a problem hiding this comment.
MINOR: In all three horseshoes the evaluation point lies on the bound filament's line, so bound_velocity is exactly zero and the change sold as 'adds all three filaments' checks nothing Python did not. Either assert bound_velocity == zeros(3) so the claim is tested, or drop the call and say in the card that the case only covers the trailing legs.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
TL;DR
New
test/verification/test_verification.jlports the five cases in the Pythontests/verification_casesthat check against something outside the code: an elliptic wing against lifting-line theory, a curved Clark Y wing against RANS, a rectangular AR 12 wing against CFD, the V3 kite against RANS, and three horseshoe vortices against Biot-Savart. Until now nothing in the Julia suite compared a whole-wing CL or CD with theory or measured data. The existing reference tests only compare against the old thesis port, which is a copy of the same maths.What was ported and what was not
Each case keeps the Python geometry, flow speed, relaxation factor,
core_radius_fraction = 1e-20and angles of attack, and every tolerance is copied unchanged from awegroup/Vortex-Step-Method@c82d521. The Python asserts comparing its "old" thesis code with its "new" package are left out, because they compare two Python codes. Geometry reuses the generators already intest/utils.jl. The V3 kite's 10 CAD section pairs are written into the test and split 4× withSPLIT_PROVIDED(37 sections, as in Python). The six CSVs are intest/verification/data/, with a README giving the source of each.Julia passes every tolerance. The tightest margins are the V3 kite's CL at 9° (0.079 against 0.1) and the elliptic wing's VSM CD (0.00137 against 0.002):
Where the port differs from the Python test
if evaluation_point[0] == filament.x1[0]), so it only ever tested the trailing legs. The Julia test adds all three filaments. The bound filament really does induce exactly zero here, because the evaluation point lies on its line, so the reference values are unchanged.swept_wingcase has sweep 0. It is named for what it is here: a rectangular AR 12 wing.clarky_maneia.csvrepeats its 20–32° block three times, which makes alpha non-monotonic, and its comment says radians although the values are degrees. Only the first block is kept.Found on the way
.github/workflows/CI.yml:22hasfail-fast: false, which the agent rules want gone. I did not change it here, since it is a separatecleanup:change.Verification
src/filament.jlgave18 passed, 4 failed(elliptic VSM CD and the three semi-infinite horseshoe sums). Withsrc/restored it went back to 22/22 greentest/verification/test_verification.jl: 22/22 pass. Throughruntests.jltogether withbody_aerodynamics/test_body_aerodynamics.jl, which includes the sameutils.jl: 4880/4880 pass, verification set 18.7 s cold (juliaserver)agent ci-local, Julia 1.12): still running when this was written · GitHub CI: pendingScope
+350 / −0 across 10 files, all under
test/. That is 226 lines of test (50 of them the kite's CAD coordinates), 107 lines of reference CSV, a 13-line data README, and one line each inruntests.jlandtest/README.md.Closes #93 · task
VortexStepMethod.jl-93