Test: Astra's actuated seam fixture (angle 0.7, half-width 0.85)

Asserts 21 aperture links, all with nonzero velocity, and 3 halo-writer
plus 2 halo-donor aperture rows in each decomposed layout (actuation
coverage across seams, not only geometric cut-link coverage). Velocity
is given in coarse units; prepare_fine_boundary scales it once. The GPU
gate remains storage equivalence; no zero-mass-change claim.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Claude
2026-10-15 04:45:57 +00:00
co-authored by Claude Opus 5.5
parent 7bf6101460
commit 1a274817cd
@@ -55,8 +55,10 @@ def circle(spec=None):
def actuation(speed):
"""Aperture centred on +x: hits links straddling the horizontal y 15|16 seam."""
return SurfaceActuation(0.0, 0.6, speed)
"""Astra's seam fixture: 21 aperture links; in each decomposed layout 3 of them
write a halo image and 2 read a q<.5 donor from a halo. Coarse lattice units:
prepare_fine_boundary does the (acoustic) fine scaling, never scale twice."""
return SurfaceActuation(0.7, 0.85, speed)
def fine_circle(mode, spec=None):
@@ -233,16 +235,20 @@ class BlockedFineCPU(unittest.TestCase):
np.testing.assert_array_equal(aperture, soa.aperture)
self.assertEqual(curved_links.surface_link_velocity(
(circle(),), cfg, boundary.flags, fluid_idx, dirs, body_id, rx, ry), (None, None))
# The aperture must actually cross a block seam in both decomposed layouts.
# Actuated (not just geometric) seam coverage in both decomposed layouts.
self.assertEqual(int(aperture.sum()), 21, mode)
self.assertTrue(np.all(np.any(velocity[aperture] != 0, axis=1)), mode)
for by, bx in FINE_BLOCKS[1:]:
layout = BlockLayout2D.build(*patch.fine_shape, by, bx, periodic=(False, False))
_, mapped = blocked_link_tables(layout, boundary.flags, fluid_idx, dirs,
boundary.curved_host[2], boundary.curved_host[7])
L = int(np.prod(layout.local_shape))
core = set(layout.owner.ravel().tolist())
seam = [int(w) // (9 * L) * L + int(w) % L not in core for w in mapped.write]
self.assertTrue(np.any(np.array(seam) & aperture & np.any(velocity != 0, axis=1)),
(mode, by, bx))
halo_write = np.array([int(w) // (9 * L) * L + int(w) % L not in core
for w in mapped.write])
halo_donor = np.array([d != NO_DONOR and int(d) not in core for d in mapped.donor])
self.assertEqual((int((halo_write & aperture).sum()),
int((halo_donor & aperture).sum())), (3, 2), (mode, by, bx))
def test_tables_map_back_to_dense_slots_in_order(self):
patch = FixedPatch2D.from_config(config("periodic"), BOUNDS)