Skip to content

SU2 (.su2)

The SU2 mesh format: an ASCII format with NDIME, NPOIN, NELEM volume cells and NMARK boundary markers, using VTK-style numeric type codes.

Format namesu2
Extensions.su2
Read / Write✓ / ✓
Extra dependencies

Reading & writing

python
import meshioplusplus

mesh = meshioplusplus.read("mesh.su2")
meshioplusplus.su2.write("out.su2", mesh)

write takes no keyword arguments.

File structure

Line-oriented KEY= value records (% = comment; blank lines skipped; malformed lines without = just warn and are skipped).

  • NDIME= 2|3 — dimension.
  • NPOIN= n [extra columns] — the first point row is read separately to auto-detect whether an extra trailing global-index column is present (some SU2 files append one); the remaining n-1 rows follow with the same column count, then the extra column(s) are stripped from all rows.
  • NELEM= n or MARKER_ELEMS= n — reads exactly n element lines; the first line is peeked to determine the node count (from the VTK type code) and whether an extra trailing column is present, then all n lines are parsed as one integer block and binned by VTK type code (elements of different types within one block are separated into distinct cell blocks). NELEM cells get su2:tag = 0; MARKER_ELEMS cells get the current marker's tag id.
  • NMARK= n — expected marker count (soft-checked; a mismatch only warns).
  • MARKER_TAG= <value> — sets the tag used for the following MARKER_ELEMS block. If the tag isn't parseable as an integer, an auto-incrementing integer id is assigned instead, with a warning that string tags aren't supported.
  • Boundary cell blocks of the same type from separate MARKER_ELEMS sections are merged into one block per type after the full-file scan, concatenating their su2:tag values in the same order.

Write: NDIME= from points.shape[1]; NPOIN= + coordinates; volume cells (triangle/quad for 2D, tetra/hexahedron/wedge/pyramid for 3D) under NELEM=, each row prefixed by its type code; boundary markers grouped by the first integer-typed cell_data array found (via the same "first-int-array" convention used by several other formats), one MARKER_TAG=/MARKER_ELEMS= pair per distinct tag value.

Cell types

codenodesmeshio++ type
32line
53triangle
94quad
104tetra
128hexahedron
136wedge
145pyramid

Data mapping

  • cell_data["su2:tag"] — volume cells always get tag 0; boundary (MARKER_ELEMS) cells get their marker's tag id (an auto-incrementing int starting from 1 for the first non-numeric string tag encountered, if any).

Quirks & limitations

  • Unsupported cell types on write trigger a warning, but a latent message bug means the warning text shows Python's type builtin rather than the actual cell type name — cosmetic only, doesn't affect behavior.
  • Only one integer cell-data array can be used as the boundary-marker tag source on write; if others exist, they're dropped with a warning.
  • Point coordinates use np.savetxt's default format in the Python writer (%.18e) vs. %.16e in the C++ writer — a formatting difference, not a round-trip correctness issue.

Notes

  • tests/meshes/su2/square.su2 (official SU2-docs example: structured 2D quad mesh, 9 points/8 quads/markers) — checked for 16 total cells, 9 points, 4 unique tags summing to 20.
  • tests/meshes/su2/mixgrid.su2 (mixed-cell 3D grid) — checked for 30 cells, 16 points, 6 unique tags summing to 62.
  • Fully handled by the C++ core.

Released under the MIT License.