Skip to content

Commit 926925d

Browse files
committed
Submesh: support tuple subdomain_id
1 parent 951bcd2 commit 926925d

2 files changed

Lines changed: 34 additions & 3 deletions

File tree

firedrake/mesh.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4806,10 +4806,11 @@ def Submesh(mesh, subdim=None, subdomain_id=None, label_name=None, name=None, ig
48064806
subdim : int | None
48074807
Topological dimension of the submesh.
48084808
Defaults to ``mesh.topological_dimension``.
4809-
subdomain_id : int | None
4809+
subdomain_id : int | Sequence | None
48104810
Subdomain ID representing the submesh.
4811-
If `None` the submesh will cover the entire domain.
4812-
This is useful to obtain a codim-1 submesh over all facets or
4811+
If multiple subdomain IDs are provided, their union is taken.
4812+
If `None` the submesh will cover the entire domain,
4813+
this is useful to obtain a codim-1 submesh over all facets or
48134814
a submesh over a different communicator.
48144815
label_name : str | None
48154816
Name of the label to search ``subdomain_id`` in.
@@ -4876,8 +4877,23 @@ def Submesh(mesh, subdim=None, subdomain_id=None, label_name=None, name=None, ig
48764877
label_name = dmcommon.CELL_SETS_LABEL
48774878
elif subdim == dim - 1:
48784879
label_name = dmcommon.FACE_SETS_LABEL
4880+
4881+
if isinstance(subdomain_id, (tuple, list)):
4882+
# A list of subdomain ids requires us to build an internal DM label with the union
4883+
iset = PETSc.IS().createGeneral([], comm=comm or mesh.comm)
4884+
for sub in subdomain_id:
4885+
iset = iset.union(plex.getStratumIS(label_name, sub))
4886+
label_name = "temp_union"
4887+
subdomain_id = 1
4888+
plex.createLabel(label_name)
4889+
label = plex.getLabel(label_name)
4890+
label.setStratumIS(subdomain_id, iset)
4891+
48794892
subplex = dmcommon.submesh_create(plex, subdim, label_name, subdomain_id, ignore_halo, comm=comm)
48804893

4894+
if label_name == "temp_union":
4895+
plex.removeLabel(label_name)
4896+
48814897
comm = comm or mesh.comm
48824898
name = name or _generate_default_submesh_name(mesh.name)
48834899
subplex.setName(_generate_default_mesh_topology_name(name))

tests/firedrake/submesh/test_submesh_facet.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,18 @@ def test_submesh_facet_all_facets():
134134
rmesh = RelabeledMesh(mesh, [facet_function], [facet_value])
135135
submesh2 = Submesh(rmesh, mesh.topological_dimension - 1, facet_value)
136136
assert submesh2.cell_set.size == submesh1.cell_set.size
137+
138+
139+
def test_submesh_facet_subdomain_id_tuple():
140+
mesh = UnitCubeMesh(2, 2, 2)
141+
subdomain_id = (1, 3, 6)
142+
submesh1 = Submesh(mesh, mesh.topological_dimension - 1, subdomain_id=subdomain_id)
143+
assert abs(assemble(1*dx(domain=submesh1)) - len(subdomain_id)) < 1E-12
144+
145+
V = FunctionSpace(mesh, "HDiv Trace", 0)
146+
facet_function = Function(V)
147+
DirichletBC(V, 1, subdomain_id).apply(facet_function)
148+
facet_value = 999
149+
rmesh = RelabeledMesh(mesh, [facet_function], [facet_value])
150+
submesh2 = Submesh(rmesh, mesh.topological_dimension - 1, facet_value)
151+
assert submesh2.cell_set.size == submesh1.cell_set.size

0 commit comments

Comments
 (0)