Compare commits

...
Author SHA1 Message Date
ClaudeandClaude Opus 5.5 caa573f978 test: adopt native-validated 24-target probe layout
Horizontal y=56 and vertical x=38 through box 1, normal coordinates
[12.5..26.125] (root128 physical). Nearest-ACTIVE mapping with
deterministic tie rule (distance, finer level, smaller j, smaller i),
duplicate-cell rejection, stored centers and displacements. Replaces my
earlier offsets, which mapped two target pairs to the same U128 cell.
U512 spacing 128/512 and root step r -> U512 step 4r unchanged.
Tests: 24 unique cells per case, nested 3 L0 + 5 L1 + 4 L2 per transect,
U128 max displacement 0.625.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 03:13:43 +00:00
ClaudeandClaude Opus 5.5 1e188e7419 test: signed interface-probe trace diagnostic (--probe-trace)
Test-only mechanism diagnostic, no pass gates. New pinned shear_probes.py:
24 fixed root-physical points on vertical/horizontal interface-normal
transects (>=8 root cells from corners), ACTIVE-leaf selection storing
level/i/j/actual centers, root-sync rho/ux/uy at root steps 0-128 and
1920-2048 (U512 every 4 lattice steps), analytic residuals at actual
centers, schedule/finite/600 kB validation. run_case: --probe-trace for
nested U128/U512/projected d3 and twin projected d2 (not with
--final-snapshot), shear_probes.py pin, probe-only steps skip metrics,
five qualification samples unchanged. shear_wave/shear_nested/shear_twin/
oracle byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 03:11:48 +00:00
ClaudeandClaude Opus 5.5 02bde0f751 test: depth-2 twin of the nested shear preset (twin_shear_n128)
Test-only opt-in. New shear_twin.py: same two L0->L1 boxes as
shear_nested, no L2; leaves [7936,33792], hops [2048,4096], work
154664960. Four fresh cases U128/U256/constant R128 d2/projected R128 d2;
physics is the unchanged depth-2/2N shear_wave.assess. run_case:
--diagnostic twin_shear_n128 with shear_twin.py+shear_nested.py pins, no
snapshot. assess_shear_wave: nested contract made preset-generic (PRESETS)
with nested behaviour unchanged. Labels: twin vs nested = effect of adding
this nested refinement (not abstract depth). shear_wave.py, shear_nested.py
and oracle.py byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 02:52:20 +00:00
ClaudeandClaude Opus 5.5 335624c27b test: fixed three-level/two-region nested shear preset (nested_shear_n128)
Test-only opt-in. New shear_nested.py: fixed parent-frame rectangles
(L0->L1 (16,16,60,112),(68,24,112,120); L1->L2 (44,44,108,212),
(148,60,212,228)), exact leaves/hops/work/nu/tau, depth-3 + 4N-finest
generalization of the shear assessment (same summaries/screens/budgets),
bounded final macro snapshot writer/reader (packed ACTIVE leaves + rho/u,
metadata, sha256, 8 MiB cap; no populations/restart/time series).
run_case: --diagnostic nested_shear_n128 (U128, U512, constant/projected
R128 depth 3), --final-snapshot only for projected depth 3, shear_nested.py
path+hash pin. assess_shear_wave: assess_nested contract and CLI.
shear_wave.py and oracle.py byte-identical; old guards/defaults unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 02:14:23 +00:00
ClaudeandClaude Opus 5.5 9748ef91ef test: portable few-ULP check for recomputed shear eps metadata
Cross-platform replay of the frozen assessor returned INVALID_SET because
recomputed eps(128) differed from the Horsea receipt by one ULP. Compare
only that derived float within 4 ULPs (close_ulps); hashes, case identity,
other metadata and scientific thresholds stay exact. Tests accept the
observed one/two-ULP differences and reject 1e-12 relative, 2x, string,
NaN and missing values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 01:15:59 +00:00
7 changed files with 1270 additions and 14 deletions

No files matched your search

+122
View File
@@ -337,3 +337,125 @@ Assessment:
- These are descriptive. Passing or failing another floor-controlled
screen is not the conclusion, and a two-resolution ratio is not a
convergence order.
- Portability: the receipt's recomputed `eps = |k|^2` is compared within
4 ULPs (`close_ulps`), not by exact equality. A cross-runtime replay
differed by one ULP: 0.012047856934923534 on Horsea vs
0.012047856934923532 elsewhere. Source and file hashes, case identity,
the other metadata and every scientific threshold stay exact.
### Nested shear preset (opt-in `nested_shear_n128`)
A fixed three-level, two-region preset, defined in `shear_nested.py`. The
wave, phase, Re100/U=0.03, initialization, five sample times, eps(root N),
limits and floors are the same as before.
- Refinements, given as parent-frame `(x0, y0, x1, y1)` rectangles on
level-wide, zero-origin unions:
- L0→L1: `(16,16,60,112)`, `(68,24,112,120)`
- L1→L2: `(44,44,108,212)`, `(148,60,212,228)`
- Leaves `[7936, 12288, 86016]`, hops `[2048, 4096, 8192]`, work
771227648 per refined case; 3723493376 for all four cases.
- Level ν `[.0384, .0768, .1536]`, τ `[.6152, .7304, .9608]`.
Cases (`run_case.py --flow shear_wave --diagnostic nested_shear_n128 --re 100`):
- `--n 128 --depth 1`
- `--n 512 --depth 1` — the finest control is 4N, not 2N
- `--n 128 --depth 3`
- `--n 128 --depth 3 --explosion projected_linear [--final-snapshot]`
`--final-snapshot` is allowed only for the projected depth-3 case. It writes
`<output>.final_macro.npz`, containing:
- ACTIVE leaves packed as `level`/`i`/`j`;
- `rho`, `ux`, `uy` from the FP64 physical populations at the final root
synchronization;
- embedded metadata: exact time, phase, mode and config.
It contains no populations, restart state or time series. Its SHA-256 and
size go into the receipt. A file over 8 MiB is removed and reported, never
kept. All old paths stay scalar-only.
Assessment: `assess_shear_wave.py U128.json U512.json R128c.json R128p.json
--diagnostic nested_shear_n128 --output report.json --expected-revision <sha>`.
- It reuses the case-agnostic provenance checks from the TG assessor, plus
exact nested scales, builds, patch, workload, metadata and the pinned
`shear_nested.py` hash.
- The physics is `shear_wave.assess` generalized only in its depth-3 / 4N
shape contract; the metrics are unchanged.
- `shear_wave.py` is byte-identical (81d5c8ee…), so historical receipt
identities and verdicts are untouched.
- This preset changes placement and refined volume as well as depth. It
gives no isolated cost of an extra level and no resolution trend.
### Depth-2 twin of the nested preset (opt-in `twin_shear_n128`)
`shear_twin.py` uses the same two L0→L1 boxes as `shear_nested.py`, with no
L2. Leaves are `[7936, 33792]`, hops `[2048, 4096]`, and work is 154664960 per
refined case (611319808 for all four).
The campaign is four fresh runs:
`run_case.py --flow shear_wave --diagnostic twin_shear_n128 --re 100` with
- `--n 128 --depth 1`
- `--n 256 --depth 1` (the finest control is 2N)
- `--n 128 --depth 2`
- `--n 128 --depth 2 --explosion projected_linear`
There is no snapshot option. Older exact controls serve only as consistency
checks; they are not reused as references.
Assessment uses the same preset contract as the nested preset, through
`assess_shear_wave.py ... --diagnostic twin_shear_n128`:
- the physics is the unchanged depth-2 / 2N `shear_wave.assess`;
- receipts must pin `shear_twin.py`, `shear_nested.py` and `shear_wave.py`;
- `shear_nested.py` stays byte-identical (fa6cfe87…), so the 335624c nested
receipts still validate.
Labels:
- *Twin vs nested* is the effect of adding this nested L2 refinement.
Removing L2 also changes the finest spacing and refined volume, so it does
not isolate abstract depth.
- *Twin vs the single-box depth-2 runs* is a placement/geometry contrast at
equal depth.
- Neither contrast is additive by construction.
- The thin-band/acoustic explanation for the nested L1 pressure is a
hypothesis, not established.
### Signed interface-probe traces (opt-in `--probe-trace`, mechanism diagnostic)
`shear_probes.py` (pinned) uses native's validated 24-target layout through
box 1, in root-128 physical coordinates:
- a horizontal line y = 56, crossing the vertical faces x = 16 and 22;
- a vertical line x = 38, crossing the horizontal faces y = 16 and 22;
- normal coordinates 12.5, 14.5, 15.5, 16.25, 17.25, 19.25, 20.75, 21.75,
22.125, 23.125, 24.125, 26.125.
Each target maps to the nearest ACTIVE leaf center. The deterministic tie
rule is: distance, then finer level, then smaller j, then smaller i. This
gives 24 unique cells in every case, and nested has 3 L0 + 5 L1 + 4 L2 per
transect. Maximum displacement from target to center is 0.625 root cells in
U128 (0.177 in U512).
Allowed cases:
- nested U128, nested U512, nested projected depth 3;
- twin projected depth 2.
The option can't be combined with `--final-snapshot`.
Sampling:
- The receipt stores each probe's leaf level, `i`/`j`, actual cell center
and displacement from its target, all in root-physical units (N=128).
- Grids differ between cases, so centers are *not* collocated. Analytic
fields are evaluated at each actual center (`shear_probes.residuals`), and
comparisons across cases are between residuals at nearby but distinct
centers.
- Times are root-physical steps 0–128 and 1920–2048. U512 is sampled every 4
lattice steps to match.
- Each sample stores `rho`, `ux`, `uy` from the FP64 physical populations,
POST-collision G at root synchronization only. No substep content is
observed, and grid-scale alternation can alias.
What's kept and enforced:
- The five qualification samples stay unchanged.
- No field dumps. The trace is validated for exact schedule, finiteness and
a 600 kB cap. If invalid it is dropped and an error is recorded, keeping
the scalar receipt.
- There are no new pass gates; this is a mechanism diagnostic only.
@@ -13,11 +13,15 @@ Taylor-Green-specific checks are replaced by shear-wave metadata and physics.
import argparse
import hashlib
import json
import math
from pathlib import Path
import assess_projected_pairs as tg
import shear_wave as sw
from run_case import SCALED_DIAGNOSTIC, SCALED_SHEAR, SHEAR_WAVE_SHA256
import shear_nested as nested
import shear_twin as twin
from run_case import (NESTED_SHEAR, SCALED_DIAGNOSTIC, SCALED_SHEAR, SHEAR_NESTED_SHA256,
SHEAR_TWIN_SHA256, SHEAR_WAVE_SHA256, TWIN_SHEAR, sample_steps)
# Audited de5b0cc N128 receipts (evidence commit cba6bca, shear-wave-de5b0cc zip).
REFERENCE_REVISION = "de5b0cc080794d0ce44d37f845aa8e8dbf8c2016"
@@ -36,11 +40,26 @@ PER_CASE = ("complete_times", "scales", "actual_builds", "reference", "runtime_s
"patch", "workload")
METADATA_ULPS = 4
def close_ulps(recorded, expected, ulps=METADATA_ULPS):
"""Portable check for recomputed float metadata only (e.g. eps = |k|^2).
The recorded value comes from another runtime/libm, so exact equality can
fail by one ULP (observed: 0.012047856934923534 Horsea vs ...532 here).
A few ULPs is far below any meaningful change; hashes, case identity and
scientific thresholds stay exact.
"""
return (isinstance(recorded, float) and math.isfinite(recorded)
and abs(recorded - expected) <= ulps * math.ulp(max(abs(recorded), abs(expected))))
def metadata_ok(record, n):
return (record.get("flow") == "shear_wave" and record.get("mode") == list(sw.MODE)
and record.get("polarization") == sw.E.tolist()
and record.get("angle_deg") == sw.ANGLE_DEG and record.get("phase") == sw.PHI
and record.get("eps") == sw.eps(n)
and close_ulps(record.get("eps"), sw.eps(n))
and record.get("numerics") == tg.NUMERICS
and record.get("initialization") == sw.INITIALIZATION
and record.get("limits") == sw.LIMITS
@@ -98,6 +117,126 @@ def assess(records, expected_revision=None, *, scaled=False):
return result
CASE_AGNOSTIC = ("finite_receipts", "same_source_and_harness", "clean_a135252_numerical_source",
"same_recorded_runtime", "same_explicit_device", "same_early_sampling")
# Fixed multi-box presets sharing one contract; only geometry, controls, pins differ.
PRESETS = {
NESTED_SHEAR: dict(
module=nested, physics=nested.assess, snapshot=True,
pins={"shear_nested_sha256": SHEAR_NESTED_SHA256},
finest_control="uniform 4N (U512)",
scope="2D periodic Re100 oblique (2,1) shear wave; fixed three-level/two-region "
"placement; changes placement and refined volume as well as depth, so no "
"isolated-level cost or resolution trend"),
TWIN_SHEAR: dict(
module=twin, physics=sw.assess, snapshot=False,
pins={"shear_nested_sha256": SHEAR_NESTED_SHA256,
"shear_twin_sha256": SHEAR_TWIN_SHA256},
finest_control="uniform 2N (U256)",
scope="2D periodic Re100 oblique (2,1) shear wave; depth-2 twin of the nested "
"preset (same two L0->L1 boxes, no L2). Twin vs nested is the effect of adding "
"this nested refinement; it also changes finest spacing and refined volume, so it "
"does not isolate abstract depth"),
}
def _nested_case_ok(r, n, depth, diagnostic=NESTED_SHEAR):
"""Per-case identity of a fixed multi-box preset (scales, builds, patch, work, pins)."""
preset = PRESETS[diagnostic]
geometry = preset["module"]
runtime = r.get("runtime_source", {})
package = Path(runtime.get("checkout", "")) / "src/CelerisLab"
cells = [n * n] if depth == 1 else geometry.LEAVES
hops = [16 * n * 2**level for level in range(depth)]
work = r.get("workload", {})
snapshot = r.get("final_snapshot")
expected_patch = [] if depth == 1 else geometry.REFINEMENTS
return {
"complete_times": r.get("completed") is True and tg.at_steps(
r.get("rows", []), sample_steps(n)[0], n),
"scales": (r.get("U") == sw.U and tg.finite(r.get("viscosity"))
and abs(r["viscosity"] - sw.U * n / 100) < 1e-15
and r.get("tau_by_level") == [0.5 + 3 * sw.U * n / 100 * 2**l
for l in range(depth)]
and r.get("mach") == sw.U * math.sqrt(3)),
"actual_builds": tg.valid_builds(r, n, depth),
"reference": (r.get("numerical_revision") == tg.NUMERICAL_REVISION
and r.get("reference_harness") == tg.REFERENCE_HARNESS),
"runtime_source": bool(runtime.get("checkout")) and all(
runtime.get(k) == str(package / tail) for k, tail in
(("module", "__init__.py"), ("compiler", "cuda/compiler_v2.py"),
("kernel_root", "lbm/kernels"))),
"patch": json.dumps(r.get("refinements")) == json.dumps(expected_patch),
"workload": (work.get("active_cells_by_level") == cells and work.get("level_hops") == hops
and work.get("root_intervals") == 16 * n
and work.get("active_collision_updates_by_level") == [
c * h for c, h in zip(cells, hops)]
and work.get("active_collision_updates") == sum(
c * h for c, h in zip(cells, hops))),
"shear_metadata": metadata_ok(r, n),
"nested_module_pin": all((r.get("source") or {}).get(key) == pin
for key, pin in preset["pins"].items()),
# Optional, nested projected depth-3 only; bounded and hashed when present.
"snapshot": snapshot is None or (
preset["snapshot"] and depth == nested.DEPTH and r.get("explosion") == "projected_linear"
and snapshot.get("kept") is True and isinstance(snapshot.get("sha256"), str)
and len(snapshot["sha256"]) == 64
and 0 < snapshot.get("bytes", 0) <= nested.SNAPSHOT_MAX_BYTES
and snapshot.get("leaf_counts") == nested.LEAVES
and snapshot.get("step") == sample_steps(n)[0][-1]),
}
def assess_nested(records, expected_revision=None, diagnostic=NESTED_SHEAR):
"""Fixed four-case preset contract: nested_shear_n128 (U128, U512, constant/projected
R128 depth 3) or twin_shear_n128 (U128, U256, constant/projected R128 depth 2)."""
preset = PRESETS[diagnostic]
geometry = preset["module"]
if not isinstance(records, list) or not all(isinstance(r, dict) for r in records):
raise ValueError("records must be a list of receipt objects")
base_checks = tg.assess(records, expected_revision)["checks"]
checks = {name: base_checks.get(name, False) for name in CASE_AGNOSTIC}
indexed, duplicates = {}, []
for r in records:
key = tuple(r.get(k) for k in ("re_L", "n", "depth", "explosion"))
(duplicates.append(key) if key in indexed else indexed.__setitem__(key, r))
checks.update(complete_matrix=all(k in indexed for k in geometry.CASES),
no_extra_cases=set(indexed) <= set(geometry.CASES),
no_duplicate_cases=not duplicates,
shear_diagnostic_identity=all(r.get("diagnostic") == diagnostic
for r in records))
for key in geometry.CASES:
_, n, depth, scheme = key
label = f"{n}/{depth}/{scheme}"
case = _nested_case_ok(indexed[key], n, depth, diagnostic) if key in indexed else {}
for name in ("complete_times", "scales", "actual_builds", "reference", "runtime_source",
"patch", "workload", "shear_metadata", "nested_module_pin", "snapshot"):
checks[f"{label} {name}"] = bool(case.get(name, False))
contract_valid = all(checks.values())
result = dict(checks=checks, contract_valid=contract_valid, diagnostic=diagnostic,
cases=[list(k) for k in geometry.CASES], expected_revision=expected_revision,
finest_control=preset["finest_control"], scope=preset["scope"])
if not contract_valid:
result.update(status="INVALID_SET", passed=False)
return result
try:
cases = geometry.CASES
physics = preset["physics"](indexed[cases[0]], indexed[cases[1]],
[indexed[cases[2]], indexed[cases[3]]])
except (KeyError, ValueError) as error:
result.update(status="INVALID_SET", passed=False, reason=str(error))
return result
result.update(physics=physics, status=physics["status"], passed=physics["status"] == "PASS")
try:
# Role "uniform_fine" is the preset's finest control (4N nested, 2N twin).
result["signed"] = signed_summary([indexed[k] for k in geometry.CASES])
except (KeyError, TypeError, ValueError) as error:
result["signed_unavailable"] = str(error)
return result
def _signed(record):
"""Raw signed quantities of one valid record (None when the fit is unavailable)."""
s = sw.summarize(record)
@@ -167,11 +306,20 @@ if __name__ == "__main__":
p.add_argument("files", type=Path, nargs=4)
p.add_argument("--output", type=Path, required=True)
p.add_argument("--expected-revision", required=True)
p.add_argument("--diagnostic", choices=[SCALED_SHEAR])
p.add_argument("--diagnostic", choices=[SCALED_SHEAR, NESTED_SHEAR, TWIN_SHEAR])
p.add_argument("--reference-files", type=Path, nargs=4)
args = p.parse_args()
if args.output.exists():
p.error("Output already exists; choose a new path to retain prior evidence")
if args.diagnostic in PRESETS:
if args.reference_files:
p.error(f"{args.diagnostic} takes no reference files (no resolution trend)")
result = assess_nested([json.loads(path.read_text()) for path in args.files],
args.expected_revision, args.diagnostic)
text = json.dumps(result, indent=2, allow_nan=False) + "\n"
args.output.write_text(text)
print(text, end="")
raise SystemExit(0 if result["passed"] else 1)
if bool(args.diagnostic) != bool(args.reference_files):
p.error("--diagnostic scaled_shear_n256 requires --reference-files (N128 receipts)")
result = assess([json.loads(path.read_text()) for path in args.files], args.expected_revision,
+100 -11
View File
@@ -21,6 +21,11 @@ INITIALIZATION = "physical FP64 equilibrium G at actual cell centers; rho=1+3p"
SHEAR_WAVE_SHA256 = "81d5c8ee60864372887cddf9239580c82fb6750d956038f1e3ee9de61aa4e877"
SCALED_DIAGNOSTIC = "scaled_n256"
SCALED_SHEAR = "scaled_shear_n256" # mutually exclusive with scaled_n256 (one flow each)
NESTED_SHEAR = "nested_shear_n128" # fixed three-level/two-region shear preset
SHEAR_NESTED_SHA256 = "fa6cfe87fb4df8c6d732c637c885276833c81973b950c7724d734f8fc350bcb0"
TWIN_SHEAR = "twin_shear_n128" # depth-2 twin: nested L0->L1 boxes without L2
SHEAR_TWIN_SHA256 = "1cbf37f18e89aea577581631c4565f51e68d22a3739b698816ef64acbf2b2bb4"
SHEAR_PROBES_SHA256 = "53ba8af8ac9c8078c40f84488c7ade4c11ccc91dd1fc275ff806042e9af30166" # signed interface-probe mechanism diagnostic
def flow_functions(flow="taylor_green"):
@@ -90,7 +95,7 @@ def provenance(repo):
)
def verify_source(repo, revision, flow="taylor_green"):
def verify_source(repo, revision, flow="taylor_green", probes=False):
"""Exact clean harness commit, fixed production tree, and reviewed capture helper."""
import oracle
from tests.validation.multigrid import check_projected_pairs as gate
@@ -109,7 +114,28 @@ def verify_source(repo, revision, flow="taylor_green"):
if result["source_tree_sha256"] != SOURCE_SHA256:
raise RuntimeError("Wrong numerical source fingerprint")
result["build_capture_sha256"] = BUILD_CAPTURE_SHA256
if flow == "shear_wave":
if probes:
import shear_probes
module = harness / "shear_probes.py"
if (Path(shear_probes.__file__).resolve() != module
or hashlib.sha256(module.read_bytes()).hexdigest() != SHEAR_PROBES_SHA256):
raise RuntimeError("Wrong shear_probes module checkout or content")
result["shear_probes_sha256"] = SHEAR_PROBES_SHA256
if flow == "shear_twin":
import shear_twin
module = harness / "shear_twin.py"
if (Path(shear_twin.__file__).resolve() != module
or hashlib.sha256(module.read_bytes()).hexdigest() != SHEAR_TWIN_SHA256):
raise RuntimeError("Wrong shear_twin module checkout or content")
result["shear_twin_sha256"] = SHEAR_TWIN_SHA256
if flow in ("shear_nested", "shear_twin"): # the twin reuses the nested geometry
import shear_nested
module = harness / "shear_nested.py"
if (Path(shear_nested.__file__).resolve() != module
or hashlib.sha256(module.read_bytes()).hexdigest() != SHEAR_NESTED_SHA256):
raise RuntimeError("Wrong shear_nested module checkout or content")
result["shear_nested_sha256"] = SHEAR_NESTED_SHA256
if flow in ("shear_wave", "shear_nested", "shear_twin"):
import shear_wave
module = harness / "shear_wave.py"
if (Path(shear_wave.__file__).resolve() != module
@@ -182,21 +208,50 @@ def main():
p.add_argument("--depth", type=int, choices=[1, 2, 3], required=True)
p.add_argument("--output", type=Path, required=True)
p.add_argument("--explosion", choices=["constant", "projected_linear"], default="constant")
p.add_argument("--diagnostic", choices=[SCALED_DIAGNOSTIC, SCALED_SHEAR],
p.add_argument("--diagnostic",
choices=[SCALED_DIAGNOSTIC, SCALED_SHEAR, NESTED_SHEAR, TWIN_SHEAR],
help="explicit four-case N256/fine512 same-placement diagnostic "
"(scaled_n256: Taylor-Green; scaled_shear_n256: shear wave)")
"(scaled_n256: Taylor-Green; scaled_shear_n256: shear wave) or the "
"fixed three-level/two-region shear preset (nested_shear_n128) "
"or its depth-2 twin (twin_shear_n128)")
p.add_argument("--probe-trace", action="store_true",
help="signed interface-probe trace (nested U128/U512/projected d3, "
"twin projected d2); mechanism diagnostic, no gates")
p.add_argument("--final-snapshot", action="store_true",
help="nested_shear_n128 projected depth-3 only: final macro snapshot")
p.add_argument("--early-pressure", action="store_true",
help="also save 65 scalar pressure samples at t*=k*.001875, k=0..64")
p.add_argument("--flow", choices=["taylor_green", "shear_wave"], default="taylor_green")
args = p.parse_args()
if args.flow == "shear_wave" and (args.re != 100 or args.depth == 3 or args.early_pressure):
nested = args.diagnostic == NESTED_SHEAR
if args.flow == "shear_wave" and (args.re != 100 or (args.depth == 3 and not nested)
or args.early_pressure):
p.error("shear_wave requires --re 100, depth 1 or 2 and no --early-pressure")
probe_cases = {(NESTED_SHEAR, 128, 1, "constant"), (NESTED_SHEAR, 512, 1, "constant"),
(NESTED_SHEAR, 128, 3, "projected_linear"),
(TWIN_SHEAR, 128, 2, "projected_linear")}
if args.probe_trace and (args.final_snapshot or (
args.diagnostic, args.n, args.depth, args.explosion) not in probe_cases):
p.error("--probe-trace requires nested U128/U512/projected depth 3 or twin projected "
"depth 2, without --final-snapshot")
if args.final_snapshot and not (nested and args.depth == 3
and args.explosion == "projected_linear"):
p.error("--final-snapshot requires nested_shear_n128 projected depth 3")
initial, metrics, limits, initialization = flow_functions(args.flow)
if args.output.exists():
p.error("Output already exists; choose a new path to retain prior evidence")
if args.explosion != "constant" and args.depth != 2:
if args.explosion != "constant" and args.depth != 2 and not nested:
p.error("projected_linear requires depth 2")
if args.diagnostic:
twin = args.diagnostic == TWIN_SHEAR
if nested or twin:
import shear_nested
import shear_twin
preset = shear_nested if nested else shear_twin
if args.flow != "shear_wave":
p.error(f"--diagnostic {args.diagnostic} requires --flow shear_wave")
if (args.re, args.n, args.depth, args.explosion) not in preset.CASES:
p.error(f"{args.diagnostic} requires one of its four Re100 cases")
elif args.diagnostic:
cases = {(256, 1, "constant"), (512, 1, "constant"),
(256, 2, "constant"), (256, 2, "projected_linear")}
flow = "shear_wave" if args.diagnostic == SCALED_SHEAR else "taylor_green"
@@ -209,13 +264,15 @@ def main():
if args.diagnostic == SCALED_SHEAR and (args.n, args.depth, args.explosion) not in cases:
p.error("scaled_shear_n256 requires one of its four Re100 cases")
elif args.n == 512:
p.error("N512 requires --diagnostic scaled_n256 or scaled_shear_n256")
p.error("N512 requires --diagnostic scaled_n256, scaled_shear_n256 or nested_shear_n128")
selected = os.environ.get("CUDA_VISIBLE_DEVICES", "")
if not args.dry_run and (not args.run_gpu or not selected or "," in selected or selected == "-1"):
p.error("--run-gpu and exactly one explicit CUDA_VISIBLE_DEVICES are required")
repo = args.repo.resolve()
sys.path[:0] = [str(repo / "src"), str(repo)]
source = verify_source(repo, args.expected_revision, args.flow)
source = verify_source(repo, args.expected_revision,
"shear_nested" if nested else "shear_twin" if twin else args.flow,
probes=args.probe_trace)
runtime = runtime_source(repo)
if args.dry_run:
print(json.dumps(dict(source=source, runtime_source=runtime, dry_run=True,
@@ -229,7 +286,12 @@ def main():
from CelerisLab.lbm.hierarchy import build_hierarchy, leaf_partition
cfg = config(args.n, args.re)
refinements = [] if args.depth == 1 else rectangles(args.n, args.depth)
if args.depth == 1:
refinements = []
elif nested or twin:
refinements = [list(level) for level in preset.REFINEMENTS]
else:
refinements = rectangles(args.n, args.depth)
h = build_hierarchy(cfg, refinements)
np.testing.assert_array_equal(leaf_partition(h), np.ones((args.n, args.n)))
masks = [k == ACTIVE for k in h.kinds]
@@ -308,8 +370,23 @@ def main():
]
)
initial_mass = None
for step in sorted(set(main_steps + early_steps)):
probe_steps = set()
if args.probe_trace:
import shear_probes
probe_root = dict(zip(shear_probes.case_steps(args.n), shear_probes.STEPS))
probe_steps = set(probe_root)
probes = shear_probes.select(masks, args.n)
report["probe_trace"] = shear_probes.new_trace(
probes, cfg.viscosity, [args.diagnostic, args.n, args.depth, args.explosion])
for step in sorted(set(main_steps + early_steps) | probe_steps):
run.step(step - run.step_count)
if step in probe_steps:
trace = report["probe_trace"]
trace["steps"].append(probe_root[step]) # root-physical step
trace["values"].append(shear_probes.sample(
(run.download(),) if args.depth == 1 else run.download(), probes))
if step not in main_steps and step not in early_steps:
continue # probe-only step: no qualification metrics
row = sample(run, masks, step, args.n, cfg.viscosity, initial_mass,
metrics, args.depth)
row["step"] = step
@@ -317,6 +394,13 @@ def main():
initial_mass = row["mass"]
if step in main_steps:
report["rows"].append(row)
if args.final_snapshot and step == main_steps[-1]:
# Optional macro-only snapshot; scalar receipt stays authoritative.
report["final_snapshot"] = shear_nested.write_snapshot(
args.output.with_name(args.output.stem + ".final_macro.npz"),
run.download(), masks,
shear_nested.snapshot_meta(step, cfg.viscosity, args.explosion,
source.get("revision")))
if step in early_steps:
trace = report["early_pressure"]
trace["rows"].append({key: row[key] for key in ("step", "tstar", "pressure_l2")})
@@ -355,6 +439,11 @@ def main():
),
flush=True,
)
if args.probe_trace:
try:
report["probe_trace"]["bytes"] = shear_probes.validate(report["probe_trace"])
except ValueError as error: # keep the scalar receipt; drop an invalid trace
report["probe_trace"] = dict(error=str(error))
report.update(
completed=True,
seconds=time.monotonic() - started,
@@ -0,0 +1,174 @@
"""Fixed three-level/two-region shear preset (opt-in nested_shear_n128).
Four fresh cases: U128, U512 (finest control = 4N), constant R128 depth 3,
projected R128 depth 3. Same wave, phase, Re100/U=0.03, initialization, five
sample times, eps(root N), limits and floors as shear_wave. This changes
placement and refined volume as well as depth: no isolated-level cost or
resolution-trend label. shear_wave.py is reused unchanged (historical receipt
identities stay valid); only the depth/finest-control contract is generalized
here.
"""
import hashlib
import json
from pathlib import Path
import numpy as np
import shear_wave as sw
from oracle import CX, CY, U, centers
ROOT_N = 128
DEPTH = 3
FINEST_FACTOR = 2 ** (DEPTH - 1) # finest-spacing uniform control is 4N
# Parent-frame (x0, y0, x1, y1) rectangles; level-wide, zero-origin unions.
REFINEMENTS = [
[(16, 16, 60, 112), (68, 24, 112, 120)], # L0 -> L1, root coordinates
[(44, 44, 108, 212), (148, 60, 212, 228)], # L1 -> L2, L1 coordinates
]
CASES = ((100, ROOT_N, 1, "constant"), (100, FINEST_FACTOR * ROOT_N, 1, "constant"),
(100, ROOT_N, DEPTH, "constant"), (100, ROOT_N, DEPTH, "projected_linear"))
ROOT_STEPS = 16 * ROOT_N
LEAVES = [7936, 12288, 86016]
HOPS = [ROOT_STEPS * 2**level for level in range(DEPTH)] # [2048, 4096, 8192]
WORK = sum(c * h for c, h in zip(LEAVES, HOPS)) # 771227648 per refined case
NU = [U * ROOT_N / sw.RE * 2**level for level in range(DEPTH)] # [.0384, .0768, .1536]
TAU = [0.5 + 3 * nu for nu in NU] # [.6152, .7304, .9608]
SNAPSHOT_MAX_BYTES = 8 * 1024 * 1024
SNAPSHOT_KEYS = ("level", "i", "j", "rho", "ux", "uy", "meta")
def leaf_masks():
"""Independent numpy leaf masks of the fixed preset (root, L1, L2 level-wide grids)."""
masks, covered = [], None
for level in range(DEPTH):
size = ROOT_N * 2**level
inside = np.ones((size, size), bool) if level == 0 else covered
if level < DEPTH - 1:
child = np.zeros((size, size), bool)
for x0, y0, x1, y1 in REFINEMENTS[level]:
child[y0:y1, x0:x1] = True
masks.append(inside & ~child)
covered = np.kron(child, np.ones((2, 2), bool))
else:
masks.append(inside)
return masks
def assess(base_control, finest_control, refined):
"""shear_wave.assess generalized to depth 3 with a 4N finest control.
Same summaries, screens, budgets and outcome semantics; only the
(depth, finest-control) shape contract differs.
"""
if base_control is None or finest_control is None or not refined:
return dict(status="INVALID_CONTROL", reason="missing control or refined run")
n = base_control["n"]
if (base_control["depth"], finest_control["depth"], finest_control["n"]) != (
1, 1, FINEST_FACTOR * n):
raise ValueError("controls must be uniform N and uniform 4N")
if any(r["depth"] != DEPTH or r["n"] != n for r in refined):
raise ValueError("refined runs must be depth 3 at root N")
if len({r.get("explosion") for r in refined}) != len(refined):
raise ValueError("duplicate refined explosion scheme")
sources = {repr(r.get("source")) for r in [base_control, finest_control, *refined]}
base, fine = sw._usable(base_control), sw._usable(finest_control)
if base is None or fine is None or len(sources) != 1:
return dict(status="INVALID_CONTROL", reason="incomplete/invalid control or mixed source")
controls_pass = base["own_screens_pass"] and fine["own_screens_pass"]
report = dict(base_control=base, finest_control=fine, refined={},
controls_pass=controls_pass)
statuses = []
for r in refined:
try:
s = sw.summarize(r)
except (KeyError, TypeError, ValueError) as error:
report["refined"][r["explosion"]] = dict(valid=False, reason=str(error))
statuses.append("INVALID_RUN")
continue
s["valid"] = True
s["budget"] = {
key: (None if base[key] is None else max(sw.BASELINE_FACTOR * base[key], floor))
for key, floor in sw.FLOORS.items()
}
s["budget_pass"] = all(
s[key] is not None and s["budget"][key] is not None and s[key] <= s["budget"][key]
for key in sw.FLOORS)
s["control_ratios"] = {
name: {key: (s[key] / c[key] if s[key] is not None and c[key] else None)
for key in (*sw.FLOORS, "spurious_pressure_rms")}
for name, c in (("root", base), ("finest", fine))
}
s["controlled_pass"] = controls_pass and s["own_screens_pass"] and s["budget_pass"]
report["refined"][r["explosion"]] = s
statuses.append("PASS" if s["controlled_pass"] else "FAIL")
if "INVALID_RUN" in statuses:
report["status"] = "INVALID_RUN"
elif not controls_pass:
report["status"] = "CONTROL_SCREEN_FAIL"
else:
report["status"] = "PASS" if all(v == "PASS" for v in statuses) else "FAIL"
return report
def write_snapshot(path, arrays, masks, meta):
"""Final macro snapshot: packed ACTIVE leaves (level, i, j), rho, ux, uy only.
No populations, no restart state, no time series. Returns the receipt block;
a file over SNAPSHOT_MAX_BYTES is removed and reported, never kept.
"""
path = Path(path)
if path.exists():
raise FileExistsError(path)
cols = {k: [] for k in ("level", "i", "j", "rho", "ux", "uy")}
counts = []
for level, (g, mask) in enumerate(zip(arrays, masks)):
if g.shape != (9, *mask.shape):
raise ValueError("population/mask shape mismatch")
values = g[:, mask].astype(float)
rho = values.sum(axis=0)
j, i = np.nonzero(mask) # row = y index, column = x index
cols["level"].append(np.full(rho.size, level, np.uint8))
cols["i"].append(i.astype(np.uint16))
cols["j"].append(j.astype(np.uint16))
cols["rho"].append(rho)
cols["ux"].append(CX @ values / rho)
cols["uy"].append(CY @ values / rho)
counts.append(int(rho.size))
packed = {k: np.concatenate(v) for k, v in cols.items()}
if not all(np.isfinite(packed[k]).all() for k in ("rho", "ux", "uy")):
raise FloatingPointError("nonfinite snapshot macros")
meta = dict(meta, leaf_counts=counts, cell_center="h*(index+0.5), h=2**-level",
fields="rho, ux, uy from FP64 physical populations at ACTIVE leaves")
with path.open("xb") as handle:
np.savez_compressed(handle, meta=np.array(json.dumps(meta, sort_keys=True)), **packed)
size = path.stat().st_size
block = dict(file=path.name, bytes=size, leaf_counts=counts, max_bytes=SNAPSHOT_MAX_BYTES,
step=meta.get("step"), tstar=meta.get("tstar"))
if size > SNAPSHOT_MAX_BYTES:
path.unlink()
return dict(block, kept=False, sha256=None, reason="exceeds snapshot byte cap")
block.update(kept=True, sha256=hashlib.sha256(path.read_bytes()).hexdigest())
return block
def read_snapshot(path):
"""Validate a snapshot: exact keys, no populations, consistent packed arrays."""
with np.load(path, allow_pickle=False) as data:
if tuple(sorted(data.files)) != tuple(sorted(SNAPSHOT_KEYS)):
raise ValueError("unexpected snapshot contents")
out = {k: data[k] for k in data.files}
meta = json.loads(str(out.pop("meta")))
n = len(out["rho"])
if any(len(v) != n for v in out.values()) or sum(meta["leaf_counts"]) != n:
raise ValueError("inconsistent snapshot arrays")
return meta, out
def snapshot_meta(step, viscosity, explosion, source_revision):
"""Exact time/phase/config identity stored inside the snapshot."""
return dict(step=step, tstar=step * U / ROOT_N, phase=sw.PHI, mode=list(sw.MODE),
polarization=sw.E.tolist(), amplitude=U, re_L=sw.RE, n=ROOT_N, depth=DEPTH,
explosion=explosion, viscosity=viscosity, tau_by_level=TAU,
refinements=REFINEMENTS, source_revision=source_revision,
origin="level-wide zero-origin grids", time="root synchronization, postcollision")
@@ -0,0 +1,123 @@
"""Signed interface-probe traces for the nested/twin shear presets (mechanism diagnostic).
No pass gates. Native-validated 24-target layout through box 1, in root-128
physical coordinates, crossing L0->L1 and (nested only) L1->L2 away from corners:
horizontal line y = 56 across the vertical faces x = 16 and x = 22;
vertical line x = 38 across the horizontal faces y = 16 and y = 22;
normal coordinates NORMAL_COORDS on both (nested: 3 L0 + 5 L1 + 4 L2 each).
Each target maps to the nearest ACTIVE leaf center (tie rule: distance, then
finer level, then smaller j, then smaller i). Grids differ between cases
(U128, U512, nested, twin), so actual centers, levels and displacements are
stored and analytic fields are evaluated at the actual centers.
Samples are POST-collision G at root synchronization only (root-step units);
no substep content is observed, and grid-scale alternation can alias.
"""
import math
import numpy as np
import shear_wave as sw
from oracle import CX, CY, U
ROOT_N = 128
NORMAL_COORDS = (12.5, 14.5, 15.5, 16.25, 17.25, 19.25, 20.75, 21.75,
22.125, 23.125, 24.125, 26.125)
TRANSECTS = {"horizontal_y56": dict(axis=0, other=56.0), # x varies, y fixed
"vertical_x38": dict(axis=1, other=38.0)} # y varies, x fixed
STEPS = tuple(range(0, 129)) + tuple(range(1920, 2049)) # root steps, both inclusive
TRACE_MAX_BYTES = 600_000
def points():
out = []
for name, t in TRANSECTS.items():
for along in NORMAL_COORDS:
xy = (along, t["other"]) if t["axis"] == 0 else (t["other"], along)
out.append((name, along, xy))
return out
def case_steps(n):
"""Case lattice steps at the fixed root-physical sample times (U512: 4 per root step)."""
return [s * (n // ROOT_N) for s in STEPS]
def select(masks, n=ROOT_N):
"""Nearest ACTIVE leaf center for each target (deterministic tie rule).
Targets and stored centers are in root-physical units (root cell = 1); a case
with root N = n has cell size h = ROOT_N / (n * 2**level) there (U512: 0.25).
"""
if n % ROOT_N:
raise ValueError("case root N must be a multiple of 128")
probes = []
for name, along, (x, y) in points():
best = None
for level, mask in enumerate(masks):
h = ROOT_N / (n * 2 ** level)
i0, j0 = int(math.floor(x / h)), int(math.floor(y / h))
for j in range(j0 - 2, j0 + 3):
for i in range(i0 - 2, i0 + 3):
if 0 <= j < mask.shape[0] and 0 <= i < mask.shape[1] and mask[j, i]:
cx, cy = h * (i + 0.5), h * (j + 0.5)
key = (math.hypot(cx - x, cy - y), -level, j, i)
if best is None or key < best[0]:
best = (key, level, i, j, cx, cy)
if best is None:
raise ValueError(f"no ACTIVE leaf near target {(x, y)}")
_, level, i, j, cx, cy = best
probes.append(dict(transect=name, normal=along, point=[x, y], level=level, i=i, j=j,
center=[cx, cy], displacement=[cx - x, cy - y]))
if len({(p["level"], p["i"], p["j"]) for p in probes}) != len(probes):
raise ValueError("probe targets map to duplicate cells")
return probes
def sample(arrays, probes):
"""Flat [rho, ux, uy] per probe from FP64 physical populations."""
row = []
for p in probes:
f = np.asarray(arrays[p["level"]][:, p["j"], p["i"]], dtype=float)
rho = float(f.sum())
row += [rho, float(CX @ f) / rho, float(CY @ f) / rho]
return row
def new_trace(probes, case_viscosity, case):
"""Times/coordinates are root-physical (N=128); nu_root = U*128/Re for all cases."""
return dict(schema=1, kind="mechanism diagnostic, no pass gates", case=case,
time_unit="root step (N=128)", sample_phase="postcollision G at root synchronization",
root_n=ROOT_N, viscosity_root=U * ROOT_N / sw.RE, case_viscosity=case_viscosity,
mode=list(sw.MODE), phase=sw.PHI,
amplitude=U, fields=["rho", "ux", "uy"], probes=probes, steps=[], values=[])
def residuals(trace):
"""Signed (drho, dux, duy) per step and probe, analytic field at each actual center."""
out = []
for step, row in zip(trace["steps"], trace["values"]):
res = []
for n, p in enumerate(trace["probes"]):
x, y = p["center"]
ux, uy, _ = sw.exact(x, y, step, trace["root_n"], trace["viscosity_root"])
rho, vx, vy = row[3 * n: 3 * n + 3]
res.append((rho - 1.0, vx - float(ux), vy - float(uy)))
out.append(res)
return out
def validate(trace):
"""Exact schedule, finite values, fixed probe count and byte cap."""
import json
if trace.get("steps") != list(STEPS) or len(trace["values"]) != len(STEPS):
raise ValueError("trace steps differ from the fixed schedule")
if len(trace["probes"]) != len(NORMAL_COORDS) * len(TRANSECTS):
raise ValueError("unexpected probe count")
width = 3 * len(trace["probes"])
if any(len(r) != width or not all(math.isfinite(v) for v in r) for r in trace["values"]):
raise ValueError("malformed or nonfinite trace row")
size = len(json.dumps(trace, allow_nan=False).encode())
if size > TRACE_MAX_BYTES:
raise ValueError(f"trace exceeds {TRACE_MAX_BYTES} bytes ({size})")
return size
@@ -0,0 +1,36 @@
"""Depth-2 twin of the nested shear preset (opt-in twin_shear_n128).
Same two L0->L1 boxes as shear_nested, no L2. Four fresh cases: U128, U256
(finest control = 2N), constant R128 depth 2, projected R128 depth 2; same
wave, phase, Re100/U=0.03, initialization, times, eps(root N), limits, floors.
Twin vs nested measures the effect of adding this nested L2 refinement.
Removing L2 also changes the finest spacing and refined volume, so the
contrast does not isolate abstract depth. Physics is the unchanged depth-2,
2N-control shear_wave.assess; shear_nested.py stays byte-identical.
"""
import numpy as np
import shear_nested as nested
ROOT_N = nested.ROOT_N
DEPTH = 2
FINEST_FACTOR = 2
REFINEMENTS = [nested.REFINEMENTS[0]] # L0 -> L1 only, root coordinates
CASES = ((100, ROOT_N, 1, "constant"), (100, FINEST_FACTOR * ROOT_N, 1, "constant"),
(100, ROOT_N, DEPTH, "constant"), (100, ROOT_N, DEPTH, "projected_linear"))
ROOT_STEPS = 16 * ROOT_N
LEAVES = [7936, 33792]
HOPS = [ROOT_STEPS * 2**level for level in range(DEPTH)] # [2048, 4096]
WORK = sum(c * h for c, h in zip(LEAVES, HOPS)) # 154664960 per refined case
NU = nested.NU[:DEPTH]
TAU = nested.TAU[:DEPTH]
def leaf_masks():
"""Independent numpy leaf masks (root complement, full L1 boxes)."""
child = np.zeros((ROOT_N, ROOT_N), bool)
for x0, y0, x1, y1 in REFINEMENTS[0]:
child[y0:y1, x0:x1] = True
return [~child, np.kron(child, np.ones((2, 2), bool))]
@@ -427,6 +427,19 @@ class ContractTests(unittest.TestCase):
self.assertTrue(result["contract_valid"], [k for k, v in result["checks"].items() if not v])
self.assertEqual(result["status"], "PASS")
def test_eps_metadata_is_portable_but_bounded(self):
import assess_shear_wave
self.assertTrue(assess_shear_wave.close_ulps(0.012047856934923534, 0.012047856934923532))
exact = sw.eps(128)
for value, ok in ((math.nextafter(exact, 1.0), True),
(math.nextafter(math.nextafter(exact, 0.0), 0.0), True),
(exact * (1 + 1e-12), False), (exact * 2, False),
(str(exact), False), (float("nan"), False), (None, False)):
records = [dict(r) for r in self.records]
records[2]["eps"] = value
status = self.assess(records, "r")["status"]
self.assertEqual(status == "PASS", ok, (value, status))
def test_reproduced_false_passes_are_rejected(self):
a = self.assess
self.assertEqual(a(self.records[:2], "r")["status"], "INVALID_SET") # empty refined
@@ -558,3 +571,554 @@ class DefaultPathTests(unittest.TestCase):
if __name__ == "__main__":
unittest.main()
class NestedPresetTests(unittest.TestCase):
"""Fixed three-level/two-region shear preset (nested_shear_n128)."""
def setUp(self):
import assess_shear_wave
import shear_nested
self.mod, self.nested = assess_shear_wave, shear_nested
def test_exact_geometry_work_and_levels(self):
nested = self.nested
masks = nested.leaf_masks()
self.assertEqual([int(m.sum()) for m in masks], [7936, 12288, 86016])
self.assertEqual(nested.LEAVES, [7936, 12288, 86016])
self.assertEqual(nested.HOPS, [2048, 4096, 8192])
self.assertEqual(nested.WORK, 771227648)
uniform = 128 * 128 * 2048 + 512 * 512 * 8192
self.assertEqual(uniform + 2 * nested.WORK, 3723493376)
np.testing.assert_allclose(nested.NU, [.0384, .0768, .1536], rtol=0, atol=1e-15)
np.testing.assert_allclose(nested.TAU, [.6152, .7304, .9608], rtol=0, atol=1e-14)
self.assertEqual(sum(float(m.sum()) * 0.25**l for l, m in enumerate(masks)), 128.0**2)
# Production host hierarchy builds the same leaves from the same rectangles.
from CelerisLab.lbm.hierarchy import build_hierarchy, leaf_partition
from CelerisLab.lbm.refinement import ACTIVE
h = build_hierarchy(run_case.config(128, 100), nested.REFINEMENTS)
np.testing.assert_array_equal(leaf_partition(h), np.ones((128, 128)))
for mine, kinds in zip(masks, h.kinds):
np.testing.assert_array_equal(mine, kinds == ACTIVE)
def test_historical_shear_identity_is_preserved(self):
digest = hashlib.sha256((HERE / "shear_wave.py").read_bytes()).hexdigest()
self.assertEqual(digest, "81d5c8ee60864372887cddf9239580c82fb6750d956038f1e3ee9de61aa4e877")
self.assertEqual(run_case.SHEAR_WAVE_SHA256, digest)
nested_digest = hashlib.sha256((HERE / "shear_nested.py").read_bytes()).hexdigest()
self.assertEqual(run_case.SHEAR_NESTED_SHA256, nested_digest)
def nested_set(self):
out = []
for n, depth, scheme in ((128, 1, "constant"), (512, 1, "constant"),
(128, 3, "constant"), (128, 3, "projected_linear")):
r = receipt(n, depth, scheme, diagnostic=run_case.NESTED_SHEAR)
r["source"]["shear_nested_sha256"] = run_case.SHEAR_NESTED_SHA256
if depth == 3:
cells, hops = self.nested.LEAVES, self.nested.HOPS
r["refinements"] = [list(level) for level in self.nested.REFINEMENTS]
r["workload"] = dict(active_cells_by_level=cells, level_hops=hops,
root_intervals=2048,
active_collision_updates_by_level=[c * h for c, h in zip(cells, hops)],
active_collision_updates=self.nested.WORK)
out.append(r)
return out
def test_nested_contract_and_rejections(self):
a = self.mod.assess_nested
good = self.nested_set()
result = a(good, "r")
self.assertTrue(result["contract_valid"], [k for k, v in result["checks"].items() if not v])
self.assertEqual(result["status"], "PASS")
self.assertIn("finest", result["physics"]["refined"]["constant"]["control_ratios"])
wrong_finest = self.nested_set()
wrong_finest[1] = receipt(256, 1, diagnostic=run_case.NESTED_SHEAR)
wrong_finest[1]["source"]["shear_nested_sha256"] = run_case.SHEAR_NESTED_SHA256
self.assertEqual(a(wrong_finest, "r")["status"], "INVALID_SET")
for mutate in (
lambda s: s[2].update(refinements=[s[2]["refinements"][1], s[2]["refinements"][0]]),
lambda s: s[3].update(refinements=rectangles(128, 3)),
lambda s: s[2]["rows"][2].update(spurious_pressure_scaled_by_level=[0.0, 0.0]),
lambda s: s[0].update(diagnostic=run_case.SCALED_SHEAR),
lambda s: s[2]["source"].pop("shear_nested_sha256"),
lambda s: s[2].update(final_snapshot=dict(kept=True, sha256="a" * 64, bytes=10,
leaf_counts=self.nested.LEAVES, step=2048)),
lambda s: s[3].update(final_snapshot=dict(kept=True, sha256="a" * 64,
bytes=self.nested.SNAPSHOT_MAX_BYTES + 1,
leaf_counts=self.nested.LEAVES, step=2048)),
):
records = self.nested_set()
mutate(records)
self.assertNotEqual(a(records, "r")["status"], "PASS")
ok = self.nested_set()
ok[3]["final_snapshot"] = dict(kept=True, sha256="a" * 64, bytes=1000,
leaf_counts=self.nested.LEAVES, step=2048)
self.assertEqual(a(ok, "r")["status"], "PASS")
with self.assertRaises(ValueError):
self.nested.assess(good[0], good[1], [good[2], dict(good[2])])
def test_nested_runner_options(self):
repo = Path(__file__).resolve().parents[3]
with tempfile.TemporaryDirectory() as tmp:
base = ["run_case.py", "--repo", str(repo), "--expected-revision", "f" * 40,
"--output", str(Path(tmp) / "case.json"), "--dry-run", "--re", "100"]
nest = ["--flow", "shear_wave", "--diagnostic", run_case.NESTED_SHEAR]
proj = ["--explosion", "projected_linear"]
for extra, valid in (
(["--n", "128", "--depth", "1"] + nest, True),
(["--n", "512", "--depth", "1"] + nest, True),
(["--n", "128", "--depth", "3"] + nest, True),
(["--n", "128", "--depth", "3"] + proj + nest + ["--final-snapshot"], True),
(["--n", "256", "--depth", "1"] + nest, False), # finest control is 4N
(["--n", "128", "--depth", "2"] + nest, False),
(["--n", "128", "--depth", "3", "--flow", "shear_wave"], False),
(["--n", "128", "--depth", "3", "--diagnostic", run_case.NESTED_SHEAR], False),
(["--n", "128", "--depth", "3"] + nest + ["--final-snapshot"], False),
(["--n", "128", "--depth", "3"] + proj + ["--flow", "shear_wave"], False),
(["--n", "128", "--depth", "2", "--flow", "shear_wave", "--final-snapshot"], False)):
argv = base + extra
with self.subTest(argv=argv), patch.object(sys, "argv", argv), \
patch.object(run_case, "verify_source", return_value={}) as verify, \
patch.object(run_case, "runtime_source", return_value={}), \
redirect_stdout(io.StringIO()), patch("sys.stderr", io.StringIO()):
if valid:
self.assertEqual(run_case.main(), 0)
self.assertEqual(verify.call_args.args[2], "shear_nested")
else:
with self.assertRaises(SystemExit):
run_case.main()
def test_mocked_nested_execution_with_bounded_snapshot(self):
from types import SimpleNamespace
from contextlib import nullcontext
from CelerisLab.lbm.hierarchy import build_hierarchy
h = build_hierarchy(run_case.config(128, 100), self.nested.REFINEMENTS)
nu = U * 128 / sw.RE
arrays = [sw.initial(k.shape, level, 128, nu) for level, k in enumerate(h.kinds)]
class FakeRun:
def __init__(self, *args, **kwargs):
self.step_count = 0
self.kwargs = kwargs
def __enter__(self):
return self
def __exit__(self, *args):
pass
def initialize(self, *given):
assert len(given) == 3
def step(self, count):
assert count >= 0
self.step_count += count
def download(self):
return arrays
modules = {"CelerisLab.cuda.context": SimpleNamespace(CudaContext=FakeRun),
"CelerisLab.lbm.block_stepper": SimpleNamespace(PeriodicBlockStepper=FakeRun),
"CelerisLab.lbm.refinement_stepper": SimpleNamespace(FixedPatchStepper=FakeRun)}
repo = Path(__file__).resolve().parents[3]
with tempfile.TemporaryDirectory() as tmp:
output = Path(tmp) / "projected_nested.json"
argv = ["run_case.py", "--repo", str(repo), "--re", "100", "--n", "128", "--depth", "3",
"--explosion", "projected_linear", "--flow", "shear_wave",
"--diagnostic", run_case.NESTED_SHEAR, "--final-snapshot",
"--output", str(output), "--expected-revision", "f" * 40, "--run-gpu"]
with patch.dict(sys.modules, modules), patch.object(sys, "argv", argv), \
patch.dict("os.environ", CUDA_VISIBLE_DEVICES="mock"), \
patch.object(run_case, "verify_source", return_value=dict(revision="f" * 40)), \
patch.object(run_case, "runtime_source", return_value={}), \
patch.object(run_case, "runtime_identity", return_value={}), \
patch.object(run_case, "build_capture", return_value=nullcontext()), \
redirect_stdout(io.StringIO()):
run_case.main()
rec = json.loads(output.read_text())
self.assertTrue(rec["completed"])
self.assertEqual(rec["diagnostic"], run_case.NESTED_SHEAR)
self.assertEqual(rec["workload"]["active_cells_by_level"], self.nested.LEAVES)
self.assertEqual(rec["workload"]["active_collision_updates"], self.nested.WORK)
self.assertEqual(rec["tau_by_level"], self.nested.TAU)
self.assertTrue(all(len(r["spurious_pressure_scaled_by_level"]) == 3 for r in rec["rows"]))
snap = rec["final_snapshot"]
path = output.with_name(output.stem + ".final_macro.npz")
self.assertTrue(snap["kept"])
self.assertEqual(snap["sha256"], hashlib.sha256(path.read_bytes()).hexdigest())
self.assertLessEqual(snap["bytes"], self.nested.SNAPSHOT_MAX_BYTES)
meta, fields = self.nested.read_snapshot(path)
self.assertEqual((meta["step"], meta["phase"]), (2048, sw.PHI))
self.assertEqual(meta["tstar"], 2048 * U / 128)
self.assertEqual(meta["leaf_counts"], self.nested.LEAVES)
self.assertEqual(sorted(fields), ["i", "j", "level", "rho", "ux", "uy"])
np.testing.assert_allclose(fields["rho"], 1.0, atol=1e-12)
def test_snapshot_contents_and_cap(self):
nested = self.nested
masks = nested.leaf_masks()
arrays = [sw.initial(m.shape, level, 128, 0.0384) for level, m in enumerate(masks)]
meta = nested.snapshot_meta(2048, 0.0384, "projected_linear", "r")
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "s.npz"
block = nested.write_snapshot(path, arrays, masks, meta)
self.assertTrue(block["kept"])
got, fields = nested.read_snapshot(path)
self.assertEqual(got["refinements"], [[list(r) for r in level] for level in nested.REFINEMENTS])
self.assertEqual(int(fields["level"].max()), 2)
with self.assertRaises(FileExistsError):
nested.write_snapshot(path, arrays, masks, meta)
bad = Path(tmp) / "bad.npz"
np.savez_compressed(bad, populations=np.zeros(3), **{k: np.zeros(1) for k in ("level", "i", "j", "rho", "ux", "uy")}, meta=np.array("{}"))
with self.assertRaises(ValueError):
nested.read_snapshot(bad)
with patch.object(nested, "SNAPSHOT_MAX_BYTES", 10):
capped = nested.write_snapshot(Path(tmp) / "c.npz", arrays, masks, meta)
self.assertFalse(capped["kept"])
self.assertFalse((Path(tmp) / "c.npz").exists())
class TwinPresetTests(unittest.TestCase):
"""Depth-2 twin (twin_shear_n128): nested L0->L1 boxes, no L2, fresh U128/U256."""
def setUp(self):
import assess_shear_wave
import shear_nested
import shear_twin
self.mod, self.nested, self.twin = assess_shear_wave, shear_nested, shear_twin
def test_exact_geometry_work_and_nested_identity(self):
twin = self.twin
masks = twin.leaf_masks()
self.assertEqual([int(m.sum()) for m in masks], [7936, 33792])
self.assertEqual((twin.LEAVES, twin.HOPS, twin.WORK), ([7936, 33792], [2048, 4096], 154664960))
self.assertEqual(128 * 128 * 2048 + 256 * 256 * 4096 + 2 * twin.WORK, 611319808)
self.assertEqual(twin.REFINEMENTS, [self.nested.REFINEMENTS[0]])
np.testing.assert_array_equal(masks[0], self.nested.leaf_masks()[0]) # same root leaves
from CelerisLab.lbm.hierarchy import build_hierarchy, leaf_partition
from CelerisLab.lbm.refinement import ACTIVE
h = build_hierarchy(run_case.config(128, 100), twin.REFINEMENTS)
np.testing.assert_array_equal(leaf_partition(h), np.ones((128, 128)))
for mine, kinds in zip(masks, h.kinds):
np.testing.assert_array_equal(mine, kinds == ACTIVE)
# Historical nested identity is unchanged; the twin is pinned separately.
self.assertEqual(hashlib.sha256((HERE / "shear_nested.py").read_bytes()).hexdigest(),
"fa6cfe87fb4df8c6d732c637c885276833c81973b950c7724d734f8fc350bcb0")
self.assertEqual(run_case.SHEAR_TWIN_SHA256,
hashlib.sha256((HERE / "shear_twin.py").read_bytes()).hexdigest())
def twin_set(self):
out = []
for n, depth, scheme in ((128, 1, "constant"), (256, 1, "constant"),
(128, 2, "constant"), (128, 2, "projected_linear")):
r = receipt(n, depth, scheme, diagnostic=run_case.TWIN_SHEAR)
r["source"].update(shear_nested_sha256=run_case.SHEAR_NESTED_SHA256,
shear_twin_sha256=run_case.SHEAR_TWIN_SHA256)
if depth == 2:
cells, hops = self.twin.LEAVES, self.twin.HOPS
r["refinements"] = [list(level) for level in self.twin.REFINEMENTS]
r["workload"] = dict(active_cells_by_level=cells, level_hops=hops, root_intervals=2048,
active_collision_updates_by_level=[c * h for c, h in zip(cells, hops)],
active_collision_updates=self.twin.WORK)
out.append(r)
return out
def test_twin_contract_and_rejections(self):
a = lambda records: self.mod.assess_nested(records, "r", run_case.TWIN_SHEAR)
result = a(self.twin_set())
self.assertTrue(result["contract_valid"], [k for k, v in result["checks"].items() if not v])
self.assertEqual(result["status"], "PASS")
self.assertIn("does not isolate abstract depth", result["scope"])
self.assertEqual(result["finest_control"], "uniform 2N (U256)")
for mutate in (
lambda s: s.__setitem__(1, receipt(512, 1, diagnostic=run_case.TWIN_SHEAR)), # 4N control
lambda s: s[2].update(refinements=[list(level) for level in self.nested.REFINEMENTS]),
lambda s: s[3].update(refinements=rectangles(128, 2)), # old single box
lambda s: s[2]["rows"][1].update(spurious_pressure_scaled_by_level=[0.0, 0.0, 0.0]),
lambda s: s[0].update(diagnostic=run_case.NESTED_SHEAR),
lambda s: s[2]["source"].pop("shear_twin_sha256"),
lambda s: s[3].update(final_snapshot=dict(kept=True, sha256="a" * 64, bytes=10,
leaf_counts=self.twin.LEAVES, step=2048)),
):
records = self.twin_set()
mutate(records)
self.assertNotEqual(a(records)["status"], "PASS")
# Twin and nested sets never validate as each other.
self.assertEqual(self.mod.assess_nested(self.twin_set(), "r")["status"], "INVALID_SET")
def test_twin_runner_options(self):
repo = Path(__file__).resolve().parents[3]
with tempfile.TemporaryDirectory() as tmp:
base = ["run_case.py", "--repo", str(repo), "--expected-revision", "f" * 40,
"--output", str(Path(tmp) / "case.json"), "--dry-run", "--re", "100"]
tw = ["--flow", "shear_wave", "--diagnostic", run_case.TWIN_SHEAR]
proj = ["--explosion", "projected_linear"]
for extra, valid in (
(["--n", "128", "--depth", "1"] + tw, True),
(["--n", "256", "--depth", "1"] + tw, True),
(["--n", "128", "--depth", "2"] + tw, True),
(["--n", "128", "--depth", "2"] + proj + tw, True),
(["--n", "512", "--depth", "1"] + tw, False),
(["--n", "128", "--depth", "3"] + tw, False),
(["--n", "128", "--depth", "2"] + proj + tw + ["--final-snapshot"], False),
(["--n", "128", "--depth", "2", "--diagnostic", run_case.TWIN_SHEAR], False)):
argv = base + extra
with self.subTest(argv=argv), patch.object(sys, "argv", argv), \
patch.object(run_case, "verify_source", return_value={}) as verify, \
patch.object(run_case, "runtime_source", return_value={}), \
redirect_stdout(io.StringIO()), patch("sys.stderr", io.StringIO()):
if valid:
self.assertEqual(run_case.main(), 0)
self.assertEqual(verify.call_args.args[2], "shear_twin")
else:
with self.assertRaises(SystemExit):
run_case.main()
def test_mocked_twin_execution(self):
from types import SimpleNamespace
from contextlib import nullcontext
from CelerisLab.lbm.hierarchy import build_hierarchy
h = build_hierarchy(run_case.config(128, 100), self.twin.REFINEMENTS)
arrays = [sw.initial(k.shape, level, 128, U * 128 / sw.RE) for level, k in enumerate(h.kinds)]
selectors = []
class FakeRun:
def __init__(self, *args, **kwargs):
self.step_count = 0
if "refinements" in kwargs:
selectors.append((kwargs["explosion"], kwargs["refinements"]))
def __enter__(self):
return self
def __exit__(self, *args):
pass
def initialize(self, *given):
assert len(given) == 2
def step(self, count):
self.step_count += count
def download(self):
return arrays
modules = {"CelerisLab.cuda.context": SimpleNamespace(CudaContext=FakeRun),
"CelerisLab.lbm.block_stepper": SimpleNamespace(PeriodicBlockStepper=FakeRun),
"CelerisLab.lbm.refinement_stepper": SimpleNamespace(FixedPatchStepper=FakeRun)}
repo = Path(__file__).resolve().parents[3]
with tempfile.TemporaryDirectory() as tmp:
output = Path(tmp) / "projected_twin.json"
argv = ["run_case.py", "--repo", str(repo), "--re", "100", "--n", "128", "--depth", "2",
"--explosion", "projected_linear", "--flow", "shear_wave",
"--diagnostic", run_case.TWIN_SHEAR, "--output", str(output),
"--expected-revision", "f" * 40, "--run-gpu"]
with patch.dict(sys.modules, modules), patch.object(sys, "argv", argv), \
patch.dict("os.environ", CUDA_VISIBLE_DEVICES="mock"), \
patch.object(run_case, "verify_source", return_value=dict(revision="f" * 40)), \
patch.object(run_case, "runtime_source", return_value={}), \
patch.object(run_case, "runtime_identity", return_value={}), \
patch.object(run_case, "build_capture", return_value=nullcontext()), \
redirect_stdout(io.StringIO()):
run_case.main()
rec = json.loads(output.read_text())
self.assertTrue(rec["completed"])
self.assertEqual(rec["diagnostic"], run_case.TWIN_SHEAR)
self.assertEqual(rec["workload"]["active_cells_by_level"], self.twin.LEAVES)
self.assertEqual(rec["workload"]["active_collision_updates"], self.twin.WORK)
self.assertNotIn("final_snapshot", rec)
self.assertTrue(all(len(r["spurious_pressure_scaled_by_level"]) == 2 for r in rec["rows"]))
self.assertEqual(selectors, [("projected_linear", [list(self.twin.REFINEMENTS[0])])])
self.assertEqual(sorted(p.name for p in Path(tmp).iterdir()), ["projected_twin.json"])
class ProbeTraceTests(unittest.TestCase):
"""Signed interface-probe mechanism diagnostic (--probe-trace); no pass gates."""
def setUp(self):
import shear_nested
import shear_probes
import shear_twin
self.nested, self.probes, self.twin = shear_nested, shear_probes, shear_twin
def exact_arrays(self, masks, n, t):
"""Equilibrium of the exact wave at root-physical time t on a case grid of root N=n."""
out = []
for level, m in enumerate(masks):
x, y = centers(m.shape, level)
x, y = x * 128 / n, y * 128 / n
ux, uy, _ = sw.exact(x, y, t, 128, U * 128 / sw.RE)
out.append(sw.equilibrium(np.ones_like(ux), ux, uy))
return out
def test_frozen_history_identities(self):
for name, digest in (("shear_wave.py", "81d5c8ee60864372887cddf9239580c82fb6750d956038f1e3ee9de61aa4e877"),
("shear_nested.py", "fa6cfe87fb4df8c6d732c637c885276833c81973b950c7724d734f8fc350bcb0"),
("shear_twin.py", "1cbf37f18e89aea577581631c4565f51e68d22a3739b698816ef64acbf2b2bb4"),
("oracle.py", ORACLE_SHA256_EEC4677)):
self.assertEqual(hashlib.sha256((HERE / name).read_bytes()).hexdigest(), digest, name)
self.assertEqual(run_case.SHEAR_PROBES_SHA256,
hashlib.sha256((HERE / "shear_probes.py").read_bytes()).hexdigest())
def test_probe_selection_per_case(self):
sp = self.probes
self.assertEqual(len(sp.points()), 24)
corners = [(x, y) for level in (self.nested.REFINEMENTS[0],
[tuple(v / 2 for v in r) for r in self.nested.REFINEMENTS[1]])
for x0, y0, x1, y1 in level for x in (x0, x1) for y in (y0, y1)]
for _, _, (x, y) in sp.points():
self.assertGreaterEqual(min(math.hypot(x - cx, y - cy) for cx, cy in corners), 8.0)
pattern = [0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2]
nested = sp.select(self.nested.leaf_masks())
self.assertEqual([p["level"] for p in nested], pattern * 2)
twin = sp.select(self.twin.leaf_masks())
self.assertEqual([p["level"] for p in twin], [min(v, 1) for v in pattern] * 2)
u128 = sp.select([np.ones((128, 128), bool)], 128)
u512 = sp.select([np.ones((512, 512), bool)], 512)
self.assertTrue(all(p["level"] == 0 for p in u128 + u512))
for case in (nested, twin, u128, u512):
self.assertEqual(len({(p["level"], p["i"], p["j"]) for p in case}), 24) # unique
for p in case:
dx, dy = p["displacement"]
self.assertEqual([p["center"][0] - p["point"][0], p["center"][1] - p["point"][1]],
[dx, dy])
self.assertEqual(max(math.hypot(*p["displacement"]) for p in u128), 0.625)
self.assertLessEqual(max(math.hypot(*p["displacement"]) for p in u512), 0.25 * 0.7072)
# Nested: 3 L0 + 5 L1 + 4 L2 per transect, as checked by native review.
for name in sp.TRANSECTS:
levels = [p["level"] for p in nested if p["transect"] == name]
self.assertEqual([levels.count(v) for v in (0, 1, 2)], [3, 5, 4])
# Different grids give different centers: no pretended collocation.
self.assertNotEqual(u128[3]["center"], u512[3]["center"])
self.assertEqual(sp.case_steps(512)[:3], [0, 4, 8])
self.assertEqual(sp.case_steps(128), list(sp.STEPS))
def test_residuals_vanish_for_the_exact_field(self):
sp = self.probes
for masks, n in ((self.nested.leaf_masks(), 128), ([np.ones((512, 512), bool)], 512)):
probes = sp.select(masks, n)
trace = sp.new_trace(probes, U * n / sw.RE, ["x", n, len(masks), "c"])
for t in (0, 100, 2048):
trace["steps"].append(t)
trace["values"].append(sp.sample(self.exact_arrays(masks, n, t), probes))
for res in sp.residuals(trace):
self.assertLess(max(abs(v) for r in res for v in r), 1e-14)
def test_validate_schedule_values_and_cap(self):
sp = self.probes
probes = sp.select(self.nested.leaf_masks())
trace = sp.new_trace(probes, 0.0384, ["n", 128, 3, "projected_linear"])
trace["steps"] = list(sp.STEPS)
trace["values"] = [[1.0, 0.01, -0.02] * 24 for _ in sp.STEPS]
size = sp.validate(trace)
self.assertLess(size, sp.TRACE_MAX_BYTES)
realistic = dict(trace, values=[[1.0000012345678901, 0.012345678901234567,
-0.023456789012345678] * 24 for _ in sp.STEPS])
self.assertLess(sp.validate(realistic), sp.TRACE_MAX_BYTES)
for bad in (dict(trace, steps=trace["steps"][:-1]),
dict(trace, values=trace["values"][:-1] + [[float("nan")] * 72]),
dict(trace, probes=trace["probes"][:-1])):
with self.assertRaises(ValueError):
sp.validate(bad)
with patch.object(sp, "TRACE_MAX_BYTES", 1000):
with self.assertRaises(ValueError):
sp.validate(trace)
def test_probe_runner_options(self):
repo = Path(__file__).resolve().parents[3]
with tempfile.TemporaryDirectory() as tmp:
base = ["run_case.py", "--repo", str(repo), "--expected-revision", "f" * 40,
"--output", str(Path(tmp) / "case.json"), "--dry-run", "--re", "100",
"--flow", "shear_wave", "--probe-trace"]
nest = ["--diagnostic", run_case.NESTED_SHEAR]
tw = ["--diagnostic", run_case.TWIN_SHEAR]
proj = ["--explosion", "projected_linear"]
for extra, valid in (
(["--n", "128", "--depth", "1"] + nest, True),
(["--n", "512", "--depth", "1"] + nest, True),
(["--n", "128", "--depth", "3"] + proj + nest, True),
(["--n", "128", "--depth", "2"] + proj + tw, True),
(["--n", "128", "--depth", "3"] + nest, False), # constant d3
(["--n", "128", "--depth", "1"] + tw, False),
(["--n", "128", "--depth", "3"] + proj + nest + ["--final-snapshot"], False),
(["--n", "128", "--depth", "2"], False)):
argv = base + extra
with self.subTest(argv=argv), patch.object(sys, "argv", argv), \
patch.object(run_case, "verify_source", return_value={}) as verify, \
patch.object(run_case, "runtime_source", return_value={}), \
redirect_stdout(io.StringIO()), patch("sys.stderr", io.StringIO()):
if valid:
self.assertEqual(run_case.main(), 0)
self.assertIs(verify.call_args.kwargs["probes"], True)
else:
with self.assertRaises(SystemExit):
run_case.main()
def run_mocked(self, n, depth, diagnostic, scheme, masks):
from types import SimpleNamespace
from contextlib import nullcontext
arrays = self.exact_arrays(masks, n, 0.0)
counts = []
class FakeRun:
def __init__(self, *args, **kwargs):
self.step_count = 0
def __enter__(self):
return self
def __exit__(self, *args):
pass
def initialize(self, *given):
pass
def step(self, count):
self.step_count += count
counts.append(self.step_count)
def download(self):
return arrays[0] if depth == 1 else arrays
modules = {"CelerisLab.cuda.context": SimpleNamespace(CudaContext=FakeRun),
"CelerisLab.lbm.block_stepper": SimpleNamespace(PeriodicBlockStepper=FakeRun),
"CelerisLab.lbm.refinement_stepper": SimpleNamespace(FixedPatchStepper=FakeRun)}
repo = Path(__file__).resolve().parents[3]
with tempfile.TemporaryDirectory() as tmp:
output = Path(tmp) / "probe.json"
argv = ["run_case.py", "--repo", str(repo), "--re", "100", "--n", str(n),
"--depth", str(depth), "--explosion", scheme, "--flow", "shear_wave",
"--diagnostic", diagnostic, "--probe-trace", "--output", str(output),
"--expected-revision", "f" * 40, "--run-gpu"]
with patch.dict(sys.modules, modules), patch.object(sys, "argv", argv), \
patch.dict("os.environ", CUDA_VISIBLE_DEVICES="mock"), \
patch.object(run_case, "verify_source", return_value=dict(revision="f" * 40)), \
patch.object(run_case, "runtime_source", return_value={}), \
patch.object(run_case, "runtime_identity", return_value={}), \
patch.object(run_case, "build_capture", return_value=nullcontext()), \
redirect_stdout(io.StringIO()):
run_case.main()
return json.loads(output.read_text()), counts, sorted(p.name for p in Path(tmp).iterdir())
def test_mocked_probe_traces(self):
sp = self.probes
rec, counts, files = self.run_mocked(128, 3, run_case.NESTED_SHEAR, "projected_linear",
self.nested.leaf_masks())
trace = rec["probe_trace"]
self.assertEqual(trace["steps"], list(sp.STEPS))
self.assertEqual(len(trace["values"]), len(sp.STEPS))
self.assertLessEqual(trace["bytes"], sp.TRACE_MAX_BYTES)
self.assertEqual(trace["case"], [run_case.NESTED_SHEAR, 128, 3, "projected_linear"])
self.assertEqual(len(rec["rows"]), 5) # qualification samples preserved
self.assertEqual(files, ["probe.json"]) # no field dumps
self.assertEqual(sp.validate(trace) <= sp.TRACE_MAX_BYTES, True)
rec512, counts512, _ = self.run_mocked(512, 1, run_case.NESTED_SHEAR, "constant",
[np.ones((512, 512), bool)])
t512 = rec512["probe_trace"]
self.assertEqual(t512["steps"], list(sp.STEPS)) # root-physical times
self.assertEqual(t512["viscosity_root"], U * 128 / sw.RE)
self.assertEqual(t512["case_viscosity"], U * 512 / sw.RE)
self.assertIn(4 * 1920, counts512) # U512 advanced to 4x lattice steps
self.assertTrue(all(p["level"] == 0 for p in t512["probes"]))
res = sp.residuals(t512)
self.assertLess(abs(res[0][0][1]), 1e-14) # exact field at t=0 at actual centers