Skip to content

ymf: hypot in the notation; dam-break fixture uses it (C5 step 2) - #28

Merged
cekees merged 3 commits into
proteustoolkit:mainfrom
cekees:main
Nov 6, 2026
Merged

cekees merged 3 commits into
proteustoolkit:mainfrom
cekees:main

Conversation

@cekees

@cekees cekees commented Nov 6, 2026

Copy link
Copy Markdown
Collaborator

One reviewed PR from cekees/ymf, merged there. cekees/ymf main is a fast-forward of this repository's main.

  • C5 step 2, notation: hypot(a, b), so a spec can match a deck's distance bitwise (C5 step 2) cekees/ymf#12: hypot(a, b) in the notation and language tables (sympy.codegen.cfunctions.hypot;
    to_code prints numpy.hypot), with printer, docs and a test (d51ca2d). The dam-break fixture writes its φ
    initial condition with it (6feb177).
    • Why: proteus's damBreakLevelSet.py uses numpy.hypot; the spec's sqrt(max(dx,0)²+max(dy,0)²) form differs by
      1 ulp (max 4.4e-16) at 2 of 109 stored-mesh nodes, so deck and spec could not agree bitwise from t=0.
    • Measured (deck vs spec, proteus ymf_run): t=0, 4 values differ before, 0 after; t=0.03, 1182 values differ
      (max 1.5e-12) before, 0 after.

proteus CI installs ymf from this repository's main, so this must merge before cekees/proteus#211 (C5 step 2), whose
three dam-break tests fail without it (24 pass / 3 fail with ymf main, 27 pass with ymf#12).

🤖 Generated with Claude Code

cekees and others added 3 commits November 6, 2026 08:47
…hypot bitwise

C5 step 2 runs the dam break from the spec (proteus ymf_run) and compares it bitwise with
test/TwoPhaseFlow/damBreakLevelSet.py. The spec's initial signed distance,
sqrt(max(x - 1.2, 0)^2 + max(y - 0.6, 0)^2) + min(max(x - 1.2, y - 0.6), 0), rounds twice
where the deck's phi_init calls hypot once.

Measured (numpy 2, macOS arm64):
  stored mesh meshDambreak (109 nodes): sqrt form differs at 2 nodes (1 ulp); hypot form 0
  20000 random points in the tank:      hypot form differs at 0

hypot is sympy.codegen.cfunctions.hypot: differentiable (d/dx hypot(x, y) = x/hypot(x, y)),
printed as numpy.hypot by to_code and as hypot(a, b) by to_notation. hypot(a, 0) = |a| exactly,
so one formula is all three of the deck's branches.

Tests: 795 passed, 11 skipped (tests/, -n 4); two new in test_notation_functions.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…k's phi_init

tests/fixtures/two_phase/dambreak.ymf states the case of proteus's test/TwoPhaseFlow/damBreakLevelSet.py. Its
initial signed distance is now written with hypot (previous commit), as the deck's phi_init computes it. The sqrt of
a sum of squares rounds twice.

Measured with proteus cekees/proteus#211 (C5 step 2), macOS arm64, numpy 2. The deck is damBreakLevelSet.py
-C "final_time=0.03 dt_output=0.01 he=0.08 genMesh=True"; the spec is the same case run through ymf_run, with
161 nodes:

                                               sqrt form                          hypot form
  phi0 at the deck's stored mesh (109 nodes)   2 nodes differ, max 4.4e-16        0 differ
                                               (1 ulp)
  phi0 at the run's mesh (161 nodes)           2 nodes differ, max 4.4e-16        0 differ
  deck vs spec archive at t = 0                4 values differ (phi, phid),       0 differ (103/103 datasets
                                               max 4.4e-16                        bitwise)
  deck vs spec archive at t = 0.03             1182 values differ, max 1.5e-12    0 differ
                                               (p)

So without hypot no run from a spec can reproduce the deck bitwise. test_notation_functions keeps the sqrt form's
three-branch check at abs_tol 1e-15, and adds the hypot form's bitwise one.

Tests: 795 passed, 11 skipped (tests/, -n 4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
notation: hypot(a, b), so a spec can match a deck's distance bitwise (C5 step 2)
@cekees
cekees merged commit 3a3a061 into proteustoolkit:main Nov 6, 2026
10 checks passed
cekees added a commit to cekees/proteus that referenced this pull request Nov 6, 2026
…e three new modules

The coverage job of run 42186697517 (proteus/cli/ymfrun.py 91.5% against its floor of 93.6%, 44 of 520
statements missed) found these step-2 paths untested:
- an output already in the archive;
- --check reproduced;
- --check refused, and --keep-different (with the <key>~2 slot);
- the dispatch differing from its record;
- --ignore leaving out a split it cannot run;
- pro msh with a split.
Two in-process tests now run them on dambreak_short.ymf (each run about 2 s). The refused case comes from editing
the recorded dispatch (runCFL 0.25 -> 0.3) in the archive. The --ignore test keeps level_set_clsvof (refused at
its atmosphere) beside level_set_five.

Measured locally (coverage run over test_pro_cli, test_adr_problem and test/dispatch, subprocesses included,
ymf main 3a3a061 = proteustoolkit/ymf#28): ymfrun.py misses 27 of 522 statements (94.8%). On CI the missed lines
of the run above that these tests reach are 810-838, 665, 673-675 and 256: 21 of the 44.

Floors for the modules this PR adds, at what the combined CI report measured, as 33f30b1 floored new modules:
Dispatch.py 91.3, DispatchRun.py 90.1, DispatchTable.py 100.0.

Also merged cekees/main afcedf6 (train proteustoolkit#1343). Its NCLS3P floor hunk is identical to 68f5df0.

Tests: test_pro_cli + test_adr_problem + test/dispatch: 207 passed, 1 skipped (-n 4, ymf main 3a3a061).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant