Ansys / Fluent mesh (.msh)
The Ansys Fluent .msh mesh format: fully parenthesis-nested "Scheme-like" sections, in ASCII, binary, or a mix of both within one file.
| Format name | ansys |
| Extensions | .msh |
| Read / Write | ✓ / ✓ |
| Extra dependencies | — |
Reading & writing
import meshioplusplus
mesh = meshioplusplus.read("mesh.msh", file_format="ansys")
meshioplusplus.ansys.write("out.msh", mesh, binary=True)binary— write binary (True) or ASCII section bodies.
File structure
Every section is (<index> ...); the file is opened and always read in binary mode, since ASCII and binary sections may be mixed in one file. The index may be a bare decimal (ASCII payload) or prefixed 20/30 (binary payload — 20xx = float32/int32, 30xx = float64/int64).
(0 ...)comment,(1 "...")header,(2 <dim>)dimensionality — bracket- skipped, not otherwise interpreted.- Nodes —
(<pfx>10 (zone-id first last type ND) ( <data> )): header integers are hexadecimal;first/lastgive the point-count range,NDis the spatial dimension. Body is(last-first+1) × NDvalues — ASCII one point per line, binary a raw float32/float64 block. A self-contained line (equal(and)counts, no body) is a pure declaration and is skipped. - Cells —
(<pfx>12 (zone-id first last zone-type element-type) ( <data> )):zone-type == 0marks a dead zone, skipped with no cells produced.element-typeselects a fixed node count (table below);mixed(element-type 0) zones are parsed structurally but their body is not decoded at all (Fluent's own mixed-cell-type encoding is unresolved in this reader). - Faces —
(<pfx>13 (zone-id first last type element-type) ( <data> )): body rows aren0 n1 ... cr cl(face nodes plus 2 adjacent-cell ids, the latter discarded). ASCIImixed(element-type 0) faces are parsed, each row prefixed by its own per-row type index; binary mixed faces are not supported and raiseReadError. Faces are folded into the same flat cell list as volume cells — in the resultingMesh.cells, boundary faces and interior cells are only distinguished bycell.type. (39 ...)and(45 ...)(zone specifications) are always warned-and- skipped, never parsed for content.
All cells/faces across every zone are collected into one flat list, then every connectivity array has the first point-zone's first index subtracted, so files whose node numbering doesn't start at 0 or 1 still normalize correctly.
Write emits, in order:
(1 "meshio++ VERSION")
(2 DIM)
(10 (0 1 N_POINTS 0)) -- node-count declaration
(12 (0 1 TOTAL_CELLS 0)) -- cell-count declaration
(10|3010 (1 1 N 1 DIM)( DATA )) -- node block
(12|2012|3012 (1 FIRST LAST 1 ANSYS_TYPE)( DATA )) -- per cell blockCell types
Volume/element-type codes (element-type field of a 12 section):
| code | meshio++ type | nodes |
|---|---|---|
| 0 | mixed (unhandled) | — |
| 1 | triangle | 3 |
| 2 | tetra | 4 |
| 3 | quad | 4 |
| 4 | hexahedron | 8 |
| 5 | pyramid | 5 |
| 6 | wedge | 6 |
Face-type codes (13 sections, read-only — not used on write): 0=mixed, 2=line(2), 3=triangle(3), 4=quad(4).
meshio++ → Ansys type codes on write: triangle:1, tetra:2, quad:3, hexahedron:4, pyramid:5, wedge:6 (no writer support for mixed/polyhedral).
Data mapping
None — point_data/cell_data/field_data are always empty; this format carries geometry and zone/boundary structure only.
Quirks & limitations
- All connectivity and zone-header integers are hexadecimal, in both ASCII bodies and headers — the defining quirk of this format among the ones meshio++ supports.
- Binary vs. ASCII is signalled purely by an optional
"20"/"30"prefix glued onto the section-index digits (e.g.2010= binary float32 nodes,3012= binary int64 cells). - Dead zones (
zone-type == 0) produce no cells at all. mixedcell zones (element-type 0) are structurally skipped — Fluent's own encoding for heterogeneous cell zones is not decoded, and no cells result from them.- The C++ reader defers any face section (
13) carrying a data body to the Python fallback — meaning any Fluent.mshwith real boundary face zones (a very common real-world case) is always parsed by Python, not C++. - 2D/3D validity (
dim in {2,3}) is only checked on write, not on read.
Notes
- No reference fixture exists under
tests/meshes/ansys/; tests round-trip synthetic meshes (empty_mesh,tri_mesh,tri_mesh_2d,quad_mesh,tri_quad_mesh,tet_mesh,hex_mesh,pyramid_mesh,wedge_mesh), parametrized over both ASCII and binary. .mshis shared withgmshandfreefem; on auto-detectionansysis tried first. Passfile_formatto disambiguate.