From fb58c7982763d3b26d9485fc63580009e6629016 Mon Sep 17 00:00:00 2001 From: Frank14f <1515444314@qq.com> Date: Tue, 3 Nov 2026 01:26:54 +0800 Subject: [PATCH] Use committed Taylor body IDs after topology sync --- research/fig2_collection/run.py | 5 ++++- tests/unit/test_fig2_collection.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/research/fig2_collection/run.py b/research/fig2_collection/run.py index 25b3a68..f325d62 100644 --- a/research/fig2_collection/run.py +++ b/research/fig2_collection/run.py @@ -249,8 +249,11 @@ def make_release(scene, plan, cfgpath, base, out, started, cap, release_dir): warm = 32 if plan['smoke'] else (512000 if scene == 'taylor' else 2048000) if scene == 'taylor': base.warmup(sim, warm, started, cap) - bodies = [sim.add_body('circle', point, 20.) for point in CENTRES] + first = sim.bodies.count + for point in CENTRES: + sim.add_body('circle', point, 20.) # runtime additions return staged ID -1 sim.sync_bodies() + bodies = list(range(first, first+len(CENTRES))) base.warmup(sim, warm-1, started, cap) sim.run(1, zero_obs=True, sync_obs=True) force = sum(float(sim.read_force(body)[1]) for body in bodies) diff --git a/tests/unit/test_fig2_collection.py b/tests/unit/test_fig2_collection.py index b81a577..7dae6df 100644 --- a/tests/unit/test_fig2_collection.py +++ b/tests/unit/test_fig2_collection.py @@ -182,6 +182,36 @@ class CollectionContracts(unittest.TestCase): class SelectionContracts(unittest.TestCase): + def test_taylor_release_uses_committed_ids_not_staged_minus_one(self): + reads=[] + class Sim: + def __init__(self,*args): + self.bodies=types.SimpleNamespace(count=0) + self.stepper=types.SimpleNamespace(step_count=0) + self.initialized=False;self.pending=0 + def __enter__(self):return self + def __exit__(self,*args):pass + def add_body(self,*args,**kwargs): + if self.initialized:self.pending+=1;return -1 + index=self.bodies.count;self.bodies.count+=1;return index + def initialize(self):self.initialized=True + def sync_bodies(self):self.bodies.count+=self.pending;self.pending=0 + def run(self,n,**kwargs):self.stepper.step_count+=n + def read_force(self,body): + if body<0:raise IndexError('staged ID') + reads.append(body);return [0.,float(body),0.] + pkg=types.ModuleType('CelerisLab');pkg.Simulation=Sim + motion=types.ModuleType('CelerisLab.body.motion');motion.Translation=None + base=types.SimpleNamespace(warmup=lambda sim,n,*args:sim.run(n), + capture_seed=lambda sim:(np.zeros(18,np.float32),np.ones(18,np.float32), + np.ones(2,np.uint16),sim.stepper.step_count)) + with tempfile.TemporaryDirectory() as directory,patch.dict(sys.modules,{'CelerisLab':pkg,'CelerisLab.body.motion':motion}): + seed,force,_=driver.make_release('taylor',driver.schedule('taylor',True),'unused',base, + Path(directory),0,60,None) + self.assertEqual(reads,[3,4,5]) + self.assertEqual(force,12.) + self.assertEqual(seed[3],64) + def test_recorded_clock_must_equal_observed_solver(self): driver.check_clock(types.SimpleNamespace(step_count=4579200),4576000,3200) with self.assertRaisesRegex(RuntimeError,'observed solver clock'):