- curved_links.surface_link_velocity: pure host helper extracted from
CurvedLinkSoA.assign_surface (which now calls it; dense path unchanged).
Rows follow physical cut-link order.
- blocks.cu BlockCurvedBoundary: one nullable trailing surface_velocity
argument (2 floats/link), same convention as CurvedBoundaryKernel; no
exchange output. Both call sites pass it explicitly (PeriodicBlockStepper
passes null; single-level behaviour unchanged).
- FixedPatchStepper blocked mode accepts actuated stationary circles,
validated against the physical fine_cfg; uploads the velocity table only
when any actuation spec exists and fails before BFL if that buffer is
missing (even at zero amplitude). Blocked exchange diagnostics are
unavailable; dense exchange behaviour unchanged. No force aggregation,
no motion, no new numerical formula.
Tests: 1x1 seam (0,0), receivers in 4 blocks, all q<.5 links fallback 0;
dense SoA never built in blocked mode; launch order incl. null vs velocity
pointer; missing-buffer guard at 0 and 0.002; helper == assign_surface;
aperture crosses a seam; GPU: periodic and slot_reservoir, +/-0.002,
8 coarse steps, dense vs 1x1/2x2/4x2 exact values + NaN masks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>