Skip to content

Write polar CSV coefficients at 16 significant digits instead of 4 decimals - #369

Merged
1-Bart-1 merged 6 commits into
mainfrom
agent/362-polar-matrices-tables-are-written-with-4
Sep 21, 2026
Merged

1-Bart-1 merged 6 commits into
mainfrom
agent/362-polar-matrices-tables-are-written-with-4

Conversation

@1-Bort-1

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

Copy link
Copy Markdown
Member

TL;DR

write_polar_csv, write_polar_matrix_csv and write_aero_matrix now write every column at 16 significant digits, where they used to round coefficients to 4 decimals. On a kite section Cd ≈ 0.009, so 4 decimals wiped out the drag response to a small flap deflection, and every POLAR_MATRICES wing built by obj_to_yaml had a zero or step-quantised ∂Cd/∂δ.

What was wrong

The two AirfoilAero table writers used @sprintf("%.4f"), so the 1e-4 rounding step was about 1% of Cd. write_aero_matrix (create_2d_polars) had the same bug through round(v; digits=4). The issue's own measurement shows the scale. On a table regenerated from ram_air_kite_body.obj (n_sections=4, α and δ over ±1°), max |cd_interp(α, 1°) − cd_interp(α, 0°)| now ranges from 2.8e-5 to 6.3e-5 across the 20 panels. The issue measured exactly 0.0 on the outboard panels.

What changed

  • One csv_fields(values) formats every row at %.16g. The NeuralFoilResult write_polar_csv in airfoil_io.jl already wrote %.16g and now calls the same helper, so there is one row-join where there were three. A row now reads 0,-1,0.08439307659864426,0.008839144371449947,0.004150335676968098.
  • Tables round-trip exactly, so the angle knots load back bit for bit, which assemble_polar_matrix needs because it rebuilds the (α, δ) grid with an exact unique. %.16g also writes rad2deg(deg2rad(3)) as 3.
  • write_aero_matrix keeps its δ=…° / α=…° labels at 1 decimal, because read_aero_matrix's regex does not accept an exponent. Only its coefficient columns changed.

Tables already written are not rewritten; regenerate them to pick this up. Nothing errors if they stay as they are. No tracked data file comes from these writers. The test/generated/ fixture cache is gitignored, and its key does not include the file format, so a local cache keeps its 4-decimal tables until it is deleted.

Where I would push back

An earlier round on this branch wrote coefficients at 4 significant digits, as asked on the thread. That cost a two-argument formatter (angles have to stay at 16 digits for the exact grid rebuild), a rtol=5e-4 on every round-trip test, and a precision cut in the NeuralFoilResult writer. The files at 16 digits are about 2.5× larger, roughly 35 KB instead of 14 KB for a 50 α × 7 δ section, and none of them are committed. So this goes back to 16 digits for every column.

Tests

  • New testset a Cd deflection response under 1e-4 survives the polar CSV round-trip (test/airfoil_aero/test_airfoil_aero.jl). It writes a Cd with a 2e-5/degree deflection slope through all four writers (both write_polar_csv methods, write_polar_matrix_csv, write_aero_matrix). It reads each back through load_polar_data or read_aero_matrix, requires ≈ on the coefficients and exact equality on the angle knots.
  • test/ram_geometry/test_kite_geometry.jl: the write_aero_matrix round-trip allowed an absolute 5e-5 "because coefficients are rounded to 4 decimals". It is now plain ≈.

Verification

  • Reproduced first: the new testset on unchanged code failed 3 of 6. The vectors CSV came back [0.0082, 0.0092, …] for [0.00824, 0.00924, …], the labelled matrix likewise, and the POLAR_MATRICES matrices failed as well.
  • Same testset green on 7b826f7 (8/8, juliaserver). test/airfoil_aero/test_airfoil_aero.jl and test/ram_geometry/test_kite_geometry.jl have no failures. The one Broken in the kite file is the existing @test_skip false.
  • The issue's measurement above, rerun on 7b826f7 against a freshly regenerated test/generated/.
  • Fixture consumers, run in an earlier round of this branch against a regenerated fixture: test/obj_adapter/test_obj_adapter.jl 51/51, test/body_aerodynamics/test_results.jl 30/30, test/solver/test_forwarddiff.jl 10/10, test/wake/test_wake.jl 3/3. Not rerun on 7b826f7.
  • test/plotting/test_plotting.jl: not run locally, because the test environment has no manifest and no CairoMakie. runtests.jl includes it on Linux CI. Its deflected[2] != stored[2] guard on panel 3 rests on the 4.0e-5 difference above.
  • GitHub CI on 50ba4ce: running at time of writing. Docs build: left to the CI Documentation job, because the docs environment has no manifest. Local full suite: not run. REUSE: the repo has no bin/reuse_lint.
  • Merges cleanly with main (8754b6d, git merge-tree); not synced, since nothing there conflicts or is needed here.
  • Benchmark: n/a
  • Risk: a local test/generated/ cache made before this change keeps its 4-decimal tables until it is deleted.

Scope

+55 / −8 across 7 files. src/ is a one-line helper with its docstring, and four call sites. The rest is the new testset, the tightened kite assertion, a changelog line and a docs index entry.

Closes #362 · task VortexStepMethod.jl-362

1-Bort-1 and others added 2 commits September 21, 2026 14:00
write_polar_csv, write_polar_matrix_csv and write_aero_matrix rounded
every coefficient to 4 decimals, which on a Cd near 0.009 wipes out the
response to a small flap deflection. All three, and the NeuralFoilResult
writer that already used %.16g, now format rows through one csv_fields.

Closes #362

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Coefficients go out at %.4g, which still resolves a 7e-6 Cd change on a
0.009 base. Angles stay at %.16g so a grid knot such as 100.25 deg is not
rounded onto a neighbour, which assemble_polar_matrix matches exactly.

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 21, 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

  • One csv_fields helper replaces three copies of the row-join. I checked with a grep: no %.4f or digits=4 formatting is left in src/.
  • Values below 1e-4 come out of %.4g in exponent form (1.234e-05). Both readers parse the coefficient columns with parse(Float64, …), which reads that fine (polars.jl:96, yaml_geometry.jl data loop).
  • Angle columns stay at %.16g, so assemble_polar_matrix's exact unique still rebuilds the (α, δ) grid. The new testset checks this with alphas == alpha_range && deltas == delta_range.
  • The kite-geometry assertion is not weakened. For the values it checks, an elementwise rtol=5e-4 is tighter than the old absolute 5e-5, and the stale 'rounded to 4 decimals' comment is gone.
  • The PR had a bug-first test: the card reports the new testset failing 3 of 6 on unchanged code. The write_aero_matrix labels were left at 1 decimal on purpose, because the reader's regex takes no exponent, and the card says so.

Not good

  • CHANGELOG.md:38 — The entry says all three writers used to write 4 decimals. The NeuralFoilResult method of write_polar_csv wrote 16 significant digits and now writes 4, so for its users this is a precision cut the changelog does not mention.
  • The NeuralFoilResult write_polar_csv goes from %.16g to %.4g coefficients, which loses precision. The card attributes this to the thread, but no test covers that writer, and the changelog only speaks of '4 decimals → 4 significant digits', which is wrong for this method.
  • The testset name 'keep a Cd deflection response below 1e-4' says 'below 1e-4' where it means a response smaller than 1e-4 survives the round-trip; 'survives' would read clearer.
  • csv_fields is defined in airfoil_io.jl but used from airfoil_solvers/common.jl and polar_export.jl, so it works only because of include order and nothing states that coupling.
  • The rtol of 5e-4 is exactly the worst-case %.4g rounding error (half a unit in the 4th digit at mantissa 1.000). The test has no margin and would flake if a value landed on that edge.
  • Tables already written keep their 4-decimal values with no warning. The card says this openly and the changelog says to regenerate, so it is acceptable, but the test/generated/ cache key still ignores the file format.

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 CHANGELOG.md Outdated

### Fixed

- `write_polar_csv`, `write_polar_matrix_csv` and `write_aero_matrix` write coefficients

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: The entry says all three writers used to write 4 decimals. The NeuralFoilResult method of write_polar_csv wrote 16 significant digits and now writes 4, so for its users this is a precision cut the changelog does not mention.

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.

Moot since 7b826f7: every writer is back at 16 significant digits, so the NeuralFoilResult method writes what it always did and the changelog's '4 decimals → 16 significant digits' holds for the two writers it names. The round-trip test still covers the NeuralFoilResult writer.

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.

Fixed in 50ba4ce: every writer is back at 16 significant digits (7b826f7), and the entry now names the SectionSolution method of write_polar_csv, so it no longer claims the NeuralFoilResult one wrote 4 decimals. The round-trip test still covers both.

@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 21, 2026
1-Bort-1 and others added 2 commits September 21, 2026 15:11
The changelog now says that writer went from 16 significant digits to 4,
and the testset name says what survives the round-trip.

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

codecov Bot commented Sep 21, 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 21, 2026
@1-Bort-1
1-Bort-1 requested a review from 1-Bart-1 September 21, 2026 14:16
@1-Bort-1 1-Bort-1 added agent:steered Agent task state and removed agent:review Agent task state labels Sep 21, 2026
1-Bort-1 and others added 2 commits September 21, 2026 16:20
Every column now goes out through the one-line %.16g csv_fields, so the
tables round-trip exactly and the tests compare with plain ≈. The
NeuralFoilResult writer keeps the 16 digits it always had.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@1-Bort-1 1-Bort-1 changed the title Write polar CSV coefficients at 4 significant digits instead of 4 decimals Write polar CSV coefficients at 16 significant digits instead of 4 decimals Sep 21, 2026
@1-Bort-1 1-Bort-1 added agent:queued Agent task state and removed agent:steered Agent task state agent:queued Agent task state labels Sep 21, 2026
@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 21, 2026
@1-Bort-1

Copy link
Copy Markdown
Member Author

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

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

POLAR_MATRICES tables are written with %.4f, so Cd carries no deflection dependence at small deltas

2 participants