Relax coarse wall transfer guard to reconstructed rows only

Rows 2 and ny-3 are ordinary bulk cells that explosion only reads as
donors; only rows 0/1 and ny-2/ny-1 are dropped or reconstructed after
coalescence. Matches the existing y0>=4, y1<=ny-4 slot_reservoir contract.
Adds margin-4 acceptance and margin-3 rejection for a central circle.
This commit is contained in:
2026-10-15 10:40:39 +08:00
parent 3a7967f4cc
commit 103f144404
2 changed files with 21 additions and 2 deletions
+3 -2
View File
@@ -282,8 +282,9 @@ def prepare_fine_boundary(cfg, patch, objects, *, wall_aware=False):
y, x = divmod(k, cfg.nx)
if x0 <= x < x1 and y0 <= y < y1:
raise ValueError("Transfer coarse donor/target is not an uncovered bulk cell")
# Coarse reconstruction targets y=1,ny-2 pull from y=0..2,ny-3..ny-1.
if wall_aware and (y <= 2 or y >= cfg.ny-3):
# Rows 0/ny-1 are never computed and rows 1/ny-2 are reconstructed after
# coalescence; rows 2/ny-3 are ordinary bulk cells only read as donors.
if wall_aware and (y <= 1 or y >= cfg.ny-2):
raise ValueError("Transfer footprint touches the coarse wall reconstruction stencil")
return FineBoundary2D(tuple(local), _readonly(flags, np.uint16),
tuple(_readonly(a, a.dtype) for a in pack_cut_links_to_soa(links)),
+18
View File
@@ -213,3 +213,21 @@ def test_fine_rejects_ghost_solids_unresolved_circle_and_overlap(objects):
cfg, patch = setup_patch()
with pytest.raises(ValueError):
refinement.prepare_fine_boundary(cfg, patch, objects)
@pytest.mark.parametrize('margin, ok', [(4, True), (3, False)])
def test_fine_wall_guard_allows_read_only_bulk_donor_rows(margin, ok):
cfg = LBMConfig(nx=24, ny=24, viscosity=.05)
cfg.validate()
patch = FixedPatch2D.from_config(cfg, (4, margin, 20, 24-margin))
_, coarse, _ = refinement._transfer_footprint(patch)
rows = {k // cfg.nx for k in coarse}
assert min(rows) == margin-2 and max(rows) == cfg.ny-margin+1
source = circle(center=(12.25, 12.25))
# Footprint never violates the plain bulk-cell checks; only the wall rule differs.
refinement.prepare_fine_boundary(cfg, patch, [source])
if ok:
refinement.prepare_fine_boundary(cfg, patch, [source], wall_aware=True)
else:
with pytest.raises(ValueError, match='wall reconstruction'):
refinement.prepare_fine_boundary(cfg, patch, [source], wall_aware=True)