graintrace.ipf_postprocess#

Inverse pole figure (IPF) coloring of meshes (Exodus/VTK) and legend charts.

class graintrace.ipf_postprocess.IPFProcessor(reduction=neml2.texture.IPFReduction, projection='stereographic', crystal_symmetry='1', sample_symmetry='1', save_dir='.')[source]#

Bases: object

Compute and apply IPF (inverse pole figure) coloring to meshes and legends.

available_projections = {'lambert': neml2.texture.LambertProjection, 'stereographic': neml2.texture.StereographicProjection}#
class IPFColorScheme(v0=None, v1=None, v2=None)[source]#

Bases: object

Map fundamental-sector crystal directions to RGB IPF colors.

ipf_color_chart(savefig_name='ipf_legend.png', axis_labels=('100', '110', '111'), ngrid=100, nline=100, fill=True, ax=None, label_fontsize=None)[source]#

Render the IPF triangle and return its axes.

Parameters:
  • savefig_name – output image path (relative to save_dir). If None, the figure is not saved (useful when drawing the triangle as a background for an overlay).

  • axis_labels – labels for the three corners (100, 110, 111).

  • ngrid – resolution of the color-fill grid.

  • nline – resolution for drawing the great-circle triangle edges.

  • fill – when True (default) fill the triangle with the IPF color key; when False draw only the triangle outline (white interior), e.g. as a background behind an orientation overlay.

  • ax – existing matplotlib axes to draw into; a new figure/axes is created when None.

  • label_fontsize – font size for the three corner labels; None uses the matplotlib default.

get_reduced_ipf_directions(orientations, direction)[source]#

Reduce (N, 3, 3) crystal->sample rotation matrices to their IPF fundamental-sector directions for the given sample direction.

get_ipf_color(orientations, direction)[source]#

Return per-orientation IPF RGB colors for the given sample direction.

get_ipf_points(orientations, direction)[source]#

Return per-orientation 2D IPF-triangle coordinates (N, 2).

Chains get_reduced_ipf_directions() (order-preserving, one fundamental-sector representative per orientation) with the configured stereographic/Lambert projection, so the returned points share the exact frame drawn by ipf_color_chart(). Unlike neml2.texture.inverse_pole_figure_points (whose ragged fundamental-region reduction drops/reorders points and cannot be mapped back to inputs), this preserves the input count and order – required for plotting per-entity trajectories.

Parameters:
  • orientations – (N, 3, 3) crystal->sample rotation matrices.

  • direction – length-3 sample direction to project.

Returns:

(N, 2) projected IPF coordinates, one per input.

Return type:

torch.Tensor

add_block_rgb_to_exodus(mesh_file, orientations_csv, direction, output_file='mesh_rgb.e', angle_convention='kocks', angle_type='radians')[source]#

Write per-block IPF RGB element variables into an Exodus mesh copy.

Reads a headerless orientation CSV with one row per block, colours each block by the IPF colour of direction, and writes rgb_x/y/z element variables into a copy of mesh_file.

Warning

The defaults do not match the files graintrace writes. This method defaults to angle_convention="kocks" and angle_type="radians", while an FF orientations.dat is Bunge in degrees and an NF/voxel orientations.csv is neml2 MRP. Relying on the defaults produces a plausible-looking but wrong colouring with no error. Always pass the convention explicitly: angle_convention="mrp" for orientations.csv, angle_convention="bunge", angle_type="degrees" for orientations.dat.

Parameters:
  • mesh_file – Exodus mesh to copy and annotate.

  • orientations_csv – headerless CSV, one row per block, either three MRP components or three Euler angles.

  • direction – sample direction the IPF is taken along, e.g. [0, 0, 1].

  • output_file – destination Exodus path, relative to save_dir.

  • angle_convention – "mrp", or a Euler convention. See the warning.

  • angle_type – "degrees" or "radians", Euler only. See the warning.

add_element_field_to_exodus(mesh_file, element_centroids, values, field_name='fragment_label', output_file='mesh_field.e')[source]#

Write a per-element scalar field into an Exodus mesh copy.

Unlike add_block_rgb_to_exodus() (block-constant), this fills each element individually. Incoming values are aligned to element_centroids and mapped onto the mesh’s elements by a centroid KD-tree, so the caller can pass per-element data keyed by centroid (e.g. fragment_label codes from mesh_out CSV rows). The result opens in ParaView with field_name as an element variable.

Parameters:
  • mesh_file – source Exodus (.e) mesh path.

  • element_centroids – (N, 3) centroids for the incoming values.

  • values – (N,) numeric per-element values aligned to the centroids.

  • field_name – element-variable name to write.

  • output_file – output Exodus path (relative to save_dir).

Returns:

The output Exodus path.

add_element_rgb_to_exodus(mesh_file, element_centroids, rgb, output_file='mesh_rgb.e', var_names=('rgb_x', 'rgb_y', 'rgb_z'))[source]#

Write a per-element RGB color into an Exodus mesh copy.

Like add_block_rgb_to_exodus() but per-element (not block-constant) and from an arbitrary color array rather than an IPF map: the caller passes one RGB triple per element (e.g. a categorical fragment palette), aligned to element_centroids, and each mesh element is filled by a centroid KD-tree (cf. add_element_field_to_exodus()). This lets a ParaView view of the fragments use the same colors as the branching IPF figure. The result has three float element variables (var_names); render true color by mapping that 3-component array to RGB in ParaView (turn scalar mapping off).

Parameters:
  • mesh_file – source Exodus (.e) mesh path.

  • element_centroids – (N, 3) centroids for the incoming colors.

  • rgb – (N, 3) RGB(A) values in [0, 1] aligned to the centroids (a 4th alpha column, if present, is ignored).

  • output_file – output Exodus path (relative to save_dir).

  • var_names – the three element-variable names to write.

Returns:

The output Exodus path.

add_block_rgb_to_vtk(vtk_file, direction, output_file='mesh_rgb.vtk', angle_convention='kocks', angle_type='radians', orientation_fields=('Eul1', 'Eul2', 'Eul3'))[source]#

Write per-cell IPF RGB colors into a VTK mesh copy.

Reads three Euler cell-data arrays from vtk_file, colours each cell by the IPF colour of direction, and writes the result to output_file.

Warning

The defaults do not match the file graintrace writes. This method defaults to angle_convention="kocks" and angle_type="radians", while the reconstruction VTK whose Eul1/Eul2/Eul3 arrays it reads holds Bunge angles in degrees. The mismatch is silent – it yields a wrong colouring, not an error. Pass angle_convention="bunge", angle_type="degrees" for a graintrace-produced VTK.

Parameters:
  • vtk_file – input VTK mesh carrying the Euler cell-data arrays.

  • direction – sample direction the IPF is taken along.

  • output_file – destination VTK path, relative to save_dir.

  • angle_convention – Euler convention of the cell arrays. See the warning.

  • angle_type – "degrees" or "radians". See the warning.

  • orientation_fields – the three cell-data array names to read.