Mesh¶
Introduction¶
mufem reads the computational mesh from a file and uses it for the lifetime
of the simulation. The mesh is loaded either through the Simulation.New
factory or, later, through the domain:
sim = mufem.Simulation.New("My Example", "data/geometry.mesh")
# Equivalent two-step form:
sim = mufem.Simulation.New("My Example")
sim.get_domain().load_mesh("data/geometry.mesh")
The same load_mesh call accepts optional matching and merging interface
conditions, a non-conforming option for adaptively refined meshes, an element
ordering, and a partitioning strategy. Refer to Load Options.
Load Options¶
sim.get_domain().load_mesh(...) accepts these parameters:
| Parameter | Description |
|---|---|
mesh_path |
Path to the mesh file. |
matching |
List of MatchingInterfaceCondition objects. mufem keeps
the volume cells that touch each marker pair on the same MPI process.
The default is an empty list. |
merging |
List of MergedInterfaceCondition objects. mufem joins
the vertices on each marker pair into one set of degrees of freedom.
The default is an empty list. |
nonconforming |
A mufem.NonConformingOption(is_nonconforming, simplicies_nonconforming).
Set is_nonconforming=True to make the mesh
non-conforming, so that local refinement makes hanging nodes. For a
mesh with tetrahedra, also set simplicies_nonconforming=True.
If not, the tetrahedral mesh stays conforming. The default is a
conforming mesh. |
ordering |
Element ordering, see Element Ordering.
The default is mufem.MeshOrdering.HILBERT. |
partitioning |
MPI partitioning strategy, see Partitioning.
The default is mufem.Partitioning.Balanced. |
Example of a non-conforming mesh for adaptive refinement:
sim = mufem.Simulation.New("My Example")
sim.get_domain().load_mesh(
"data/geometry.mesh",
nonconforming=mufem.NonConformingOption(
is_nonconforming=True, simplicies_nonconforming=True
),
partitioning=mufem.Partitioning.Contiguous,
)
Element Ordering¶
mufem can change the order of the elements before it partitions the mesh. Neighbouring elements then have near indices. This gives better memory locality of the degrees of freedom. The ordering does not change the problem that mufem solves.
| Value | Description |
|---|---|
MeshOrdering.NONE |
Keep the element order of the mesh file. |
MeshOrdering.HILBERT |
Sort the elements along a Hilbert space-filling curve. This is fast and geometric. Default. Use it for most meshes. |
MeshOrdering.GECKO |
Gecko graph ordering. The setup takes more time. The memory locality is better on irregular or anisotropic meshes. |
mufem does not change the element order of non-conforming meshes and NURBS
meshes. If you use Simulation.New with a mesh path, set the ordering with the
mesh_ordering parameter.
Partitioning¶
In an MPI run, mufem divides the cells between the MPI processes.
| Value | Description |
|---|---|
Partitioning.Balanced |
Multilevel graph partitioning (METIS). The subdomains have almost the same size and a small interface between them. This gives the lowest communication cost, but the setup takes more time. Default. |
Partitioning.Contiguous |
Equal contiguous ranges of the space-filling curve, one range for each process. The setup is almost free, but the interfaces between the processes are larger. This applies to non-conforming meshes only. For a conforming mesh, mufem uses graph partitioning. |
If you set matching interface conditions, mufem uses a special partition
that keeps the matched cells on the same process. It then ignores
partitioning.
Note
Up to mufem v0.5.25, non-conforming meshes always used the contiguous
partitioning. Now they use Partitioning.Balanced by default. To get the
old behaviour, set partitioning=mufem.Partitioning.Contiguous.
Supported Formats¶
The underlying MFEM library parses the mesh file. The mufem test suite exercises two formats:
| Extension | Format | Notes |
|---|---|---|
.mesh |
MFEM native | Recommended for in-house workflows; preserves curvature directly. |
.msh |
Gmsh | Write the MSH 2.2 format (see note below). Both integer
attributes and PhysicalNames are read. |
Write Gmsh meshes in the MSH 2.2 format
mufem reads the Gmsh 2.2 format reliably. The current Gmsh default
(MSH 4.x) can fail on import with
Gmsh file : vertices indices are not unique, especially for meshes that
carry several physical groups. Select the 2.2 format explicitly: in the
Gmsh Python API set
gmsh.option.setNumber("Mesh.MshFileVersion", 2.2) before
gmsh.write(...), or on the command line pass -format msh22.
On import, mufem converts NURBS meshes to a piecewise-polynomial curved mesh.
Entities and Attributes¶
mufem exposes two kinds of mesh entities:
| Entity | Marker keyword | Used for |
|---|---|---|
| Volume | Vol |
Material assignment, model regions, volumetric reports. |
| Boundary | Bnd |
Boundary conditions, interfaces, surface reports. |
Edges and points are not addressable from the Python interface.
Each entity carries a mesh attribute. This is either an integer (for example the
Gmsh physical tag 11) or a string name (for example the PhysicalNames entry
"Bnd1"). You can use both forms when you construct a
Marker:
Named tags are recommended: they survive renumbering by the mesher and make case scripts self-documenting. See Markers for the full syntax, including list and union markers.
Mesh Coefficients¶
A set of mesh-derived coefficients (Position, Cell Attribute,
Cell Volume, Cell Aspect Ratio, Element Type, Element Order,
Global Cell Index, Local Cell Index) is registered automatically and
listed in Built-in Coefficients.
You can export them with the
Field Exporter to inspect mesh
quality and topology.
Quality Check on Import¶
When you load a mesh, mufem automatically scans every element and reports any geometry that would compromise the solution. The check runs once per import. It costs a single Jacobian evaluation per element node. It is negligible compared to partitioning.
mufem reports these conditions:
| Condition | Meaning |
|---|---|
| Inverted element | The Jacobian determinant \(\det(J)\) is non-positive at one or more nodal points of the element. The element has folded onto itself and will cause solver instability or wrong results. Most commonly produced by midpoint snapping on curved boundaries in second-order meshes. |
| Sliver element | \(\det(J)\) is positive but below \(10^{-14}\). The element is nearly degenerate; the solution stays valid but iterative solvers may converge slowly. |
| Non-finite geometry | The Jacobian of an element or a boundary face is NaN or infinite at its centre. The mesh geometry is corrupt. mufem stops with an error. The error message gives the number of bad elements and boundary faces, and the index and attribute of the first bad boundary face. Examine the mesh file and the matching and merging interface conditions. |
An inverted-element report looks like:
============================================================
!! INVERTED MESH ELEMENTS DETECTED !!
============================================================
Inverted element count : 3
min det(J) : -1.842e-04
max det(J) : 7.531e-02
worst local cell : 18427
Such elements will cause solver instability or incorrect results.
Fix the mesh before trusting the solution -- typically by refining
near curved surfaces.
============================================================
If mufem reports inverted elements, regenerate the mesh before you use the solution. Use finer resolution along curved surfaces. Sliver warnings are advisory. They do not invalidate results.