Skip to content

Commit 95b1219

Browse files
committed
add a bunch of examples
1 parent 3c5f20d commit 95b1219

1 file changed

Lines changed: 76 additions & 10 deletions

File tree

firedrake/mesh.py

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from pyop2.mpi import (
2626
MPI, COMM_WORLD, temp_internal_comm
2727
)
28-
from functools import cached_property, reduce
28+
from functools import cached_property
2929
from pyop2.utils import as_tuple
3030
import petsctools
3131
from petsctools import OptionsManager, get_external_packages
@@ -4854,17 +4854,86 @@ def Submesh(mesh, subdim=None, subdomain_id=None, label_name=None, name=None, ig
48544854
ridges to be contained in the quad mesh are shared by at most two
48554855
facets to make the quad mesh orientation algorithm work.
48564856
4857+
Examples
4858+
--------
4859+
4860+
Mark a cell subdomain and construct a codim-0 submesh from all cells in the subdomain
4861+
4862+
>>> mesh = UnitSquareMesh(4, 4)
4863+
>>> x, y = SpatialCoordinate(mesh)
4864+
>>> DG = FunctionSpace(mesh, "DG", 0)
4865+
>>> cell_marker = assemble(interpolate(conditional(lt(x, 0.5), 1, 0), DG))
4866+
>>> mesh.mark_entities(cell_marker, 111)
4867+
>>> submesh = Submesh(mesh, subdomain_id=111)
4868+
4869+
Mark a facet subdomain and construct a codim-1 submesh from all facets in the subdomain
4870+
4871+
>>> mesh = UnitSquareMesh(4, 4)
4872+
>>> x, y = SpatialCoordinate(mesh)
4873+
>>> DGT = FunctionSpace(mesh, "DGT", 0)
4874+
>>> facet_marker = assemble(interpolate(conditional(lt(abs(x-0.5), 1E-12), 1, 0), DGT))
4875+
>>> mesh.mark_entities(facet_marker, 222)
4876+
>>> submesh = Submesh(mesh, dim=mesh.topological_dimension-1, subdomain_id=222)
4877+
4878+
Construct a codim-0 submesh of the union of multiple subdomains by passing a list
4879+
4880+
>>> mesh = UnitSquareMesh(4, 4)
4881+
>>> x, y = SpatialCoordinate(mesh)
4882+
>>> DG = FunctionSpace(mesh, "DG", 0)
4883+
>>> mesh.mark_entities(assemble(interpolate(conditional(lt(x, 0.5), 1, 0), DG)), 1)
4884+
>>> mesh.mark_entities(assemble(interpolate(conditional(lt(y, 0.5), 1, 0), DG)), 2)
4885+
>>> submesh = Submesh(mesh, subdomain_id=[1, 2])
4886+
4887+
Construct a codim-0 submesh of the intersection of multiple subdomains by passing a nested list
4888+
4889+
>>> mesh = UnitSquareMesh(4, 4)
4890+
>>> x, y = SpatialCoordinate(mesh)
4891+
>>> DG = FunctionSpace(mesh, "DG", 0)
4892+
>>> mesh.mark_entities(assemble(interpolate(conditional(lt(x, 0.5), 1, 0), DG)), 1)
4893+
>>> mesh.mark_entities(assemble(interpolate(conditional(lt(y, 0.5), 1, 0), DG)), 2)
4894+
>>> submesh = Submesh(mesh, subdomain_id=[(1, 2)])
4895+
4896+
Construct a codim-1 submesh of all the facets (the skeleton mesh)
4897+
4898+
>>> mesh = UnitSquareMesh(4, 4)
4899+
>>> submesh = Submesh(mesh, subdim=1)
4900+
4901+
Construct a codim-1 submesh of the entire boundary
4902+
4903+
>>> mesh = UnitSquareMesh(4, 4)
4904+
>>> submesh = Submesh(mesh, subdomain_id="on_boundary")
4905+
4906+
Construct a codim-1 submesh of the union of multiple boundaries
4907+
4908+
>>> mesh = UnitSquareMesh(4, 4)
4909+
>>> submesh = Submesh(mesh, subdim=mesh.topological_dimension-1, subdomain_id=[1, 2, 3])
4910+
4911+
Construct a codim-0 submesh of the part of the mesh owned by each MPI rank
4912+
4913+
>>> mesh = UnitSquareMesh(4, 4)
4914+
>>> submesh = Submesh(mesh, comm=COMM_SELF)
4915+
48574916
"""
48584917
if not isinstance(mesh, MeshGeometry):
48594918
raise TypeError("Parent mesh must be a `MeshGeometry`")
48604919
if isinstance(mesh.topology, ExtrudedMeshTopology):
48614920
raise NotImplementedError("Can not create a submesh of an ``ExtrudedMesh``")
48624921
elif isinstance(mesh.topology, VertexOnlyMeshTopology):
48634922
raise NotImplementedError("Can not create a submesh of a ``VertexOnlyMesh``")
4923+
4924+
if subdomain_id == "on_boundary":
4925+
if subdim is None:
4926+
subdim = mesh.topological_dimension - 1
4927+
elif subdim != mesh.topological_dimension - 1:
4928+
raise ValueError('subdomain_id="on_boundary" requires subdim=dim-1')
4929+
if label_name is None:
4930+
label_name = "exterior_facets"
4931+
elif label_name != "exterior_facets":
4932+
raise ValueError('subdomain_id="on_boundary" requires label_name="exterior_facets"')
4933+
subdomain_id = 1
4934+
48644935
if subdim is None:
48654936
subdim = mesh.topological_dimension
4866-
if subdomain_id == "on_boundary":
4867-
subdim = subdim - 1
48684937
plex = mesh.topology_dm
48694938
dim = plex.getDimension()
48704939
if subdim not in {dim, dim - 1}:
@@ -4883,13 +4952,9 @@ def Submesh(mesh, subdim=None, subdomain_id=None, label_name=None, name=None, ig
48834952

48844953
# Parse non-integer subdomain_id
48854954
if isinstance(subdomain_id, str):
4886-
if subdomain_id == "on_boundary":
4887-
subdomain_id = tuple(mesh.exterior_facets.unique_markers)
4888-
else:
4889-
raise ValueError(f"Submesh construction got invalid subdomain_id {subdomain_id}.")
4890-
4891-
if isinstance(subdomain_id, Sequence):
4892-
# Create a temporary DMLabel with the union of the labels in the list
4955+
raise ValueError(f"Submesh construction got invalid subdomain_id {subdomain_id}.")
4956+
elif isinstance(subdomain_id, Sequence):
4957+
# Take the union of the labels in the list
48934958
iset = PETSc.IS().createGeneral([], comm=mesh.comm)
48944959
for sub in subdomain_id:
48954960
if isinstance(sub, Sequence):
@@ -4898,6 +4963,7 @@ def Submesh(mesh, subdim=None, subdomain_id=None, label_name=None, name=None, ig
48984963
else:
48994964
cur = plex.getStratumIS(label_name, sub)
49004965
iset = iset.union(cur)
4966+
# Create a temporary label
49014967
label_name = "temp_label"
49024968
subdomain_id = 1
49034969
plex.createLabel(label_name)

0 commit comments

Comments
 (0)