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:
@@ -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)),
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user