Add synchronized CPU leaf population remap

This commit is contained in:
TRON committed 2026-10-16 10:07:34 -07:00
1 parent a24e6d2742
commit 999d3a0e94
3 files changed
+422

No files matched your search

+70
View File
@@ -0,0 +1,70 @@
# Synchronized leaf G remap (CPU only)
This is a CPU state-transfer component, **not a runtime adaptive solver**.
It changes only a separated L2 rectangle set in a three-level, body-free,
periodic hierarchy. L0/L1 topology, relaxation parameters, direction order,
physical frame and completed time remain unchanged. Existing geometry checks
validate child support/nesting and separation. No CUDA, scheduler, allocator,
boundary handling, collision, ghost refill or runtime installation is added.
```python
from CelerisLab.lbm.refinement import FixedPatchSet2D
from CelerisLab.lbm.synchronized_remap import RemapTopology, remap_synchronized
# cfg: D2Q9/SRT/FP32/unshifted/double_buffer, nz=1, no LES
parent = FixedPatchSet2D.from_config(cfg, [(4, 4, 20, 28), (24, 4, 44, 28)])
old = RemapTopology.from_config(cfg, parent, [(16, 16, 32, 40)])
new = RemapTopology.from_config(cfg, parent, [(20, 16, 36, 40)])
candidate = remap_synchronized(
old, new, current_g, base_count=7, level_steps=(7, 14, 28),
phase="postcollision_g", origin=(0., 0.), spacing=1.,
)
```
The example has a 48×32 root; both child supports allow 4×4 blocks.
Child bounds use the parent's allocated L1 coordinates, not rectangle-local
indices. A scalar FixedPatch2D parent is also supported: its shifted L1 window
origin is retained. Physical lower edges are `origin + spacing*(x,y)` on L0,
`origin + spacing*(parent.fine_origin + (x,y)/2)` on L1 and
`origin + spacing*(parent.fine_origin + (x,y)/4)` on L2.
Factory options `coarse_boundary` and `objects` must declare `"periodic"` and
an empty body collection (all levels). LBMConfig's channel settings do not
select this operator's boundary mode. Geometry metadata is factory-created;
manual mutation/forging of metadata is unsupported. Caller certifies the
actual state has no bodies/forcing, that all device work and old readers are
quiescent, and that inputs are the **current owned-leaf postcollision G**.
Count/phase stamps check consistency, not freshness or active-buffer identity.
`current_g` is three NumPy Q-major arrays `(9,ny,nx)`. For blocked inputs,
pass `layouts=(base_layout, fine_layout, child_layout)`; each optional `None`
entry denotes dense input. Every leaf must have an owner. Only owner cores
are read, never redundant block halos. Mixed precision is rejected. FP64 is
accepted for CPU reference tests; this does not enable FP64 runtime storage.
Outputs `candidate.g` are separate dense arrays regardless of input layout.
Memory scales with public grid extents, not only sparse allocated blocks.
Same-level leaf overlap is copied bitwise in physical coordinates. Newly
refined L2 copies all nine values from its valid old L1 parent. Newly exposed
L1 receives the complete four-child mean, including q0. Covered parents,
ghosts and holes never serve as donors; NaN/Inf outside leaves is ignored,
while nonfinite required leaves or nonpositive density reject the operation.
Restriction uses FP64 quarter-weight accumulation and rounds to the input
dtype. New nonleaves are NaN. Source arrays/metadata are not changed.
`candidate` retains `base_count`, `level_steps`, `phase`, `origin`, `spacing`
and new `topology.leaf_masks`. Existing `FixedPatchStepper.initialize` resets
the counter: using it is **not** a continuation adapter. This component neither
publishes a candidate nor retires old state. Runtime table rebuild/halo refill
and correct first-step scheduling remain separate integration work.
Tests accumulate leaf-area integrals in FP64 for each population, mass and
momentum. The declared absolute tolerance is `2e-13 * sum(abs(old population
integrals))` for FP64, `2e-7 * scale` for FP32, accounting for reduction and
restriction rounding (not a solver accuracy bound). Coarse→fine→coarse copy
round-trips preserve state; coarsening arbitrary fine structure loses it and
is not invertible. No kinetic accuracy or stability claim follows.
```sh
PYTHONPATH=src python -m unittest discover -s tests/unit -p 'test_synchronized_remap.py' -v
```