Skip to content

Commit e6b8ce1

Browse files
committed
additional test
1 parent 738d624 commit e6b8ce1

5 files changed

Lines changed: 282 additions & 0 deletions

File tree

test/conftest.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import zipfile
2+
from pathlib import Path
3+
4+
import pytest
5+
6+
from foam2dolfinx import OpenFOAMReader
7+
8+
9+
@pytest.fixture
10+
def two_regions_reader(tmp_path):
11+
zip_path = Path("test/data/test_2Regions.zip")
12+
extract_path = tmp_path / "test_2Regions"
13+
with zipfile.ZipFile(zip_path, "r") as zf:
14+
zf.extractall(extract_path)
15+
foam_file = extract_path / "test_2Regions/pv.foam"
16+
return OpenFOAMReader(filename=str(foam_file), cell_type=12)

test/test_get_connectivity.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import dolfinx
2+
import numpy as np
3+
import pytest
4+
from pyvista import examples
5+
6+
from foam2dolfinx import OpenFOAMReader
7+
8+
9+
@pytest.fixture
10+
def hex_reader():
11+
return OpenFOAMReader(filename=examples.download_cavity(load=False), cell_type=12)
12+
13+
14+
@pytest.fixture
15+
def tet_reader():
16+
return OpenFOAMReader(filename=examples.download_cavity(load=False), cell_type=10)
17+
18+
19+
@pytest.mark.parametrize(
20+
"cell_type, n_verts, expected_shape",
21+
[(12, 8, "hexahedron"), (10, 4, "tetrahedron")],
22+
)
23+
def test_get_connectivity_returns_correct_shape_name(cell_type, n_verts, expected_shape):
24+
reader = OpenFOAMReader(filename=examples.download_cavity(load=False), cell_type=cell_type)
25+
shape_name, _ = reader._get_connectivity(np.zeros((3, n_verts), dtype=int))
26+
assert shape_name == expected_shape
27+
28+
29+
@pytest.mark.parametrize("cell_type, n_verts", [(12, 8), (10, 4)])
30+
def test_get_connectivity_output_shape_matches_input(cell_type, n_verts):
31+
reader = OpenFOAMReader(filename=examples.download_cavity(load=False), cell_type=cell_type)
32+
cells = np.arange(5 * n_verts).reshape(5, n_verts)
33+
_, connectivity = reader._get_connectivity(cells)
34+
assert connectivity.shape == cells.shape
35+
36+
37+
def test_get_connectivity_raises_for_unsupported_cell_type():
38+
reader = OpenFOAMReader(filename=examples.download_cavity(load=False), cell_type=12)
39+
reader._cell_type = 5
40+
with pytest.raises(ValueError, match="not supported"):
41+
reader._get_connectivity(np.zeros((3, 4), dtype=int))
42+
43+
44+
def test_get_connectivity_hexahedron_applies_vtk_to_dolfinx_permutation(hex_reader):
45+
cells = np.arange(8).reshape(1, 8)
46+
_, connectivity = hex_reader._get_connectivity(cells)
47+
np.testing.assert_array_equal(connectivity[0], [0, 1, 3, 2, 4, 5, 7, 6])
48+
49+
50+
def test_get_connectivity_tetrahedron_sorts_vertices(tet_reader):
51+
cells = np.array([[40, 10, 30, 20]])
52+
_, connectivity = tet_reader._get_connectivity(cells)
53+
np.testing.assert_array_equal(connectivity[0], [10, 20, 30, 40])
54+
55+
56+
def test_build_dolfinx_mesh_returns_dolfinx_mesh(hex_reader):
57+
hex_reader._read_with_pyvista(t=0)
58+
shape, connectivity = hex_reader._get_connectivity(hex_reader.OF_cells_dict["default"])
59+
result = hex_reader._build_dolfinx_mesh(
60+
hex_reader.OF_meshes_dict["default"].points, connectivity, shape
61+
)
62+
assert isinstance(result, dolfinx.mesh.Mesh)
63+
64+
65+
@pytest.mark.parametrize("attr", ["mesh_vector_element", "mesh_scalar_element"])
66+
def test_build_dolfinx_mesh_sets_element_attributes(hex_reader, attr):
67+
hex_reader._read_with_pyvista(t=0)
68+
shape, connectivity = hex_reader._get_connectivity(hex_reader.OF_cells_dict["default"])
69+
hex_reader._build_dolfinx_mesh(
70+
hex_reader.OF_meshes_dict["default"].points, connectivity, shape
71+
)
72+
assert getattr(hex_reader, attr) is not None

test/test_meshtags.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import numpy as np
2+
import pytest
3+
from pyvista import examples
4+
5+
from foam2dolfinx import OpenFOAMReader
6+
7+
8+
# --- create_cell_meshtags: multidomain ---
9+
10+
11+
def test_create_cell_meshtags_dim_equals_mesh_dim(two_regions_reader):
12+
ct = two_regions_reader.create_cell_meshtags()
13+
mesh = two_regions_reader.dolfinx_meshes_dict["_global"]
14+
assert ct.dim == mesh.topology.dim
15+
16+
17+
def test_create_cell_meshtags_multidomain_fluid_count(two_regions_reader):
18+
ct = two_regions_reader.create_cell_meshtags()
19+
assert np.sum(ct.values == 1) == 2100
20+
21+
22+
def test_create_cell_meshtags_multidomain_solid_count(two_regions_reader):
23+
ct = two_regions_reader.create_cell_meshtags()
24+
assert np.sum(ct.values == 2) == 945
25+
26+
27+
def test_create_cell_meshtags_multidomain_no_untagged_cells(two_regions_reader):
28+
ct = two_regions_reader.create_cell_meshtags()
29+
assert np.all(ct.values > 0)
30+
31+
32+
# --- create_cell_meshtags: single domain ---
33+
34+
35+
def test_create_cell_meshtags_single_domain_dim_equals_mesh_dim():
36+
reader = OpenFOAMReader(filename=examples.download_cavity(load=False), cell_type=12)
37+
ct = reader.create_cell_meshtags(t=0)
38+
mesh = reader.dolfinx_meshes_dict["default"]
39+
assert ct.dim == mesh.topology.dim
40+
41+
42+
def test_create_cell_meshtags_single_domain_all_values_are_one():
43+
reader = OpenFOAMReader(filename=examples.download_cavity(load=False), cell_type=12)
44+
ct = reader.create_cell_meshtags(t=0)
45+
assert np.all(ct.values == 1)
46+
47+
48+
# --- create_facet_meshtags: multidomain ---
49+
50+
51+
def test_create_facet_meshtags_dim_equals_fdim(two_regions_reader):
52+
ft = two_regions_reader.create_facet_meshtags()
53+
mesh = two_regions_reader.dolfinx_meshes_dict["_global"]
54+
assert ft.dim == mesh.topology.dim - 1
55+
56+
57+
@pytest.mark.parametrize("tag, expected_count", [(1, 15), (2, 15), (3, 70)])
58+
def test_create_facet_meshtags_boundary_patch_counts(two_regions_reader, tag, expected_count):
59+
ft = two_regions_reader.create_facet_meshtags()
60+
assert np.sum(ft.values == tag) == expected_count
61+
62+
63+
def test_create_facet_meshtags_interface_count(two_regions_reader):
64+
ft = two_regions_reader.create_facet_meshtags()
65+
# interface facets receive the highest tag (assigned after all boundary patches)
66+
assert np.sum(ft.values == ft.values.max()) == 60
67+
68+
69+
def test_create_facet_meshtags_all_tag_values_positive(two_regions_reader):
70+
ft = two_regions_reader.create_facet_meshtags()
71+
assert np.all(ft.values > 0)
72+
73+
74+
# --- create_facet_meshtags: single domain ---
75+
76+
77+
def test_create_facet_meshtags_single_domain_dim_equals_fdim():
78+
reader = OpenFOAMReader(filename=examples.download_cavity(load=False), cell_type=12)
79+
ft = reader.create_facet_meshtags()
80+
mesh = reader.dolfinx_meshes_dict["default"]
81+
assert ft.dim == mesh.topology.dim - 1

test/test_read_with_pyvista.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,48 @@ def test_error_rasied_when_wrong_subdomain_given_in_multidomain_case(tmpdir):
5252
my_of_reader._read_with_pyvista(t=20.0, subdomain="coucou")
5353

5454

55+
def test_read_with_pyvista_no_subdomain_single_domain_populates_cells():
56+
reader = OpenFOAMReader(filename=examples.download_cavity(load=False), cell_type=12)
57+
reader._read_with_pyvista(t=0)
58+
assert "default" in reader.OF_cells_dict
59+
assert reader.OF_cells_dict["default"] is not None
60+
61+
62+
def test_read_with_pyvista_no_subdomain_single_domain_sets_multidomain_false():
63+
reader = OpenFOAMReader(filename=examples.download_cavity(load=False), cell_type=12)
64+
reader._read_with_pyvista(t=0)
65+
assert reader.multidomain is False
66+
67+
68+
def test_read_with_pyvista_no_subdomain_multidomain_populates_all_meshes(
69+
two_regions_reader,
70+
):
71+
two_regions_reader._read_with_pyvista(t=20.0)
72+
assert "fluid" in two_regions_reader.OF_meshes_dict
73+
assert "solid" in two_regions_reader.OF_meshes_dict
74+
75+
76+
def test_read_with_pyvista_no_subdomain_multidomain_excludes_defaultRegion(
77+
two_regions_reader,
78+
):
79+
two_regions_reader._read_with_pyvista(t=20.0)
80+
assert "defaultRegion" not in two_regions_reader.OF_meshes_dict
81+
82+
83+
def test_read_with_pyvista_no_subdomain_multidomain_does_not_populate_cells(
84+
two_regions_reader,
85+
):
86+
two_regions_reader._read_with_pyvista(t=20.0)
87+
assert len(two_regions_reader.OF_cells_dict) == 0
88+
89+
90+
def test_read_with_pyvista_no_subdomain_multidomain_sets_multidomain_true(
91+
two_regions_reader,
92+
):
93+
two_regions_reader._read_with_pyvista(t=20.0)
94+
assert two_regions_reader.multidomain is True
95+
96+
5597
@pytest.mark.parametrize("subdomain", ["fluid", "solid"])
5698
def test_read_with_pyvista_finds_all_mesh_data(tmpdir, subdomain):
5799
zip_path = Path("test/data/test_2Regions.zip")

test/test_tag_boundary_patch.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import dolfinx.mesh
2+
import numpy as np
3+
import pyvista
4+
import pytest
5+
from mpi4py import MPI
6+
from scipy.spatial import cKDTree
7+
from dolfinx.mesh import exterior_facet_indices
8+
9+
from foam2dolfinx.helpers import tag_boundary_patch
10+
11+
12+
@pytest.fixture
13+
def unit_cube_topology():
14+
mesh = dolfinx.mesh.create_box(
15+
MPI.COMM_WORLD, [[0, 0, 0], [1, 1, 1]], [2, 2, 2], dolfinx.mesh.CellType.hexahedron
16+
)
17+
fdim = mesh.topology.dim - 1
18+
mesh.topology.create_connectivity(fdim, 0)
19+
mesh.topology.create_connectivity(0, fdim)
20+
mesh.topology.create_connectivity(fdim, mesh.topology.dim)
21+
facet_indices = exterior_facet_indices(mesh.topology)
22+
c_to_v = mesh.topology.connectivity(fdim, 0)
23+
facet_vertices = np.vstack([c_to_v.links(f) for f in facet_indices])
24+
tree = cKDTree(mesh.geometry.x)
25+
return mesh, tree, facet_indices, facet_vertices
26+
27+
28+
def test_tag_boundary_patch_returns_empty_when_no_points_match(unit_cube_topology):
29+
mesh, tree, facet_indices, facet_vertices = unit_cube_topology
30+
patch = pyvista.PolyData(np.array([[100.0, 100.0, 100.0]]))
31+
matched, tags = tag_boundary_patch(
32+
mesh, patch, 1, tree=tree, facet_indices=facet_indices, facet_vertices=facet_vertices
33+
)
34+
assert len(matched) == 0
35+
assert len(tags) == 0
36+
37+
38+
def test_tag_boundary_patch_tags_equal_patch_id(unit_cube_topology):
39+
mesh, tree, facet_indices, facet_vertices = unit_cube_topology
40+
x0_points = mesh.geometry.x[mesh.geometry.x[:, 0] < 1e-10]
41+
patch = pyvista.PolyData(x0_points)
42+
_, tags = tag_boundary_patch(
43+
mesh, patch, 42, tree=tree, facet_indices=facet_indices, facet_vertices=facet_vertices
44+
)
45+
assert np.all(tags == 42)
46+
47+
48+
def test_tag_boundary_patch_matched_facets_are_subset_of_exterior(unit_cube_topology):
49+
mesh, tree, facet_indices, facet_vertices = unit_cube_topology
50+
x0_points = mesh.geometry.x[mesh.geometry.x[:, 0] < 1e-10]
51+
patch = pyvista.PolyData(x0_points)
52+
matched, _ = tag_boundary_patch(
53+
mesh, patch, 1, tree=tree, facet_indices=facet_indices, facet_vertices=facet_vertices
54+
)
55+
assert np.all(np.isin(matched, facet_indices))
56+
57+
58+
@pytest.mark.parametrize("patch_points", [
59+
np.array([[100.0, 100.0, 100.0]]), # no match
60+
None, # match (x=0 face, filled below)
61+
])
62+
def test_tag_boundary_patch_output_arrays_are_int32(unit_cube_topology, patch_points):
63+
mesh, tree, facet_indices, facet_vertices = unit_cube_topology
64+
if patch_points is None:
65+
patch_points = mesh.geometry.x[mesh.geometry.x[:, 0] < 1e-10]
66+
patch = pyvista.PolyData(patch_points)
67+
matched, tags = tag_boundary_patch(
68+
mesh, patch, 1, tree=tree, facet_indices=facet_indices, facet_vertices=facet_vertices
69+
)
70+
assert matched.dtype == np.int32
71+
assert tags.dtype == np.int32

0 commit comments

Comments
 (0)