Skip to content

Commit b05f0f5

Browse files
committed
support labels on COMM_SELF
1 parent d3a06a6 commit b05f0f5

File tree

2 files changed

+59
-25
lines changed

2 files changed

+59
-25
lines changed

firedrake/mesh.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4818,24 +4818,21 @@ def Submesh(mesh, subdim, subdomain_id, label_name=None, name=None, ignore_halo=
48184818
raise NotImplementedError("Can not create a submesh of a ``VertexOnlyMesh``")
48194819
plex = mesh.topology_dm
48204820
dim = plex.getDimension()
4821+
if subdim not in [dim, dim - 1]:
4822+
raise NotImplementedError(f"Found submesh dim ({subdim}) and parent dim ({dim})")
4823+
if label_name is None:
4824+
if subdim == dim:
4825+
label_name = dmcommon.CELL_SETS_LABEL
4826+
elif subdim == dim - 1:
4827+
label_name = dmcommon.FACE_SETS_LABEL
48214828
if subdomain_id is None:
48224829
# Filter the plex with PETSc's default label (cells owned by comm)
4823-
if label_name is not None:
4824-
raise ValueError("subdomain_id == None requires label_name == None.")
4825-
if subdim != dim:
4826-
raise NotImplementedError(f"Found submesh dim ({subdim}) and parent dim ({dim})")
4827-
subplex, _ = plex.filter(sanitizeSubMesh=True, ignoreHalo=ignore_halo, comm=comm)
4830+
if label_name != dmcommon.CELL_SETS_LABEL:
4831+
raise ValueError("subdomain_id == None requires label_name == CELL_SETS_LABEL.")
4832+
subplex, sf = plex.filter(sanitizeSubMesh=True, ignoreHalo=ignore_halo, comm=comm)
48284833
dmcommon.submesh_update_facet_labels(plex, subplex)
4834+
dmcommon.submesh_correct_entity_classes(plex, subplex, sf)
48294835
else:
4830-
if comm is not None and comm != mesh.comm:
4831-
raise NotImplementedError("Submesh on sub-communicator not implemented on cell subsets.")
4832-
if subdim not in [dim, dim - 1]:
4833-
raise NotImplementedError(f"Found submesh dim ({subdim}) and parent dim ({dim})")
4834-
if label_name is None:
4835-
if subdim == dim:
4836-
label_name = dmcommon.CELL_SETS_LABEL
4837-
elif subdim == dim - 1:
4838-
label_name = dmcommon.FACE_SETS_LABEL
48394836
subplex = dmcommon.submesh_create(plex, subdim, label_name, subdomain_id, ignore_halo, comm=comm)
48404837

48414838
comm = comm or mesh.comm
Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
import pytest
22
import numpy as np
33
from firedrake import *
4+
from firedrake.petsc import PETSc
5+
6+
7+
def assert_local_equality(A, B):
8+
i0, j0, v0 = A.getValuesCSR()
9+
i1, j1, v1 = B.getValuesCSR()
10+
j0 -= A.createVecs()[0].getOwnershipRange()[0]
11+
j1 -= B.createVecs()[0].getOwnershipRange()[0]
12+
assert np.array_equal(i0, i1)
13+
assert np.array_equal(j0, j1)
14+
assert np.allclose(v0, v1)
415

516

617
@pytest.mark.parallel([1, 3])
718
def test_create_submesh_comm_self():
8-
comm = COMM_SELF
919
subdomain_id = None
1020
nx = 4
1121
mesh = UnitSquareMesh(nx, nx, quadrilateral=True, reorder=False)
12-
submesh = Submesh(mesh, mesh.topological_dimension, subdomain_id, ignore_halo=True, comm=comm, reorder=False)
22+
submesh = Submesh(mesh, mesh.topological_dimension, subdomain_id, ignore_halo=True, reorder=False, comm=COMM_SELF)
1323
assert submesh.submesh_parent is mesh
1424
assert submesh.comm.size == 1
1525
assert submesh.cell_set.size == mesh.cell_set.size
@@ -18,24 +28,51 @@ def test_create_submesh_comm_self():
1828

1929
@pytest.mark.parallel([1, 3])
2030
def test_assemble_submesh_comm_self():
21-
comm = COMM_SELF
2231
subdomain_id = None
2332
nx = 6
2433
ny = 5
2534
px = -np.cos(np.linspace(0, np.pi, nx))
2635
py = -np.cos(np.linspace(0, np.pi, ny))
2736
mesh = TensorRectangleMesh(px, py, reorder=False)
28-
submesh = Submesh(mesh, mesh.topological_dimension, subdomain_id, ignore_halo=True, comm=comm, reorder=False)
37+
submesh = Submesh(mesh, mesh.topological_dimension, subdomain_id, ignore_halo=True, reorder=False, comm=COMM_SELF)
38+
39+
Vsub = FunctionSpace(submesh, "DG", 0)
40+
Asub = assemble(inner(TrialFunction(Vsub), TestFunction(Vsub))*dx)
2941

3042
V = FunctionSpace(mesh, "DG", 0)
3143
A = assemble(inner(TrialFunction(V), TestFunction(V))*dx)
44+
assert_local_equality(A.petscmat, Asub.petscmat)
45+
46+
47+
@pytest.mark.parallel([1, 3])
48+
@pytest.mark.parametrize("label", ["some", "all"])
49+
def test_label_submesh_comm_self(label):
50+
subdomain_id = 999
51+
nx = 8
52+
mesh = UnitSquareMesh(nx, nx, reorder=False)
53+
54+
M = FunctionSpace(mesh, "DG", 0)
55+
marker = Function(M)
56+
if label == "some":
57+
x, y = SpatialCoordinate(mesh)
58+
marker.interpolate(conditional(Or(x > 0.5, y > 0.5), 1, 0))
59+
elif label == "all":
60+
marker.assign(1)
61+
else:
62+
raise ValueError(f"Unrecognized label {label}")
63+
64+
mesh = RelabeledMesh(mesh, [marker], [subdomain_id])
65+
submesh = Submesh(mesh, mesh.topological_dimension, subdomain_id, ignore_halo=True, reorder=False, comm=COMM_SELF)
3266

3367
Vsub = FunctionSpace(submesh, "DG", 0)
34-
Asub = assemble(inner(TrialFunction(Vsub), TestFunction(Vsub))*dx)
68+
Asub = assemble(inner(TrialFunction(Vsub), TestFunction(Vsub)) * dx)
3569

36-
i0, j0, v0 = A.petscmat.getValuesCSR()
37-
j0 -= V.dof_dset.layout_vec.getOwnershipRange()[0]
38-
i1, j1, v1 = Asub.petscmat.getValuesCSR()
39-
assert np.array_equal(i0, i1)
40-
assert np.array_equal(j0, j1)
41-
assert np.allclose(v0, v1)
70+
V = FunctionSpace(mesh, "DG", 0)
71+
A = assemble(inner(TrialFunction(V), TestFunction(V)) * dx)
72+
if label == "all":
73+
assert_local_equality(A.petscmat, Asub.petscmat)
74+
else:
75+
lgmap = V.dof_dset.lgmap
76+
indices = PETSc.IS().createGeneral(lgmap.apply(np.flatnonzero(marker.dat.data).astype(PETSc.IntType)))
77+
Amat = A.petscmat.createSubMatrix(indices, indices)
78+
assert_local_equality(Amat, Asub.petscmat)

0 commit comments

Comments
 (0)