Modulef Formatted Mesh — MFM (.mfm)
The Modulef Formatted Mesh is a compact ASCII format used by FEconv (a simplified NOPO/Modulef mesh). A file holds a single element type (non-hybrid): an 8-integer header, the connectivity, per-entity reference arrays, the vertex coordinates and a per-element subdomain array.
| Format name | mfm |
| Extensions | .mfm |
| Read / Write | ✓ / ✓ |
| Extra dependencies | — |
Reading & writing
import meshioplusplus
mesh = meshioplusplus.read("mesh.mfm")
meshioplusplus.mfm.write("out.mfm", mesh, float_fmt=".16e")float_fmt(default".16e") — coordinate format string.
File structure
nel nnod nver dim lnn lnv lne lnf # header, 8 intsnel/nver are the element/vertex counts; lnn/lnv/lne/lnf are the local (per-element) node/vertex/edge/face counts, which together identify the element type. After the header, the file is a flat whitespace-token stream (no line-structure requirement — Python reads it with f.read().split() and the C++ reader does the equivalent) laid out as:
mm— connectivity,nel × lnvintegers, 1-based, element-major.nrc— face reference array,nel × lnfintegers — only present ifdim == 3— read but discarded.nra— edge reference array,nel × lneintegers — only present ifdim >= 2— discarded.nrv— vertex reference array,nel × lnvintegers — always present — discarded.z— vertex coordinates,nver × dimfloats, vertex-major.nsd— per-element subdomain/material integer,nelvalues →cell_data["mfm:ref"].
The writer emits the same sections in the same order, with nrc/nra/nrv written as all-zero placeholders (they carry no meshio++-side data).
Cell types
The element type is recovered from (lnv, lne, lnf) plus lnn == lnv:
| type | lnv | lne | lnf |
|---|---|---|---|
line | 2 | 1 | 0 |
triangle | 3 | 3 | 1 |
quad | 4 | 4 | 1 |
tetra | 4 | 6 | 4 |
hexahedron | 8 | 12 | 6 |
wedge | 6 | 9 | 5 |
Linear elements only. Because MFM only stores vertex coordinates (no mid-edge node positions), second-order (P2) elements would necessarily be straight-sided if forced through this representation — meshio++ rejects them outright (requires lnn == lnv) rather than silently discarding curvature information.
Data mapping
cell_data["mfm:ref"]— per-element subdomain/material reference (a single int array; defaults to all-ones on write if absent).
Quirks & limitations
- Single element type per file: the writer requires exactly one cell type across the whole mesh, raising
WriteErrorfor a mixed-type mesh — MFM is fundamentally single-type ("non-hybrid"). nrc/nra/nrv(face/edge/vertex reference arrays) are read and discarded entirely — there is no meshio++-side representation for them, and they're always written as zeros.- Requires
nnod == nver(no separate "node" vs "vertex" numbering) in addition tolnn == lnv— both checks reject P2 elements.
Notes
- Fully handled by the C++ core (Python fallback only for buffers or a non-default
float_fmt). - No reference fixture exists under
tests/meshes/mfm/; tests round-trip every supported linear type and explicitly verifyWriteErroron a mixed-type mesh.