Skip to content

Format conformance ​

What every writable format keeps when meshio++ writes a file and reads it back. One canonical mesh — one cell of each linear type, float64/int32/vector point data, float64/int32 cell data, field data and one point, cell and side region — goes through write and read for each format, and the observed result must match the declaration in tests/python/conformance_spec.py exactly: tests/python/test_conformance.py fails when a format starts losing something or starts keeping something, so this page cannot drift from the code. It is generated by tools/gen_conformance_table.py; do not edit it by hand.

The per-format pages say why something is lost; this page says what. Region membership is checked in depth by the region round-trip matrix, and node-ordering by node ordering.

Legend ​

  • Cell columns: ✓ the cell comes back node for node; ↻ the same nodes in another order; → types written as other cells (a quad as two triangles, a volume as its skin); ✗ silently dropped when written next to the other types; blank: the writer refuses the type on its own.
  • Points: exact; approx (within 1e-6, single precision); 2d (z dropped); subset (the points of dropped cells are gone, the rest exact); none (a format with no geometry); changed.
  • Point data / cell data: the arrays that come back, with the dtype read (~: values only approximately equal; ?: shape or values changed). p_f64/c_f64 are float64, p_i32/c_i32 int32, p_vec a float64 3-vector.
  • F: the field-data array fd survives. Regions: the kinds (point, cell, side) whose region comes back under its own name.

Matrix ​

FormatvtxlinetriquadtethexwdgpyrPointsPoint dataCell dataFRegions
abaqus✓✓✓✓✓✓exact———cell, point, side
abaqus_fil✓✓✓✓✓✓✓exact———cell, point, side
ansys✗✗↻↻✓✓exact———cell
ansys_rst✓✓✓✓✓✓✓✓exact———cell, point
ansysInp✓✓✓✓✓✓✓✓exact———cell, point
avsucd✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 float64, p_vec float64c_f64 float64——
cad_json✓✓exact————
cae✗✗→ tri→ tri→ tri→ trisubset————
cgns✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 float64, p_vec float64—✓cell, point
code_aster✓✓✓✓✓✓✓✓exact———cell, point
dex✗✗✗✗✗✗✗✗exactp_f64 float64———
dolfin-xml✗✓exactp_f64 float64, p_i32 int64c_f64 float64, c_i32 int64——
dxf✓exact————
elmer✓✓✓✓✓✓✓exact———cell
ensight✓✓✓✓✓✓✓✓approxp_f64 float64, p_i32 float64, p_vec float64c_f64 float64, c_i32 float64——
exodus✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32—cell, point, side
febio✓✓✓✓✓✓✓exactp_f64 float64, p_i32 float64, p_vec float64c_f64 float64?, c_i32 float64?—cell, point, side
femap✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 float64c_f64 float64, c_i32 float64—cell, point
flac3d✓✓✓✓↻✓exact————
flux✓✓✓✓✓✓✓✓exact————
frd✓✓✓✓✓✓exactp_f64 float64, p_i32 float64, p_vec float64———
freefem✓✓exact————
gid✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 float64, p_vec float64c_f64 float64, c_i32 float64——
gltf✓✓✓→ tri→ tri→ tri→ tri→ triapproxp_f64 float64, p_i32 float64, p_vec float64——cell
gmsh✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 float64, p_vec float64c_f64 float64, c_i32 float64✓cell
gmsh22✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 float64, p_vec float64c_f64 float64, c_i32 float64✓cell
h5m✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64———
hmf✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32——
ip✗✗✗✗✗✗✗✗exactp_f64 float64, p_i32 float64———
libmesh✓✓✓✓✓✓✓✓exact———cell, point, side
lsdyna✓✓✓✓✓✓✓✓exact———cell, point, side
lsdyna_binout✓→ vtx→ vtx→ vtx→ vtx→ vtx→ vtx→ vtxapproxp_f64 float64, p_i32 float64———
lsdyna_d3plot✓✓✓✓✓✓✓✓approx———cell
marc✓✓✓✓✓✓✓exact———cell, point
marc_t19✓✓✓✓✓✓✓exactp_f64 float64, p_i32 float64, p_vec float64c_f64 float64, c_i32 float64—cell, point
mdpa✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 float64, p_vec float64———
med✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32—cell, point
medit✓✓✓✓✓✓✓exact————
medit_sol✗✗✗✗✗✗✗✗none————
mfem✗✓✓✓✓✓✓exact———cell
mff✗✗✗✗✗✗✗✗none————
mfm??????fails: WriteError
mphbin✓✓✓✓✓✓✓✓exact———cell
mphtxt✓✓✓✓✓✓✓✓exact———cell
nastran✓✓✓✓✓✓✓✓exact———cell
nastran_h5✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 float64, p_vec float64———
nastran_op2✓✓✓✓✓✓✓✓approx————
netgen✓✓✓✓✓✓✓✓exact——✓—
neuroglancer✓exact————
obj✓✓exact————
off✓✓exact————
openfoam↻↻✓✓exactp_f64 float64, p_i32 float64, p_vec float64c_f64 float64, c_i32 float64—cell, point, side
patran✓✓✓✓✓✓✓exact———cell, point
pcd✓→ vtx→ vtx→ vtx→ vtx→ vtx→ vtx→ vtxapproxp_f64 float64, p_i32 int32, p_vec float64———
permas✓✓✓✓✓✓✓✓exact————
ply✗✗✗✗→ tri→ quad→ quad+tri→ quad+trisubset————
pmsh✗✗✗✗✓→ tet→ tet→ tetapproxp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32✓—
pvd✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32✓cell, point, side
pvtp✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32✓cell, point
pvtu✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32✓cell, point, side
radioss✓✓✓✓✓✓✓exact———cell, point, side
radioss_anim✓✓✓✓✓✓✓✓approxp_f64 float64, p_i32 float64, p_vec float64c_f64 float64, c_i32 float64—cell
radioss_th✗✗✗✗✗✗✗✗none————
step→ tri→ tri→ tri→ triexact————
stl✗→ tri→ tri→ tri→ trisubset————
su2✓✓✓✓✓✓exact————
svg✓✓✓exact————
szplt✗✓✓✓✓✓→ hex→ hexsubset—c_f64 float64, c_i32 float64—cell
tecplot✓✓✓✓✓→ hex→ hexexactp_f64 float64, p_i32 float64c_f64 float64, c_i32 float64—cell
tetgen✓exact————
tikz✓✓✓exact————
triangle✓exact————
ugrid✓✓✓✓✓✓exact————
unv✓✓✓✓✓✓✓exactp_f64 float64, p_i32 float64, p_vec float64c_f64 float64, c_i32 float64—cell, point
usd✗✗→ tri→ quad→ quad+tri→ quad+trisubset————
vtifails: no cell type round-trips
vtk✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32——
vtk42✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32——
vtk51✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32——
vtkhdf✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32✓—
vtm✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32—cell
vtp✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32✓cell, point
vtrfails: no cell type round-trips
vtsfails: no cell type round-trips
vtu✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32✓cell, point, side
vtx✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32——
wkt✓exact————
xdmf✓✓✓✓✓✓✓✓exactp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32—cell, point, side
xplt✗✓✓✓✓✓✓✓approxp_f64 float64, p_i32 float64, p_vec float64c_f64 float64, c_i32 float64✓cell, point, side
xyz✓→ vtx→ vtx→ vtx→ vtx→ vtx→ vtx→ vtxexactp_f64 float64, p_i32 float64———
z88✓✓✓exact———cell, point
zarr✗✗✗✗✓→ tet→ tet→ tetapproxp_f64 float64, p_i32 int32, p_vec float64c_f64 float64, c_i32 int32✓—

Notes ​

  • abaqus_fil: A results file holds the model and the results Abaqus names: only point data named like a nodal result (U, RF...) and cell data named like an element result (S, E...) are written, so the canonical arrays and fd have no place; a vertex has no Abaqus element. Side regions are contact surfaces.
  • ansys: A Fluent mesh stores volume cells and the faces that bound them; lower-dimensional cells that are not boundary faces of a volume cell are dropped with a warning.
  • ansys_rst: A results file holds the solution MAPDL names: point data called U, ROT, TEMP ... (and RF reactions) and cell data S, EPEL, EPPL, EPCR, EPTH come back; arbitrary arrays such as the probe's are not kept. Side regions are dropped with a warning.
  • cad_json: Kratos IGA geometry: without a B-rep side channel, quads are written as bilinear NURBS faces and lines as edges.
  • cae: The physics-ML .npz stores the surface of the volume cells.
  • cgns: Cell data cannot be written for the probe: it mixes cell dimensions, which a zone-wide CellCenter solution cannot span. Side regions are not written, and a region's cells must lie in fixed-size sections.
  • dex: DEX stores one nodal field over a node set: cells are not kept.
  • dxf: A drawing exchange file: a line mesh is written as one LINE per segment, a fit_curves sketch as LINE, ARC and CIRCLE entities, and only the drawing comes back (dxf:entity, dxf:type). Vertex cells are skipped and surface or volume cells are refused by name.
  • frd: Nodal, with no sets: cell data, regions and other field data are dropped with a warning, and values print at six digits (E12.5). No vertex or pyramid element exists. Only frd:group and frd:material come back as cell data.
  • gltf: A surface export: volume and 2-D cells come back as their triangulated skin, positions are float32, and weld=True merges the vertices split per smooth fan.
  • ip: An integration-point cloud: points and nodal values, no cells.
  • libmesh: A .xda/.xdr holds geometry, subdomains, p-levels, boundaries and the refinement tree, and no data arrays; libmesh:level is derived from the tree.
  • lsdyna_binout: A binout holds nodout's nodes, not elements: the points come back as a vertex cloud, single precision, and only nodout's own vectors (displacement...) are (n, 3); per-point scalars come back as float64 (an integer one is stored as int32, and the reader widens every per-point array to float64), and the canonical fd is not a binout: name.
  • lsdyna_d3plot: Single-precision words, so coordinates and data come back rounded to float32. Only what the state layout names is kept: the nodal variables (displacement, velocity, temperature ...), the element variables (stress, strain, history_variables, the shell and beam resultants ...), lsdyna:alive and the global_* field data; the probe's arrays are not. Blocks come back by family (solids, beams, shells, SPH particles; a vertex is an SPH particle), and a cell belongs to one part, so only the first cell region holding it survives.
  • marc: A deck holds no data arrays; Marc's face and edge numbering is not mapped to facets, so side regions are dropped (roadmap §1.2.11); a vertex has no type; Herrmann, bubble and generalized plane strain types come back as the default type of their shape.
  • marc_t19: Reals are e13.6, six digits, and integers come back as float64; the model is the input deck's, so a vertex has no type, side regions are dropped, and Herrmann, bubble and generalized plane strain types come back as the default type of their shape. A post file is checked against meshio++'s own reader only, until a Mentat run (roadmap §1.2.11).
  • medit_sol: Fields without geometry: the float data comes back renamed medit:sol:<i>, element fields only through medit.read(path, sol=...).
  • mff: A field without geometry: one array of values, no points or cells.
  • mfm: MFM holds one element type per file, so the mixed canonical mesh is refused; each type alone round-trips.
  • mphtxt: A Selection selects elements, so point and side regions (which address points and facets, not elements) have no form in the file; several Mesh objects merge into one mesh on read and are written as one.
  • nastran_h5: Results are the schema's own tables: point data is nodal tables (float64), cell data only <G>:<M> centre values, so the canonical cell arrays, field data and regions (derived from property ids on read) have no place.
  • nastran_op2: Single precision; results are the OP2 tables' own point and cell data (DISPLACEMENT, STRESS:<M>...), so the canonical arrays have no place; the property and material values are field data (nastran:<CARD>_<id>:<MEMBER>), and the regions come from the property ids; cells come back ordered by element card.
  • netgen: Field data is interpreted as Netgen name tables ([id, dimension]), not arbitrary numeric arrays; periodic tables use reserved netgen:* keys.
  • openfoam: Fields are written to time directory 0 as volume and point fields (float64); OpenFOAM has no field_data.
  • pcd: A point cloud: every node is kept as a vertex, cells are not.
  • ply: PLY stores faces: volume cells are written as their skin.
  • pmsh: The physics-ML mesh stores tetrahedra: other volume cells are simplexified, and non-volume blocks dropped.
  • radioss: A starter deck holds no data arrays; a vertex has no element card.
  • radioss_anim: Everything is stored as 32-bit floats, so coordinates and data are approximate and integers come back as float64; the animation holds one state, so the data are the state's and field data other than the time are not kept.
  • radioss_th: A time-history file holds radioss_th:* field data only: points, cells, regions and other data are not kept (a warning names the field data dropped); the canonical fd is not a radioss_th: name.
  • step: A B-rep solid for CAD tools (coplanar facets merged into one face), read back through OpenCASCADE as its triangulation: volume cells come back as their skin, and data is not kept. Checked only in a build with OpenCASCADE (the meshioplusplus-occt wheel carries it).
  • stl: STL stores triangles: volume cells are written as their skin, and other blocks are dropped when volume cells are present.
  • su2: SU2 holds volume cells and boundary markers: a volume region has no slot (separate meshes are NZONE zones, su2:zone), and data arrays are not stored.
  • svg: A 2-D drawing, read back as planar (z = 0) from the scale and offset meshio++ records in a comment. Observed with float_fmt=".17g": the default .3f keeps three decimals of a drawing 100 units wide, so corners come back to about 1.5e-5 of its width. A 3-D mesh is drawn projected, and what comes back is that picture. Data arrays are not drawn; a colour comes back as an RGB svg:fill.
  • szplt: SZL has no wedge or pyramid zone type: both are written as degenerate bricks and come back as hexahedra, and a zone has no vertex element. TecIO shares a variable between zones only with their connectivity, so with several blocks each zone holds the points its cells use (a point several blocks use is repeated: the mixed mesh reads back with more points, and its point data with them); one block alone round-trips exactly.
  • tecplot: Tecplot has no wedge or pyramid zone type: both are written as degenerate bricks and come back as hexahedra.
  • tikz: A 2-D drawing, read back as planar (z = 0) with its coordinates verbatim, to the digits float_fmt kept. A 3-D mesh is drawn projected, and what comes back is that picture. Data arrays are not drawn; a colour comes back as an RGB tikz:fill.
  • triangle: Triangle reads and writes 2-D triangulations only, so this row is observed on the planar part of the canonical mesh.
  • unv: Entities a dataset does not list are NaN, and NaN rows are not written back.
  • usd: A UsdGeom mesh stores faces: volume cells are written as their skin.
  • vti: ImageData holds one regular hexahedral lattice; the canonical mesh is not one (VTI).
  • vtr: RectilinearGrid holds one axis-aligned lattice; the canonical mesh is not one.
  • vts: StructuredGrid holds one curvilinear lattice; the canonical mesh is not one.
  • vtx: A mesh of several cell types is one block per type, each with the points it uses and the ghost arrays that let the reader weld the shared points back, so the mixed canonical mesh round-trips exactly (DOLFINx and ParaView read a single type only); the file holds the mesh and its arrays, with no regions or field data other than the time.
  • xplt: Everything is stored as 32-bit floats and comes back as float64 (the probe's coordinates are exact in float32, general ones are not); a plot file has no vertex element. A side region is a facet set.
  • xyz: A point cloud: every node is kept as a vertex, cells are not.
  • z88: A deck has no slot for an arbitrary array, and z88o2/z88o3/z88o4 are what Z88R writes from the deck, so none is written; Aurora's sets hold elements and nodes only, so side regions are dropped.
  • zarr: As pmsh: tetrahedra only, other volume cells simplexified.

Formats missing a direction ​

Every registered format is meant to read and write, in both engines (roadmap decisions). A format that does only one is a tracked gap, listed here with the roadmap item that closes it; ansys_rst_cyclic, iges and step are the exemptions. test_conformance.py fails when a format reads without writing, or writes without reading, and is not listed here, or is listed and has gained the missing direction, in either the Python or the native registry.

FormatMissingWhy, and the item that closes it
ansys_rst_cyclicwriterExempt, not a gap: not a file of its own but the full rotor that a static cyclic-symmetry .rst expands to, read from ansys_rst's file. Its write side is ansys_rst's cyclic option (roadmap non-goals: every format reads and writes).
igeswriterExempt, not a gap: a CAD exchange format read through OpenCASCADE (roadmap non-goals: every format reads and writes); STEP is the CAD format meshio++ writes.

Released under the MIT License.