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>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
1e188e7419
commit
caa573f978
@@ -25,7 +25,7 @@ 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 = "98ea8090ace48f04b83dfb015db10e681e414e57eb748b34c0fbb90fb790d13b" # signed interface-probe mechanism diagnostic
|
||||
SHEAR_PROBES_SHA256 = "53ba8af8ac9c8078c40f84488c7ade4c11ccc91dd1fc275ff806042e9af30166" # signed interface-probe mechanism diagnostic
|
||||
|
||||
|
||||
def flow_functions(flow="taylor_green"):
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
"""Signed interface-probe traces for the nested/twin shear presets (mechanism diagnostic).
|
||||
|
||||
No pass gates. 24 fixed physical points on two interface-normal transects, away
|
||||
from corners, crossing L0->L1 and (nested only) L1->L2:
|
||||
V: y = 64.1, across the vertical faces x = 16 (L0/L1) and x = 22 (L1/L2) of box 1;
|
||||
H: x = 90.1, across the horizontal faces y = 24 (L0/L1) and y = 30 (L1/L2) of box 2.
|
||||
Each point is sampled at the ACTIVE leaf cell containing it, so cases with
|
||||
different grids (U128, U512, nested, twin) give different cell centers: the
|
||||
actual center and level are stored and analytic fields are evaluated there.
|
||||
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.
|
||||
"""
|
||||
@@ -19,9 +21,10 @@ import shear_wave as sw
|
||||
from oracle import CX, CY, U
|
||||
|
||||
ROOT_N = 128
|
||||
OFFSETS = (-3.9, -1.9, -0.4, 0.1, 0.6, 2.1, 4.1, 5.6, 6.1, 6.6, 8.1, 10.1) # from outer face
|
||||
TRANSECTS = {"V": dict(axis=0, face=16.0, other=64.1), # x varies, y fixed
|
||||
"H": dict(axis=1, face=24.0, other=90.1)} # y varies, x fixed
|
||||
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
|
||||
|
||||
@@ -29,10 +32,9 @@ TRACE_MAX_BYTES = 600_000
|
||||
def points():
|
||||
out = []
|
||||
for name, t in TRANSECTS.items():
|
||||
for offset in OFFSETS:
|
||||
along = t["face"] + offset
|
||||
for along in NORMAL_COORDS:
|
||||
xy = (along, t["other"]) if t["axis"] == 0 else (t["other"], along)
|
||||
out.append((name, offset, xy))
|
||||
out.append((name, along, xy))
|
||||
return out
|
||||
|
||||
|
||||
@@ -42,25 +44,33 @@ def case_steps(n):
|
||||
|
||||
|
||||
def select(masks, n=ROOT_N):
|
||||
"""Leaf cell containing each point: finest level whose ACTIVE mask covers it.
|
||||
"""Nearest ACTIVE leaf center for each target (deterministic tie rule).
|
||||
|
||||
Points and stored centers are in root-physical units (root cell = 1); a case
|
||||
with root N = n has cells of size ROOT_N / (n * 2**level) there.
|
||||
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, offset, (x, y) in points():
|
||||
for level in reversed(range(len(masks))):
|
||||
scale = (n // ROOT_N) * 2 ** level
|
||||
i, j = int(math.floor(x * scale)), int(math.floor(y * scale))
|
||||
if masks[level][j, i]:
|
||||
h = 1.0 / scale
|
||||
probes.append(dict(transect=name, offset=offset, point=[x, y], level=level,
|
||||
i=i, j=j, center=[h * (i + 0.5), h * (j + 0.5)]))
|
||||
break
|
||||
else:
|
||||
raise ValueError(f"point {(x, y)} is not covered by an ACTIVE leaf")
|
||||
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
|
||||
|
||||
|
||||
@@ -102,7 +112,7 @@ def validate(trace):
|
||||
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(OFFSETS) * len(TRANSECTS):
|
||||
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"]):
|
||||
|
||||
@@ -977,11 +977,17 @@ class ProbeTraceTests(unittest.TestCase):
|
||||
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:
|
||||
# The stored center is the actual cell center containing the point (root units).
|
||||
h = 1.0 / (2 ** p["level"]) if case is not u512 else 0.25
|
||||
self.assertLessEqual(abs(p["center"][0] - p["point"][0]), h / 2)
|
||||
self.assertLessEqual(abs(p["center"][1] - p["point"][1]), h / 2)
|
||||
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])
|
||||
|
||||
Reference in New Issue
Block a user