Conformal hex meshing#

Overview#

Conversion of a segmented voxel/grain grid into a hexahedral finite-element mesh for CPFE. The stage is driven by VoxelMeshBuilder, which produces an Exodus mesh (mesh.e) with per-block grain assignments plus a per-block MRP orientation file. The default backend is CUBIT/SCULPT (conformal, smoothed hex); a no-external-tools voxel dump is available as a fallback.

Method#

The input is a dense voxel grid where each voxel carries a grain (block) ID. Two meshing paths produce hex elements from it:

  • mesher="sculpt" (default): CUBIT/SCULPT reads the voxel field as an .spn file and builds an all-hex, grain-conformal mesh. SCULPT fits and smooths element faces to the grain-boundary surfaces implied by the voxel labels, controlled by adaptation, dilation, and smoothing flags. The result is a body-conforming mesh with far fewer elements than the raw voxel count and well-shaped (positive scaled-Jacobian) hexes.

  • mesher="voxel": each voxel is emitted directly as one cube hex, straight to Exodus, with no external tools and no inverted elements. This is a fast, exact-but-blocky fallback when CUBIT/SCULPT is unavailable; boundaries are stair-stepped rather than smoothed.

graintrace performs the segmentation and voxel-grid assembly; CUBIT/SCULPT performs the hex generation and smoothing on the SCULPT path.

Why conformal hexes#

Crystal plasticity is a stiff, strongly anisotropic constitutive law evaluated at every quadrature point, and grain boundaries are where its gradients are largest. Two properties follow.

The elements must be hexes. Linear tets lock under the near-incompressible plastic flow that crystal plasticity produces, and the locking is worst exactly where the strain localises. The whole downstream pipeline – the block_id convention, the per-block orientation file, the REI element paths – is built around hexes for this reason.

The mesh must be grain-conformal. An element straddling a grain boundary would need two orientations, and it gets one, so the boundary is smeared across an element width. Making element faces follow the boundary is what SCULPT contributes beyond a voxel dump, and it is why the blocky mesher="voxel" fallback is a fallback: its stair-stepped boundaries are geometrically conformal to the voxel boundary, which is itself an approximation of the grain boundary at the reconstruction resolution.

The element-count argument points the same way. A grain-conformal SCULPT mesh resolves a grain with far fewer, better-shaped elements than one cube per voxel, and CPFE cost is roughly linear in quadrature points. At NF-HEDM resolutions the voxel path is usually unaffordable for anything but a test run.

The label domain#

Three label values mean three different things on the segmented grid:

Label

Meaning

Treatment at mesh time

0

void

skipped; no block

\(\ge 1\)

a grain

becomes an Exodus block

-1

material, unsegmented

raises

The -1 case is not a flood-fill leftover only. remove_small_segments reassigns a sub-threshold segment to -1 whenever it has no kept neighbour to merge into, so the NF path – which infills then removes – can still be holding orphans when meshing starts. nf.mesh.write_spn raises a ValueError naming the remedy rather than meshing them, and deliberately does not map them to void for you: that would silently delete material that the reconstruction says is there. Run infill_nearest_neighbor after remove_small_segments, or mask the orphans to void explicitly if that is what you mean.

The .spn writer renumbers labels out of place, so it is collision-proof for any label set rather than only a contiguous 1..N. See File formats for the on-disk ordering (Eq. 1) and the axis-convention caveat.

Algorithm#

  1. Load the gridded orientation CSV onto a dense voxel grid and (optionally) smooth it.

  2. Segment the grid into grains via graph (Leiden) or flood-fill; remove small segments and infill (see Grain segmentation).

  3. SCULPT path: write the .spn voxel file and per-voxel orientations, invoke psculpt under the configured launcher, and run epu to join the parallel Exodus parts. Voxel path: emit one cube hex per voxel directly to Exodus.

  4. Write the per-block MRP orientation file and the Exodus mesh.e.

  5. Recommended check: verify grain preservation (block counts) and element scaled-Jacobian before using the mesh for CPFE.

Parameters that matter#

See Configuration reference for the full list.

  • mesher: sculpt (conformal hex) vs. voxel (one cube per voxel, no external tools).

  • sculpt_config: required keys psculpt, epu, nprocs; plus launcher and environment for MPI execution.

  • sculpt_options: SCULPT CLI flags (adaptation -A, dilation -df, smoothing -S / -CS, --void_mat); use the vetted safe configs.

  • Segmentation settings that set the grain field being meshed.

Further details#

For the full hex-meshing algorithm, see the CUBIT/SCULPT documentation: https://cubit.sandia.gov/ (SCULPT all-hex meshing).

See also#