KW becomes levels() (scalar L1 + scalar L2, per-level blocks, objects,
Jets). All rejection cases are kept per level. Two cases change branch:
L2 bodies/Jets with no nested child (legacy 'child_objects/child_jets
require a nested child') are now an entry for a level that does not
exist ('needs one entry per level'); several L1 patches + scalar child
now meets 'a scalar child requires a scalar parent'. Both still reject
before CUDA. Assertions unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
baba5e0 replaced _advance_child with _advance(index, parent_buffer) driven
from _hop; the two feed-order tests still patched the removed method.
Patch _advance and record only index 2 (L1 hop feeding L2); assertions,
expected order and the stale-feed negative control are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 3f47436073)
FixedPatchStepper(..., child=(x0,y0,x1,y1), child_block=(by,bx)) adds an L2
patch in L1 window cells (requires fine_block/base_block, one L1 patch, no
bodies/jets). nest_patch() builds the L1->L2 FixedPatch2D (2*nu on L1) and
the composed L1 kind (inherited INNER/OUTER kept, child-covered ACTIVE made
OUTER), rejecting from the actual tables: coverage outside ACTIVE, donors or
receivers not uncovered ACTIVE, surviving ACTIVE pulls of covered/OUTER cells
without a child-supplied arrival, and overlap with L1's restriction footprint.
Step order per L1 hop: explode L1(src)->L2, two L2 hops (halo, step), L1 halo,
receiver-local L2->L1 staging into src, L1 step. The second hop thus feeds L2
from the new L1 G; L2 is never refilled from L0; L0 stays once per step (1:2:4).
Existing kernels only; a small _Pair holds the child transfer bindings (explode
from the child module, parent window stride). Two-level API unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>