Point ↔ cell data averaging
point_data_to_cell_data and cell_data_to_point_data move data between locations without changing the geometry. They are data operations, not file formats.
- point → cell: each cell's value is the mean over its own nodes.
- cell → point: each point's value is the mean over the cells incident to it, optionally weighted by each cell's |measure|.

import meshioplusplus as mp
mesh = mp.read("part.vtu")
# Every point_data array becomes a cell_data array of the same name.
cells = mp.point_data_to_cell_data(mesh)
# Only the named arrays, written under a suffixed name.
cells = mp.point_data_to_cell_data(mesh, keys=["T", "p"], suffix="_c")
# Cell -> point, weighted by cell area/volume so large cells count for more.
points = mp.cell_data_to_point_data(mesh, keys=["stress"], weighted=True)Weighting
weighted=False (the default) counts every incident cell equally. weighted=True weights each contribution by the cell's |measure| — length for a 1D cell, area for a 2D cell, volume for a 3D one. On a mesh with cells of very different sizes the two differ substantially; on a uniform mesh they coincide.
Cells whose measure cannot be computed — ragged polygon blocks; a polyhedron block's volume is computable since v9.16.0 — fall back to a unit weight, with one warning per call.
Components and data types
Both directions work component-wise, so scalar, vector and tensor arrays are handled identically. A scalar array stays 1-D; a vector array keeps its (n, ncomp) shape.
The output is always float64, whatever the input dtype: the mean of an int32 field is not an int32.
Edge cases
- A point touched by no cell — or by no cell carrying a finite value — yields
NaN. So does a cell whose nodes all carry non-finite values. - Non-finite values never contribute to an average. See the NaN policy.
- Ragged polygon blocks average over the row's nodes; polyhedron blocks average over the distinct nodes across all of a cell's faces.
Determinism
The cell → point direction is a scatter, and floating-point addition is not associative, so getting the same result at any thread count takes care: since v16.19.0 each point's incident cells are gathered in parallel, adding their terms in the same order the old serial scatter used, rather than running the accumulation itself serially.
CLI
meshioplusplus data to-cell in.vtu out.vtu --keys T,p --target-suffix _c
meshioplusplus data to-point in.vtu out.vtu --keys stress --weightedOmit --keys to convert every array at the source location. See the CLI reference.
Other languages
- C API —
mio_data_point_to_cell(mesh, names, count, suffix)andmio_data_cell_to_point(mesh, names, count, weight, suffix), whereweightisMIO_WEIGHT_UNIFORMorMIO_WEIGHT_MEASURE. Passcount == 0for "every array". See the C API reference. - Fortran —
m%data_point_to_cell()andm%data_cell_to_point(["stress"], weight=MIO_WEIGHT_MEASURE). See the Fortran reference. - WebAssembly / JavaScript —
dataPointToCell(mesh, ["T"], "_c")anddataCellToPoint(mesh, ["stress"], "measure", ""). See the WebAssembly reference.