CPO representation
CPOs are represented by their distributions of crystallographic axes in orientation space (\(S^2\)), neglecting grain sizes/mass and other topological information.
Supported grain symmetry groups are:
Grain symmetry | CPO components | Definition |
---|---|---|
Transversely isotropic | \(n(\theta,\phi)\) | Distribution of slip-plane normals |
Orthotropic | \(n(\theta,\phi),\,b(\theta,\phi)\) | Distribution of slip-plane normals and slip directions |
Thus, depending on which crystallographic slip system is preferentially activated, \(n(\theta,\phi)\) and \(b(\theta,\phi)\) may refer to the distributions of different crystallographic axes.
Glacier ice
Since ice grains are approximately transversely isotropic, tracking \(n(\theta,\phi)\) (the \(c\)-axis distribution) is sufficient for representing the CPO.
Olivine
For orthotropic grains such as olivine, both \(n(\theta,\phi)\) and \(b(\theta,\phi)\) distributions must be tracked to represent the CPO.
Note that \(n(\theta,\phi)\) and \(b(\theta,\phi)\) represent the distributions of particular crystallographic axes (\({\bf m}'_i\)) depending on fabric type (A—E type).
ODF
The orientation distribution function (ODF) of a given slip-system axis (crystallographic axis) \(f\in \lbrace n,b\rbrace\) is defined as the normalized distribution
Normalization
\(n(\theta,\phi)\) may be understood either as the number density of grains with a given slip-plane normal orientation, or as the mass density fraction (Faria, 2006; Richards et al., 2021) of grains with a given slip-plane normal orientation; \(\varrho^*(\theta,\phi)\) in literature. The same goes for \(b(\theta,\phi)\).
From specfab's point-of-view, the difference is a matter of normalization: since the models of CPO evolution (lattice rotation, DDRX, CDRX) conserve the normalization, the two views are effectively the same, not least because CPO-derived quantities depend on the normalized distributions (which are identical). The mass-density-fraction interpretation rests, however, on stronger physical grounds as mass is conserved but grain numbers are not.
Harmonic expansion
The distributions \(n(\theta,\phi)\) and \(b(\theta,\phi)\) are represented as spherical harmonic expansion series:
The CPO state is thus described by the state vectors of complex-valued expansion coefficients
where the magnitude and complex phase of the coefficients determine the size and rotation of the contribution from the associated harmonic mode.
Reduced form
Not all expansion coefficients are independent for real-valued expansion series, but must fulfill (likewise for \(b\))
This can be taken advantage of for large problems where many (e.g. gridded) CPOs must be stored in memory, thereby effectively reducing the size of the problem. The vector of reduced expansion coefficients is defined as
Converting between full and reduced forms is done as follows:
import numpy as np
from specfabpy import specfabpy as sf
lm, nlm_len = sf.init(2) # L=2 truncation is sufficient in this case
### Construct an arbitrary fabric
a2 = np.diag([0.1,0.2,0.7]) # arbitrary second-order structure tensor
nlm = np.zeros((nlm_len), dtype=np.complex64) # array of expansion coefficients
nlm[:sf.L2len] = sf.a2_to_nlm(a2) # determine l<=2 expansion coefficients of ODF
print('original:', nlm)
### Get reduced form of coefficient array, rnlm
rnlm_len = sf.get_rnlm_len()
rnlm = np.zeros((rnlm_len), dtype=np.complex64) # array of reduced expansion coefficients
rnlm[:] = sf.nlm_to_rnlm(nlm, rnlm_len) # reduced form
print('reduced:', rnlm)
### Recover full form (nlm) from reduced form (rnlm)
nlm[:] = sf.rnlm_to_nlm(rnlm, nlm_len)
print('recovered:', nlm)