Skip to content

Commit 6c900cf

Browse files
authored
Tidy up Submesh (#4999)
* Tidy up Submesh * Make everything a kwarg
1 parent 43a5050 commit 6c900cf

6 files changed

Lines changed: 36 additions & 23 deletions

File tree

firedrake/mesh.py

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4797,22 +4797,27 @@ def SubDomainData(geometric_expr):
47974797
return op2.Subset(m.cell_set, indices)
47984798

47994799

4800-
def Submesh(mesh, subdim, subdomain_id, label_name=None, name=None, ignore_halo=False, reorder=None, comm=None):
4800+
def Submesh(mesh, subdim=None, subdomain_id=None, label_name=None, name=None, ignore_halo=False, reorder=None, comm=None):
48014801
"""Construct a submesh from a given mesh.
48024802
48034803
Parameters
48044804
----------
48054805
mesh : MeshGeometry
48064806
Parent mesh (`MeshGeometry`).
4807-
subdim : int
4807+
subdim : int | None
48084808
Topological dimension of the submesh.
4809+
Defaults to ``mesh.topological_dimension``.
48094810
subdomain_id : int | None
48104811
Subdomain ID representing the submesh.
4811-
`None` defines the submesh owned by the sub-communicator.
4812+
If `None` the submesh will cover the entire domain.
4813+
This is useful to obtain a codim-1 submesh over all facets or
4814+
a submesh over a different communicator.
48124815
label_name : str | None
48134816
Name of the label to search ``subdomain_id`` in.
4817+
Defaults to ``'Cell Sets'`` or ``'Face Sets'`` depending on ``subdim``.
48144818
name : str | None
48154819
Name of the submesh.
4820+
Defaults to ``mesh.name + "_submesh"``·
48164821
ignore_halo : bool
48174822
Whether to exclude the halo from the submesh.
48184823
reorder : bool | None
@@ -4855,24 +4860,24 @@ def Submesh(mesh, subdim, subdomain_id, label_name=None, name=None, ignore_halo=
48554860
raise NotImplementedError("Can not create a submesh of an ``ExtrudedMesh``")
48564861
elif isinstance(mesh.topology, VertexOnlyMeshTopology):
48574862
raise NotImplementedError("Can not create a submesh of a ``VertexOnlyMesh``")
4863+
if subdim is None:
4864+
subdim = mesh.topological_dimension
48584865
plex = mesh.topology_dm
48594866
dim = plex.getDimension()
4860-
if subdim not in [dim, dim - 1]:
4867+
if subdim not in {dim, dim - 1}:
48614868
raise NotImplementedError(f"Found submesh dim ({subdim}) and parent dim ({dim})")
4862-
if label_name is None:
4869+
if subdomain_id is None:
4870+
if label_name is not None:
4871+
raise ValueError("subdomain_id=None requires label_name=None.")
4872+
# Select all entities
4873+
label_name = "depth"
4874+
subdomain_id = subdim
4875+
elif label_name is None:
48634876
if subdim == dim:
48644877
label_name = dmcommon.CELL_SETS_LABEL
48654878
elif subdim == dim - 1:
48664879
label_name = dmcommon.FACE_SETS_LABEL
4867-
if subdomain_id is None:
4868-
# Filter the plex with PETSc's default label (cells owned by comm)
4869-
if label_name != dmcommon.CELL_SETS_LABEL:
4870-
raise ValueError("subdomain_id == None requires label_name == CELL_SETS_LABEL.")
4871-
subplex, sf = plex.filter(sanitizeSubMesh=True, ignoreHalo=ignore_halo, comm=comm)
4872-
dmcommon.submesh_update_facet_labels(plex, subplex)
4873-
dmcommon.submesh_correct_entity_classes(plex, subplex, sf)
4874-
else:
4875-
subplex = dmcommon.submesh_create(plex, subdim, label_name, subdomain_id, ignore_halo, comm=comm)
4880+
subplex = dmcommon.submesh_create(plex, subdim, label_name, subdomain_id, ignore_halo, comm=comm)
48764881

48774882
comm = comm or mesh.comm
48784883
name = name or _generate_default_submesh_name(mesh.name)

firedrake/mg/mesh.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,8 @@ def MeshHierarchy(mesh, refinement_levels,
126126
# Effectively "invert" addOverlap().
127127
# -- The resulting plex is to have the identical data structure as the one before addOverlap().
128128
# This is algorithmically guaranteed.
129-
dm_cell_type, = mesh.dm_cell_types
130129
tdim = mesh.topology_dm.getDimension()
131-
cdm = dmcommon.submesh_create(mesh.topology_dm, tdim, "celltype", dm_cell_type, True)
130+
cdm = dmcommon.submesh_create(mesh.topology_dm, tdim, "depth", tdim, True)
132131
cdm.removeLabel("pyop2_core")
133132
cdm.removeLabel("pyop2_owned")
134133
cdm.removeLabel("pyop2_ghost")

firedrake/mg/netgen.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,7 @@ def NetgenHierarchy(mesh, levs, flags, distribution_parameters=None):
265265
)
266266
mesh = reconstruct_mesh(mesh, coordinates)
267267
# Make a plex (cdm) without overlap.
268-
dm_cell_type, = mesh.dm_cell_types
269-
cdm = dmcommon.submesh_create(mesh.topology_dm, tdim, "celltype", dm_cell_type, True)
268+
cdm = dmcommon.submesh_create(mesh.topology_dm, tdim, "depth", tdim, True)
270269
cdm.removeLabel("pyop2_core")
271270
cdm.removeLabel("pyop2_owned")
272271
cdm.removeLabel("pyop2_ghost")

firedrake/preconditioners/bddc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def local_mesh(mesh):
199199
return cache[key]
200200
except KeyError:
201201
if mesh.comm.size > 1:
202-
submesh = Submesh(mesh, mesh.topological_dimension, None, ignore_halo=True, reorder=False, comm=COMM_SELF)
202+
submesh = Submesh(mesh, ignore_halo=True, comm=COMM_SELF)
203203
else:
204204
submesh = None
205205
return cache.setdefault(key, submesh)

tests/firedrake/submesh/test_submesh_comm.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@ def assert_local_equality(A, Asub, V, Vsub):
2828
@pytest.mark.parametrize("reorder", [False, True])
2929
@pytest.mark.parametrize("ignore_halo", [False, True])
3030
def test_create_submesh_comm_self(reorder, ignore_halo):
31-
subdomain_id = None
3231
nx = 4
3332
mesh = UnitSquareMesh(nx, nx, quadrilateral=True, reorder=reorder, distribution_parameters={"overlap_type": (DistributedMeshOverlapType.VERTEX, 1)})
34-
submesh = Submesh(mesh, mesh.topological_dimension, subdomain_id, ignore_halo=ignore_halo, reorder=reorder, comm=COMM_SELF)
33+
submesh = Submesh(mesh, ignore_halo=ignore_halo, reorder=reorder, comm=COMM_SELF)
3534
assert submesh.submesh_parent is mesh
3635
assert submesh.comm.size == 1
3736
# Submesh on COMM_SELF should not have halo
@@ -49,13 +48,12 @@ def test_create_submesh_comm_self(reorder, ignore_halo):
4948
@pytest.mark.parametrize("family,degree", [("DG", 0), ("CG", 1)])
5049
@pytest.mark.parametrize("reorder", [False, True])
5150
def test_assemble_submesh_comm_self(family, degree, reorder):
52-
subdomain_id = None
5351
nx = 6
5452
ny = 5
5553
px = -np.cos(np.linspace(0, np.pi, nx))
5654
py = -np.cos(np.linspace(0, np.pi, ny))
5755
mesh = TensorRectangleMesh(px, py, reorder=reorder)
58-
submesh = Submesh(mesh, mesh.topological_dimension, subdomain_id, ignore_halo=True, reorder=reorder, comm=COMM_SELF)
56+
submesh = Submesh(mesh, ignore_halo=True, reorder=reorder, comm=COMM_SELF)
5957

6058
Vsub = FunctionSpace(submesh, family, degree)
6159
Asub = assemble(inner(TrialFunction(Vsub), TestFunction(Vsub))*dx)

tests/firedrake/submesh/test_submesh_facet.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,15 @@ def test_submesh_facet_corner_case_2():
122122
facet_value = 999
123123
mesh = RelabeledMesh(mesh, [facet_function], [facet_value])
124124
_ = Submesh(mesh, mesh.topological_dimension - 1, facet_value)
125+
126+
127+
def test_submesh_facet_all_facets():
128+
mesh = UnitCubeMesh(2, 2, 2)
129+
submesh1 = Submesh(mesh, mesh.topological_dimension - 1)
130+
131+
V = FunctionSpace(mesh, "HDiv Trace", 0)
132+
facet_function = Function(V).assign(1)
133+
facet_value = 999
134+
rmesh = RelabeledMesh(mesh, [facet_function], [facet_value])
135+
submesh2 = Submesh(rmesh, mesh.topological_dimension - 1, facet_value)
136+
assert submesh2.cell_set.size == submesh1.cell_set.size

0 commit comments

Comments
 (0)