This small tutorial demonstrates how to work with global meshes, submeshes, tags, and interface integrals in DOLFINx (FEniCSx). The goal is to provide a minimal and transparent setup that helps debug multi-domain problems such as fluid–structure interaction (FSI).
The script intentionally focuses on understanding the mesh infrastructure before adding physics.
The example walks through the following steps.
A rectangular domain is generated and divided into two regions (left and right).
(0,1) ------------------------
| | |
| | |
(0,0) ------------------------
x = 0.5
The mesh specifically generated in submesh_tutorial.py using
Nx, Ny, Lx, Ly = 4, 2, 2.0, 1.0
domain = mesh.create_rectangle(comm,
[[0.0, 0.0], [Lx, Ly]],
[Nx, Ny],
cell_type=mesh.CellType.triangle)
looks as follows:
Numbered mesh (if not visible, just click the text.)
- Cell tags define the two subdomains.
- Facet tags identify the internal interface.
Custom measures are created for
- left domain
- right domain
- interface
This allows integration over specific regions of the mesh.
Two submeshes are extracted from the global mesh:
- left_mesh
- right_mesh
Each submesh has its own numbering of cells, facets, and vertices, independent of the parent mesh.
Simple linear functions are interpolated on the meshes and integrated over
- global subdomains
- submeshes
- the interface
The results should match, confirming that tags, measures, submesh mappings are correctly defined.
When working with multi-domain problems in FEniCSx it is common to run into confusion about
- mesh entity numbering
- mesh tags
- submesh mappings
- interface measures
This example provides a minimal debugging reference.
Typical issues it helps diagnose include
- integrals returning zero
- incorrect interface detection
- mismatched submesh numbering
- wrong tag propagation.
FEniCSx assigns internal indices for
- vertices
- facets
- cells
These indices are local to each mesh.
Tags are stored in a separate object:
MeshTags ├─ indices └─ values
Meaning
entity_index → tag_value
Important: Tags belong to the mesh that created them.
Parent mesh indices and submesh indices are therefore different.
Submeshes provide
submesh cell → parent cell submesh vertex → parent vertex
These mappings are essential when reconstructing tags or coupling fields across meshes.
Interior interfaces are detected using
- facet tags
- facet–cell connectivity
- geometric checks (facet midpoints).
This is crucial for FSI and multi-physics coupling. Topology based interface detection is preferred, since it is not affected by round-off errors or geometric changes due to deformation.
The tutorial includes a helper function that prints
- number of mesh entities
- connectivity relations
- parent–submesh mappings
- facet midpoints
- boundary vs interior facets.
This significantly simplifies debugging.
There are two additional helper functions for
- Submesh facet mappings
- Visualizing a mesh or submesh using PyVista together with node, cell and facet numberings
with own README files. These functions can be independent of this tutorial.
This template is useful for
- fluid–structure interaction
- multi-material elasticity
- coupled PDE systems
- Nitsche or mortar coupling
- domain decomposition methods.
- Python 3
- NumPy
- MPI
- DOLFINx / FEniCSx
- UFL
python submesh_tutorial.py
