pydrex

Simulate crystallographic preferred orientation evolution in polycrystals


This software is currently in early development (alpha) and therefore subject to breaking changes without notice.

About

Viscoplastic deformation of minerals, e.g. in Earth's mantle, leads to distinct signatures in the mineral texture. Many minerals naturally occur in polycrystalline form, which means that they are composed of many grains with different volumes and lattice orientations. Preferential alignment of the average lattice orientation is called crystallographic preferred orientation (CPO). PyDRex simulates the development and evolution of CPO in deforming polycrystals, as well as tracking macroscopic finite strain measures. Currently, the code supports olivine and enstatite mineral phases. The following features are provided:

  • JIT-compiled CPO solver, based on the D-Rex model, which updates the polycrystal orientation distribution depending on the macroscopic velocity gradients
  • Mineral class which stores attributes of a distinct mineral phase in the polycrystal and its texture snapshots
  • Voigt averaging to calculate the average elastic tensor of a textured, multiphase polycrystal
  • Decomposition of average elastic tensors into components attributed to minerals with distinct lattice symmetries
  • Crystallographic pole figure visualisation (contouring is a work in progress)
  • [work in progress] Texture diagnostics: M-index, bingham average, Point-Girdle-Random symmetry, coaxial a.k.a "BA" index, etc.
  • [work in progress] Seismic anisotropy diagnostics: % tensorial anisotropy, hexagonal symmetry a.k.a transverse isotropy direction, etc.

The core CPO solver is based on the original Fortran 90 implementation by Édouard Kaminski, which can be downloaded from this link (~90KB). The reference papers are Kaminski & Ribe (2001) and Kaminski & Ribe (2004), and an open-access paper which discusses the model is Fraters & Billen (2021).

Installation

The minimum required Python version is set using requires-python in the pyproject.toml file. For installation instructions, see the README file.

Documentation

The website menu can be used to discover the public API of this package. Some of the tests are also documented and can serve as usage examples. Their docstrings can be viewed in this section. Documentation is also available from the Python REPL via the help() method.

The D-Rex kinematic CPO model

The D-Rex model is used to compute crystallographic preferred orientation (CPO) for polycrystals deforming by plastic deformation and dynamic recrystallization. Polycrystals are discretized into "grains" which represent fractional volumes of the total crystal that are characterised by a particular crystal lattice orientation. For numerical efficiency, the number of grains in the model does not change, and should only be interpreted as an approximation of the number of (unrecrystallised) physical grains. Dynamic recrystallization is modelled using statistical expressions which approximate the interaction of each grain with an effective medium based on the averaged dislocation energy of all other grains. Note that the model is not suited to situations where static recrystallization processes are significant.

The primary microphysical mechanism for plastic deformation of the polycrystal is dislocation creep, which involves dislocation glide ("slip") along symmetry planes of the mineral and dislocation climb, which allows for dislocations to annihilate each other so that the number of dislocations reaches a steady-state. The D-Rex model does not simulate dislocation climb, but implicitly assumes that the dislocations are in steady-state so that the dislocation density of the crystal can be described by

$$ ρ ∝ b^{-2} \left(\frac{σ}{μ}\right)^{p} $$

where $b$ is the length of the Burgers' vector, $σ$ is the stress and $μ$ is the shear modulus. The value of the exponent $p$ is given by the stress_exponent input parameter. For an overview of available parameters, see [the pydrex.mock source code, for now...]

The effects of dynamic recrystallization are twofold. Grains with a higher than average dislocation density may be affected by either grain nucleation, which is the formation of initially small, strain-free sub-grains, or grain boundary migration, by which process other grains of lower strain energy annex a portion of its volume. Nucleation occurs mostly in grains oriented favourably for dislocation glide, and the new grains also grow by grain boundary migration. If nucleation is too inefficient, the dislocation density in deformation-aligned grains will remain high and these grains will therefore shrink in volume. On the other hand, if grain boundaries are too immobile, then nucleated grains will take longer to grow, reducing the speed of CPO development and re-orientation. Because nucleated grains are assumed to inherit the orientation of the parent, they do not affect the model except by reducing the average dislocation density. A grain boundary mobility parameter of $M^{∗} = 0$ will therefore disable any recrystallization effects. Finally, the process of grain boundary sliding can also be included, which simply disallows rotation of grains with very small volume. This only affects CPO evolution by introducing a latency for the onset of grain boundary migration in nucleated grains. It also manifests as an upper bound on texture strength.

Parameter reference

Model parameters will eventually be provided in a .toml file. For now just pass a dictionary to config in the Mineral.update_orientations method. A draft of the input file spec is shown below:

# PyDRex TOML configuration specification.
# Exactly one valid combination of fields from the [input] section are required,
# the rest is optional.

# Simulation name is optional but recommended.
name = "pydrex-spec"

# Input files/options are given in this section:
[input]

# Input data can be provided in one of three ways:
# 1. An input mesh with the steady-state numerical velocity gradient field
#    and a plain text SCSV file specifying the FINAL locations of the polycrystals.
#    In this case, polycrystals will first be back-propagated along flow pathlines,
#    and then forward-propagated while the CPO is calculated.
#    The SCSV file should have column names 'X', 'Y', 'Z' for 3D or any two of those for 2D.
# 2. A built-in (analytical) velocity gradient function from `pydrex.velocity_gradients`,
#    its arguments, and INITIAL locations of the polycrystals. In this case,
#    polycrystals will immediately be forward-advected in the specified field.
# 3. Pre-computed pathline files with velocity gradients at each point.
#    These can be either plain text SCSV files or binary NPZ files.
#    They should have columns/fields called: 'X_id', 'Y_id', 'Z_id', 'L11_id', 'L12_id', 'L13_id', etc.
#    where 'id' is replaced by an unique identifier of the particle/pathline.
#    If a field called 't' is also present, it will be used for the timestamps.
#    Alternatively, a fixed timestep for all paths can be specified using `timestep`.
# 4. Names of fields to be read from a geodynamics framework during runtime (not implemented yet).

# Example for method 1, not only .vtu but any format supported by meshio should work:
# mesh = "filename.vtu"
# locations_final = "filename.scsv"
# timestep = 1e9

# Example for method 2:
velocity_gradient = ["simple_shear_2d", "Y", "X", 5e-6]
locations_initial = "start.scsv"
timestep = 1e9

# Example for method 3:
# timestep = 1e9
# paths = ["path001.npz", "path002.scsv"]

# In cases where the pathlines do not exit the domain,
# a maximum strain threshold can bee provided, after which advection is halted.
# strain_final = 10

# Output files/options are given in this section:
[output]

# Optional output directory, will be created if missing.
# This is also relative to the parent directory of the TOML file,
# unless an absolute path is given.
directory = "out"

# Optional choice of mineral phases to include in raw output.
# Raw output means rotation matrices and grain volumes, so 10 floats per grain per mineral.
# By default, raw output for all supported minerals is saved.
raw_output = ["olivine"]

# Optional choice of mineral phases to include in diagnostic output.
# Diagnostic output includes texture symmetry, strength and mean angle results.
# By default, diagnostic output for all supported minerals is saved.
diagnostics = ["olivine"]

# Should anisotropy postprocessing results be calculated?
# This uses voigt averaging so the effective values for the multiphase polycrystal are calculated.
anisotropy = true

# Optional pathline output files (velocity gradients, positions, timestamps, particle ids).
# Pathline output files use the same format as pathline inputs (by default, they are not produced).
# They are stored inside the output directory unless absolute paths are given.
# paths = ["pathline001.scsv"]

# Optional logging level for log files.
# This sets the log level for all log files, overriding the default value of "WARNING".
# Supported levels are controlled by Python's logging module.
# Usually they are "CRITICAL", "ERROR", "WARNING", "INFO" and "DEBUG".
log_level = "DEBUG"

# DREX and simulation parameters are given in this section:
[parameters]

# Optional mineral phase assemblage to use for the aggregate.
# phase_assemblage = ["olivine", "enstatite"]

# Optional volume fractions of the mineral phases present in the aggregate.
# phase_fractions = [0.7, 0.3]

# Optional initial olivine fabric. A-type by default.
initial_olivine_fabric = "A"

# Optional DREX stress_exponent, see documentation for details.
stress_exponent = 1.5

# Optional DREX deformation_exponent, see documentation for details.
deformation_exponent = 3.5

# Optional DREX grain boudary mobility, see documentation for details.
gbm_mobility = 125

# Optional DREX grain boundary sliding threshold, see documentation for details.
gbs_threshold = 0.3

# Optional DREX nucleation efficiency, see documentation for details.
nucleation_efficiency = 5.0

# Optional number of (initial) grains per mineral phase per polycrystal.
number_of_grains = 2000
  1r"""
  2#### Simulate crystallographic preferred orientation evolution in polycrystals
  3
  4---
  5
  6.. warning::
  7    **This software is currently in early development (alpha)
  8    and therefore subject to breaking changes without notice.**
  9
 10## About
 11
 12Viscoplastic deformation of minerals, e.g. in Earth's mantle, leads to distinct
 13signatures in the mineral texture. Many minerals naturally occur in
 14polycrystalline form, which means that they are composed of many grains with
 15different volumes and lattice orientations. Preferential alignment of the
 16average lattice orientation is called crystallographic preferred orientation
 17(CPO). PyDRex simulates the development and evolution of CPO in deforming
 18polycrystals, as well as tracking macroscopic finite strain measures.
 19Currently, the code supports olivine and enstatite mineral phases. The
 20following features are provided:
 21- JIT-compiled CPO solver, based on the D-Rex model, which updates the
 22  polycrystal orientation distribution depending on the macroscopic velocity
 23  gradients
 24- `Mineral` class which stores attributes of a distinct mineral phase in the
 25  polycrystal and its texture snapshots
 26- Voigt averaging to calculate the average elastic tensor of a textured,
 27  multiphase polycrystal
 28- Decomposition of average elastic tensors into components attributed to
 29  minerals with distinct lattice symmetries
 30- Crystallographic pole figure visualisation (contouring is a work in progress)
 31- [work in progress] Texture diagnostics: M-index, bingham average,
 32  Point-Girdle-Random symmetry, coaxial a.k.a "BA" index, etc.
 33- [work in progress] Seismic anisotropy diagnostics: % tensorial anisotropy,
 34  hexagonal symmetry a.k.a transverse isotropy direction, etc.
 35
 36The core CPO solver is based on the original Fortran 90 implementation by Édouard Kaminski,
 37which can be [downloaded from this link (~90KB)](http://www.ipgp.fr/~kaminski/web_doudoud/DRex.tar.gz).
 38The reference papers are [Kaminski & Ribe (2001)](https://doi.org/10.1016/s0012-821x(01)00356-9)
 39and [Kaminski & Ribe (2004)](https://doi.org/10.1111%2Fj.1365-246x.2004.02308.x),
 40and an open-access paper which discusses the model is [Fraters & Billen (2021)](https://doi.org/10.1029/2021gc009846).
 41
 42## Installation
 43
 44The minimum required Python version is set using `requires-python` in the
 45[`pyproject.toml`](https://github.com/seismic-anisotropy/PyDRex/blob/main/pyproject.toml) file.
 46For installation instructions,
 47see [the README](https://github.com/seismic-anisotropy/PyDRex/blob/main/README.md) file.
 48
 49## Documentation
 50
 51The website menu can be used to discover the public API of this package.
 52Some of the tests are also documented and can serve as usage examples.
 53Their docstrings can be viewed [in this section](../tests.html).
 54Documentation is also available from the Python REPL via the `help()` method.
 55
 56## The D-Rex kinematic CPO model
 57
 58The D-Rex model is used to compute crystallographic preferred orientation (CPO)
 59for polycrystals deforming by plastic deformation and dynamic recrystallization.
 60Polycrystals are discretized into "grains" which represent fractional volumes
 61of the total crystal that are characterised by a particular crystal lattice
 62orientation. For numerical efficiency, the number of grains in the model does
 63not change, and should only be interpreted as an approximation of the number
 64of (unrecrystallised) physical grains. Dynamic recrystallization is modelled using
 65statistical expressions which approximate the interaction of each grain with an
 66effective medium based on the averaged dislocation energy of all other grains. Note that
 67the model is not suited to situations where static recrystallization processes are
 68significant.
 69
 70The primary microphysical mechanism for plastic deformation of the polycrystal
 71is dislocation creep, which involves dislocation glide ("slip") along symmetry
 72planes of the mineral and dislocation climb, which allows for dislocations to
 73annihilate each other so that the number of dislocations reaches a steady-state.
 74The D-Rex model does not simulate dislocation climb, but implicitly assumes that
 75the dislocations are in steady-state so that the dislocation density of the
 76crystal can be described by
 77
 78$$
 79ρ ∝ b^{-2} \left(\frac{σ}{μ}\right)^{p}
 80$$
 81
 82where $b$ is the length of the Burgers' vector, $σ$ is the stress
 83and $μ$ is the shear modulus. The value of the exponent $p$ is given by the
 84`stress_exponent` input parameter. For an overview of available parameters,
 85see [the `pydrex.mock` source code, for now...]
 86
 87The effects of dynamic recrystallization are twofold. Grains with a higher than
 88average dislocation density may be affected by either grain nucleation, which is
 89the formation of initially small, strain-free sub-grains, or grain boundary
 90migration, by which process other grains of lower strain energy annex a portion
 91of its volume. Nucleation occurs mostly in grains oriented favourably for
 92dislocation glide, and the new grains also grow by grain boundary migration.
 93If nucleation is too inefficient, the dislocation density in deformation-aligned
 94grains will remain high and these grains will therefore shrink in volume. On the
 95other hand, if grain boundaries are too immobile, then nucleated grains will take
 96longer to grow, reducing the speed of CPO development and re-orientation.
 97Because nucleated grains are assumed to inherit the orientation of the parent,
 98they do not affect the model except by reducing the average dislocation density.
 99A grain boundary mobility parameter of $M^{∗} = 0$ will therefore disable any
100recrystallization effects. Finally, the process of grain boundary sliding can
101also be included, which simply disallows rotation of grains with very small volume.
102This only affects CPO evolution by introducing a latency for the onset of grain
103boundary migration in nucleated grains. It also manifests as an upper bound on
104texture strength.
105
106## Parameter reference
107
108Model parameters will eventually be provided in a `.toml` file.
109For now just pass a dictionary to `config` in the `Mineral.update_orientations` method.
110A draft of the input file spec is shown below:
111
112```toml
113.. include:: data/specs/spec.toml
114```
115
116"""
117
118# Set up the top-level pydrex namespace for convenient usage.
119# To keep it clean, we don't want every single symbol here, especially not those from
120# `utils` or `visualisation` modules, which should be explicitly imported instead.
121import pydrex.axes  # Defines the 'pydrex.polefigure' Axes subclass.
122from pydrex.core import (
123    DefaultParams,
124    DeformationRegime,
125    MineralFabric,
126    MineralPhase,
127    derivatives,
128    get_crss,
129)
130from pydrex.diagnostics import (
131    bingham_average,
132    coaxial_index,
133    elasticity_components,
134    finite_strain,
135    misorientation_index,
136    misorientation_indices,
137    smallest_angle,
138    symmetry_pgr,
139)
140from pydrex.geometry import (
141    LatticeSystem,
142    misorientation_angles,
143    poles,
144    symmetry_operations,
145    to_cartesian,
146    to_indices2d,
147    to_spherical,
148)
149from pydrex.io import data, logfile_enable, read_scsv, save_scsv
150from pydrex.minerals import (
151    OLIVINE_PRIMARY_AXIS,
152    OLIVINE_SLIP_SYSTEMS,
153    Mineral,
154    StiffnessTensors,
155    peridotite_solidus,
156    voigt_averages,
157    update_all,
158)
159from pydrex.stats import (
160    misorientation_hist,
161    misorientations_random,
162    resample_orientations,
163)