polycrystal#

anri.phantom.polycrystal(n, step, radius, n_grains, cell_size=1.5, cell_spread_deg=0.3, twin_grains=1, twin_axis=(1.0, 1.0, 1.0), twin_angle_deg=60.0, twin_period=5.0, twin_thickness=2.0, cell_walk_deg=0.0, cell_sig_deg=0.0, bend_grains=0, bend_deg=1.0, seed=0)[source]#

Make a disk-shaped polycrystal of grains with misoriented cells and twin lamellae.

The disk is split into Voronoi grains with random orientations, and into Voronoi cells of about cell_size (across grain boundaries alike), each turned from its grain by a small random rotation. The twin_grains largest grains carry twin lamellae: the twin is the grain turned by twin_angle_deg about the crystal direction twin_axis (60 degrees about <111> is the Sigma3 twin of FCC metals), in lamellae twin_thickness thick every twin_period with the twin plane normal to that axis.

Three options make orientation vary along the rays, as in deformed metals (all off by default):

  • Accumulating cells (cell_walk_deg): on top of its own random rotation, each cell is turned by a random field sampled at the cell’s seed, whose increments grow like a random walk with distance (a 2D Brownian field, each rotation-vector component independent). Two cells cell_size apart differ by cell_walk_deg rms per component, cells d apart by cell_walk_deg * sqrt(d / cell_size). Cells stay constant inside, with sharp boundaries.

  • Intrinsic spread (cell_sig_deg): the standard deviation of each component of a small rotation spread inside every voxel (dislocations within a cell, and what the beam height averages), returned as a “sig_rot” map in radians, as the renderer takes it (anri.fwd.render_row()).

  • Bent grains (bend_grains): that many grains (the largest after the twinned ones) turn steadily about one random axis along one random in-plane direction, by bend_deg per radius of distance, about the grain’s centre: lattice curvature with one dominant axis.

These draw from their own random stream, so a phantom without them is the same as before they existed.

Parameters:
  • n (int) – Grid of n x n voxels (reconstruction order)

  • step (float) – Voxel size

  • radius (float) – Disk radius, same units as step

  • n_grains (int) – Number of grains

  • cell_size (float, default: 1.5) – Typical cell size

  • cell_spread_deg (float, default: 0.3) – Standard deviation of each component of a cell’s rotation from its grain, degrees

  • twin_grains (int, default: 1) – How many grains are twinned

  • twin_axis (tuple[float, float, float], default: (1.0, 1.0, 1.0)) – The twin rotation, about a crystal direction

  • twin_angle_deg (float, default: 60.0) – The twin rotation, about a crystal direction

  • twin_period (float, default: 5.0) – Lamella spacing and thickness

  • twin_thickness (float, default: 2.0) – Lamella spacing and thickness

  • cell_walk_deg (float, default: 0.0) – Rms difference per rotation-vector component between cells cell_size apart, from the accumulating field, degrees

  • cell_sig_deg (float, default: 0.0) – Intrinsic spread inside each voxel, degrees (standard deviation per rotation-vector component)

  • bend_grains (int, default: 0) – How many grains are bent

  • bend_deg (float, default: 1.0) – Bend of those grains: degrees of rotation per radius of distance along the bend direction

  • seed (int, default: 0) – Random seed

Returns:

dict – Maps in reconstruction order: “U” [n, n, 3, 3] (crystal to sample; NaN outside), “grain” and “cell” [n, n] (-1 outside), “twin” and “inside” [n, n] bool; “pos” [n * n, 3], the voxel positions; and with cell_sig_deg, “sig_rot” [n, n] (radians, NaN outside)