XDMF2 writes data with insufficient precision
MWE:
import numpy
import vtk
from vtk.util import numpy_support
def _generate_vtk_mesh(points, cells):
mesh = vtk.vtkUnstructuredGrid()
# set points
vtk_points = vtk.vtkPoints()
# Not using a deep copy here results in a segfault.
vtk_array = numpy_support.numpy_to_vtk(points, deep=True)
vtk_points.SetData(vtk_array)
mesh.SetPoints(vtk_points)
# Set cells.
meshio_to_vtk_type = {
'vertex': vtk.VTK_VERTEX,
'line': vtk.VTK_LINE,
'triangle': vtk.VTK_TRIANGLE,
'quad': vtk.VTK_QUAD,
'tetra': vtk.VTK_TETRA,
'hexahedron': vtk.VTK_HEXAHEDRON,
'wedge': vtk.VTK_WEDGE,
'pyramid': vtk.VTK_PYRAMID
}
# create cell_array. It's a one-dimensional vector with
# (num_points2, p0, p1, ... ,pk, numpoints1, p10, p11, ..., p1k, ...
cell_types = []
cell_offsets = []
cell_connectivity = []
len_array = 0
for meshio_type, data in cells.items():
numcells, num_local_nodes = data.shape
vtk_type = meshio_to_vtk_type[meshio_type]
# add cell types
cell_types.append(numpy.empty(numcells, dtype=numpy.ubyte))
cell_types[-1].fill(vtk_type)
# add cell offsets
cell_offsets.append(numpy.arange(
len_array,
len_array + numcells * (num_local_nodes + 1),
num_local_nodes + 1,
dtype=numpy.int64
))
cell_connectivity.append(
numpy.c_[
num_local_nodes * numpy.ones(numcells, dtype=data.dtype),
data
].flatten()
)
len_array += len(cell_connectivity[-1])
cell_types = numpy.concatenate(cell_types)
cell_offsets = numpy.concatenate(cell_offsets)
cell_connectivity = numpy.concatenate(cell_connectivity)
connectivity = vtk.util.numpy_support.numpy_to_vtkIdTypeArray(
cell_connectivity.astype(numpy.int64),
deep=1
)
# wrap the data into a vtkCellArray
cell_array = vtk.vtkCellArray()
cell_array.SetCells(len(cell_types), connectivity)
# Add cell data to the mesh
mesh.SetCells(
numpy_support.numpy_to_vtk(
cell_types,
deep=1,
array_type=vtk.vtkUnsignedCharArray().GetDataType()
),
numpy_support.numpy_to_vtk(
cell_offsets,
deep=1,
array_type=vtk.vtkIdTypeArray().GetDataType()
),
cell_array
)
return mesh
points = numpy.array([
[0.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[1.0, 1.0, 0.0],
[0.0, 1.0, 0.0]
]) / 3.0
cells = {
'triangle': numpy.array([
[0, 1, 2],
[0, 2, 3]
])
}
point_data = numpy.array([
0.12345678901234567890123,
2.718281828,
3.14,
1.414,
])
mesh = _generate_vtk_mesh(points, cells)
# add point data
pd = mesh.GetPointData()
array = vtk.util.numpy_support.numpy_to_vtk(point_data, deep=1)
array.SetName('my_array')
pd.AddArray(array)
writer = vtk.vtkXdmfWriter()
writer.SetFileName('test.xdmf')
writer.SetInputData(mesh)
writer.Write()
The resulting file test.xdmf
contains single-precision data although Precision="8"
is specified.