Jets: freeze origins, guard set_body, fine-boundary hit helper
Sector/Tube/Radial store origin as a validated float 2-tuple, so caller lists/arrays cannot change a registered definition. Simulation.set_body rejects nonzero motion for bodies with Jet-driven links once initialized (before initialize the sync-time stationary check applies). prepare_fine_boundary accepts jets in the same coarse cell-edge frame as fine objects, records read-only FP64 edge-frame hits (FineBoundary2D .curved_hits, default None) and rejects empty or overlapping selections before CUDA. FixedPatchStepper wiring is not included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
da8bfb0d4a
commit
62c525e735
4 files changed
+82
-5
No files matched your search
@@ -221,3 +221,52 @@ def test_manager_rejects_overlapping_jets_and_moving_bodies(device):
|
||||
bodies.jets.append(a)
|
||||
with pytest.raises(ValueError, match="stationary"):
|
||||
bodies.sync_to_gpu(field)
|
||||
|
||||
|
||||
def test_origins_are_frozen_float_pairs():
|
||||
point = [6., 5.]
|
||||
array = np.array([6., 5.])
|
||||
jets = [Jet(Sector(point, 0., .5, 4.), Radial(array)), Jet(Tube(array, 0., 1., 1.), Parallel(0.))]
|
||||
point[0], array[0] = 100., 100.
|
||||
assert jets[0].region.origin == (6., 5.) and jets[0].field.origin == (6., 5.)
|
||||
assert jets[1].region.origin == (6., 5.)
|
||||
assert all(type(v) is float for v in jets[0].region.origin)
|
||||
for bad in ((1., 2., 3.), (1., float("nan"))):
|
||||
with pytest.raises(ValueError):
|
||||
Radial(bad)
|
||||
|
||||
|
||||
def test_set_body_rejects_motion_of_jet_driven_body(device):
|
||||
from CelerisLab.simulation import Simulation
|
||||
jet = Jet(Sector(CENTER, 0., .6, 3.), Radial(CENTER, inward=False), "quartic", 2e-3)
|
||||
field, bodies = jet_case(device, [jet])
|
||||
sim = SimpleNamespace(bodies=bodies, field=field, lbm_cfg=field.cfg, _initialized=True)
|
||||
with pytest.raises(ValueError, match="stationary"):
|
||||
Simulation.set_body(sim, 0, omega=.01)
|
||||
assert bodies.get(0).state.omega == 0
|
||||
Simulation.set_body(sim, 0, omega=0.) # stationary updates stay allowed
|
||||
|
||||
|
||||
def test_fine_boundary_keeps_edge_frame_hits_and_checks_jets():
|
||||
from CelerisLab.body.objects import SimObject
|
||||
from CelerisLab.body.geometry.circle import CircleGeometry
|
||||
from CelerisLab.config import LBMConfig
|
||||
from CelerisLab.lbm import refinement
|
||||
cfg = LBMConfig(nx=24, ny=24, viscosity=.05)
|
||||
cfg.validate()
|
||||
patch = refinement.FixedPatch2D.from_config(cfg, (4, 4, 20, 20))
|
||||
C, R = (12.25, 12.25), 2.15 # coarse cell-edge frame, as fine_objects
|
||||
body = SimObject(0, geometry=CircleGeometry(*C, R), center=C, radius=R)
|
||||
plan = refinement.prepare_fine_boundary(cfg, patch, [body])
|
||||
assert plan.curved_hits.shape == (len(plan.curved_host[0]), 2)
|
||||
assert not plan.curved_hits.flags.writeable
|
||||
np.testing.assert_allclose(np.hypot(*(plan.curved_hits - C).T), R, rtol=0, atol=1e-12)
|
||||
jet = Jet(Sector(C, 0., .5, R + .01), Radial(C, inward=False))
|
||||
refinement.prepare_fine_boundary(cfg, patch, [body], jets=[jet])
|
||||
away = Jet(Sector((2., 2.), 0., .1, .5), Parallel(0.))
|
||||
with pytest.raises(ValueError, match="selects no"):
|
||||
refinement.prepare_fine_boundary(cfg, patch, [body], jets=[away])
|
||||
with pytest.raises(ValueError, match="overlaps"):
|
||||
refinement.prepare_fine_boundary(cfg, patch, [body], jets=[jet, jet])
|
||||
with pytest.raises(ValueError, match="need fine boundary objects"):
|
||||
refinement.prepare_fine_boundary(cfg, patch, [], jets=[jet])
|
||||
Reference in new issue
Block a user