upxo.pxtal.fm_steel_3d.with_blocks_3d module

FMSteel3DWithBlocks: State class representing PAGs partitioned into martensitic blocks.

This module contains the class for FM steel structures after block generation. It adds block-level hierarchical structure (blocks within packets within PAGs).

Classes:

FMSteel3DWithBlocks: PAGs + blocks state class.

class upxo.pxtal.fm_steel_3d.with_blocks_3d.FMSteel3DWithBlocks(parent, all_blocks: Dict[str, numpy.ndarray], grain_to_blocks_map: Dict[int, List[str]], grain_to_plane_idx: Dict[int, int] | None = None, block_slicing_normals: Dict[str, numpy.ndarray] | None = None, slicing_planes: Dict | None = None, random_seed: int | None = None, verbosity: int | None = None, log_sink=None)[source]

Bases: object

FM steel grain structure with block hierarchy.

Holds the PAG structure plus computed martensitic blocks within each PAG. Blocks represent the smallest scale of microstructural organization in this model (below blocks are grains, above blocks are PAGs).

This is an intermediate state in the pipeline. It is created by calling generate_blocks() on a FMSteel3DWithPAGs instance, and transitions to FMSteel3DWithOrientations by calling assign_orientations().

_parent

Reference to parent PAG structure (read-only intermediate state).

Type:

FMSteel3DWithPAGs

all_blocks

Maps block_id (str) → (n_voxels, 3) array of voxel coordinates. Block naming convention: ‘B_{pag_id}_{grain_id}_{local_id}’.

Type:

dict[str, np.ndarray]

grain_to_blocks_map

Maps grain_id (= packet identifier, global integer) → list of block_ids produced from that packet. Keys are grain_ids, NOT local packet ordinals. Use parent.grain_to_local_pkt_idx to convert grain_id to a local ordinal.

Type:

dict[int, list[str]]

slicing_planes

Stores the Plane objects used for slicing (for visualization/debugging).

Type:

dict

_random_seed

Random seed used for block generation.

Type:

int

all_blocks
grain_to_blocks_map
grain_to_plane_idx
block_slicing_normals
slicing_planes
property lgi: numpy.ndarray

Labeled grain image from base parent.

property grain_locs: Dict[int, numpy.ndarray]

Grain voxel coordinates from base parent.

property clusters_dict: Dict[int, List[int]]

PAG clustering from parent.

property neigh_clid: Dict[int, List[int]]

PAG adjacency from parent.

property pag_orientations: Dict[int, Tuple[float, float, float]]

PAG orientations from parent.

property grain_to_pag_id: Dict[int, int]

Reverse lookup grain_id -> pag_id, derived from parent clusters_dict.

property grain_to_local_pkt_idx: Dict[int, int]

grain_id -> local_idx.

Type:

1-based local packet ordinal within each PAG

property n_grains: int

Total grains in base structure.

property physical_dimensions

Physical domain size.

property n_pags: int

Number of PAGs.

property n_blocks: int

Number of blocks.

property voxel_size: float

Voxel size.

property units: str

Physical unit string (‘microns’, ‘mm’, ‘m’).

property isolated_grains

Isolated grains from parent PAG level.

property isolated_grain_orientations

Isolated-grain orientations from parent PAG level (see FMSteel3DWithPAGs docstring).

property retained_austenite_pag_ids

Retained-austenite PAG IDs from parent PAG level (see FMSteel3DWithPAGs docstring). These PAG IDs were skipped by generate_blocks(), so they never appear in all_blocks/ grain_to_blocks_map.

property neigh_gid: Dict[int, List[int]]

Grain-level neighbour graph from base level.

property n_retained_austenite_pags: int

Number of retained-austenite PAGs from parent PAG level.

property n_transformed_pags: int

Number of transformed (martensite-forming) PAGs from parent PAG level.

ensure_isolated_grain_orientations(random_seed: int | None = None) → None[source]

See FMSteel3DWithPAGs.ensure_isolated_grain_orientations.

get_isolated_grain_orientation(gid: int) → Tuple[float, float, float] | None[source]

See FMSteel3DWithPAGs.get_isolated_grain_orientation.

assign_orientations(ks_variant_selection: str = 'random_per_block', random_seed: int | None = None) → FMSteel3DWithOrientations[source]

Assign BCC crystal orientations to blocks via the Kurdjumov-Sachs relationship.

PAG orientations must already be set (via assign_pag_orientations on the parent FMSteel3DWithPAGs). Each block receives one of the 24 KS variants from the physically appropriate packet for its habit plane.

Parameters:
  • ks_variant_selection (str, optional) – 'random_per_block' — adjacency-aware greedy graph-colouring: adjacent blocks within a packet receive different KS variants where possible, with a random choice among the free variants. 'deterministic' — always assigns KS variant index 0 from the packet; reproducible for geometry verification. Default 'random_per_block'.

  • random_seed (int, optional) – Random seed for reproducibility.

Returns:

New instance with computed orientations; does not modify self.

Return type:

FMSteel3DWithOrientations

assign_custom_block_orientations(euler_dict: Dict[str, Tuple[float, float, float]], random_seed: int | None = None) → FMSteel3DWithOrientations[source]

Bypass KS variant assignment with a user-supplied block orientation dict.

Use this as injection point C: apply any arbitrary orientation distribution to the existing block morphology without re-running the KS pipeline.

Parameters:
  • euler_dict (dict) – {block_id: (phi1, Phi, phi2)} — Bunge ZXZ Euler angles in degrees. Extra keys not in all_blocks are ignored (warning issued). Missing blocks will have no orientation in the returned object.

  • random_seed (int, optional) – Stored in the returned FMSteel3DWithOrientations for reproducibility.

Return type:

FMSteel3DWithOrientations

get_block_statistics() → Dict[source]

Compute statistics on block structure.