Commit 8e196bc9 authored by René Fritze's avatar René Fritze Committed by René Fritze

[test] move grid fixtures and tests to hypothesis

parent 64daf399
......@@ -5,10 +5,11 @@
import numpy as np
import pytest
from hypothesis import given, settings
from pymor.discretizers.builtin.grids.interfaces import ReferenceElement
from pymortests.base import runmodule
from pymortests.fixtures.grid import grid, grid_with_orthogonal_centers
from pymortests.fixtures.grid import hy_grid, hy_grid_with_orthogonal_centers
# monkey np.testing.assert_allclose to behave the same as np.allclose
# for some reason, the default atol of np.testing.assert_allclose is 0
......@@ -22,6 +23,7 @@ def monkey_allclose(a, b, rtol=1.e-5, atol=1.e-8):
np.testing.assert_allclose = monkey_allclose
@given(hy_grid)
def test_reference_element_wrong_arguments(grid):
g = grid
with pytest.raises(AssertionError):
......@@ -30,18 +32,21 @@ def test_reference_element_wrong_arguments(grid):
g.reference_element(g.dim + 1)
@given(hy_grid)
def test_reference_element_type(grid):
g = grid
for d in range(g.dim + 1):
assert isinstance(g.reference_element(d), ReferenceElement)
@given(hy_grid)
def test_reference_element_transitivity(grid):
g = grid
for d in range(1, g.dim + 1):
assert g.reference_element(d) is g.reference_element(0).sub_reference_element(d)
@given(hy_grid)
def test_embeddings_wrong_arguments(grid):
g = grid
with pytest.raises(AssertionError):
......@@ -50,6 +55,7 @@ def test_embeddings_wrong_arguments(grid):
g.embeddings(g.dim + 1)
@given(hy_grid)
def test_embeddings_shape(grid):
g = grid
for d in range(g.dim + 1):
......@@ -60,6 +66,8 @@ def test_embeddings_shape(grid):
assert B.shape == (g.size(d), g.dim)
@settings(deadline=None)
@given(hy_grid)
def test_embeddings_transitivity(grid):
g = grid
for d in range(1, g.dim + 1):
......@@ -73,6 +81,7 @@ def test_embeddings_transitivity(grid):
np.testing.assert_allclose(BD[e], np.dot(AD1[SE[e, 0]], BSUB[SEI[e, 0]]) + BD1[SE[e, 0]])
@given(hy_grid)
def test_jacobian_inverse_transposed_wrong_arguments(grid):
g = grid
with pytest.raises(AssertionError):
......@@ -83,12 +92,16 @@ def test_jacobian_inverse_transposed_wrong_arguments(grid):
g.jacobian_inverse_transposed(g.dim)
@settings(deadline=None)
@given(hy_grid)
def test_jacobian_inverse_transposed_shape(grid):
g = grid
for d in range(g.dim):
assert g.jacobian_inverse_transposed(d).shape == (g.size(d), g.dim, g.dim - d)
@settings(deadline=None)
@given(hy_grid)
def test_jacobian_inverse_transposed_values(grid):
g = grid
for d in range(g.dim):
......@@ -98,6 +111,7 @@ def test_jacobian_inverse_transposed_values(grid):
np.testing.assert_allclose(JIT[e], np.linalg.pinv(A[e]).T)
@given(hy_grid)
def test_integration_elements_wrong_arguments(grid):
g = grid
with pytest.raises(AssertionError):
......@@ -106,12 +120,15 @@ def test_integration_elements_wrong_arguments(grid):
g.integration_elements(g.dim + 1)
@given(hy_grid)
def test_integration_elements_shape(grid):
g = grid
for d in range(g.dim):
assert g.integration_elements(d).shape == (g.size(d),)
@settings(deadline=500)
@given(hy_grid)
def test_integration_elements_values(grid):
g = grid
for d in range(g.dim - 1):
......@@ -122,6 +139,7 @@ def test_integration_elements_values(grid):
np.testing.assert_allclose(g.integration_elements(g.dim), 1)
@given(hy_grid)
def test_volumes_wrong_arguments(grid):
g = grid
with pytest.raises(AssertionError):
......@@ -130,12 +148,14 @@ def test_volumes_wrong_arguments(grid):
g.volumes(g.dim + 1)
@given(hy_grid)
def test_volumes_shape(grid):
g = grid
for d in range(g.dim):
assert g.volumes(d).shape == (g.size(d),)
@given(hy_grid)
def test_volumes_values(grid):
g = grid
for d in range(g.dim - 1):
......@@ -144,6 +164,7 @@ def test_volumes_values(grid):
np.testing.assert_allclose(V, IE * g.reference_element(d).volume)
@given(hy_grid)
def test_volumes_inverse_wrong_arguments(grid):
g = grid
with pytest.raises(AssertionError):
......@@ -152,12 +173,14 @@ def test_volumes_inverse_wrong_arguments(grid):
g.volumes_inverse(g.dim + 1)
@given(hy_grid)
def test_volumes_inverse_shape(grid):
g = grid
for d in range(g.dim):
assert g.volumes_inverse(d).shape == (g.size(d),)
@given(hy_grid)
def test_volumes_inverse_values(grid):
g = grid
for d in range(g.dim - 1):
......@@ -166,18 +189,23 @@ def test_volumes_inverse_values(grid):
np.testing.assert_allclose(VI, np.reciprocal(V))
@given(hy_grid)
def test_unit_outer_normals_shape(grid):
g = grid
SE = g.subentities(0, 1)
assert g.unit_outer_normals().shape == SE.shape + (g.dim,)
@settings(deadline=None)
@given(hy_grid)
def test_unit_outer_normals_normed(grid):
g = grid
UON = g.unit_outer_normals()
np.testing.assert_allclose(np.sum(UON ** 2, axis=-1), 1)
@settings(deadline=None)
@given(hy_grid)
def test_unit_outer_normals_normal(grid):
g = grid
SE = g.subentities(0, 1)
......@@ -187,6 +215,8 @@ def test_unit_outer_normals_normal(grid):
np.testing.assert_allclose(np.sum(SEE * UON[..., np.newaxis], axis=-2), 0)
@settings(deadline=None)
@given(hy_grid)
def test_unit_outer_normals_neighbours(grid):
g = grid
UON = g.unit_outer_normals()
......@@ -200,6 +230,7 @@ def test_unit_outer_normals_neighbours(grid):
np.testing.assert_allclose(UON[se[0], sei[0]], -UON[se[1], sei[1]])
@given(hy_grid)
def test_centers_wrong_arguments(grid):
g = grid
with pytest.raises(AssertionError):
......@@ -208,12 +239,14 @@ def test_centers_wrong_arguments(grid):
g.centers(g.dim + 1)
@given(hy_grid)
def test_centers_shape(grid):
g = grid
for d in range(g.dim):
assert g.centers(d).shape == (g.size(d), g.dim)
@given(hy_grid)
def test_centers_values(grid):
g = grid
for d in range(g.dim):
......@@ -221,6 +254,7 @@ def test_centers_values(grid):
np.testing.assert_allclose(g.centers(d), B + A.dot(g.reference_element(d).center()))
@given(hy_grid)
def test_diameters_wrong_arguments(grid):
g = grid
with pytest.raises(AssertionError):
......@@ -229,18 +263,21 @@ def test_diameters_wrong_arguments(grid):
g.diameters(g.dim + 1)
@given(hy_grid)
def test_diameters_shape(grid):
g = grid
for d in range(g.dim):
assert g.diameters(d).shape == (g.size(d),)
@given(hy_grid)
def test_diameters_non_negative(grid):
g = grid
for d in range(g.dim - 1):
assert np.min(g.diameters(d)) >= 0
@given(hy_grid)
def test_diameters_values(grid):
g = grid
for d in range(g.dim - 1):
......@@ -248,6 +285,7 @@ def test_diameters_values(grid):
np.testing.assert_allclose(g.diameters(d), g.reference_element(d).mapped_diameter(A))
@given(hy_grid)
def test_quadrature_points_wrong_arguments(grid):
g = grid
for d in range(g.dim):
......@@ -263,6 +301,7 @@ def test_quadrature_points_wrong_arguments(grid):
g.quadrature_points(d, npoints=max(ps[t]) + 1, quadrature_type=t)
@given(hy_grid)
def test_quadrature_points_shape(grid):
g = grid
for d in range(g.dim):
......@@ -273,6 +312,7 @@ def test_quadrature_points_shape(grid):
assert g.quadrature_points(d, npoints=p, quadrature_type=t).shape == (g.size(d), p, g.dim)
@given(hy_grid)
def test_quadrature_points_values(grid):
g = grid
for d in range(g.dim):
......@@ -286,6 +326,7 @@ def test_quadrature_points_values(grid):
np.testing.assert_allclose(Q, B[:, np.newaxis, :] + np.einsum('eij,qj->eqi', A, q))
@given(hy_grid)
def test_bounding_box(grid):
g = grid
bbox = g.bounding_box()
......@@ -295,6 +336,8 @@ def test_bounding_box(grid):
assert np.all(g.centers(g.dim) <= bbox[1])
@settings(deadline=None)
@given(hy_grid_with_orthogonal_centers)
def test_orthogonal_centers(grid_with_orthogonal_centers):
g = grid_with_orthogonal_centers
C = g.orthogonal_centers()
......@@ -309,5 +352,6 @@ def test_orthogonal_centers(grid_with_orthogonal_centers):
SPROD = EMB[s].dot(SEGMENT)
np.testing.assert_allclose(SPROD, 0)
if __name__ == "__main__":
runmodule(filename=__file__)
......@@ -3,8 +3,7 @@
# License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
import math as m
import random
from hypothesis import strategies as hyst
import numpy as np
import pytest
......@@ -15,99 +14,57 @@ from pymor.discretizers.builtin.grids.tria import TriaGrid
from pymor.discretizers.builtin.grids.unstructured import UnstructuredTriangleGrid
rect_grid_generators = [lambda arg=arg, kwargs=kwargs: RectGrid(arg, **kwargs) for arg, kwargs in
[((2, 4), {}),
((1, 1), {}),
((42, 42), {}),
((2, 4), dict(identify_left_right=True)),
((2, 4), dict(identify_bottom_top=True)),
((2, 4), dict(identify_left_right=True, identify_bottom_top=True)),
((2, 1), dict(identify_left_right=True)),
((1, 2), dict(identify_bottom_top=True)),
((2, 2), dict(identify_left_right=True, identify_bottom_top=True)),
((42, 30), dict(identify_left_right=True)),
((42, 30), dict(identify_bottom_top=True)),
((42, 30), dict(identify_left_right=True, identify_bottom_top=True))]]
# TODO let domain be drawn too
def hy_rect_tria_kwargs(draw):
identify_left_right = draw(hyst.booleans())
identify_bottom_top = draw(hyst.booleans())
interval_i = hyst.integers(min_value=1, max_value=42)
num_intervals = draw(hyst.tuples(interval_i.filter(lambda x: (not identify_left_right) or x > 1),
interval_i.filter(lambda y: (not identify_bottom_top) or y > 1)))
# domain_value = hyst.floats(allow_infinity=False, allow_nan=False)
# domain_point = hyst.tuples(domain_value, domain_value)
# domain = draw(hyst.tuples(domain_point, domain_point).filter(lambda d: d[0][0] < d[1][0] and d[0][1] < d[1][1]))
domain = ((0,0), (1,1))
return {"num_intervals": num_intervals, "domain": domain, "identify_left_right": identify_left_right,
"identify_bottom_top": identify_bottom_top}
@hyst.composite
def hy_rect_grid(draw):
return RectGrid(**hy_rect_tria_kwargs(draw))
tria_grid_generators = [lambda arg=arg, kwargs=kwargs: TriaGrid(arg, **kwargs) for arg, kwargs in
[((2, 4), {}),
((1, 1), {}),
((42, 42), {}),
((2, 4), dict(identify_left_right=True)),
((2, 4), dict(identify_bottom_top=True)),
((2, 4), dict(identify_left_right=True, identify_bottom_top=True)),
((2, 1), dict(identify_left_right=True)),
((1, 2), dict(identify_bottom_top=True)),
((2, 2), dict(identify_left_right=True, identify_bottom_top=True)),
((42, 30), dict(identify_left_right=True)),
((42, 30), dict(identify_bottom_top=True)),
((42, 30), dict(identify_left_right=True, identify_bottom_top=True))]]
@hyst.composite
def hy_tria_grid(draw):
return RectGrid(**hy_rect_tria_kwargs(draw))
oned_grid_generators = [lambda kwargs=kwargs: OnedGrid(**kwargs) for kwargs in
[dict(domain=np.array((-2, 2)), num_intervals=10),
dict(domain=np.array((-4, -2)), num_intervals=100),
dict(domain=np.array((-4, -2)), num_intervals=100, identify_left_right=True),
dict(domain=np.array((2, 3)), num_intervals=10),
dict(domain=np.array((2, 3)), num_intervals=10, identify_left_right=True),
dict(domain=np.array((1, 2)), num_intervals=10000)]]
unstructured_grid_generators = \
[lambda: UnstructuredTriangleGrid.from_vertices(np.array([[0, 0], [-1, -1], [1, -1], [1, 1], [-1, 1]]),
np.array([[0, 1, 2], [0, 3, 4], [0, 4, 1]]))]
@hyst.composite
def hy_oned_grid(draw):
identify_left_right = draw(hyst.booleans())
interval_i = hyst.integers(min_value=1, max_value=10000)
num_intervals = draw(interval_i.filter(lambda x: (not identify_left_right) or x > 1))
domain_point = hyst.floats(allow_infinity=False, allow_nan=False)
domain = draw(hyst.tuples(domain_point, domain_point).filter(lambda d: d[0] < d[1]))
return OnedGrid(num_intervals=num_intervals, domain=domain, identify_left_right=identify_left_right)
def subgrid_factory(grid_generator, neq, seed):
np.random.seed(seed)
g = grid_generator()
# TODO re-use other grid strategies
@hyst.composite
def hy_subgrid(draw):
grid = draw(hyst.sampled_from([RectGrid((1, 1)), TriaGrid((1, 1)), RectGrid((8, 8)), TriaGrid((24, 24))]))
neq = draw(hyst.sampled_from([0, 2, 4]))
if neq == 0:
return SubGrid(g, np.arange(g.size(0), dtype=np.int32))
return SubGrid(grid, np.arange(grid.size(0), dtype=np.int32))
else:
return SubGrid(g, np.array(random.sample(range(g.size(0)), max(int(m.floor(g.size(0) / neq)), 1))))
subgrid_generators = [lambda args=args: subgrid_factory(*args) for args in
[(lambda: RectGrid((1, 1)), 0, 123),
(lambda: RectGrid((1, 1)), 2, 123),
(lambda: RectGrid((1, 1)), 4, 123),
(lambda: TriaGrid((1, 1)), 0, 123),
(lambda: TriaGrid((1, 1)), 2, 123),
(lambda: TriaGrid((1, 1)), 4, 123),
(lambda: RectGrid((8, 8)), 0, 123),
(lambda: RectGrid((8, 8)), 2, 123),
(lambda: RectGrid((8, 8)), 4, 123),
(lambda: TriaGrid((24, 24)), 0, 123),
(lambda: TriaGrid((24, 24)), 2, 123),
(lambda: TriaGrid((24, 24)), 4, 123)]]
@pytest.fixture(params=(
rect_grid_generators
+ tria_grid_generators
+ oned_grid_generators
+ subgrid_generators
+ unstructured_grid_generators
))
def grid(request):
return request.param()
@pytest.fixture(params=(rect_grid_generators + tria_grid_generators))
def rect_or_tria_grid(request):
return request.param()
@pytest.fixture(params=(rect_grid_generators + oned_grid_generators))
def grid_with_orthogonal_centers(request):
return request.param()
random = draw(hyst.randoms())
sample = random.sample(range(grid.size(0)), max(int(m.floor(grid.size(0) / neq)), 1))
return SubGrid(grid, np.array(sample))
@pytest.fixture(params=(
rect_grid_generators
+ tria_grid_generators
+ oned_grid_generators
+ unstructured_grid_generators
))
def grids_with_visualize(request):
return request.param()
hy_grid = hy_rect_grid() | hy_tria_grid() | hy_oned_grid() | hy_subgrid()
hy_rect_or_tria_grid = hy_rect_grid() | hy_tria_grid()
hy_unstructured_grid = hyst.just(UnstructuredTriangleGrid.from_vertices(
np.array([[0, 0], [-1, -1], [1, -1], [1, 1], [-1, 1]]), np.array([[0, 1, 2], [0, 3, 4], [0, 4, 1]])))
hy_grid_with_orthogonal_centers = hy_rect_grid() | hy_oned_grid()
hy_grids_with_visualize = hy_rect_grid() | hy_tria_grid() | hy_oned_grid() | hy_unstructured_grid
This diff is collapsed.
......@@ -7,10 +7,12 @@ import numpy as np
import pytest
import itertools
from hypothesis import given
from pymor.core.logger import getLogger
from pymor.tools.io import SafeTemporaryFileName
from pymortests.base import runmodule
from pymortests.fixtures.grid import rect_or_tria_grid
from pymortests.fixtures.grid import hy_rect_or_tria_grid
from pymor.discretizers.builtin.grids.vtkio import write_vtk
from pymor.discretizers.builtin.quadratures import GaussQuadratures
from pymor.tools.deprecated import Deprecated
......@@ -101,8 +103,8 @@ def test_float_cmp():
assert not float_cmp(-inf, inf, rtol, atol), msg
def test_vtkio(rect_or_tria_grid):
grid = rect_or_tria_grid
@given(hy_rect_or_tria_grid)
def test_vtkio(grid):
steps = 4
for dim in range(1, 2):
for codim, data in enumerate((NumpyVectorSpace.from_numpy(np.zeros((steps, grid.size(c))))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment