Skip to content

Commit d54ead6

Browse files
committed
tests: Expand testing for Border, refactor, and bugfix
1 parent 5c5591a commit d54ead6

2 files changed

Lines changed: 82 additions & 20 deletions

File tree

devito/types/grid.py

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,7 +1071,7 @@ def _parse_border(border: BorderSpec, grid: Grid) -> ParsedBorderSpec:
10711071
if not len(border) == len(grid.dimensions):
10721072
raise ValueError("Length of border thickness specification should "
10731073
"match number of dimensions")
1074-
retval = [] # FIXME: make a better name later
1074+
retval = []
10751075
for b, d in zip(border, grid.dimensions):
10761076
if isinstance(b, tuple):
10771077
if not len(b) == 2:
@@ -1157,22 +1157,17 @@ def _build_domains_nooverlap(self, grid: Grid) -> tuple[int, tuple[np.ndarray]]:
11571157
domain_map[d] = (CENTER,)
11581158
interval_map[d] = {CENTER: (0, 0)}
11591159

1160-
# Get the cartesian product, then remove any which solely consist of
1161-
# the central region. The sides are used to make this step more
1162-
# straightforward.
1163-
abstract_domains = list(product(*domain_map.values()))
1164-
for d in abstract_domains:
1165-
if all(i == CENTER for i in d):
1166-
abstract_domains.remove(d)
1167-
1168-
# If 'no corners' option selected, then remove any corners
1169-
if self.corners == 'nocorners' and not any(i == CENTER for i in d):
1170-
abstract_domains.remove(d)
1171-
1160+
# Get the cartesian product, then select the required domains. The sides are used
1161+
# to make this step more straightforward.
1162+
maybe_domains = list(product(*domain_map.values()))
11721163
domains = []
1173-
for dom in abstract_domains:
1174-
domains.append([interval_map[d][i]
1175-
for d, i in zip(grid.dimensions, dom)])
1164+
for d in maybe_domains:
1165+
if not all(i == CENTER for i in d):
1166+
# Don't add any domains that are completely centered
1167+
if self.corners != 'nocorners' or any(i == CENTER for i in d):
1168+
# Don't add corners if 'no corners' option selected
1169+
domains.append([interval_map[dim][dom] for (dim, dom)
1170+
in zip(grid.dimensions, d)])
11761171

11771172
domains = np.array(domains)
11781173

tests/test_subdomains.py

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -726,11 +726,78 @@ class Dummy(SubDomainSet):
726726

727727

728728
class TestBorder:
729+
def test_exceptions(self):
730+
"""Test exceptions are raised for malformed specifications"""
731+
grid = Grid(shape=(5,))
732+
733+
with pytest.raises(ValueError):
734+
_ = Border(grid, (1, 1))
735+
736+
with pytest.raises(ValueError):
737+
_ = Border(grid, ((1, 1, 1),))
738+
739+
@pytest.mark.parametrize('corners', ['nooverlap', 'overlap', 'nocorners'])
740+
def test_uneven_border(self, corners):
741+
"""Test border specifications which vary by dimension"""
742+
shape = (6, 8)
743+
grid = Grid(shape=shape)
744+
x, y = grid.dimensions
745+
746+
border = Border(grid, (1, (2, 1)), corners=corners)
747+
748+
f = Function(name='f', grid=grid, dtype=np.int32)
749+
750+
eq = Eq(f, f+1, subdomain=border)
751+
752+
Operator(eq)()
753+
754+
check = np.ones(shape)
755+
check[1:-1, 2:-1] = 0
756+
757+
if corners == 'nocorners':
758+
check[0, :2] = 0
759+
check[-1, :2] = 0
760+
check[0, -1] = 0
761+
check[-1, -1] = 0
762+
elif corners == 'overlap':
763+
check[0, :2] = 2
764+
check[-1, :2] = 2
765+
check[0, -1] = 2
766+
check[-1, -1] = 2
767+
768+
assert np.all(f.data == check)
769+
770+
@pytest.mark.parametrize('corners', ['nooverlap', 'overlap', 'nocorners'])
771+
def test_one_sided_border(self, corners):
772+
"""Test borders where a particular side is specified"""
773+
shape = (6, 8)
774+
grid = Grid(shape=shape)
775+
x, y = grid.dimensions
776+
777+
# border = Border(grid, 2, dims={x: x, y: 'right'})
778+
border = Border(grid, 1, dims={x: 'left', y: 'right'}, corners=corners)
779+
780+
f = Function(name='f', grid=grid, dtype=np.int32)
781+
782+
eq = Eq(f, f+1, subdomain=border)
783+
784+
Operator(eq)()
785+
786+
check = np.zeros(shape)
787+
check[0, :] = 1
788+
check[:, -1] = 1
789+
790+
if corners == 'overlap':
791+
check[0, -1] = 2
792+
elif corners == 'nocorners':
793+
check[0, 0] = 0
794+
check[0, -1] = 0
795+
check[-1, -1] = 0
796+
797+
assert np.all(f.data == check)
798+
729799
def test_border_3d(self):
730-
"""
731-
Test the functionality of the Border class in higher dimensions.
732-
Note that this class is also covered by doctests and examples.
733-
"""
800+
"""Test the functionality of the Border class in higher dimensions"""
734801
grid = Grid(shape=(3, 3, 3))
735802

736803
border = Border(grid, 1)

0 commit comments

Comments
 (0)