diff --git a/tests/validation/multigrid/test_refinement_multipatch.py b/tests/validation/multigrid/test_refinement_multipatch.py index 3fe05ac..3003340 100644 --- a/tests/validation/multigrid/test_refinement_multipatch.py +++ b/tests/validation/multigrid/test_refinement_multipatch.py @@ -26,6 +26,12 @@ FACE = ((4, 4, 8, 12), (12, 4, 16, 12)) S1 = ((4, 4, 12, 12), (20, 4, 28, 12)) +def levels(bounds, blocks=(None, None), objects=(), jets=(), **rest): + """Two-level constructor keywords: one L1 rectangle or set, per-level blocks, L1 bodies/Jets.""" + return dict(refinements=[bounds], level_blocks=list(blocks), + level_objects=[(), tuple(objects)], level_jets=[(), tuple(jets)], **rest) + + def level_fine(patch_set, windows): """Level-wide fine array with each patch window filled from `windows`.""" out = np.full((9, *patch_set.fine_shape), np.nan, np.float32) @@ -45,21 +51,21 @@ class MultipatchCPU(unittest.TestCase): def test_rejections_before_cuda(self): cfg = config("periodic") context = object() # never activated: every case must fail first - for kw in (dict(), dict(fine_block=(8, 4)), dict(base_block=(4, 4)), - dict(fine_block=(8, 4), base_block=(4, 4), fine_objects=[circle()]), - dict(fine_block=(5, 4), base_block=(4, 4))): + for kw in (dict(), dict(blocks=(None, (8, 4))), dict(blocks=((4, 4), None)), + dict(blocks=((4, 4), (8, 4)), objects=[circle()]), + dict(blocks=((4, 4), (5, 4)))): with self.subTest(kw=kw), self.assertRaises(ValueError): - FixedPatchStepper(cfg, ((4, 4, 8, 12), (14, 4, 18, 12)), context=context, **kw) + FixedPatchStepper(cfg, context=context, **levels(((4, 4, 8, 12), (14, 4, 18, 12)), **kw)) with self.assertRaisesRegex(ValueError, "margin"): - FixedPatchStepper(cfg, ((1, 4, 8, 12), (10, 4, 14, 12)), context=context, - fine_block=(8, 4), base_block=(4, 4)) + FixedPatchStepper(cfg, context=context, + **levels(((1, 4, 8, 12), (10, 4, 14, 12)), blocks=((4, 4), (8, 4)))) from CelerisLab.body.jets import Jet, Parallel, Tube cfg32 = LBMConfig(nx=32, ny=16, viscosity=.1) span = Jet(Tube((5., 8.), 0., 22., .6), Parallel(0.), amplitude=0.) with self.assertRaisesRegex(ValueError, "one jet"): # same obj_id cannot bypass it - FixedPatchStepper(cfg32, ((2, 2, 14, 14), (18, 2, 30, 14)), context=context, - fine_block=(4, 4), base_block=(4, 4), - fine_objects=[body(8., 8.), body(24., 8.)], jets=[span]) + FixedPatchStepper(cfg32, context=context, + **levels(((2, 2, 14, 14), (18, 2, 30, 14)), blocks=((4, 4), (4, 4)), + objects=[body(8., 8.), body(24., 8.)], jets=[span])) class MultipatchGPU(unittest.TestCase): @@ -67,7 +73,7 @@ class MultipatchGPU(unittest.TestCase): def run_steps(self, context, cfg, bounds, coarse, fine, **kw): out = [] - with FixedPatchStepper(cfg, bounds, context=context, **kw) as backend: + with FixedPatchStepper(cfg, context=context, **levels(bounds, **kw)) as backend: backend.initialize(coarse, fine) for step in self.STEPS: backend.step(step - backend.step_count) @@ -82,7 +88,7 @@ class MultipatchGPU(unittest.TestCase): p = FixedPatch2D.from_config(cfg, BOUNDS) s = FixedPatchSet2D.from_config(cfg, (BOUNDS,)) coarse, fine = state(NY, NX, 1), state(*p.fine_shape, 2) - kw = dict(coarse_boundary=mode, fine_block=(8, 4), base_block=(3, 4)) + kw = dict(coarse_boundary=mode, blocks=((3, 4), (8, 4))) old = self.run_steps(context, cfg, BOUNDS, coarse, fine, **kw) new = self.run_steps(context, cfg, (BOUNDS,), coarse, level_fine(s, [fine]), **kw) for step, a, b in zip(self.STEPS, old, new): @@ -99,7 +105,7 @@ class MultipatchGPU(unittest.TestCase): one = FixedPatchSet2D.from_config(cfg16, (S1[0],)) two = FixedPatchSet2D.from_config(cfg32, S1) coarse, fine = state(16, 16, 3), state(*one.patches[0].fine_shape, 4) - kw = dict(fine_block=(4, 4), base_block=(4, 4)) + kw = dict(blocks=((4, 4), (4, 4))) with CudaContext(0) as context: ref = self.run_steps(context, cfg16, (S1[0],), coarse, level_fine(one, [fine]), **kw) tiled = np.concatenate([coarse, coarse], axis=2) @@ -118,7 +124,7 @@ class MultipatchGPU(unittest.TestCase): s = FixedPatchSet2D.from_config(cfg, FACE) coarse = state(16, 24, 5) fine = level_fine(s, [state(*p.fine_shape, 6 + i) for i, p in enumerate(s.patches)]) - kw = dict(fine_block=(4, 4), base_block=(4, 4)) + kw = dict(blocks=((4, 4), (4, 4))) leaf = s.fine_kind == ACTIVE support = s.fine_layout((4, 4)).owned outer = support & (s.fine_kind == OUTER_GHOST) @@ -164,7 +170,7 @@ class MultipatchBodiesGPU(unittest.TestCase): def run_steps(self, context, cfg, bounds, coarse, fine, switch=None, **kw): out = [] - with FixedPatchStepper(cfg, bounds, context=context, **kw) as backend: + with FixedPatchStepper(cfg, context=context, **levels(bounds, **kw)) as backend: backend.initialize(coarse, fine) for step in self.STEPS: if switch is not None and step == 8: @@ -182,8 +188,7 @@ class MultipatchBodiesGPU(unittest.TestCase): p = FixedPatch2D.from_config(cfg, BOUNDS) s = FixedPatchSet2D.from_config(cfg, (BOUNDS,)) coarse, fine = state(NY, NX, 1), state(*p.fine_shape, 2) - kw = dict(coarse_boundary=mode, fine_block=(8, 4), base_block=(3, 4), - fine_objects=[circle()]) + kw = dict(coarse_boundary=mode, blocks=((3, 4), (8, 4)), objects=[circle()]) old = self.run_steps(context, cfg, BOUNDS, coarse, fine, **kw) new = self.run_steps(context, cfg, (BOUNDS,), coarse, level_fine(s, [fine]), **kw) for step, a, b in zip(self.STEPS, old, new): @@ -202,17 +207,17 @@ class MultipatchBodiesGPU(unittest.TestCase): two = FixedPatchSet2D.from_config(cfg32, self.PATCHES) coarse, fine = state(16, 16, 3), state(*one.patches[0].fine_shape, 4) jet = lambda x: Jet(Tube((x, 8.), 0., 6., .6), Parallel(0.), amplitude=.002) - kw = dict(fine_block=(4, 4), base_block=(4, 4)) + kw = dict(blocks=((4, 4), (4, 4))) with CudaContext(0) as context: for jets in ((), (jet(5.),)): ref = self.run_steps(context, cfg16, self.PATCHES[:1], coarse, level_fine(one, [fine]), switch=[(0, -.001)] if jets else None, - fine_objects=[body(8., 8.)], jets=jets, **kw) + objects=[body(8., 8.)], jets=jets, **kw) both = jets and (jet(5.), jet(21.)) got = self.run_steps(context, cfg32, self.PATCHES, np.concatenate([coarse, coarse], 2), level_fine(two, [fine, fine]), switch=[(0, -.001), (1, -.001)] if jets else None, - fine_objects=[body(8., 8., 5), body(24., 8., 5)], + objects=[body(8., 8., 5), body(24., 8., 5)], jets=both or (), **kw) for step, a, b in zip(self.STEPS, ref, got): label = f"jets={len(jets)} step {step}"