Repository navigation
ymf: closure records the split; mesh fingerprint; typed inline values (cekees/ymf#10, #11) - #27
Merged
Merged
Conversation
The alias expansion (#9) made a closed spec say what was solved for its boundary conditions. Two more things were still left to a reader's defaults: a split discretization's sub-problems (a lag written `φ: previous_step`, a coefficient read through the sub-problem that carries it, a sub-problem's solver refining the entry's, its regularization replacing the entry's function by function, its `for` defaulting to what it introduces), and which coefficients are functions of the state. ymf.explicit writes them out, and closure.write and closure.input_slice use it in place of the bare expansion: - each coefficient whose formula names an unknown, directly or through another coefficient, in the map form with `depends_on` (ρ, μ, χ: [φ] in the dam break; τb, Fd, Fr, β: [h, q] in Torino); - each sub-problem with its `for`, merged `solver` and `regularize`, and every lag as {of, via, at, carried_by} (flow's χ: {via: vof, at: previous_step, carried_by: χh}). The names are read without sympy: the notation's tokenizer moves to ymf.names (ymf.symbolic.notation re-exports it) with the parser's rule for a run of letters (a declared name, else the product of its letters; a function call is not a name), so the core closes a spec as the front end does. It agrees with ymf.symbolic.problem.state_coefficients on every coefficient that resolves (14 in examples and fixtures) and also names the abstract model's ρ and μ, which the symbolic reader leaves out for lack of values. A test checks the name reader's function list is the parser's. `depends_on` and `carried_by` are checked on load (a false one is refused) and `depends_on` does not count towards a key. Measured, closing every example and fixture with closure.write on cekees/ymf main b77262a and on this commit: 9 specs without coefficients of the state or sub-problems close to byte-identical documents with the same keys; examples/nonlinear_diffusion gains `depends_on: [u]` and keeps its 6 keys; the dam break, lake at rest and Torino re-key (the split is written out; no solver has run a split spec, Proteus refuses one), and each closed spec reloads with its spec's keys. split_problem gives equal results for the dam break spec and its closed form. ymf suite 845 passed, 2 skipped (was 827; 16 new in tests/test_explicit.py, 2 core-import cases), macOS arm64, petsc-dev env. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
§ 7 of the C42 model-family note left this for the next PR: adr_problem and split_problem substitute ρ = ρw (1 − χ) + ρa χ into every slot, which is all a runner needs, but a kernel generator (C19) and the dispatcher want ρ once, as an inline function of the state, and the slots over the name. Beside the substituted form, each coefficient of the state now has - `inline`: its formula over the state, constants substituted and other coefficients of the state kept by name (`uses`); and the problem (or sub-problem) has `named`: the `order` to evaluate those coefficients in, each naming only earlier ones, and the ADR slot values (m, f, a, r, H) over the names. The equations are read a second time with each coefficient of the state a known field rather than a constant, so a divergence of ρ v stays a flux and a gradient of ρ is kept (grad_ρ_0). The derivatives and depends_on stay the substituted form's, which are exact; in `named` a name is held fixed. Both are absent without coefficients of the state. The dam break's flow sub-problem now reads: order χ, ρ, μ; χ := χh (VOF's carrier), ρ := 998.2 - 996.995*χ, μ := 0.0010021928 - 0.0009841178*χ; momentum m = v_0*ρ, f = [p + v_0**2*ρ, v_0*v_1*ρ], a = [2*μ, μ], the vertical's r = 9.8*ρ. Torino's drag law keeps Fr, β and Fd (a vector) by name; nonlinear_diffusion's a = [k, k] with k := u**2 + 1. Measured: evaluating each named slot after its inline coefficients equals the substituted slot at 7 random points per name to 1e-13 (dam-break flow 15 slot values, Torino swe, nonlinear_diffusion; tests/test_named_coefficients.py). ymf suite 850 passed, 2 skipped (was 845; 5 new, one test updated for the new key), macOS arm64, petsc-dev env. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…_hReg)
The model-family note's regularization list (§ 3.1 item 5) had three
entries: heaviside and sign, done in round 1, and u = q/h at h = 0, which
the shallow-water fixture left to a comment. A split discretization (or one
sub-problem) may now give
regularize:
inverse: {by: wet_dry_cutoff, of: h, width: hε}
and every negative power of the scalar unknown h it solves for (q⊗q/h,
Manning's h^(-7/3), Fr's h^(-3/2)) is read through Proteus SW2DCV.h's
one_over_hReg, 2h/(h² + max(h, hε)²): 1/h wherever h ≥ hε, bounded below,
0 at h = 0. The rewrite happens after parsing and before differentiation,
so the derivatives are the regularized expression's, and it reaches the
named form's inline coefficients too. `inverse` is the one regularization
that is not a function of the notation, so it names its unknown (`of`);
checked on load (`of` required for inverse, an unknown, and refused on
heaviside or sign). The shallow-water numerics bind hε (meaning:
dry_depth, the solver's 1e-5 max(h0)) and use it; split_problem records
it under `regularized` with its `of`.
Measured: the lake-at-rest flux q_0²/h + 4.905 h² is the unregularized
value to 1e-12 at h = 1, 2hε and hε, equals 4.905 h² + 0.09·2h/(h² + hε²)
at h = hε/4, and is 0 at h = 0 (hε = 1e-5); Torino's Froude drag still
matches the deck to 1e-12 at h = 0.1. ymf suite 854 passed, 2 skipped (was
850; 3 refusal cases, 1 dry-node test; 3 shallow-water tests updated for
the regularized code), macOS arm64, petsc-dev env.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…spec file Decided by cekees 2026-11-05 (C7.1 round 2, decision 2): store the mesh's fingerprint in the archive now, in the mesh's provenance, so a restart or `pro gauge` can verify the mesh before reading. ymf carries the definition so every writer computes the same digest; proteus writes and checks it on cekees/proteus#200. - archive.provenance(..., fingerprint=) records {method: ymf-mesh-1, sha256}; the canonicalizer takes the key (anything but {method, sha256} is refused), validation checks the digest's form. - ymf.mesh.fingerprint(nodes, cells): SHA-256 over a tag, the shapes (int64), the nodes (float64, three columns, 2D padded with z = 0) and the cells (int64), little-endian, in the order given. grid_fingerprint(grid) of a stored grid; check_fingerprint(grid, base_dir, digest=None) returns the recorded digest, None if none, raises on another mesh or another method; `digest` is the input-order digest for a writer whose rows are permuted. Two gaps proteus found posing a `discrete` domain from a spec file (proteus#200's end-to-end test worked around both): - the strict spec schema had no `attributes` (or `provenance`) on a discrete domain, though ymf.domain allows them; added. - strictyaml reads the mesh's keys as Any, so inline values came back as text ("'0' is not a number" from the canonicalizer). ymf.domain.type_discrete_block, run on load in compose._check_document, types each data item's values by its data_type (and dimensions, precision, topology counts as integers), refusing text that is not a number. The archive's own refusal of text values (test_inline_values_are_checked) is kept. Measured: tests 764 passed, 11 skipped (was 751 + 13 new: 7 fingerprint, 1 spec-file round trip with attributes and typed values, and the parametrized refusals). The unit square of test_mesh digests to 4631cb7c6e4c040d...; the digest is pinned so a change of definition must change the method. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… `dimension` Found by proteus once the previous commit let a spec carry an inline mesh: proteus writes 2D meshes with three coordinates (XYZ, z = 0), and adr_problem took the space dimension from the geometry's columns, so `dimension: 2` was ignored: dim 3, upper z = 0, and proteus solved a 3D problem on a 2D mesh (L2 error nan for square4x4_tagged). _inline_nodes now keeps the first `dimension` coordinates when the block gives one, refuses coordinates beyond it that vary (a tilted mesh is not planar), and refuses a dimension above the geometry's width. Measured: ymf tests 765 passed, 11 skipped (+1). proteus (cekees/proteus#200, test_a_discrete_domain_inline_with_its_attributes_solves_as_its_file): square4x4_tagged inline with its node and element tags, before L2 nan at levels 1 and 2, after < 1e-12 and the archive bit-equal to the `kind: file` run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
C42 round 2: closure records the split and state coefficients; names kept in the plain data; wet/dry cutoff
docs/changes.md conflicted (both added 2026-11-05 entries): both kept, this branch's first; its entry now also names the inline XYZ planar mesh fix (7ae230c). schema.py and symbolic/problem.py merged cleanly. ymf tests after the merge: 792 passed, 11 skipped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
C7.1: a mesh records its fingerprint; a discrete domain loads from a spec file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two reviewed PRs from cekees/ymf, merged there in order.
cekees/ymfmainis a fast-forward of this repository'smain.ρas an inline function of the state), for C19's kernel generator and the C5 dispatcher;provenance(fingerprint=), withymf.mesh.fingerprint,grid_fingerprintandcheck_fingerprint;attributesandprovenance;data_typeon load;proteus CI installs ymf from this repository's
main, so this must merge before the next proteus main train: cekees/proteus#200 records and checks the fingerprint, and its tests skip until then.Merge with "Create a merge commit", so that the fork's
mainstays a fast-forward of this one.🤖 Generated with Claude Code