Skip to content

Test the solver against the references in the Python verification cases - #334

Merged
1-Bart-1 merged 1 commit into
mainfrom
agent/93-add-test-cases-from-the-python-verificat
Sep 16, 2026
Merged

1-Bart-1 merged 1 commit into
mainfrom
agent/93-add-test-cases-from-the-python-verificat

Conversation

@1-Bort-1

Copy link
Copy Markdown
Member

TL;DR

New test/verification/test_verification.jl ports the five cases in the Python tests/verification_cases that 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-20 and 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 in test/utils.jl. The V3 kite's 10 CAD section pairs are written into the test and split 4× with SPLIT_PROVIDED (37 sections, as in Python). The six CSVs are in test/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):

case reference Julia VSM Julia LLT tolerance
elliptic AR 20, 3°/9° CL 0.2991/0.8972, CDi 0.001424/0.01281 CL 0.2954/0.8861, CD 0.001578/0.01418 CL 0.2991/0.8967, CD 0.001423/0.01278 LLT CL 1e-2, CD 1e-3 · VSM CL 1e-1, CD 2e-3
curved Clark Y, 9° CL 0.7921, CD 0.07507 CL 0.7904, CD 0.1034 CL 0.9093, CD 0.1029 VSM 1e-1 · LLT−VSM CL 2e-1, CD 4e-2
rectangular AR 12, 3°/6°/9° CL 0.6094/0.8821/1.144 CL 0.6252/0.8618/1.101 CL 0.6374/0.8868/1.141 VSM CL 1e-1 · LLT−VSM CL 2e-1, CD 4e-2
V3 kite, 3°/6°/9° CL 0.4608/0.6728/0.8605, CD 0.04815/0.06400/0.08148 CL 0.4470/0.7020/0.9391, CD 0.0685/0.0960/0.1346 – VSM 1e-1

Where the port differs from the Python test

  • Horseshoes: the Python test sets the bound-vortex velocity to zero whenever the evaluation point has the filament's x (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" wing: Python's swept_wing case has sweep 0. It is named for what it is here: a rectangular AR 12 wing.
  • Clark Y polar: Python's clarky_maneia.csv repeats 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.
  • Kite CD reference: Python first resamples the CD data onto the CL data's angles and then interpolates again. Here CD is interpolated directly, which moves the reference by at most 3e-4 against a 0.1 tolerance.

Found on the way

Verification

  • Reproduced first: n/a, these are tests of existing behaviour with no bug to reproduce
  • The tests can fail: making the semi-infinite trailing vortex 10 % stronger in src/filament.jl gave 18 passed, 4 failed (elliptic VSM CD and the three semi-infinite horseshoe sums). With src/ restored it went back to 22/22 green
  • test/verification/test_verification.jl: 22/22 pass. Through runtests.jl together with body_aerodynamics/test_body_aerodynamics.jl, which includes the same utils.jl: 4880/4880 pass, verification set 18.7 s cold (juliaserver)
  • Local full suite (agent ci-local, Julia 1.12): still running when this was written · GitHub CI: pending
  • Docs: n/a, no public symbols · Changelog: none, test-only · up to date with main
  • Risk: the kite CL at 9° has 0.021 of headroom, so a physics fix that raises kite lift may need this reference looked at again, not the tolerance loosened.

Scope

+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 in runtests.jl and test/README.md.

Closes #93 · task VortexStepMethod.jl-93

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 1-Bort-1 added agent:running Agent task state agent:ci Agent task state and removed agent:running Agent task state labels Sep 16, 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

  • 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_* and flip_created_coord_in_pairs in test/utils.jl; the new helper names (read_columns, polar_vectors, max_error, …) collide with nothing else in test/, 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_velocity in the finite-trailing check is safe: velocity_3D_trailing_vortex! overwrites vel in both branches (src/filament.jl)
  • No line in test_verification.jl is over 92 characters (checked by grep); the DelimitedFiles and Interpolations dependencies are already in test/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_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.
  • test/verification/test_verification.jl:201 — 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.
  • 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_error is 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;

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: 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),

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: 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

codecov Bot commented Sep 16, 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:review Agent task state and removed agent:ci Agent task state labels Sep 16, 2026
@1-Bart-1
1-Bart-1 merged commit 1fac603 into main Sep 16, 2026
7 checks passed
@1-Bart-1
1-Bart-1 deleted the agent/93-add-test-cases-from-the-python-verificat branch September 16, 2026 21:58
@1-Bort-1 1-Bort-1 added agent:done Agent task state and removed agent:review Agent task state labels Sep 16, 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 test cases from the Python verification cases

2 participants