Skip to content

AVS-UCD (.avs)

The AVS Unstructured Cell Data format: an ASCII header of counts, node coordinates, cells (with a per-cell material id), then optional node- and cell-data sections.

Format nameavsucd
Extensions.avs
Read / Write✓ / ✓
Extra dependencies

Reading & writing

python
import meshioplusplus

mesh = meshioplusplus.read("mesh.avs")
meshioplusplus.avsucd.write("out.avs", mesh)

write takes no keyword arguments.

File structure

#-comment lines are skipped. First non-comment line: 5 integers num_nodes num_cells num_node_data num_cell_data 0 (the trailing field is unused).

  • Nodes: num_nodes rows of id x y z. id is an arbitrary integer (not necessarily sequential or 1-based); an id→index map is built while reading.
  • Cells: num_cells rows of id material_id avsucd_type_name node_id0 node_id1 .... material_id (also an arbitrary integer) becomes cell_data["avsucd:material"]; node ids are resolved through the same id→index map, so cells may reference nodes by their original file ids. Node count per row is simply "everything after the first 3 fields" — no fixed per-type count table is consulted on read.
  • Node-data / cell-data (present only if the corresponding header count is nonzero): a header line n_arrays size_0 size_1 ... size_{n-1} (component count per array), then n_arrays label lines of the form "<name>, real" (the ", real" suffix is discarded — data is always treated as float), then num_entities rows of id v0 v1 ... , again resolved through the id map.

Write re-numbers everything sequentially from 1, in the same section order, with %.14e (Python) / %.14e and %.17g (C++: data vs. points respectively) float precision.

Cell types

AVS-UCDmeshio++AVS-UCDmeshio++
ptvertextettetra
linelinepyrpyramid
tritriangleprismwedge
quadquadhexhexahedron

Node-order permutation, meshio++ → AVS-UCD:

typepermutation
tetra[0, 1, 3, 2]
pyramid[4, 0, 1, 2, 3]
wedge[3, 4, 5, 0, 1, 2]
hexahedron[4, 5, 6, 7, 0, 1, 2, 3]

AVS-UCD → meshio++ is the same table for tetra/wedge/hexahedron (all involutions), but not for pyramid, which uses the (functionally correct but textually different) inverse [1, 2, 3, 4, 0].

Data mapping

  • cell_data["avsucd:material"] — the cell record's material id, one array per block.
  • Any other point_data/cell_data name comes directly from the data section's label lines.

Quirks & limitations

  • Node and cell ids in the file are arbitrary integers; both read and write maintain explicit id↔index maps so files with sparse, reordered, or non-contiguous numbering are handled correctly (write always renumbers sequentially from 1).
  • On write, avsucd:material is chosen as the first integer-typed cell_data array found; if others exist they're dropped, with a warning in the Python writer ("AVS-UCD can only write one cell data array... Skipping ...") but silently in the C++ writer.
  • Cell-data arrays spanning multiple cell blocks are read as one flat array then re-split via cumulative block-length offsets — this assumes the blocks are contiguous in the order they were originally read.
  • 2D points are promoted to 3D on write with a warning, and the Python writer does this in place on the caller's Mesh.points — a user-visible side effect worth being aware of.
  • Data-array label cleanup (strip() + replace spaces with _) is not reversible — a name with meaningful internal spaces is altered irrecoverably on read.

Notes

  • Fully handled by the C++ core.
  • No reference fixture exists under tests/meshes/avsucd/; tests round-trip empty_mesh, tri_mesh, quad_mesh, tri_quad_mesh, tet_mesh, hex_mesh, plus a data variant naming "avsucd:material" explicitly alongside a scalar and a 3-vector array.

Released under the MIT License.