Build refinement transfers from union and pin physical body support
This commit is contained in:
1 parent
1e8e2c9a69
commit
fbe73779c1
13 files changed
+357
-106
No files matched your search
@@ -50,11 +50,11 @@ class FourLevels(unittest.TestCase):
|
||||
cases = [([L1, [(10, 20, 30, 44)]], "inherited ACTIVE"),
|
||||
([L1, L2[:1] + [(54, 54, 58, 58)]], "inherited ACTIVE"),
|
||||
([L1, L2, [(40, 40, 60, 60)]], "donors/receivers"),
|
||||
([L1, L2, [(41, 41, 60, 60)]], "donors/receivers"),
|
||||
([L1, L2, [(56, 56, 64, 64), (66, 56, 72, 64)]], "closer than")]
|
||||
([L1, L2, [(41, 41, 60, 60)]], "donors/receivers")]
|
||||
for levels, reason in cases:
|
||||
with self.subTest(levels=levels), self.assertRaisesRegex(ValueError, reason):
|
||||
build_hierarchy(CFG, levels)
|
||||
build_hierarchy(CFG, [L1, L2, [(56, 56, 64, 64), (66, 56, 72, 64)]]) # gap 2 closes
|
||||
build_hierarchy(CFG, [L1, L2, [(42, 42, 60, 60)]]) # minimal legal margin
|
||||
|
||||
|
||||
|
||||
@@ -81,14 +81,9 @@ class MultiplePinnedRemap(unittest.TestCase):
|
||||
self.assertEqual(old.pinned_rectangles, PINS)
|
||||
self.check_transfer(old, new, fields(old), 2e-13)
|
||||
|
||||
def test_direct_helper_rejects_each_changed_pin_and_body_order(self):
|
||||
def test_direct_helper_rejects_changed_body_order(self):
|
||||
old = mesh(PINS+FLUID, objects())
|
||||
candidates = [mesh(PINS+FLUID, objects()[::-1])]
|
||||
for index in range(2):
|
||||
changed = list(PINS+FLUID)
|
||||
x0, y0, x1, y1 = changed[index]
|
||||
changed[index] = (x0-4, y0, x1, y1)
|
||||
candidates.append(mesh(changed, objects()))
|
||||
for new in candidates:
|
||||
# Invalid donors ensure boundary validation precedes array reads.
|
||||
with self.assertRaisesRegex(ValueError, 'pinned'):
|
||||
@@ -138,6 +133,7 @@ class MultiplePinnedRemap(unittest.TestCase):
|
||||
changed = list(PINS+FLUID)
|
||||
x0, y0, x1, y1 = changed[index]
|
||||
changed[index] = (x0-4, y0, x1, y1)
|
||||
changed[index] = (x0+8, y0, x1, y1) # removes actual body support
|
||||
cases.append((changed, bodies))
|
||||
cases.append((tuple(r for i, r in enumerate(PINS+FLUID) if i != index), bodies))
|
||||
start = len(allocations)
|
||||
|
||||
@@ -83,7 +83,7 @@ class PinnedBodyRemap(unittest.TestCase):
|
||||
run,module,allocations,storage,objects=ready()
|
||||
start=len(allocations)
|
||||
cases=[(B,()),(B,run.child_boundary.objects),(B,(body(center=(12.1,14.)),)),
|
||||
(((20,16,36,40),B[1]),objects),(((16,20,32,40),B[1]),objects),
|
||||
(((24,16,36,40),B[1]),objects),(((16,28,32,40),B[1]),objects),
|
||||
((B[1],),objects)]
|
||||
module.cuda.memcpy_dtoh.reset_mock()
|
||||
for rects,objs in cases:
|
||||
@@ -124,7 +124,9 @@ class PinnedBodyRemap(unittest.TestCase):
|
||||
for a in allocations[len(saved):]: a.free.assert_called_once()
|
||||
run.close()
|
||||
|
||||
def test_direct_helper_rejects_changed_pinned_rectangle(self):
|
||||
def test_direct_helper_allows_changed_rectangle_with_same_boundary(self):
|
||||
old=mesh(A,(body(),))
|
||||
new=mesh(((12,16,32,40),A[1]),(body(),))
|
||||
with self.assertRaisesRegex(ValueError,'pinned'): remap(old,new,fields(old))
|
||||
out = remap(old,new,fields(old))
|
||||
self.assertTrue(same_physical_boundary(old.boundary,new.boundary))
|
||||
self.assertIs(out.topology,new)
|
||||
@@ -181,14 +181,14 @@ class FixedPatchSetTests(unittest.TestCase):
|
||||
ly, lx = p.fine_shape
|
||||
np.testing.assert_array_equal(s.fine_kind[y0:y0 + ly, x0:x0 + lx], p.fine_kind)
|
||||
gy, gx = np.divmod(p.ghost_fine.astype(np.int64), lx)
|
||||
np.testing.assert_array_equal(s.ghost_fine[cells:cells + len(gy)],
|
||||
(gy + y0) * fx + gx + x0)
|
||||
np.testing.assert_array_equal(s.ghost_coarse[cells:cells + len(gy)], p.ghost_coarse)
|
||||
ghosts = dict(zip(map(int, s.ghost_fine), map(int, s.ghost_coarse)))
|
||||
for f, c in zip((gy + y0) * fx + gx + x0, p.ghost_coarse):
|
||||
self.assertEqual(ghosts[int(f)], int(c))
|
||||
q, c = np.divmod(p.coalesce_fine.astype(np.int64), ly * lx)
|
||||
cy, cx = np.divmod(c, lx)
|
||||
np.testing.assert_array_equal(s.coalesce_fine[rows:rows + len(q)],
|
||||
q * fy * fx + (cy + y0) * fx + cx + x0)
|
||||
np.testing.assert_array_equal(s.coalesce_coarse[rows:rows + len(q)], p.coalesce_coarse)
|
||||
rows_by_target = dict(zip(map(int, s.coalesce_coarse), s.coalesce_fine))
|
||||
for target, children in zip(p.coalesce_coarse, q * fy * fx + (cy + y0) * fx + cx + x0):
|
||||
np.testing.assert_array_equal(rows_by_target[int(target)], children)
|
||||
rows, cells = rows + len(q), cells + len(gy)
|
||||
self.assertEqual((rows, cells), (len(s.coalesce_coarse), len(s.ghost_fine)))
|
||||
self.assertEqual(int((s.fine_kind == ACTIVE).sum()), 4 * int(s.covered.sum()))
|
||||
@@ -207,10 +207,12 @@ class FixedPatchSetTests(unittest.TestCase):
|
||||
np.testing.assert_array_equal(s.coalesce_coarse, p.coalesce_coarse)
|
||||
np.testing.assert_array_equal(s.ghost_coarse, p.ghost_coarse)
|
||||
|
||||
def test_gap_and_overlap_rejected(self):
|
||||
for gap in (0, 2, 3):
|
||||
with self.subTest(gap=gap), self.assertRaisesRegex(ValueError, "closer"):
|
||||
self.build(((4, 4, 8, 12), (8 + gap, 4, 12 + gap, 12)))
|
||||
def test_gap_and_overlap_use_dependency_checks(self):
|
||||
for gap in (-2, 0, 1, 2, 3):
|
||||
with self.subTest(gap=gap):
|
||||
pair = self.build(((4, 4, 8, 12), (8 + gap, 4, 12 + gap, 12)))
|
||||
refinement._transfer_footprint(pair)
|
||||
refinement._check_parent_pull_closure(pair)
|
||||
with self.assertRaises(ValueError):
|
||||
self.build(())
|
||||
with self.assertRaises(ValueError): # FixedPatch2D margin still applies
|
||||
@@ -226,7 +228,7 @@ class FixedPatchSetTests(unittest.TestCase):
|
||||
support[y0:y0 + p.fine_shape[0], x0:x0 + p.fine_shape[1]] = True
|
||||
np.testing.assert_array_equal(layout.owned, support)
|
||||
self.assertTrue(layout.owned.ravel()[s.ghost_fine.astype(np.intp)].all())
|
||||
with self.assertRaisesRegex(ValueError, "aligned"):
|
||||
with self.assertRaisesRegex(ValueError, "divide"):
|
||||
self.build(self.FACE).fine_layout((5, 4))
|
||||
for block in ((0, 4), (4, 0), (-4, 4), (4.0, 4), (True, 4), (4,), (4, 4, 4), (np.bool_(1), 4)):
|
||||
with self.subTest(block=block), self.assertRaisesRegex(ValueError, "positive integers"):
|
||||
|
||||
@@ -217,7 +217,7 @@ class ConstructorAndSchedule(unittest.TestCase):
|
||||
cases=[dict(child=(8,8,16,16)),dict(child_rectangles_in_parent=[]),
|
||||
dict(child_rectangles_in_parent=[(16,16,32)]),
|
||||
dict(child_rectangles_in_parent=[(16.5,16,32,40)]),
|
||||
dict(child_rectangles_in_parent=[(16,16,32,24),(16,27,32,40)]),
|
||||
dict(child_rectangles_in_parent=[(16,16,32,24),(16,27,32,55)]),
|
||||
dict(child_rectangles_in_parent=[(40,16,48,40)]),
|
||||
dict(child_rectangles_in_parent=[(8,16,32,40)]),
|
||||
dict(child_block=None),dict(fine_block=None),dict(base_block=None),
|
||||
@@ -226,8 +226,8 @@ class ConstructorAndSchedule(unittest.TestCase):
|
||||
for changes in cases:
|
||||
with self.subTest(changes=changes),self.assertRaises((ValueError,TypeError)):
|
||||
host.FixedPatchStepper(CFG,PARENTS,context=context,**dict(KW,**changes))
|
||||
with self.assertRaisesRegex(ValueError,'closer'):
|
||||
host.FixedPatchStepper(CFG,[(4,4,20,28),(23,4,44,28)],context=context,**KW)
|
||||
with self.assertRaisesRegex(ValueError,'margin'):
|
||||
host.FixedPatchStepper(CFG,[(1,4,20,28),(23,4,44,28)],context=context,**KW)
|
||||
objects,jets=bodies_and_jets()
|
||||
with self.assertRaisesRegex(ValueError,'only on L2'):
|
||||
host.FixedPatchStepper(CFG,PARENTS,context=context,fine_objects=objects,**KW)
|
||||
|
||||
@@ -67,7 +67,7 @@ class RuntimeChildRemap(unittest.TestCase):
|
||||
run._status = status
|
||||
with self.assertRaises(RuntimeError): run.remap_child(B)
|
||||
run._status = 'ready'
|
||||
for bad in ([], [(40,16,48,40)], [(16,16,32,24),(16,27,32,40)]):
|
||||
for bad in ([], [(40,16,48,40)], [(16,16,32,24),(16,27,32,55)]):
|
||||
with self.assertRaises(ValueError): run.remap_child(bad)
|
||||
hosts, pairs = run._boundary_hosts, run.hierarchy.pairs
|
||||
for attribute, value in (('_wall_aware', True),
|
||||
|
||||
@@ -175,8 +175,7 @@ class SynchronizedRemapTests(unittest.TestCase):
|
||||
self.assertFalse(np.array_equal(self.g[2][:, lost], returned.g[2][:, lost]))
|
||||
|
||||
def test_invalid_geometry_counts_representation_frame(self):
|
||||
for rectangles in ([], [(2, 2, 10, 10)], [(16, 16, 32, 40)] * 2,
|
||||
[(16, 16, 33.5, 40)], [(16, 16, 32, 40), (33, 16, 36, 40)]):
|
||||
for rectangles in ([], [(2, 2, 10, 10)], [(16, 16, 33.5, 40)]):
|
||||
with self.assertRaises(ValueError):
|
||||
topology(rectangles)
|
||||
parent = self.old.parent
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
"""Union seam bodies and actual support pinning; CPU host-only."""
|
||||
import unittest
|
||||
import numpy as np
|
||||
from CelerisLab.config import LBMConfig
|
||||
from CelerisLab.lbm.refinement import FixedPatchSet2D,prepare_fine_boundary,_circle_in_coverage
|
||||
from CelerisLab.lbm.synchronized_remap import same_physical_boundary
|
||||
from tests.unit import test_refinement as refinement_tests
|
||||
from tests.unit.test_pinned_body_remap import mesh,body,ready,A
|
||||
from tests.unit.test_synchronized_remap import fields,remap,integrals
|
||||
|
||||
class UnionBodySupport(unittest.TestCase):
|
||||
def test_seam_circle_matches_single_rectangle(self):
|
||||
cfg=LBMConfig(nx=32,ny=16,viscosity=.1)
|
||||
obj=refinement_tests.PatchSetBoundaryTests.body(16.,8.)
|
||||
def b(rects):return prepare_fine_boundary(cfg,FixedPatchSet2D.from_config(cfg,rects),[obj])
|
||||
self.assertTrue(same_physical_boundary(b([(4,2,28,14)]),b([(4,2,16,14),(16,2,28,14)])))
|
||||
with self.assertRaisesRegex(ValueError,'union'):
|
||||
b([(4,2,16,14),(17,2,28,14)])
|
||||
|
||||
def test_continuous_disk_not_only_sampled_solids(self):
|
||||
mask=np.ones((8,8),bool);mask[3,3]=False
|
||||
self.assertFalse(_circle_in_coverage(mask,3.99,3.99,.02))
|
||||
self.assertTrue(_circle_in_coverage(mask,4.1,4.1,.1))
|
||||
|
||||
def test_repartition_and_connected_fluid_changes_do_not_pin_rectangles(self):
|
||||
old=mesh(A,(body(),));initial=fields(old)
|
||||
for rects in (((16,16,24,40),(24,16,32,40),A[1]),((12,16,32,40),A[1]),((20,16,36,40),A[1])):
|
||||
new=mesh(rects,(body(),));self.assertTrue(same_physical_boundary(old.boundary,new.boundary))
|
||||
out=remap(old,new,initial)
|
||||
np.testing.assert_allclose(integrals(old,initial),integrals(new,out.g),rtol=2e-13,atol=2e-12)
|
||||
for a,b,om,nm in zip(initial,out.g,old.leaf_masks,new.leaf_masks):
|
||||
np.testing.assert_array_equal(a[:,om&nm],b[:,om&nm])
|
||||
|
||||
def test_runtime_seam_repartition_preserves_boundary_and_live_jets(self):
|
||||
run,module,allocations,storage,objects=ready()
|
||||
try:
|
||||
run.set_jet_amplitude(0,.017,level=2)
|
||||
clone=run.remap_child(((16,16,24,40),(24,16,32,40),A[1]),child_objects=objects)
|
||||
try:
|
||||
self.assertEqual(clone._boundaries[2].jets[0].amplitude,.017)
|
||||
self.assertTrue(same_physical_boundary(run.child_boundary,clone.child_boundary))
|
||||
for a,b in zip(run.download(),clone.download()):np.testing.assert_array_equal(a,b)
|
||||
finally:clone.close()
|
||||
finally:run.close()
|
||||
@@ -0,0 +1,161 @@
|
||||
"""CPU tests: union tables vs current FixedPatchSet2D; numpy + CelerisLab on PYTHONPATH.
|
||||
Optional numerics: ADAPTER_DIR=<adapter bundle dir> [ADAPTER_FILE=adapter.py or
|
||||
multilevel_numeric_adapter.py (default: whichever exists)]."""
|
||||
from dataclasses import replace
|
||||
import importlib.util
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
from CelerisLab.config import LBMConfig
|
||||
from CelerisLab.lbm.refinement import (ACTIVE, OUTER_GHOST, FixedPatchSet2D, _middle_config,
|
||||
_nested_kind, _transfer_footprint)
|
||||
from CelerisLab.lbm.refinement_tables import blocked_kind
|
||||
|
||||
from CelerisLab.lbm.refinement import (FixedPatchSet2D as UnionPatchSet2D,
|
||||
_check_parent_pull_closure as check_parent_pull_closure, _dilate as dilate)
|
||||
|
||||
def table_sets(pair):
|
||||
return (pair.fine_kind.tobytes(), pair.covered.tobytes(),
|
||||
frozenset(zip(map(int,pair.ghost_fine),map(int,pair.ghost_coarse))),
|
||||
frozenset((int(t),tuple(map(int,c))) for t,c in zip(pair.coalesce_coarse,pair.coalesce_fine)))
|
||||
|
||||
CFG = LBMConfig(nx=30, ny=30, viscosity=.1)
|
||||
A, B, U = (8, 8, 16, 20), (16, 8, 24, 20), (8, 8, 24, 20)
|
||||
|
||||
|
||||
def union(*rects, cfg=CFG):
|
||||
return UnionPatchSet2D.from_config(cfg, rects)
|
||||
|
||||
|
||||
class Equivalence(unittest.TestCase):
|
||||
def test_abutting_boxes_equal_their_union_rectangle(self):
|
||||
reference = table_sets(FixedPatchSet2D.from_config(CFG, [U]))
|
||||
for rects in ((A, B), (B, A), (U,)):
|
||||
with self.subTest(rects=rects):
|
||||
self.assertEqual(table_sets(union(*rects)), reference)
|
||||
|
||||
def test_vertical_abutting(self):
|
||||
self.assertEqual(table_sets(union((8, 8, 20, 14), (8, 14, 20, 22))),
|
||||
table_sets(FixedPatchSet2D.from_config(CFG, [(8, 8, 20, 22)])))
|
||||
|
||||
def test_separated_rectangles_reproduce_current_tables(self):
|
||||
rects = [(4, 4, 10, 10), (16, 16, 26, 26)] # gap 6 >= MIN_PATCH_GAP
|
||||
self.assertEqual(table_sets(union(*rects)),
|
||||
table_sets(FixedPatchSet2D.from_config(CFG, rects)))
|
||||
|
||||
def test_layout_tiles_are_free_of_rectangle_alignment(self):
|
||||
pair = union(A, B)
|
||||
support = dilate(pair.fine_kind == ACTIVE, 4)
|
||||
reference = FixedPatchSet2D.from_config(CFG, [U]).fine_layout((4, 4))
|
||||
np.testing.assert_array_equal(pair.fine_layout((4, 4)).owned, reference.owned)
|
||||
layout = pair.fine_layout((6, 10)) # not aligned to the rectangles
|
||||
self.assertTrue(layout.owned[support].all())
|
||||
kind = blocked_kind(layout, pair.fine_kind)
|
||||
owned = layout.owned
|
||||
np.testing.assert_array_equal(kind[layout.owner[owned]], pair.fine_kind[owned])
|
||||
|
||||
|
||||
class NewlyLegal(unittest.TestCase):
|
||||
def check(self, pair):
|
||||
_transfer_footprint(pair)
|
||||
check_parent_pull_closure(pair)
|
||||
ghosts = pair.ghost_fine.astype(np.intp)
|
||||
self.assertFalse((pair.fine_kind.ravel()[ghosts] == ACTIVE).any())
|
||||
self.assertFalse(pair.covered.ravel()[pair.ghost_coarse.astype(np.intp)].any())
|
||||
|
||||
def test_small_gaps_and_l_shape(self):
|
||||
for rects in (((8, 8, 16, 20), (17, 8, 24, 20)), # gap 1
|
||||
((8, 8, 16, 20), (18, 8, 24, 20)), # gap 2
|
||||
((8, 8, 20, 14), (8, 14, 14, 22))): # L-shape
|
||||
with self.subTest(rects=rects):
|
||||
self.check(union(*rects))
|
||||
|
||||
def test_corner_contact_only_by_dependency_checks(self):
|
||||
# Policy: no geometric ban; accepted iff the direction-specific checks pass.
|
||||
try:
|
||||
pair = union((8, 8, 16, 16), (16, 16, 24, 24))
|
||||
except ValueError as error:
|
||||
self.assertRegex(str(error), "outer ghost|allocation|INNER|surviving|coalesce")
|
||||
else:
|
||||
self.check(pair)
|
||||
|
||||
|
||||
class Negatives(unittest.TestCase):
|
||||
def test_inputs_are_validated_before_conversion(self):
|
||||
for bad in ((8.5, 8, 16, 20), ("8", 8, 16, 20), (True, 8, 16, 20), "abcd", (8, 8, 16)):
|
||||
with self.subTest(bad=bad), self.assertRaises(ValueError):
|
||||
union(bad, B)
|
||||
self.assertEqual(union(tuple(np.int64(v) for v in A), B).bounds, (A, B))
|
||||
pair = union(A, B)
|
||||
for block in ((4.0, 4), (True, 4), (0, 4), (4,), ("4", 4)):
|
||||
with self.subTest(block=block), self.assertRaises(ValueError):
|
||||
pair.fine_layout(block)
|
||||
|
||||
def test_missing_donor_at_domain_margin(self):
|
||||
with self.assertRaisesRegex(ValueError, "margin"):
|
||||
union((1, 8, 10, 20), (10, 8, 20, 20))
|
||||
|
||||
def test_missing_or_duplicate_coalesce_row(self):
|
||||
pair = union(A, B)
|
||||
with self.assertRaisesRegex(ValueError, "lacks its coalesce row"):
|
||||
check_parent_pull_closure(replace(pair, coalesce_coarse=pair.coalesce_coarse[1:],
|
||||
coalesce_fine=pair.coalesce_fine[1:]))
|
||||
doubled = replace(pair, coalesce_coarse=np.r_[pair.coalesce_coarse, pair.coalesce_coarse[:1]],
|
||||
coalesce_fine=np.r_[pair.coalesce_fine, pair.coalesce_fine[:1]])
|
||||
with self.assertRaisesRegex(ValueError, "duplicate"):
|
||||
check_parent_pull_closure(doubled)
|
||||
|
||||
def test_direction_specific_dependency_on_outer_cell(self):
|
||||
pair = union(A, B)
|
||||
active = pair.fine_kind == ACTIVE
|
||||
kind = pair.fine_kind.copy()
|
||||
kind[dilate(active, 2) & ~dilate(active, 1)] = OUTER_GHOST # thin the INNER band
|
||||
with self.assertRaisesRegex(ValueError, "outer ghost"):
|
||||
_transfer_footprint(replace(pair, fine_kind=kind))
|
||||
|
||||
def test_nested_union_child_donors_must_be_parent_active(self):
|
||||
parent = FixedPatchSet2D.from_config(CFG, [(6, 6, 24, 24)]) # L1 ACTIVE 12..48
|
||||
middle = _middle_config(CFG, parent)
|
||||
with self.assertRaisesRegex(ValueError, "donors/receivers"):
|
||||
_nested_kind(parent, UnionPatchSet2D.from_config(middle, [(12, 20, 30, 40), (30, 20, 40, 40)]))
|
||||
child = UnionPatchSet2D.from_config(middle, [(16, 20, 30, 40), (30, 20, 40, 40)])
|
||||
reference = FixedPatchSet2D.from_config(middle, [(16, 20, 40, 40)])
|
||||
self.assertEqual(table_sets(child), table_sets(reference))
|
||||
np.testing.assert_array_equal(_nested_kind(parent, child), _nested_kind(parent, reference))
|
||||
|
||||
|
||||
@unittest.skipUnless(os.environ.get("ADAPTER_DIR"), "set ADAPTER_DIR for the CPU D2Q9 adapter run")
|
||||
class AdapterNumerics(unittest.TestCase):
|
||||
def test_eight_steps_bitwise(self):
|
||||
folder = os.environ["ADAPTER_DIR"]
|
||||
name = os.environ.get("ADAPTER_FILE") or next(
|
||||
n for n in ("multilevel_numeric_adapter.py", "adapter.py")
|
||||
if os.path.exists(os.path.join(folder, n)))
|
||||
path = os.path.join(folder, name)
|
||||
spec = importlib.util.spec_from_file_location("multilevel_numeric_adapter", path)
|
||||
adapter = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(adapter)
|
||||
results = []
|
||||
for pair in (union(A, B), FixedPatchSet2D.from_config(CFG, [U])):
|
||||
kinds = [np.where(pair.covered, OUTER_GHOST, ACTIVE).astype(np.uint8), pair.fine_kind]
|
||||
taus = [pair.tau_coarse, pair.tau_fine]
|
||||
initial = []
|
||||
for level, kind in enumerate(kinds):
|
||||
ny, nx = kind.shape
|
||||
y = (np.arange(ny) + .5) / 2 ** level
|
||||
ux = 1e-3 * np.sin(2 * np.pi * y / 30)[:, None] * np.ones((1, nx))
|
||||
cx = np.array([0, 1, -1, 0, 0, 1, -1, 1, -1], float)[:, None, None]
|
||||
w = np.array([4/9] + [1/9]*4 + [1/36]*4)[:, None, None]
|
||||
g = w * (1 + 3*cx*ux + 4.5*(cx*ux)**2 - 1.5*ux*ux)
|
||||
g[:, kind != ACTIVE] = np.nan
|
||||
initial.append(g)
|
||||
run = adapter.make_scheduler(kinds, taus, [pair], initial)
|
||||
run.step(8)
|
||||
results.append([level.current.copy() for level in run.levels])
|
||||
for a, b in zip(*results):
|
||||
np.testing.assert_array_equal(a, b)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -50,8 +50,8 @@ class MultipatchCPU(unittest.TestCase):
|
||||
dict(fine_block=(5, 4), base_block=(4, 4))):
|
||||
with self.subTest(kw=kw), self.assertRaises(ValueError):
|
||||
FixedPatchStepper(cfg, ((4, 4, 8, 12), (14, 4, 18, 12)), context=context, **kw)
|
||||
with self.assertRaisesRegex(ValueError, "closer"):
|
||||
FixedPatchStepper(cfg, ((4, 4, 8, 12), (10, 4, 14, 12)), context=context,
|
||||
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))
|
||||
from CelerisLab.body.jets import Jet, Parallel, Tube
|
||||
cfg32 = LBMConfig(nx=32, ny=16, viscosity=.1)
|
||||
|
||||
Reference in new issue
Block a user