Test: jet ownership is set membership, not row adjacency

Synthetic rows: one jet over non-contiguous rows of one body is accepted;
the same rows with a second body id are rejected (Grok case 2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Claude
2026-10-16 02:41:15 +00:00
co-authored by Claude Opus 5.5
parent 64d54ab23e
commit bf0adda45f
+27
View File
@@ -346,3 +346,30 @@ def test_separate_jets_on_separate_bodies_accepted(device):
for j in (0, 1):
assert len(np.unique(cl.body_id[cl.jet_id == j])) == 1
assert cl.body_id[cl.jet_id == 0][0] != cl.body_id[cl.jet_id == 1][0]
def test_one_body_with_noncontiguous_rows_accepted_and_mixed_rejected():
# Synthetic rows: ownership is set membership over body_id, not row adjacency.
from CelerisLab.body.geometry.circle import CircleGeometry
from CelerisLab.body.objects import SimObject
from CelerisLab.config import LBMConfig
from CelerisLab.lbm.descriptors import FLUID
cfg = LBMConfig(nx=12, ny=10, viscosity=.1)
cfg.validate()
objs = [SimObject(i, geometry=CircleGeometry(3. + 5*i, 5., 1.), center=(3. + 5*i, 5.), radius=1.)
for i in (0, 1)]
flags = np.full(cfg.nx*cfg.ny, FLUID, np.uint16)
fluid_idx = np.array([10, 20, 30], np.uint32)
dirs = np.array([1, 1, 1], np.uint8)
zeros = np.zeros(3, np.float32)
hits = np.array([[0., 0.], [5., 5.], [0., 1.]])
jet = Jet(Tube((0., -.5), math.pi/2, 2., .5), Parallel(0.)) # selects rows 0 and 2
for body_id, ok in ((np.array([0, 1, 0], np.int32), True), (np.array([0, 1, 1], np.int32), False)):
call = lambda: surface_link_velocity(objs, cfg, flags, fluid_idx, dirs, body_id,
zeros, zeros, jets=[jet], hits=hits)
if ok:
_, aperture = call()
assert aperture.tolist() == [True, False, True]
else:
with pytest.raises(ValueError, match="one jet may drive only one body"):
call()