Skip to content

Add VTKHDF output support for all structured mesh types (#3620)#3877

Open
Jarvis2001 wants to merge 5 commits intoopenmc-dev:developfrom
Jarvis2001:vtkhdf
Open

Add VTKHDF output support for all structured mesh types (#3620)#3877
Jarvis2001 wants to merge 5 commits intoopenmc-dev:developfrom
Jarvis2001:vtkhdf

Conversation

@Jarvis2001
Copy link
Contributor

@Jarvis2001 Jarvis2001 commented Mar 13, 2026

Description

PR #3252 added .vtkhdf output for UnstructuredMesh. This PR extends that support to all four structured mesh types — RegularMesh, RectilinearMesh, CylindricalMesh, and SphericalMesh — following the same pattern. The legacy ASCII .vtk path is unchanged.


Changes

StructuredMesh.write_data_to_vtk

  • volume_normalization default changed from True to None, with format-appropriate fallback: False for .vtkhdf and True for legacy ASCII .vtk. The previous hardcoded True default would silently call self.volumes on 1D/2D meshes, which raises RuntimeError since volumes are only defined for 3D meshes.

  • Fixed unconditional .T.ravel() in the ASCII path for 3D datasets. The transpose is now conditional: RegularMesh and RectilinearMesh store data in C (ijk) order that matches the VTK writer directly — no transpose is needed or correct. CylindricalMesh and SphericalMesh still require the transpose to produce Fortran (kji) order expected by the curvilinear VTK writer. The same condition applies to volumes during normalization.

MeshMaterialVolumes.by_element

  • Reverted an erroneous sort by material ID. The method now returns entries in column order (the order stored by the C ray-tracing library), which is the correct semantics for this method. Callers that need a specific ordering (e.g. from_volumes) apply their own sort explicitly.

MeshMaterialFilter.from_volumes

  • Fixed non-deterministic bin ordering. The previous implementation used np.where to scan the raw _materials array column-by-column, producing bin order dependent on which column the C library happened to write each material into. The fix explicitly sorts per-element bins by volume ascending (material ID as tiebreaker) before appending, making the output deterministic regardless of ray-traversal order.

RegularMesh._write_vtk_hdf5 (new method)

  • Writes StructuredGrid VTKHDF format with explicit Points, Dimensions, and CellData, consistent with the existing UnstructuredMesh VTKHDF writer.
  • Type attribute written as a fixed-length ASCII HDF5 string via h5py.string_dtype, matching the UnstructuredMesh pattern. Without this, h5py stores a variable-length string that reads back as str rather than bytes, breaking == b"StructuredGrid" comparisons in VTK readers.
  • Dimensions carries only ndim entries (not padded to 3), so 1D and 2D meshes write the correct number of dimensions.
  • Guards against datasets=None, calls _reshape_vtk_dataset before validation, and validates both shape and element count.

RectilinearMesh._write_vtk_hdf5, CylindricalMesh._write_vtk_hdf5, SphericalMesh._write_vtk_hdf5 (new methods)

  • Same structure as RegularMesh._write_vtk_hdf5. Points are computed from the respective coordinate grids: Cartesian for RectilinearMesh, converted from (r, φ, z) for CylindricalMesh, and from (r, θ, φ) for SphericalMesh, each respecting the mesh origin.
  • Note: vtkRectilinearGrid is not part of the VTKHDF spec, so RectilinearMesh uses StructuredGrid as the closest equivalent.

New tests (test_mesh.py)

  • test_write_vtkhdf_regular_mesh — checks StructuredGrid type, Points, Dimensions, and CellData structure.
  • test_write_vtkhdf_rectilinear_mesh — checks file is created and CellData is populated.
  • test_write_vtkhdf_cylindrical_mesh — checks vertex Dimensions match (nr+1, nφ+1, nz+1).
  • test_write_vtkhdf_spherical_mesh — checks Points and CellData are present.
  • test_write_vtkhdf_volume_normalization — verifies both normalised and unnormalised output against known cell volumes.
  • test_write_vtkhdf_multiple_datasets — verifies multiple named datasets are written with correct data ordering (data.T.ravel()).
  • test_write_vtkhdf_invalid_data_shape — verifies ValueError is raised for shape mismatches.
  • test_write_vtkhdf_1d_mesh — verifies a 1D RegularMesh writes successfully without hitting the 3D-only volumes guard.
  • test_write_vtkhdf_2d_mesh — verifies a 2D RegularMesh writes the correct number of Dimensions entries.
  • test_write_ascii_vtk_unchanged — round-trip test confirming the legacy .vtk path is unaffected by these changes.

Fixes #3620


Checklist

  • I have performed a self-review of my own code
  • I have run clang-format (version 18) on any C++ source files (if applicable)
  • I have followed the style guidelines for Python source files (if applicable)
  • I have made corresponding changes to the documentation (if applicable)
  • I have added tests that prove my fix is effective or that my feature works (if applicable)

@Jarvis2001 Jarvis2001 marked this pull request as draft March 13, 2026 17:39
@Jarvis2001 Jarvis2001 force-pushed the vtkhdf branch 2 times, most recently from 391fb53 to ede21b4 Compare March 13, 2026 19:42
@Jarvis2001 Jarvis2001 marked this pull request as ready for review March 13, 2026 21:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

adding hdfvtk format export for all meshes

1 participant