separating functionality
This commit is contained in:
parent
b55d51491d
commit
302da1f76a
|
@ -14,11 +14,11 @@ from . import tensor # noqa
|
|||
from . import mechanics # noqa
|
||||
from . import solver # noqa
|
||||
from . import grid_filters # noqa
|
||||
from . import lattice # noqa
|
||||
#Modules that contain only one class (of the same name), are prefixed by a '_'.
|
||||
#For example, '_colormap' containsa class called 'Colormap' which is imported as 'damask.Colormap'.
|
||||
from ._rotation import Rotation # noqa
|
||||
from ._lattice_family import LatticeFamily # noqa
|
||||
from ._lattice import Lattice # noqa
|
||||
from ._orientation import Orientation # noqa
|
||||
from ._table import Table # noqa
|
||||
from ._vtk import VTK # noqa
|
||||
|
|
|
@ -0,0 +1,651 @@
|
|||
import numpy as np
|
||||
|
||||
from . import util
|
||||
from . import LatticeFamily
|
||||
|
||||
lattice_symmetries = {
|
||||
'aP': 'triclinic',
|
||||
|
||||
'mP': 'monoclinic',
|
||||
'mS': 'monoclinic',
|
||||
|
||||
'oP': 'orthorhombic',
|
||||
'oS': 'orthorhombic',
|
||||
'oI': 'orthorhombic',
|
||||
'oF': 'orthorhombic',
|
||||
|
||||
'tP': 'tetragonal',
|
||||
'tI': 'tetragonal',
|
||||
|
||||
'hP': 'hexagonal',
|
||||
|
||||
'cP': 'cubic',
|
||||
'cI': 'cubic',
|
||||
'cF': 'cubic',
|
||||
}
|
||||
|
||||
|
||||
class Lattice(LatticeFamily):
|
||||
"""Lattice."""
|
||||
|
||||
def __init__(self,
|
||||
lattice = None,
|
||||
a = None,b = None,c = None,
|
||||
alpha = None,beta = None,gamma = None,
|
||||
degrees = False):
|
||||
"""
|
||||
Lattice.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
lattice : {'aP', 'mP', 'mS', 'oP', 'oS', 'oI', 'oF', 'tP', 'tI', 'hP', 'cP', 'cI', 'cF'}.
|
||||
Name of the Bravais lattice in Pearson notation.
|
||||
a : float, optional
|
||||
Length of lattice parameter 'a'.
|
||||
b : float, optional
|
||||
Length of lattice parameter 'b'.
|
||||
c : float, optional
|
||||
Length of lattice parameter 'c'.
|
||||
alpha : float, optional
|
||||
Angle between b and c lattice basis.
|
||||
beta : float, optional
|
||||
Angle between c and a lattice basis.
|
||||
gamma : float, optional
|
||||
Angle between a and b lattice basis.
|
||||
degrees : bool, optional
|
||||
Angles are given in degrees. Defaults to False.
|
||||
|
||||
"""
|
||||
super().__init__(lattice_symmetries[lattice])
|
||||
self.lattice = lattice
|
||||
|
||||
|
||||
self.a = 1 if a is None else a
|
||||
self.b = b
|
||||
self.c = c
|
||||
self.a = float(self.a) if self.a is not None else \
|
||||
(self.b / self.ratio['b'] if self.b is not None and self.ratio['b'] is not None else
|
||||
self.c / self.ratio['c'] if self.c is not None and self.ratio['c'] is not None else None)
|
||||
self.b = float(self.b) if self.b is not None else \
|
||||
(self.a * self.ratio['b'] if self.a is not None and self.ratio['b'] is not None else
|
||||
self.c / self.ratio['c'] * self.ratio['b']
|
||||
if self.c is not None and self.ratio['b'] is not None and self.ratio['c'] is not None else None)
|
||||
self.c = float(self.c) if self.c is not None else \
|
||||
(self.a * self.ratio['c'] if self.a is not None and self.ratio['c'] is not None else
|
||||
self.b / self.ratio['b'] * self.ratio['c']
|
||||
if self.c is not None and self.ratio['b'] is not None and self.ratio['c'] is not None else None)
|
||||
|
||||
self.alpha = np.radians(alpha) if degrees and alpha is not None else alpha
|
||||
self.beta = np.radians(beta) if degrees and beta is not None else beta
|
||||
self.gamma = np.radians(gamma) if degrees and gamma is not None else gamma
|
||||
if self.alpha is None and 'alpha' in self.immutable: self.alpha = self.immutable['alpha']
|
||||
if self.beta is None and 'beta' in self.immutable: self.beta = self.immutable['beta']
|
||||
if self.gamma is None and 'gamma' in self.immutable: self.gamma = self.immutable['gamma']
|
||||
|
||||
if \
|
||||
(self.a is None) \
|
||||
or (self.b is None or ('b' in self.immutable and self.b != self.immutable['b'] * self.a)) \
|
||||
or (self.c is None or ('c' in self.immutable and self.c != self.immutable['c'] * self.b)) \
|
||||
or (self.alpha is None or ('alpha' in self.immutable and self.alpha != self.immutable['alpha'])) \
|
||||
or (self.beta is None or ( 'beta' in self.immutable and self.beta != self.immutable['beta'])) \
|
||||
or (self.gamma is None or ('gamma' in self.immutable and self.gamma != self.immutable['gamma'])):
|
||||
raise ValueError (f'Incompatible parameters {self.parameters} for crystal family {self.family}')
|
||||
|
||||
if np.any(np.array([self.alpha,self.beta,self.gamma]) <= 0):
|
||||
raise ValueError ('Lattice angles must be positive')
|
||||
if np.any([np.roll([self.alpha,self.beta,self.gamma],r)[0]
|
||||
> np.sum(np.roll([self.alpha,self.beta,self.gamma],r)[1:]) for r in range(3)]):
|
||||
raise ValueError ('Each lattice angle must be less than sum of others')
|
||||
|
||||
|
||||
@property
|
||||
def parameters(self):
|
||||
"""Return lattice parameters a, b, c, alpha, beta, gamma."""
|
||||
return (self.a,self.b,self.c,self.alpha,self.beta,self.gamma)
|
||||
|
||||
|
||||
@property
|
||||
def ratio(self):
|
||||
"""Return axes ratios of own lattice."""
|
||||
_ratio = { 'hexagonal': {'c': np.sqrt(8./3.)}}
|
||||
|
||||
return dict(b = self.immutable['b']
|
||||
if 'b' in self.immutable else
|
||||
_ratio[self.family]['b'] if self.family in _ratio and 'b' in _ratio[self.family] else None,
|
||||
c = self.immutable['c']
|
||||
if 'c' in self.immutable else
|
||||
_ratio[self.family]['c'] if self.family in _ratio and 'c' in _ratio[self.family] else None,
|
||||
)
|
||||
|
||||
|
||||
@property
|
||||
def basis_real(self):
|
||||
"""
|
||||
Calculate orthogonal real space crystal basis.
|
||||
|
||||
References
|
||||
----------
|
||||
C.T. Young and J.L. Lytton, Journal of Applied Physics 43:1408–1417, 1972
|
||||
https://doi.org/10.1063/1.1661333
|
||||
|
||||
"""
|
||||
if None in self.parameters:
|
||||
raise KeyError('missing crystal lattice parameters')
|
||||
return np.array([
|
||||
[1,0,0],
|
||||
[np.cos(self.gamma),np.sin(self.gamma),0],
|
||||
[np.cos(self.beta),
|
||||
(np.cos(self.alpha)-np.cos(self.beta)*np.cos(self.gamma)) /np.sin(self.gamma),
|
||||
np.sqrt(1 - np.cos(self.alpha)**2 - np.cos(self.beta)**2 - np.cos(self.gamma)**2
|
||||
+ 2 * np.cos(self.alpha) * np.cos(self.beta) * np.cos(self.gamma))/np.sin(self.gamma)],
|
||||
],dtype=float).T \
|
||||
* np.array([self.a,self.b,self.c])
|
||||
|
||||
|
||||
@property
|
||||
def basis_reciprocal(self):
|
||||
"""Calculate reciprocal (dual) crystal basis."""
|
||||
return np.linalg.inv(self.basis_real.T)
|
||||
|
||||
|
||||
def to_lattice(self,*,direction=None,plane=None):
|
||||
"""
|
||||
Calculate lattice vector corresponding to crystal frame direction or plane normal.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
direction|normal : numpy.ndarray of shape (...,3)
|
||||
Vector along direction or plane normal.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Miller : numpy.ndarray of shape (...,3)
|
||||
lattice vector of direction or plane.
|
||||
Use util.scale_to_coprime to convert to (integer) Miller indices.
|
||||
|
||||
"""
|
||||
if (direction is not None) ^ (plane is None):
|
||||
raise KeyError('Specify either "direction" or "plane"')
|
||||
axis,basis = (np.array(direction),self.basis_reciprocal.T) \
|
||||
if plane is None else \
|
||||
(np.array(plane),self.basis_real.T)
|
||||
return np.einsum('il,...l',basis,axis)
|
||||
|
||||
|
||||
def to_frame(self,*,uvw=None,hkl=None):
|
||||
"""
|
||||
Calculate crystal frame vector along lattice direction [uvw] or plane normal (hkl).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
uvw|hkl : numpy.ndarray of shape (...,3)
|
||||
Miller indices of crystallographic direction or plane normal.
|
||||
|
||||
Returns
|
||||
-------
|
||||
vector : numpy.ndarray of shape (...,3) or (N,...,3)
|
||||
Crystal frame vector (or vectors if with_symmetry) along [uvw] direction or (hkl) plane normal.
|
||||
|
||||
"""
|
||||
if (uvw is not None) ^ (hkl is None):
|
||||
raise KeyError('Specify either "uvw" or "hkl"')
|
||||
axis,basis = (np.array(uvw),self.basis_real) \
|
||||
if hkl is None else \
|
||||
(np.array(hkl),self.basis_reciprocal)
|
||||
return np.einsum('il,...l',basis,axis)
|
||||
|
||||
|
||||
def kinematics(self,mode):
|
||||
master = self._kinematics[self.lattice][mode]
|
||||
if self.lattice == 'hP':
|
||||
return {'direction':util.Bravais_to_Miller(uvtw=master[:,0:4]),
|
||||
'plane': util.Bravais_to_Miller(hkil=master[:,4:8])}
|
||||
else:
|
||||
return {'direction':master[:,0:3],
|
||||
'plane': master[:,3:6]}
|
||||
|
||||
|
||||
@property
|
||||
def orientation_relationships(self):
|
||||
return {k:v for k,v in self._orientation_relationships.items() if self.lattice in v}
|
||||
|
||||
|
||||
_kinematics = {
|
||||
'cF': {
|
||||
'slip' : np.array([
|
||||
[+0,+1,-1, +1,+1,+1],
|
||||
[-1,+0,+1, +1,+1,+1],
|
||||
[+1,-1,+0, +1,+1,+1],
|
||||
[+0,-1,-1, -1,-1,+1],
|
||||
[+1,+0,+1, -1,-1,+1],
|
||||
[-1,+1,+0, -1,-1,+1],
|
||||
[+0,-1,+1, +1,-1,-1],
|
||||
[-1,+0,-1, +1,-1,-1],
|
||||
[+1,+1,+0, +1,-1,-1],
|
||||
[+0,+1,+1, -1,+1,-1],
|
||||
[+1,+0,-1, -1,+1,-1],
|
||||
[-1,-1,+0, -1,+1,-1],
|
||||
[+1,+1,+0, +1,-1,+0],
|
||||
[+1,-1,+0, +1,+1,+0],
|
||||
[+1,+0,+1, +1,+0,-1],
|
||||
[+1,+0,-1, +1,+0,+1],
|
||||
[+0,+1,+1, +0,+1,-1],
|
||||
[+0,+1,-1, +0,+1,+1],
|
||||
],'d'),
|
||||
'twin' : np.array([
|
||||
[-2, 1, 1, 1, 1, 1],
|
||||
[ 1,-2, 1, 1, 1, 1],
|
||||
[ 1, 1,-2, 1, 1, 1],
|
||||
[ 2,-1, 1, -1,-1, 1],
|
||||
[-1, 2, 1, -1,-1, 1],
|
||||
[-1,-1,-2, -1,-1, 1],
|
||||
[-2,-1,-1, 1,-1,-1],
|
||||
[ 1, 2,-1, 1,-1,-1],
|
||||
[ 1,-1, 2, 1,-1,-1],
|
||||
[ 2, 1,-1, -1, 1,-1],
|
||||
[-1,-2,-1, -1, 1,-1],
|
||||
[-1, 1, 2, -1, 1,-1],
|
||||
],dtype=float),
|
||||
},
|
||||
'cI': {
|
||||
'slip' : np.array([
|
||||
[+1,-1,+1, +0,+1,+1],
|
||||
[-1,-1,+1, +0,+1,+1],
|
||||
[+1,+1,+1, +0,-1,+1],
|
||||
[-1,+1,+1, +0,-1,+1],
|
||||
[-1,+1,+1, +1,+0,+1],
|
||||
[-1,-1,+1, +1,+0,+1],
|
||||
[+1,+1,+1, -1,+0,+1],
|
||||
[+1,-1,+1, -1,+0,+1],
|
||||
[-1,+1,+1, +1,+1,+0],
|
||||
[-1,+1,-1, +1,+1,+0],
|
||||
[+1,+1,+1, -1,+1,+0],
|
||||
[+1,+1,-1, -1,+1,+0],
|
||||
[-1,+1,+1, +2,+1,+1],
|
||||
[+1,+1,+1, -2,+1,+1],
|
||||
[+1,+1,-1, +2,-1,+1],
|
||||
[+1,-1,+1, +2,+1,-1],
|
||||
[+1,-1,+1, +1,+2,+1],
|
||||
[+1,+1,-1, -1,+2,+1],
|
||||
[+1,+1,+1, +1,-2,+1],
|
||||
[-1,+1,+1, +1,+2,-1],
|
||||
[+1,+1,-1, +1,+1,+2],
|
||||
[+1,-1,+1, -1,+1,+2],
|
||||
[-1,+1,+1, +1,-1,+2],
|
||||
[+1,+1,+1, +1,+1,-2],
|
||||
[+1,+1,-1, +1,+2,+3],
|
||||
[+1,-1,+1, -1,+2,+3],
|
||||
[-1,+1,+1, +1,-2,+3],
|
||||
[+1,+1,+1, +1,+2,-3],
|
||||
[+1,-1,+1, +1,+3,+2],
|
||||
[+1,+1,-1, -1,+3,+2],
|
||||
[+1,+1,+1, +1,-3,+2],
|
||||
[-1,+1,+1, +1,+3,-2],
|
||||
[+1,+1,-1, +2,+1,+3],
|
||||
[+1,-1,+1, -2,+1,+3],
|
||||
[-1,+1,+1, +2,-1,+3],
|
||||
[+1,+1,+1, +2,+1,-3],
|
||||
[+1,-1,+1, +2,+3,+1],
|
||||
[+1,+1,-1, -2,+3,+1],
|
||||
[+1,+1,+1, +2,-3,+1],
|
||||
[-1,+1,+1, +2,+3,-1],
|
||||
[-1,+1,+1, +3,+1,+2],
|
||||
[+1,+1,+1, -3,+1,+2],
|
||||
[+1,+1,-1, +3,-1,+2],
|
||||
[+1,-1,+1, +3,+1,-2],
|
||||
[-1,+1,+1, +3,+2,+1],
|
||||
[+1,+1,+1, -3,+2,+1],
|
||||
[+1,+1,-1, +3,-2,+1],
|
||||
[+1,-1,+1, +3,+2,-1],
|
||||
],'d'),
|
||||
'twin' : np.array([
|
||||
[-1, 1, 1, 2, 1, 1],
|
||||
[ 1, 1, 1, -2, 1, 1],
|
||||
[ 1, 1,-1, 2,-1, 1],
|
||||
[ 1,-1, 1, 2, 1,-1],
|
||||
[ 1,-1, 1, 1, 2, 1],
|
||||
[ 1, 1,-1, -1, 2, 1],
|
||||
[ 1, 1, 1, 1,-2, 1],
|
||||
[-1, 1, 1, 1, 2,-1],
|
||||
[ 1, 1,-1, 1, 1, 2],
|
||||
[ 1,-1, 1, -1, 1, 2],
|
||||
[-1, 1, 1, 1,-1, 2],
|
||||
[ 1, 1, 1, 1, 1,-2],
|
||||
],dtype=float),
|
||||
},
|
||||
'hP': {
|
||||
'slip' : np.array([
|
||||
[+2,-1,-1,+0, +0,+0,+0,+1],
|
||||
[-1,+2,-1,+0, +0,+0,+0,+1],
|
||||
[-1,-1,+2,+0, +0,+0,+0,+1],
|
||||
[+2,-1,-1,+0, +0,+1,-1,+0],
|
||||
[-1,+2,-1,+0, -1,+0,+1,+0],
|
||||
[-1,-1,+2,+0, +1,-1,+0,+0],
|
||||
[-1,+1,+0,+0, +1,+1,-2,+0],
|
||||
[+0,-1,+1,+0, -2,+1,+1,+0],
|
||||
[+1,+0,-1,+0, +1,-2,+1,+0],
|
||||
[-1,+2,-1,+0, +1,+0,-1,+1],
|
||||
[-2,+1,+1,+0, +0,+1,-1,+1],
|
||||
[-1,-1,+2,+0, -1,+1,+0,+1],
|
||||
[+1,-2,+1,+0, -1,+0,+1,+1],
|
||||
[+2,-1,-1,+0, +0,-1,+1,+1],
|
||||
[+1,+1,-2,+0, +1,-1,+0,+1],
|
||||
[-2,+1,+1,+3, +1,+0,-1,+1],
|
||||
[-1,-1,+2,+3, +1,+0,-1,+1],
|
||||
[-1,-1,+2,+3, +0,+1,-1,+1],
|
||||
[+1,-2,+1,+3, +0,+1,-1,+1],
|
||||
[+1,-2,+1,+3, -1,+1,+0,+1],
|
||||
[+2,-1,-1,+3, -1,+1,+0,+1],
|
||||
[+2,-1,-1,+3, -1,+0,+1,+1],
|
||||
[+1,+1,-2,+3, -1,+0,+1,+1],
|
||||
[+1,+1,-2,+3, +0,-1,+1,+1],
|
||||
[-1,+2,-1,+3, +0,-1,+1,+1],
|
||||
[-1,+2,-1,+3, +1,-1,+0,+1],
|
||||
[-2,+1,+1,+3, +1,-1,+0,+1],
|
||||
[-1,-1,+2,+3, +1,+1,-2,+2],
|
||||
[+1,-2,+1,+3, -1,+2,-1,+2],
|
||||
[+2,-1,-1,+3, -2,+1,+1,+2],
|
||||
[+1,+1,-2,+3, -1,-1,+2,+2],
|
||||
[-1,+2,-1,+3, +1,-2,+1,+2],
|
||||
[-2,+1,+1,+3, +2,-1,-1,+2],
|
||||
],'d'),
|
||||
'twin' : np.array([
|
||||
[-1, 0, 1, 1, 1, 0,-1, 2], # shear = (3-(c/a)^2)/(sqrt(3) c/a) <-10.1>{10.2}
|
||||
[ 0,-1, 1, 1, 0, 1,-1, 2],
|
||||
[ 1,-1, 0, 1, -1, 1, 0, 2],
|
||||
[ 1, 0,-1, 1, -1, 0, 1, 2],
|
||||
[ 0, 1,-1, 1, 0,-1, 1, 2],
|
||||
[-1, 1, 0, 1, 1,-1, 0, 2],
|
||||
[-1,-1, 2, 6, 1, 1,-2, 1], # shear = 1/(c/a) <11.6>{-1-1.1}
|
||||
[ 1,-2, 1, 6, -1, 2,-1, 1],
|
||||
[ 2,-1,-1, 6, -2, 1, 1, 1],
|
||||
[ 1, 1,-2, 6, -1,-1, 2, 1],
|
||||
[-1, 2,-1, 6, 1,-2, 1, 1],
|
||||
[-2, 1, 1, 6, 2,-1,-1, 1],
|
||||
[ 1, 0,-1,-2, 1, 0,-1, 1], # shear = (4(c/a)^2-9)/(4 sqrt(3) c/a) <10.-2>{10.1}
|
||||
[ 0, 1,-1,-2, 0, 1,-1, 1],
|
||||
[-1, 1, 0,-2, -1, 1, 0, 1],
|
||||
[-1, 0, 1,-2, -1, 0, 1, 1],
|
||||
[ 0,-1, 1,-2, 0,-1, 1, 1],
|
||||
[ 1,-1, 0,-2, 1,-1, 0, 1],
|
||||
[ 1, 1,-2,-3, 1, 1,-2, 2], # shear = 2((c/a)^2-2)/(3 c/a) <11.-3>{11.2}
|
||||
[-1, 2,-1,-3, -1, 2,-1, 2],
|
||||
[-2, 1, 1,-3, -2, 1, 1, 2],
|
||||
[-1,-1, 2,-3, -1,-1, 2, 2],
|
||||
[ 1,-2, 1,-3, 1,-2, 1, 2],
|
||||
[ 2,-1,-1,-3, 2,-1,-1, 2],
|
||||
],dtype=float),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
_orientation_relationships = {
|
||||
'KS': {
|
||||
'cF' : np.array([
|
||||
[[-1, 0, 1],[ 1, 1, 1]],
|
||||
[[-1, 0, 1],[ 1, 1, 1]],
|
||||
[[ 0, 1,-1],[ 1, 1, 1]],
|
||||
[[ 0, 1,-1],[ 1, 1, 1]],
|
||||
[[ 1,-1, 0],[ 1, 1, 1]],
|
||||
[[ 1,-1, 0],[ 1, 1, 1]],
|
||||
[[ 1, 0,-1],[ 1,-1, 1]],
|
||||
[[ 1, 0,-1],[ 1,-1, 1]],
|
||||
[[-1,-1, 0],[ 1,-1, 1]],
|
||||
[[-1,-1, 0],[ 1,-1, 1]],
|
||||
[[ 0, 1, 1],[ 1,-1, 1]],
|
||||
[[ 0, 1, 1],[ 1,-1, 1]],
|
||||
[[ 0,-1, 1],[-1, 1, 1]],
|
||||
[[ 0,-1, 1],[-1, 1, 1]],
|
||||
[[-1, 0,-1],[-1, 1, 1]],
|
||||
[[-1, 0,-1],[-1, 1, 1]],
|
||||
[[ 1, 1, 0],[-1, 1, 1]],
|
||||
[[ 1, 1, 0],[-1, 1, 1]],
|
||||
[[-1, 1, 0],[ 1, 1,-1]],
|
||||
[[-1, 1, 0],[ 1, 1,-1]],
|
||||
[[ 0,-1,-1],[ 1, 1,-1]],
|
||||
[[ 0,-1,-1],[ 1, 1,-1]],
|
||||
[[ 1, 0, 1],[ 1, 1,-1]],
|
||||
[[ 1, 0, 1],[ 1, 1,-1]],
|
||||
],dtype=float),
|
||||
'cI' : np.array([
|
||||
[[-1,-1, 1],[ 0, 1, 1]],
|
||||
[[-1, 1,-1],[ 0, 1, 1]],
|
||||
[[-1,-1, 1],[ 0, 1, 1]],
|
||||
[[-1, 1,-1],[ 0, 1, 1]],
|
||||
[[-1,-1, 1],[ 0, 1, 1]],
|
||||
[[-1, 1,-1],[ 0, 1, 1]],
|
||||
[[-1,-1, 1],[ 0, 1, 1]],
|
||||
[[-1, 1,-1],[ 0, 1, 1]],
|
||||
[[-1,-1, 1],[ 0, 1, 1]],
|
||||
[[-1, 1,-1],[ 0, 1, 1]],
|
||||
[[-1,-1, 1],[ 0, 1, 1]],
|
||||
[[-1, 1,-1],[ 0, 1, 1]],
|
||||
[[-1,-1, 1],[ 0, 1, 1]],
|
||||
[[-1, 1,-1],[ 0, 1, 1]],
|
||||
[[-1,-1, 1],[ 0, 1, 1]],
|
||||
[[-1, 1,-1],[ 0, 1, 1]],
|
||||
[[-1,-1, 1],[ 0, 1, 1]],
|
||||
[[-1, 1,-1],[ 0, 1, 1]],
|
||||
[[-1,-1, 1],[ 0, 1, 1]],
|
||||
[[-1, 1,-1],[ 0, 1, 1]],
|
||||
[[-1,-1, 1],[ 0, 1, 1]],
|
||||
[[-1, 1,-1],[ 0, 1, 1]],
|
||||
[[-1,-1, 1],[ 0, 1, 1]],
|
||||
[[-1, 1,-1],[ 0, 1, 1]],
|
||||
],dtype=float),
|
||||
},
|
||||
'GT': {
|
||||
'cF' : np.array([
|
||||
[[ -5,-12, 17],[ 1, 1, 1]],
|
||||
[[ 17, -5,-12],[ 1, 1, 1]],
|
||||
[[-12, 17, -5],[ 1, 1, 1]],
|
||||
[[ 5, 12, 17],[ -1, -1, 1]],
|
||||
[[-17, 5,-12],[ -1, -1, 1]],
|
||||
[[ 12,-17, -5],[ -1, -1, 1]],
|
||||
[[ -5, 12,-17],[ -1, 1, 1]],
|
||||
[[ 17, 5, 12],[ -1, 1, 1]],
|
||||
[[-12,-17, 5],[ -1, 1, 1]],
|
||||
[[ 5,-12,-17],[ 1, -1, 1]],
|
||||
[[-17, -5, 12],[ 1, -1, 1]],
|
||||
[[ 12, 17, 5],[ 1, -1, 1]],
|
||||
[[ -5, 17,-12],[ 1, 1, 1]],
|
||||
[[-12, -5, 17],[ 1, 1, 1]],
|
||||
[[ 17,-12, -5],[ 1, 1, 1]],
|
||||
[[ 5,-17,-12],[ -1, -1, 1]],
|
||||
[[ 12, 5, 17],[ -1, -1, 1]],
|
||||
[[-17, 12, -5],[ -1, -1, 1]],
|
||||
[[ -5,-17, 12],[ -1, 1, 1]],
|
||||
[[-12, 5,-17],[ -1, 1, 1]],
|
||||
[[ 17, 12, 5],[ -1, 1, 1]],
|
||||
[[ 5, 17, 12],[ 1, -1, 1]],
|
||||
[[ 12, -5,-17],[ 1, -1, 1]],
|
||||
[[-17,-12, 5],[ 1, -1, 1]],
|
||||
],dtype=float),
|
||||
'cI' : np.array([
|
||||
[[-17, -7, 17],[ 1, 0, 1]],
|
||||
[[ 17,-17, -7],[ 1, 1, 0]],
|
||||
[[ -7, 17,-17],[ 0, 1, 1]],
|
||||
[[ 17, 7, 17],[ -1, 0, 1]],
|
||||
[[-17, 17, -7],[ -1, -1, 0]],
|
||||
[[ 7,-17,-17],[ 0, -1, 1]],
|
||||
[[-17, 7,-17],[ -1, 0, 1]],
|
||||
[[ 17, 17, 7],[ -1, 1, 0]],
|
||||
[[ -7,-17, 17],[ 0, 1, 1]],
|
||||
[[ 17, -7,-17],[ 1, 0, 1]],
|
||||
[[-17,-17, 7],[ 1, -1, 0]],
|
||||
[[ 7, 17, 17],[ 0, -1, 1]],
|
||||
[[-17, 17, -7],[ 1, 1, 0]],
|
||||
[[ -7,-17, 17],[ 0, 1, 1]],
|
||||
[[ 17, -7,-17],[ 1, 0, 1]],
|
||||
[[ 17,-17, -7],[ -1, -1, 0]],
|
||||
[[ 7, 17, 17],[ 0, -1, 1]],
|
||||
[[-17, 7,-17],[ -1, 0, 1]],
|
||||
[[-17,-17, 7],[ -1, 1, 0]],
|
||||
[[ -7, 17,-17],[ 0, 1, 1]],
|
||||
[[ 17, 7, 17],[ -1, 0, 1]],
|
||||
[[ 17, 17, 7],[ 1, -1, 0]],
|
||||
[[ 7,-17,-17],[ 0, -1, 1]],
|
||||
[[-17, -7, 17],[ 1, 0, 1]],
|
||||
],dtype=float),
|
||||
},
|
||||
'GT_prime': {
|
||||
'cF' : np.array([
|
||||
[[ 0, 1, -1],[ 7, 17, 17]],
|
||||
[[ -1, 0, 1],[ 17, 7, 17]],
|
||||
[[ 1, -1, 0],[ 17, 17, 7]],
|
||||
[[ 0, -1, -1],[ -7,-17, 17]],
|
||||
[[ 1, 0, 1],[-17, -7, 17]],
|
||||
[[ 1, -1, 0],[-17,-17, 7]],
|
||||
[[ 0, 1, -1],[ 7,-17,-17]],
|
||||
[[ 1, 0, 1],[ 17, -7,-17]],
|
||||
[[ -1, -1, 0],[ 17,-17, -7]],
|
||||
[[ 0, -1, -1],[ -7, 17,-17]],
|
||||
[[ -1, 0, 1],[-17, 7,-17]],
|
||||
[[ -1, -1, 0],[-17, 17, -7]],
|
||||
[[ 0, -1, 1],[ 7, 17, 17]],
|
||||
[[ 1, 0, -1],[ 17, 7, 17]],
|
||||
[[ -1, 1, 0],[ 17, 17, 7]],
|
||||
[[ 0, 1, 1],[ -7,-17, 17]],
|
||||
[[ -1, 0, -1],[-17, -7, 17]],
|
||||
[[ -1, 1, 0],[-17,-17, 7]],
|
||||
[[ 0, -1, 1],[ 7,-17,-17]],
|
||||
[[ -1, 0, -1],[ 17, -7,-17]],
|
||||
[[ 1, 1, 0],[ 17,-17, -7]],
|
||||
[[ 0, 1, 1],[ -7, 17,-17]],
|
||||
[[ 1, 0, -1],[-17, 7,-17]],
|
||||
[[ 1, 1, 0],[-17, 17, -7]],
|
||||
],dtype=float),
|
||||
'cI' : np.array([
|
||||
[[ 1, 1, -1],[ 12, 5, 17]],
|
||||
[[ -1, 1, 1],[ 17, 12, 5]],
|
||||
[[ 1, -1, 1],[ 5, 17, 12]],
|
||||
[[ -1, -1, -1],[-12, -5, 17]],
|
||||
[[ 1, -1, 1],[-17,-12, 5]],
|
||||
[[ 1, -1, -1],[ -5,-17, 12]],
|
||||
[[ -1, 1, -1],[ 12, -5,-17]],
|
||||
[[ 1, 1, 1],[ 17,-12, -5]],
|
||||
[[ -1, -1, 1],[ 5,-17,-12]],
|
||||
[[ 1, -1, -1],[-12, 5,-17]],
|
||||
[[ -1, -1, 1],[-17, 12, -5]],
|
||||
[[ -1, -1, -1],[ -5, 17,-12]],
|
||||
[[ 1, -1, 1],[ 12, 17, 5]],
|
||||
[[ 1, 1, -1],[ 5, 12, 17]],
|
||||
[[ -1, 1, 1],[ 17, 5, 12]],
|
||||
[[ -1, 1, 1],[-12,-17, 5]],
|
||||
[[ -1, -1, -1],[ -5,-12, 17]],
|
||||
[[ -1, 1, -1],[-17, -5, 12]],
|
||||
[[ -1, -1, 1],[ 12,-17, -5]],
|
||||
[[ -1, 1, -1],[ 5,-12,-17]],
|
||||
[[ 1, 1, 1],[ 17, -5,-12]],
|
||||
[[ 1, 1, 1],[-12, 17, -5]],
|
||||
[[ 1, -1, -1],[ -5, 12,-17]],
|
||||
[[ 1, 1, -1],[-17, 5,-12]],
|
||||
],dtype=float),
|
||||
},
|
||||
'NW': {
|
||||
'cF' : np.array([
|
||||
[[ 2, -1, -1],[ 1, 1, 1]],
|
||||
[[ -1, 2, -1],[ 1, 1, 1]],
|
||||
[[ -1, -1, 2],[ 1, 1, 1]],
|
||||
[[ -2, -1, -1],[ -1, 1, 1]],
|
||||
[[ 1, 2, -1],[ -1, 1, 1]],
|
||||
[[ 1, -1, 2],[ -1, 1, 1]],
|
||||
[[ 2, 1, -1],[ 1, -1, 1]],
|
||||
[[ -1, -2, -1],[ 1, -1, 1]],
|
||||
[[ -1, 1, 2],[ 1, -1, 1]],
|
||||
[[ 2, -1, 1],[ -1, -1, 1]],
|
||||
[[ -1, 2, 1],[ -1, -1, 1]],
|
||||
[[ -1, -1, -2],[ -1, -1, 1]],
|
||||
],dtype=float),
|
||||
'cI' : np.array([
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
],dtype=float),
|
||||
},
|
||||
'Pitsch': {
|
||||
'cF' : np.array([
|
||||
[[ 1, 0, 1],[ 0, 1, 0]],
|
||||
[[ 1, 1, 0],[ 0, 0, 1]],
|
||||
[[ 0, 1, 1],[ 1, 0, 0]],
|
||||
[[ 0, 1, -1],[ 1, 0, 0]],
|
||||
[[ -1, 0, 1],[ 0, 1, 0]],
|
||||
[[ 1, -1, 0],[ 0, 0, 1]],
|
||||
[[ 1, 0, -1],[ 0, 1, 0]],
|
||||
[[ -1, 1, 0],[ 0, 0, 1]],
|
||||
[[ 0, -1, 1],[ 1, 0, 0]],
|
||||
[[ 0, 1, 1],[ 1, 0, 0]],
|
||||
[[ 1, 0, 1],[ 0, 1, 0]],
|
||||
[[ 1, 1, 0],[ 0, 0, 1]],
|
||||
],dtype=float),
|
||||
'cI' : np.array([
|
||||
[[ 1, -1, 1],[ -1, 0, 1]],
|
||||
[[ 1, 1, -1],[ 1, -1, 0]],
|
||||
[[ -1, 1, 1],[ 0, 1, -1]],
|
||||
[[ -1, 1, -1],[ 0, -1, -1]],
|
||||
[[ -1, -1, 1],[ -1, 0, -1]],
|
||||
[[ 1, -1, -1],[ -1, -1, 0]],
|
||||
[[ 1, -1, -1],[ -1, 0, -1]],
|
||||
[[ -1, 1, -1],[ -1, -1, 0]],
|
||||
[[ -1, -1, 1],[ 0, -1, -1]],
|
||||
[[ -1, 1, 1],[ 0, -1, 1]],
|
||||
[[ 1, -1, 1],[ 1, 0, -1]],
|
||||
[[ 1, 1, -1],[ -1, 1, 0]],
|
||||
],dtype=float),
|
||||
},
|
||||
'Bain': {
|
||||
'cF' : np.array([
|
||||
[[ 0, 1, 0],[ 1, 0, 0]],
|
||||
[[ 0, 0, 1],[ 0, 1, 0]],
|
||||
[[ 1, 0, 0],[ 0, 0, 1]],
|
||||
],dtype=float),
|
||||
'cI' : np.array([
|
||||
[[ 0, 1, 1],[ 1, 0, 0]],
|
||||
[[ 1, 0, 1],[ 0, 1, 0]],
|
||||
[[ 1, 1, 0],[ 0, 0, 1]],
|
||||
],dtype=float),
|
||||
},
|
||||
'Burgers' : {
|
||||
'cI' : np.array([
|
||||
[[ -1, 1, 1],[ 1, 1, 0]],
|
||||
[[ -1, 1, -1],[ 1, 1, 0]],
|
||||
[[ 1, 1, 1],[ 1, -1, 0]],
|
||||
[[ 1, 1, -1],[ 1, -1, 0]],
|
||||
|
||||
[[ 1, 1, -1],[ 1, 0, 1]],
|
||||
[[ -1, 1, 1],[ 1, 0, 1]],
|
||||
[[ 1, 1, 1],[ -1, 0, 1]],
|
||||
[[ 1, -1, 1],[ -1, 0, 1]],
|
||||
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
[[ 1, 1, -1],[ 0, 1, 1]],
|
||||
[[ -1, 1, 1],[ 0, -1, 1]],
|
||||
[[ 1, 1, 1],[ 0, -1, 1]],
|
||||
],dtype=float),
|
||||
'hP' : np.array([
|
||||
[[ -1, 2, -1, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, -1, 2, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, 2, -1, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, -1, 2, 0],[ 0, 0, 0, 1]],
|
||||
|
||||
[[ -1, 2, -1, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, -1, 2, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, 2, -1, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, -1, 2, 0],[ 0, 0, 0, 1]],
|
||||
|
||||
[[ -1, 2, -1, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, -1, 2, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, 2, -1, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, -1, 2, 0],[ 0, 0, 0, 1]],
|
||||
],dtype=float),
|
||||
},
|
||||
}
|
|
@ -5,7 +5,15 @@ from . import Rotation
|
|||
class LatticeFamily():
|
||||
|
||||
def __init__(self,family):
|
||||
"""Symmetry-related operations for crystal families."""
|
||||
"""
|
||||
Symmetry-related operations for crystal families.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
family : {'triclinic', 'monoclinic', 'orthorhombic', 'tetragonal', 'hexagonal', 'cubic'}
|
||||
Name of the crystal family.
|
||||
|
||||
"""
|
||||
if family not in self._immutable.keys():
|
||||
raise KeyError(f'invalid lattice family "{family}"')
|
||||
self.family = family
|
||||
|
@ -121,41 +129,36 @@ class LatticeFamily():
|
|||
|
||||
|
||||
_immutable = {
|
||||
'cubic':
|
||||
{
|
||||
'cubic': {
|
||||
'b': 1.0,
|
||||
'c': 1.0,
|
||||
'alpha': np.pi/2.,
|
||||
'beta': np.pi/2.,
|
||||
'gamma': np.pi/2.,
|
||||
},
|
||||
'hexagonal':
|
||||
{
|
||||
'hexagonal': {
|
||||
'b': 1.0,
|
||||
'alpha': np.pi/2.,
|
||||
'beta': np.pi/2.,
|
||||
'gamma': 2.*np.pi/3.,
|
||||
},
|
||||
'tetragonal':
|
||||
{
|
||||
'tetragonal': {
|
||||
'b': 1.0,
|
||||
'alpha': np.pi/2.,
|
||||
'beta': np.pi/2.,
|
||||
'gamma': np.pi/2.,
|
||||
},
|
||||
'orthorhombic':
|
||||
{
|
||||
'orthorhombic': {
|
||||
'alpha': np.pi/2.,
|
||||
'beta': np.pi/2.,
|
||||
'gamma': np.pi/2.,
|
||||
},
|
||||
'monoclinic':
|
||||
{
|
||||
'monoclinic': {
|
||||
'alpha': np.pi/2.,
|
||||
'gamma': np.pi/2.,
|
||||
},
|
||||
'triclinic': {}
|
||||
}
|
||||
'triclinic': {}
|
||||
}
|
||||
|
||||
|
||||
_basis = {
|
||||
|
|
|
@ -4,9 +4,9 @@ import numpy as np
|
|||
|
||||
from . import Rotation
|
||||
from . import LatticeFamily
|
||||
from . import Lattice
|
||||
from . import util
|
||||
from . import tensor
|
||||
from . import lattice as lattice_
|
||||
|
||||
|
||||
lattice_symmetries = {
|
||||
|
@ -130,13 +130,13 @@ class Orientation(Rotation):
|
|||
Defaults to no rotation.
|
||||
|
||||
"""
|
||||
Rotation.__init__(self,rotation=rotation)
|
||||
super().__init__(rotation)
|
||||
|
||||
if family in set(lattice_symmetries.values()) and lattice is None:
|
||||
self.family = family
|
||||
self.lattice = None
|
||||
|
||||
l = LatticeFamily(self.family)
|
||||
l = LatticeFamily(self.family) # noqa
|
||||
self.immutable = l.immutable
|
||||
self.basis = l.basis
|
||||
self.symmetry_operations = l.symmetry_operations
|
||||
|
@ -149,48 +149,25 @@ class Orientation(Rotation):
|
|||
self.family = lattice_symmetries[lattice]
|
||||
self.lattice = lattice
|
||||
|
||||
l = LatticeFamily(self.family)
|
||||
l = Lattice(self.lattice, a,b,c, alpha,beta,gamma, degrees) # noqa
|
||||
self.immutable = l.immutable
|
||||
self.basis = l.basis
|
||||
self.symmetry_operations = l.symmetry_operations
|
||||
|
||||
self.a = 1 if a is None else a
|
||||
self.b = b
|
||||
self.c = c
|
||||
self.a = float(self.a) if self.a is not None else \
|
||||
(self.b / self.ratio['b'] if self.b is not None and self.ratio['b'] is not None else
|
||||
self.c / self.ratio['c'] if self.c is not None and self.ratio['c'] is not None else None)
|
||||
self.b = float(self.b) if self.b is not None else \
|
||||
(self.a * self.ratio['b'] if self.a is not None and self.ratio['b'] is not None else
|
||||
self.c / self.ratio['c'] * self.ratio['b']
|
||||
if self.c is not None and self.ratio['b'] is not None and self.ratio['c'] is not None else None)
|
||||
self.c = float(self.c) if self.c is not None else \
|
||||
(self.a * self.ratio['c'] if self.a is not None and self.ratio['c'] is not None else
|
||||
self.b / self.ratio['b'] * self.ratio['c']
|
||||
if self.c is not None and self.ratio['b'] is not None and self.ratio['c'] is not None else None)
|
||||
self.a = l.a
|
||||
self.b = l.b
|
||||
self.c = l.c
|
||||
|
||||
self.alpha = np.radians(alpha) if degrees and alpha is not None else alpha
|
||||
self.beta = np.radians(beta) if degrees and beta is not None else beta
|
||||
self.gamma = np.radians(gamma) if degrees and gamma is not None else gamma
|
||||
if self.alpha is None and 'alpha' in self.immutable: self.alpha = self.immutable['alpha']
|
||||
if self.beta is None and 'beta' in self.immutable: self.beta = self.immutable['beta']
|
||||
if self.gamma is None and 'gamma' in self.immutable: self.gamma = self.immutable['gamma']
|
||||
self.alpha = l.alpha
|
||||
self.beta = l.beta
|
||||
self.gamma = l.gamma
|
||||
|
||||
if \
|
||||
(self.a is None) \
|
||||
or (self.b is None or ('b' in self.immutable and self.b != self.immutable['b'] * self.a)) \
|
||||
or (self.c is None or ('c' in self.immutable and self.c != self.immutable['c'] * self.b)) \
|
||||
or (self.alpha is None or ('alpha' in self.immutable and self.alpha != self.immutable['alpha'])) \
|
||||
or (self.beta is None or ( 'beta' in self.immutable and self.beta != self.immutable['beta'])) \
|
||||
or (self.gamma is None or ('gamma' in self.immutable and self.gamma != self.immutable['gamma'])):
|
||||
raise ValueError (f'Incompatible parameters {self.parameters} for crystal family {self.family}')
|
||||
self.ratio = l.ratio
|
||||
|
||||
if np.any(np.array([self.alpha,self.beta,self.gamma]) <= 0):
|
||||
raise ValueError ('Lattice angles must be positive')
|
||||
if np.any([np.roll([self.alpha,self.beta,self.gamma],r)[0]
|
||||
> np.sum(np.roll([self.alpha,self.beta,self.gamma],r)[1:]) for r in range(3)]):
|
||||
raise ValueError ('Each lattice angle must be less than sum of others')
|
||||
self.to_frame = l.to_frame
|
||||
|
||||
self.kinematics = l.kinematics
|
||||
self.orientation_relationships = l.orientation_relationships
|
||||
else:
|
||||
raise KeyError(f'no valid family or lattice')
|
||||
|
||||
|
@ -590,12 +567,9 @@ class Orientation(Rotation):
|
|||
https://doi.org/10.1016/j.actamat.2004.11.021
|
||||
|
||||
"""
|
||||
if model not in lattice_.relations:
|
||||
if model not in self.orientation_relationships:
|
||||
raise KeyError(f'unknown orientation relationship "{model}"')
|
||||
r = lattice_.relations[model]
|
||||
|
||||
if self.lattice not in r:
|
||||
raise KeyError(f'relationship "{model}" not supported for lattice "{self.lattice}"')
|
||||
r = self.orientation_relationships[model]
|
||||
|
||||
sl = self.lattice
|
||||
ol = (set(r)-{sl}).pop()
|
||||
|
@ -640,50 +614,6 @@ class Orientation(Rotation):
|
|||
return (self.a,self.b,self.c,self.alpha,self.beta,self.gamma)
|
||||
|
||||
|
||||
@property
|
||||
def ratio(self):
|
||||
"""Return axes ratios of own lattice."""
|
||||
_ratio = { 'hexagonal': {'c': np.sqrt(8./3.)}}
|
||||
|
||||
return dict(b = self.immutable['b']
|
||||
if 'b' in self.immutable else
|
||||
_ratio[self.family]['b'] if self.family in _ratio and 'b' in _ratio[self.family] else None,
|
||||
c = self.immutable['c']
|
||||
if 'c' in self.immutable else
|
||||
_ratio[self.family]['c'] if self.family in _ratio and 'c' in _ratio[self.family] else None,
|
||||
)
|
||||
|
||||
|
||||
@property
|
||||
def basis_real(self):
|
||||
"""
|
||||
Calculate orthogonal real space crystal basis.
|
||||
|
||||
References
|
||||
----------
|
||||
C.T. Young and J.L. Lytton, Journal of Applied Physics 43:1408–1417, 1972
|
||||
https://doi.org/10.1063/1.1661333
|
||||
|
||||
"""
|
||||
if None in self.parameters:
|
||||
raise KeyError('missing crystal lattice parameters')
|
||||
return np.array([
|
||||
[1,0,0],
|
||||
[np.cos(self.gamma),np.sin(self.gamma),0],
|
||||
[np.cos(self.beta),
|
||||
(np.cos(self.alpha)-np.cos(self.beta)*np.cos(self.gamma)) /np.sin(self.gamma),
|
||||
np.sqrt(1 - np.cos(self.alpha)**2 - np.cos(self.beta)**2 - np.cos(self.gamma)**2
|
||||
+ 2 * np.cos(self.alpha) * np.cos(self.beta) * np.cos(self.gamma))/np.sin(self.gamma)],
|
||||
],dtype=float).T \
|
||||
* np.array([self.a,self.b,self.c])
|
||||
|
||||
|
||||
@property
|
||||
def basis_reciprocal(self):
|
||||
"""Calculate reciprocal (dual) crystal basis."""
|
||||
return np.linalg.inv(self.basis_real.T)
|
||||
|
||||
|
||||
def in_SST(self,vector,proper=False):
|
||||
"""
|
||||
Check whether given crystal frame vector falls into standard stereographic triangle of own symmetry.
|
||||
|
@ -944,58 +874,6 @@ class Orientation(Rotation):
|
|||
)
|
||||
|
||||
|
||||
def to_lattice(self,*,direction=None,plane=None):
|
||||
"""
|
||||
Calculate lattice vector corresponding to crystal frame direction or plane normal.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
direction|normal : numpy.ndarray of shape (...,3)
|
||||
Vector along direction or plane normal.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Miller : numpy.ndarray of shape (...,3)
|
||||
lattice vector of direction or plane.
|
||||
Use util.scale_to_coprime to convert to (integer) Miller indices.
|
||||
|
||||
"""
|
||||
if (direction is not None) ^ (plane is None):
|
||||
raise KeyError('specify either "direction" or "plane"')
|
||||
axis,basis = (np.array(direction),self.basis_reciprocal.T) \
|
||||
if plane is None else \
|
||||
(np.array(plane),self.basis_real.T)
|
||||
return np.einsum('il,...l',basis,axis)
|
||||
|
||||
|
||||
def to_frame(self,*,uvw=None,hkl=None,with_symmetry=False):
|
||||
"""
|
||||
Calculate crystal frame vector along lattice direction [uvw] or plane normal (hkl).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
uvw|hkl : numpy.ndarray of shape (...,3)
|
||||
Miller indices of crystallographic direction or plane normal.
|
||||
with_symmetry : bool, optional
|
||||
Calculate all N symmetrically equivalent vectors.
|
||||
|
||||
Returns
|
||||
-------
|
||||
vector : numpy.ndarray of shape (...,3) or (N,...,3)
|
||||
Crystal frame vector (or vectors if with_symmetry) along [uvw] direction or (hkl) plane normal.
|
||||
|
||||
"""
|
||||
if (uvw is not None) ^ (hkl is None):
|
||||
raise KeyError('specify either "uvw" or "hkl"')
|
||||
axis,basis = (np.array(uvw),self.basis_real) \
|
||||
if hkl is None else \
|
||||
(np.array(hkl),self.basis_reciprocal)
|
||||
return (self.symmetry_operations.broadcast_to(self.symmetry_operations.shape+axis.shape[:-1],mode='right')
|
||||
@ np.broadcast_to(np.einsum('il,...l',basis,axis),self.symmetry_operations.shape+axis.shape)
|
||||
if with_symmetry else
|
||||
np.einsum('il,...l',basis,axis))
|
||||
|
||||
|
||||
def to_pole(self,*,uvw=None,hkl=None,with_symmetry=False):
|
||||
"""
|
||||
Calculate lab frame vector along lattice direction [uvw] or plane normal (hkl).
|
||||
|
@ -1013,7 +891,11 @@ class Orientation(Rotation):
|
|||
Lab frame vector (or vectors if with_symmetry) along [uvw] direction or (hkl) plane normal.
|
||||
|
||||
"""
|
||||
v = self.to_frame(uvw=uvw,hkl=hkl,with_symmetry=with_symmetry)
|
||||
# ToDo: simplify 'with_symmetry'
|
||||
v = self.to_frame(uvw=uvw,hkl=hkl)
|
||||
if with_symmetry:
|
||||
v = self.symmetry_operations.broadcast_to(self.symmetry_operations.shape+v.shape[:-1],mode='right') \
|
||||
@ np.broadcast_to(v,self.symmetry_operations.shape+v.shape)
|
||||
return ~(self if self.shape+v.shape[:-1] == () else self.broadcast_to(self.shape+v.shape[:-1],mode='right')) \
|
||||
@ np.broadcast_to(v,self.shape+v.shape)
|
||||
|
||||
|
@ -1047,15 +929,10 @@ class Orientation(Rotation):
|
|||
|
||||
"""
|
||||
try:
|
||||
master = lattice_.kinematics[self.lattice][mode]
|
||||
kinematics = {'direction':master[:,0:3],'plane':master[:,3:6]} \
|
||||
if master.shape[-1] == 6 else \
|
||||
{'direction':util.Bravais_to_Miller(uvtw=master[:,0:4]),
|
||||
'plane': util.Bravais_to_Miller(hkil=master[:,4:8])}
|
||||
d = self.to_frame(uvw=self.kinematics(mode)['direction'])
|
||||
p = self.to_frame(hkl=self.kinematics(mode)['plane'])
|
||||
except KeyError:
|
||||
raise (f'"{mode}" not defined for lattice "{self.lattice}"')
|
||||
d = self.to_frame(uvw=kinematics['direction'],with_symmetry=False)
|
||||
p = self.to_frame(hkl=kinematics['plane'] ,with_symmetry=False)
|
||||
P = np.einsum('...i,...j',d/np.linalg.norm(d,axis=-1,keepdims=True),
|
||||
p/np.linalg.norm(p,axis=-1,keepdims=True))
|
||||
|
||||
|
|
|
@ -1,444 +0,0 @@
|
|||
import numpy as _np
|
||||
|
||||
kinematics = {
|
||||
'cF': {
|
||||
'slip' : _np.array([
|
||||
[+0,+1,-1 , +1,+1,+1],
|
||||
[-1,+0,+1 , +1,+1,+1],
|
||||
[+1,-1,+0 , +1,+1,+1],
|
||||
[+0,-1,-1 , -1,-1,+1],
|
||||
[+1,+0,+1 , -1,-1,+1],
|
||||
[-1,+1,+0 , -1,-1,+1],
|
||||
[+0,-1,+1 , +1,-1,-1],
|
||||
[-1,+0,-1 , +1,-1,-1],
|
||||
[+1,+1,+0 , +1,-1,-1],
|
||||
[+0,+1,+1 , -1,+1,-1],
|
||||
[+1,+0,-1 , -1,+1,-1],
|
||||
[-1,-1,+0 , -1,+1,-1],
|
||||
[+1,+1,+0 , +1,-1,+0],
|
||||
[+1,-1,+0 , +1,+1,+0],
|
||||
[+1,+0,+1 , +1,+0,-1],
|
||||
[+1,+0,-1 , +1,+0,+1],
|
||||
[+0,+1,+1 , +0,+1,-1],
|
||||
[+0,+1,-1 , +0,+1,+1],
|
||||
],'d'),
|
||||
'twin' : _np.array([
|
||||
[-2, 1, 1, 1, 1, 1],
|
||||
[ 1,-2, 1, 1, 1, 1],
|
||||
[ 1, 1,-2, 1, 1, 1],
|
||||
[ 2,-1, 1, -1,-1, 1],
|
||||
[-1, 2, 1, -1,-1, 1],
|
||||
[-1,-1,-2, -1,-1, 1],
|
||||
[-2,-1,-1, 1,-1,-1],
|
||||
[ 1, 2,-1, 1,-1,-1],
|
||||
[ 1,-1, 2, 1,-1,-1],
|
||||
[ 2, 1,-1, -1, 1,-1],
|
||||
[-1,-2,-1, -1, 1,-1],
|
||||
[-1, 1, 2, -1, 1,-1],
|
||||
],dtype=float),
|
||||
},
|
||||
'cI': {
|
||||
'slip' : _np.array([
|
||||
[+1,-1,+1 , +0,+1,+1],
|
||||
[-1,-1,+1 , +0,+1,+1],
|
||||
[+1,+1,+1 , +0,-1,+1],
|
||||
[-1,+1,+1 , +0,-1,+1],
|
||||
[-1,+1,+1 , +1,+0,+1],
|
||||
[-1,-1,+1 , +1,+0,+1],
|
||||
[+1,+1,+1 , -1,+0,+1],
|
||||
[+1,-1,+1 , -1,+0,+1],
|
||||
[-1,+1,+1 , +1,+1,+0],
|
||||
[-1,+1,-1 , +1,+1,+0],
|
||||
[+1,+1,+1 , -1,+1,+0],
|
||||
[+1,+1,-1 , -1,+1,+0],
|
||||
[-1,+1,+1 , +2,+1,+1],
|
||||
[+1,+1,+1 , -2,+1,+1],
|
||||
[+1,+1,-1 , +2,-1,+1],
|
||||
[+1,-1,+1 , +2,+1,-1],
|
||||
[+1,-1,+1 , +1,+2,+1],
|
||||
[+1,+1,-1 , -1,+2,+1],
|
||||
[+1,+1,+1 , +1,-2,+1],
|
||||
[-1,+1,+1 , +1,+2,-1],
|
||||
[+1,+1,-1 , +1,+1,+2],
|
||||
[+1,-1,+1 , -1,+1,+2],
|
||||
[-1,+1,+1 , +1,-1,+2],
|
||||
[+1,+1,+1 , +1,+1,-2],
|
||||
[+1,+1,-1 , +1,+2,+3],
|
||||
[+1,-1,+1 , -1,+2,+3],
|
||||
[-1,+1,+1 , +1,-2,+3],
|
||||
[+1,+1,+1 , +1,+2,-3],
|
||||
[+1,-1,+1 , +1,+3,+2],
|
||||
[+1,+1,-1 , -1,+3,+2],
|
||||
[+1,+1,+1 , +1,-3,+2],
|
||||
[-1,+1,+1 , +1,+3,-2],
|
||||
[+1,+1,-1 , +2,+1,+3],
|
||||
[+1,-1,+1 , -2,+1,+3],
|
||||
[-1,+1,+1 , +2,-1,+3],
|
||||
[+1,+1,+1 , +2,+1,-3],
|
||||
[+1,-1,+1 , +2,+3,+1],
|
||||
[+1,+1,-1 , -2,+3,+1],
|
||||
[+1,+1,+1 , +2,-3,+1],
|
||||
[-1,+1,+1 , +2,+3,-1],
|
||||
[-1,+1,+1 , +3,+1,+2],
|
||||
[+1,+1,+1 , -3,+1,+2],
|
||||
[+1,+1,-1 , +3,-1,+2],
|
||||
[+1,-1,+1 , +3,+1,-2],
|
||||
[-1,+1,+1 , +3,+2,+1],
|
||||
[+1,+1,+1 , -3,+2,+1],
|
||||
[+1,+1,-1 , +3,-2,+1],
|
||||
[+1,-1,+1 , +3,+2,-1],
|
||||
],'d'),
|
||||
'twin' : _np.array([
|
||||
[-1, 1, 1, 2, 1, 1],
|
||||
[ 1, 1, 1, -2, 1, 1],
|
||||
[ 1, 1,-1, 2,-1, 1],
|
||||
[ 1,-1, 1, 2, 1,-1],
|
||||
[ 1,-1, 1, 1, 2, 1],
|
||||
[ 1, 1,-1, -1, 2, 1],
|
||||
[ 1, 1, 1, 1,-2, 1],
|
||||
[-1, 1, 1, 1, 2,-1],
|
||||
[ 1, 1,-1, 1, 1, 2],
|
||||
[ 1,-1, 1, -1, 1, 2],
|
||||
[-1, 1, 1, 1,-1, 2],
|
||||
[ 1, 1, 1, 1, 1,-2],
|
||||
],dtype=float),
|
||||
},
|
||||
'hP': {
|
||||
'slip' : _np.array([
|
||||
[+2,-1,-1,+0 , +0,+0,+0,+1],
|
||||
[-1,+2,-1,+0 , +0,+0,+0,+1],
|
||||
[-1,-1,+2,+0 , +0,+0,+0,+1],
|
||||
[+2,-1,-1,+0 , +0,+1,-1,+0],
|
||||
[-1,+2,-1,+0 , -1,+0,+1,+0],
|
||||
[-1,-1,+2,+0 , +1,-1,+0,+0],
|
||||
[-1,+1,+0,+0 , +1,+1,-2,+0],
|
||||
[+0,-1,+1,+0 , -2,+1,+1,+0],
|
||||
[+1,+0,-1,+0 , +1,-2,+1,+0],
|
||||
[-1,+2,-1,+0 , +1,+0,-1,+1],
|
||||
[-2,+1,+1,+0 , +0,+1,-1,+1],
|
||||
[-1,-1,+2,+0 , -1,+1,+0,+1],
|
||||
[+1,-2,+1,+0 , -1,+0,+1,+1],
|
||||
[+2,-1,-1,+0 , +0,-1,+1,+1],
|
||||
[+1,+1,-2,+0 , +1,-1,+0,+1],
|
||||
[-2,+1,+1,+3 , +1,+0,-1,+1],
|
||||
[-1,-1,+2,+3 , +1,+0,-1,+1],
|
||||
[-1,-1,+2,+3 , +0,+1,-1,+1],
|
||||
[+1,-2,+1,+3 , +0,+1,-1,+1],
|
||||
[+1,-2,+1,+3 , -1,+1,+0,+1],
|
||||
[+2,-1,-1,+3 , -1,+1,+0,+1],
|
||||
[+2,-1,-1,+3 , -1,+0,+1,+1],
|
||||
[+1,+1,-2,+3 , -1,+0,+1,+1],
|
||||
[+1,+1,-2,+3 , +0,-1,+1,+1],
|
||||
[-1,+2,-1,+3 , +0,-1,+1,+1],
|
||||
[-1,+2,-1,+3 , +1,-1,+0,+1],
|
||||
[-2,+1,+1,+3 , +1,-1,+0,+1],
|
||||
[-1,-1,+2,+3 , +1,+1,-2,+2],
|
||||
[+1,-2,+1,+3 , -1,+2,-1,+2],
|
||||
[+2,-1,-1,+3 , -2,+1,+1,+2],
|
||||
[+1,+1,-2,+3 , -1,-1,+2,+2],
|
||||
[-1,+2,-1,+3 , +1,-2,+1,+2],
|
||||
[-2,+1,+1,+3 , +2,-1,-1,+2],
|
||||
],'d'),
|
||||
'twin' : _np.array([
|
||||
[-1, 0, 1, 1, 1, 0, -1, 2], # shear = (3-(c/a)^2)/(sqrt(3) c/a) <-10.1>{10.2}
|
||||
[ 0, -1, 1, 1, 0, 1, -1, 2],
|
||||
[ 1, -1, 0, 1, -1, 1, 0, 2],
|
||||
[ 1, 0, -1, 1, -1, 0, 1, 2],
|
||||
[ 0, 1, -1, 1, 0, -1, 1, 2],
|
||||
[-1, 1, 0, 1, 1, -1, 0, 2],
|
||||
[-1, -1, 2, 6, 1, 1, -2, 1], # shear = 1/(c/a) <11.6>{-1-1.1}
|
||||
[ 1, -2, 1, 6, -1, 2, -1, 1],
|
||||
[ 2, -1, -1, 6, -2, 1, 1, 1],
|
||||
[ 1, 1, -2, 6, -1, -1, 2, 1],
|
||||
[-1, 2, -1, 6, 1, -2, 1, 1],
|
||||
[-2, 1, 1, 6, 2, -1, -1, 1],
|
||||
[ 1, 0, -1, -2, 1, 0, -1, 1], # shear = (4(c/a)^2-9)/(4 sqrt(3) c/a) <10.-2>{10.1}
|
||||
[ 0, 1, -1, -2, 0, 1, -1, 1],
|
||||
[-1, 1, 0, -2, -1, 1, 0, 1],
|
||||
[-1, 0, 1, -2, -1, 0, 1, 1],
|
||||
[ 0, -1, 1, -2, 0, -1, 1, 1],
|
||||
[ 1, -1, 0, -2, 1, -1, 0, 1],
|
||||
[ 1, 1, -2, -3, 1, 1, -2, 2], # shear = 2((c/a)^2-2)/(3 c/a) <11.-3>{11.2}
|
||||
[-1, 2, -1, -3, -1, 2, -1, 2],
|
||||
[-2, 1, 1, -3, -2, 1, 1, 2],
|
||||
[-1, -1, 2, -3, -1, -1, 2, 2],
|
||||
[ 1, -2, 1, -3, 1, -2, 1, 2],
|
||||
[ 2, -1, -1, -3, 2, -1, -1, 2],
|
||||
],dtype=float),
|
||||
},
|
||||
}
|
||||
|
||||
# Kurdjomov--Sachs orientation relationship for fcc <-> bcc transformation
|
||||
# from S. Morito et al., Journal of Alloys and Compounds 577:s587-s592, 2013
|
||||
# also see K. Kitahara et al., Acta Materialia 54:1279-1288, 2006
|
||||
|
||||
relations = {
|
||||
'KS': {
|
||||
'cF' : _np.array([
|
||||
[[ -1, 0, 1],[ 1, 1, 1]],
|
||||
[[ -1, 0, 1],[ 1, 1, 1]],
|
||||
[[ 0, 1, -1],[ 1, 1, 1]],
|
||||
[[ 0, 1, -1],[ 1, 1, 1]],
|
||||
[[ 1, -1, 0],[ 1, 1, 1]],
|
||||
[[ 1, -1, 0],[ 1, 1, 1]],
|
||||
[[ 1, 0, -1],[ 1, -1, 1]],
|
||||
[[ 1, 0, -1],[ 1, -1, 1]],
|
||||
[[ -1, -1, 0],[ 1, -1, 1]],
|
||||
[[ -1, -1, 0],[ 1, -1, 1]],
|
||||
[[ 0, 1, 1],[ 1, -1, 1]],
|
||||
[[ 0, 1, 1],[ 1, -1, 1]],
|
||||
[[ 0, -1, 1],[ -1, 1, 1]],
|
||||
[[ 0, -1, 1],[ -1, 1, 1]],
|
||||
[[ -1, 0, -1],[ -1, 1, 1]],
|
||||
[[ -1, 0, -1],[ -1, 1, 1]],
|
||||
[[ 1, 1, 0],[ -1, 1, 1]],
|
||||
[[ 1, 1, 0],[ -1, 1, 1]],
|
||||
[[ -1, 1, 0],[ 1, 1, -1]],
|
||||
[[ -1, 1, 0],[ 1, 1, -1]],
|
||||
[[ 0, -1, -1],[ 1, 1, -1]],
|
||||
[[ 0, -1, -1],[ 1, 1, -1]],
|
||||
[[ 1, 0, 1],[ 1, 1, -1]],
|
||||
[[ 1, 0, 1],[ 1, 1, -1]],
|
||||
],dtype=float),
|
||||
'cI' : _np.array([
|
||||
[[ -1, -1, 1],[ 0, 1, 1]],
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
[[ -1, -1, 1],[ 0, 1, 1]],
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
[[ -1, -1, 1],[ 0, 1, 1]],
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
[[ -1, -1, 1],[ 0, 1, 1]],
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
[[ -1, -1, 1],[ 0, 1, 1]],
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
[[ -1, -1, 1],[ 0, 1, 1]],
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
[[ -1, -1, 1],[ 0, 1, 1]],
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
[[ -1, -1, 1],[ 0, 1, 1]],
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
[[ -1, -1, 1],[ 0, 1, 1]],
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
[[ -1, -1, 1],[ 0, 1, 1]],
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
[[ -1, -1, 1],[ 0, 1, 1]],
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
[[ -1, -1, 1],[ 0, 1, 1]],
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
],dtype=float),
|
||||
},
|
||||
'GT': {
|
||||
'cF' : _np.array([
|
||||
[[ -5,-12, 17],[ 1, 1, 1]],
|
||||
[[ 17, -5,-12],[ 1, 1, 1]],
|
||||
[[-12, 17, -5],[ 1, 1, 1]],
|
||||
[[ 5, 12, 17],[ -1, -1, 1]],
|
||||
[[-17, 5,-12],[ -1, -1, 1]],
|
||||
[[ 12,-17, -5],[ -1, -1, 1]],
|
||||
[[ -5, 12,-17],[ -1, 1, 1]],
|
||||
[[ 17, 5, 12],[ -1, 1, 1]],
|
||||
[[-12,-17, 5],[ -1, 1, 1]],
|
||||
[[ 5,-12,-17],[ 1, -1, 1]],
|
||||
[[-17, -5, 12],[ 1, -1, 1]],
|
||||
[[ 12, 17, 5],[ 1, -1, 1]],
|
||||
[[ -5, 17,-12],[ 1, 1, 1]],
|
||||
[[-12, -5, 17],[ 1, 1, 1]],
|
||||
[[ 17,-12, -5],[ 1, 1, 1]],
|
||||
[[ 5,-17,-12],[ -1, -1, 1]],
|
||||
[[ 12, 5, 17],[ -1, -1, 1]],
|
||||
[[-17, 12, -5],[ -1, -1, 1]],
|
||||
[[ -5,-17, 12],[ -1, 1, 1]],
|
||||
[[-12, 5,-17],[ -1, 1, 1]],
|
||||
[[ 17, 12, 5],[ -1, 1, 1]],
|
||||
[[ 5, 17, 12],[ 1, -1, 1]],
|
||||
[[ 12, -5,-17],[ 1, -1, 1]],
|
||||
[[-17,-12, 5],[ 1, -1, 1]],
|
||||
],dtype=float),
|
||||
'cI' : _np.array([
|
||||
[[-17, -7, 17],[ 1, 0, 1]],
|
||||
[[ 17,-17, -7],[ 1, 1, 0]],
|
||||
[[ -7, 17,-17],[ 0, 1, 1]],
|
||||
[[ 17, 7, 17],[ -1, 0, 1]],
|
||||
[[-17, 17, -7],[ -1, -1, 0]],
|
||||
[[ 7,-17,-17],[ 0, -1, 1]],
|
||||
[[-17, 7,-17],[ -1, 0, 1]],
|
||||
[[ 17, 17, 7],[ -1, 1, 0]],
|
||||
[[ -7,-17, 17],[ 0, 1, 1]],
|
||||
[[ 17, -7,-17],[ 1, 0, 1]],
|
||||
[[-17,-17, 7],[ 1, -1, 0]],
|
||||
[[ 7, 17, 17],[ 0, -1, 1]],
|
||||
[[-17, 17, -7],[ 1, 1, 0]],
|
||||
[[ -7,-17, 17],[ 0, 1, 1]],
|
||||
[[ 17, -7,-17],[ 1, 0, 1]],
|
||||
[[ 17,-17, -7],[ -1, -1, 0]],
|
||||
[[ 7, 17, 17],[ 0, -1, 1]],
|
||||
[[-17, 7,-17],[ -1, 0, 1]],
|
||||
[[-17,-17, 7],[ -1, 1, 0]],
|
||||
[[ -7, 17,-17],[ 0, 1, 1]],
|
||||
[[ 17, 7, 17],[ -1, 0, 1]],
|
||||
[[ 17, 17, 7],[ 1, -1, 0]],
|
||||
[[ 7,-17,-17],[ 0, -1, 1]],
|
||||
[[-17, -7, 17],[ 1, 0, 1]],
|
||||
],dtype=float),
|
||||
},
|
||||
'GT_prime': {
|
||||
'cF' : _np.array([
|
||||
[[ 0, 1, -1],[ 7, 17, 17]],
|
||||
[[ -1, 0, 1],[ 17, 7, 17]],
|
||||
[[ 1, -1, 0],[ 17, 17, 7]],
|
||||
[[ 0, -1, -1],[ -7,-17, 17]],
|
||||
[[ 1, 0, 1],[-17, -7, 17]],
|
||||
[[ 1, -1, 0],[-17,-17, 7]],
|
||||
[[ 0, 1, -1],[ 7,-17,-17]],
|
||||
[[ 1, 0, 1],[ 17, -7,-17]],
|
||||
[[ -1, -1, 0],[ 17,-17, -7]],
|
||||
[[ 0, -1, -1],[ -7, 17,-17]],
|
||||
[[ -1, 0, 1],[-17, 7,-17]],
|
||||
[[ -1, -1, 0],[-17, 17, -7]],
|
||||
[[ 0, -1, 1],[ 7, 17, 17]],
|
||||
[[ 1, 0, -1],[ 17, 7, 17]],
|
||||
[[ -1, 1, 0],[ 17, 17, 7]],
|
||||
[[ 0, 1, 1],[ -7,-17, 17]],
|
||||
[[ -1, 0, -1],[-17, -7, 17]],
|
||||
[[ -1, 1, 0],[-17,-17, 7]],
|
||||
[[ 0, -1, 1],[ 7,-17,-17]],
|
||||
[[ -1, 0, -1],[ 17, -7,-17]],
|
||||
[[ 1, 1, 0],[ 17,-17, -7]],
|
||||
[[ 0, 1, 1],[ -7, 17,-17]],
|
||||
[[ 1, 0, -1],[-17, 7,-17]],
|
||||
[[ 1, 1, 0],[-17, 17, -7]],
|
||||
],dtype=float),
|
||||
'cI' : _np.array([
|
||||
[[ 1, 1, -1],[ 12, 5, 17]],
|
||||
[[ -1, 1, 1],[ 17, 12, 5]],
|
||||
[[ 1, -1, 1],[ 5, 17, 12]],
|
||||
[[ -1, -1, -1],[-12, -5, 17]],
|
||||
[[ 1, -1, 1],[-17,-12, 5]],
|
||||
[[ 1, -1, -1],[ -5,-17, 12]],
|
||||
[[ -1, 1, -1],[ 12, -5,-17]],
|
||||
[[ 1, 1, 1],[ 17,-12, -5]],
|
||||
[[ -1, -1, 1],[ 5,-17,-12]],
|
||||
[[ 1, -1, -1],[-12, 5,-17]],
|
||||
[[ -1, -1, 1],[-17, 12, -5]],
|
||||
[[ -1, -1, -1],[ -5, 17,-12]],
|
||||
[[ 1, -1, 1],[ 12, 17, 5]],
|
||||
[[ 1, 1, -1],[ 5, 12, 17]],
|
||||
[[ -1, 1, 1],[ 17, 5, 12]],
|
||||
[[ -1, 1, 1],[-12,-17, 5]],
|
||||
[[ -1, -1, -1],[ -5,-12, 17]],
|
||||
[[ -1, 1, -1],[-17, -5, 12]],
|
||||
[[ -1, -1, 1],[ 12,-17, -5]],
|
||||
[[ -1, 1, -1],[ 5,-12,-17]],
|
||||
[[ 1, 1, 1],[ 17, -5,-12]],
|
||||
[[ 1, 1, 1],[-12, 17, -5]],
|
||||
[[ 1, -1, -1],[ -5, 12,-17]],
|
||||
[[ 1, 1, -1],[-17, 5,-12]],
|
||||
],dtype=float),
|
||||
},
|
||||
'NW': {
|
||||
'cF' : _np.array([
|
||||
[[ 2, -1, -1],[ 1, 1, 1]],
|
||||
[[ -1, 2, -1],[ 1, 1, 1]],
|
||||
[[ -1, -1, 2],[ 1, 1, 1]],
|
||||
[[ -2, -1, -1],[ -1, 1, 1]],
|
||||
[[ 1, 2, -1],[ -1, 1, 1]],
|
||||
[[ 1, -1, 2],[ -1, 1, 1]],
|
||||
[[ 2, 1, -1],[ 1, -1, 1]],
|
||||
[[ -1, -2, -1],[ 1, -1, 1]],
|
||||
[[ -1, 1, 2],[ 1, -1, 1]],
|
||||
[[ 2, -1, 1],[ -1, -1, 1]],
|
||||
[[ -1, 2, 1],[ -1, -1, 1]],
|
||||
[[ -1, -1, -2],[ -1, -1, 1]],
|
||||
],dtype=float),
|
||||
'cI' : _np.array([
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
[[ 0, -1, 1],[ 0, 1, 1]],
|
||||
],dtype=float),
|
||||
},
|
||||
'Pitsch': {
|
||||
'cF' : _np.array([
|
||||
[[ 1, 0, 1],[ 0, 1, 0]],
|
||||
[[ 1, 1, 0],[ 0, 0, 1]],
|
||||
[[ 0, 1, 1],[ 1, 0, 0]],
|
||||
[[ 0, 1, -1],[ 1, 0, 0]],
|
||||
[[ -1, 0, 1],[ 0, 1, 0]],
|
||||
[[ 1, -1, 0],[ 0, 0, 1]],
|
||||
[[ 1, 0, -1],[ 0, 1, 0]],
|
||||
[[ -1, 1, 0],[ 0, 0, 1]],
|
||||
[[ 0, -1, 1],[ 1, 0, 0]],
|
||||
[[ 0, 1, 1],[ 1, 0, 0]],
|
||||
[[ 1, 0, 1],[ 0, 1, 0]],
|
||||
[[ 1, 1, 0],[ 0, 0, 1]],
|
||||
],dtype=float),
|
||||
'cI' : _np.array([
|
||||
[[ 1, -1, 1],[ -1, 0, 1]],
|
||||
[[ 1, 1, -1],[ 1, -1, 0]],
|
||||
[[ -1, 1, 1],[ 0, 1, -1]],
|
||||
[[ -1, 1, -1],[ 0, -1, -1]],
|
||||
[[ -1, -1, 1],[ -1, 0, -1]],
|
||||
[[ 1, -1, -1],[ -1, -1, 0]],
|
||||
[[ 1, -1, -1],[ -1, 0, -1]],
|
||||
[[ -1, 1, -1],[ -1, -1, 0]],
|
||||
[[ -1, -1, 1],[ 0, -1, -1]],
|
||||
[[ -1, 1, 1],[ 0, -1, 1]],
|
||||
[[ 1, -1, 1],[ 1, 0, -1]],
|
||||
[[ 1, 1, -1],[ -1, 1, 0]],
|
||||
],dtype=float),
|
||||
},
|
||||
'Bain': {
|
||||
'cF' : _np.array([
|
||||
[[ 0, 1, 0],[ 1, 0, 0]],
|
||||
[[ 0, 0, 1],[ 0, 1, 0]],
|
||||
[[ 1, 0, 0],[ 0, 0, 1]],
|
||||
],dtype=float),
|
||||
'cI' : _np.array([
|
||||
[[ 0, 1, 1],[ 1, 0, 0]],
|
||||
[[ 1, 0, 1],[ 0, 1, 0]],
|
||||
[[ 1, 1, 0],[ 0, 0, 1]],
|
||||
],dtype=float),
|
||||
},
|
||||
'Burgers' : {
|
||||
'cI' : _np.array([
|
||||
[[ -1, 1, 1],[ 1, 1, 0]],
|
||||
[[ -1, 1, -1],[ 1, 1, 0]],
|
||||
[[ 1, 1, 1],[ 1, -1, 0]],
|
||||
[[ 1, 1, -1],[ 1, -1, 0]],
|
||||
|
||||
[[ 1, 1, -1],[ 1, 0, 1]],
|
||||
[[ -1, 1, 1],[ 1, 0, 1]],
|
||||
[[ 1, 1, 1],[ -1, 0, 1]],
|
||||
[[ 1, -1, 1],[ -1, 0, 1]],
|
||||
|
||||
[[ -1, 1, -1],[ 0, 1, 1]],
|
||||
[[ 1, 1, -1],[ 0, 1, 1]],
|
||||
[[ -1, 1, 1],[ 0, -1, 1]],
|
||||
[[ 1, 1, 1],[ 0, -1, 1]],
|
||||
],dtype=float),
|
||||
'hP' : _np.array([
|
||||
[[ -1, 2, -1, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, -1, 2, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, 2, -1, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, -1, 2, 0],[ 0, 0, 0, 1]],
|
||||
|
||||
[[ -1, 2, -1, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, -1, 2, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, 2, -1, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, -1, 2, 0],[ 0, 0, 0, 1]],
|
||||
|
||||
[[ -1, 2, -1, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, -1, 2, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, 2, -1, 0],[ 0, 0, 0, 1]],
|
||||
[[ -1, -1, 2, 0],[ 0, 0, 0, 1]],
|
||||
],dtype=float),
|
||||
},
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
import pytest
|
||||
import numpy as np
|
||||
|
||||
from damask import Lattice
|
||||
|
||||
class TestLattice:
|
||||
|
||||
def test_double_to_lattice(self):
|
||||
L = Lattice('cF')
|
||||
with pytest.raises(KeyError):
|
||||
L.to_lattice(direction=np.ones(3),plane=np.ones(3))
|
||||
|
||||
def test_double_to_frame(self):
|
||||
L = Lattice('cF')
|
||||
with pytest.raises(KeyError):
|
||||
L.to_frame(uvw=np.ones(3),hkl=np.ones(3))
|
||||
|
||||
@pytest.mark.parametrize('lattice,a,b,c,alpha,beta,gamma',
|
||||
[
|
||||
('aP',0.5,2.0,3.0,0.8,0.5,1.2),
|
||||
('mP',1.0,2.0,3.0,np.pi/2,0.5,np.pi/2),
|
||||
('oI',0.5,1.5,3.0,np.pi/2,np.pi/2,np.pi/2),
|
||||
('tP',0.5,0.5,3.0,np.pi/2,np.pi/2,np.pi/2),
|
||||
('hP',1.0,None,1.6,np.pi/2,np.pi/2,2*np.pi/3),
|
||||
('cF',1.0,1.0,None,np.pi/2,np.pi/2,np.pi/2),
|
||||
])
|
||||
def test_bases_contraction(self,lattice,a,b,c,alpha,beta,gamma):
|
||||
L = Lattice(lattice=lattice,
|
||||
a=a,b=b,c=c,
|
||||
alpha=alpha,beta=beta,gamma=gamma)
|
||||
assert np.allclose(np.eye(3),np.einsum('ik,jk',L.basis_real,L.basis_reciprocal))
|
||||
|
||||
|
||||
@pytest.mark.parametrize('keyFrame,keyLattice',[('uvw','direction'),('hkl','plane'),])
|
||||
@pytest.mark.parametrize('vector',np.array([
|
||||
[1.,1.,1.],
|
||||
[-2.,3.,0.5],
|
||||
[0.,0.,1.],
|
||||
[1.,1.,1.],
|
||||
[2.,2.,2.],
|
||||
[0.,1.,1.],
|
||||
]))
|
||||
@pytest.mark.parametrize('lattice,a,b,c,alpha,beta,gamma',
|
||||
[
|
||||
('aP',0.5,2.0,3.0,0.8,0.5,1.2),
|
||||
('mP',1.0,2.0,3.0,np.pi/2,0.5,np.pi/2),
|
||||
('oI',0.5,1.5,3.0,np.pi/2,np.pi/2,np.pi/2),
|
||||
('tP',0.5,0.5,3.0,np.pi/2,np.pi/2,np.pi/2),
|
||||
('hP',1.0,1.0,1.6,np.pi/2,np.pi/2,2*np.pi/3),
|
||||
('cF',1.0,1.0,1.0,np.pi/2,np.pi/2,np.pi/2),
|
||||
])
|
||||
def test_to_frame_to_lattice(self,lattice,a,b,c,alpha,beta,gamma,vector,keyFrame,keyLattice):
|
||||
L = Lattice(lattice=lattice,
|
||||
a=a,b=b,c=c,
|
||||
alpha=alpha,beta=beta,gamma=gamma)
|
||||
assert np.allclose(vector,
|
||||
L.to_frame(**{keyFrame:L.to_lattice(**{keyLattice:vector})}))
|
||||
|
||||
|
||||
@pytest.mark.parametrize('model',['Bain','KS','GT','GT_prime','NW','Pitsch','Burgers'])
|
||||
def test_relationship_definition(self,model):
|
||||
m,o = list(Lattice._orientation_relationships[model])
|
||||
assert Lattice._orientation_relationships[model][m].shape[:-1] == \
|
||||
Lattice._orientation_relationships[model][o].shape[:-1]
|
|
@ -7,7 +7,6 @@ from damask import Orientation
|
|||
from damask import Table
|
||||
from damask import util
|
||||
from damask import grid_filters
|
||||
from damask import lattice
|
||||
from damask import _orientation
|
||||
|
||||
crystal_families = set(_orientation.lattice_symmetries.values())
|
||||
|
@ -341,29 +340,6 @@ class TestOrientation:
|
|||
with pytest.raises(KeyError):
|
||||
Orientation(family=invalid_family)
|
||||
|
||||
def test_invalid_rot(self):
|
||||
with pytest.raises(TypeError):
|
||||
Orientation.from_random(family='cubic') * np.ones(3)
|
||||
|
||||
def test_missing_symmetry_immutable(self):
|
||||
with pytest.raises(KeyError):
|
||||
Orientation(lattice=None).immutable # noqa
|
||||
|
||||
def test_missing_symmetry_basis_real(self):
|
||||
with pytest.raises(KeyError):
|
||||
Orientation(lattice=None).basis_real # noqa
|
||||
|
||||
def test_missing_symmetry_basis_reciprocal(self):
|
||||
with pytest.raises(KeyError):
|
||||
Orientation(lattice=None).basis_reciprocal # noqa
|
||||
|
||||
def test_double_to_lattice(self):
|
||||
with pytest.raises(KeyError):
|
||||
Orientation().to_lattice(direction=np.ones(3),plane=np.ones(3)) # noqa
|
||||
|
||||
def test_double_to_frame(self):
|
||||
with pytest.raises(KeyError):
|
||||
Orientation().to_frame(uvw=np.ones(3),hkl=np.ones(3)) # noqa
|
||||
|
||||
@pytest.mark.parametrize('relation',[None,'Peter','Paul'])
|
||||
def test_unknown_relation(self,relation):
|
||||
|
@ -395,12 +371,6 @@ class TestOrientation:
|
|||
o = Orientation(family='cubic') # noqa
|
||||
with pytest.raises(ValueError):
|
||||
eval(f'o.{function}(np.ones(4))')
|
||||
|
||||
@pytest.mark.parametrize('model',lattice.relations)
|
||||
def test_relationship_definition(self,model):
|
||||
m,o = list(lattice.relations[model])
|
||||
assert lattice.relations[model][m].shape[:-1] == lattice.relations[model][o].shape[:-1]
|
||||
|
||||
@pytest.mark.parametrize('model',['Bain','KS','GT','GT_prime','NW','Pitsch'])
|
||||
@pytest.mark.parametrize('lattice',['cF','cI'])
|
||||
def test_relationship_vectorize(self,set_of_quaternions,lattice,model):
|
||||
|
@ -441,46 +411,6 @@ class TestOrientation:
|
|||
)
|
||||
assert np.allclose(o.to_frame(uvw=np.eye(3)),basis), 'Lattice basis disagrees with initialization'
|
||||
|
||||
@pytest.mark.parametrize('lattice,a,b,c,alpha,beta,gamma',
|
||||
[
|
||||
('aP',0.5,2.0,3.0,0.8,0.5,1.2),
|
||||
('mP',1.0,2.0,3.0,np.pi/2,0.5,np.pi/2),
|
||||
('oI',0.5,1.5,3.0,np.pi/2,np.pi/2,np.pi/2),
|
||||
('tP',0.5,0.5,3.0,np.pi/2,np.pi/2,np.pi/2),
|
||||
('hP',1.0,None,1.6,np.pi/2,np.pi/2,2*np.pi/3),
|
||||
('cF',1.0,1.0,None,np.pi/2,np.pi/2,np.pi/2),
|
||||
])
|
||||
def test_bases_contraction(self,lattice,a,b,c,alpha,beta,gamma):
|
||||
L = Orientation(lattice=lattice,
|
||||
a=a,b=b,c=c,
|
||||
alpha=alpha,beta=beta,gamma=gamma)
|
||||
assert np.allclose(np.eye(3),np.einsum('ik,jk',L.basis_real,L.basis_reciprocal))
|
||||
|
||||
@pytest.mark.parametrize('keyFrame,keyLattice',[('uvw','direction'),('hkl','plane'),])
|
||||
@pytest.mark.parametrize('vector',np.array([
|
||||
[1.,1.,1.],
|
||||
[-2.,3.,0.5],
|
||||
[0.,0.,1.],
|
||||
[1.,1.,1.],
|
||||
[2.,2.,2.],
|
||||
[0.,1.,1.],
|
||||
]))
|
||||
@pytest.mark.parametrize('lattice,a,b,c,alpha,beta,gamma',
|
||||
[
|
||||
('aP',0.5,2.0,3.0,0.8,0.5,1.2),
|
||||
('mP',1.0,2.0,3.0,np.pi/2,0.5,np.pi/2),
|
||||
('oI',0.5,1.5,3.0,np.pi/2,np.pi/2,np.pi/2),
|
||||
('tP',0.5,0.5,3.0,np.pi/2,np.pi/2,np.pi/2),
|
||||
('hP',1.0,1.0,1.6,np.pi/2,np.pi/2,2*np.pi/3),
|
||||
('cF',1.0,1.0,1.0,np.pi/2,np.pi/2,np.pi/2),
|
||||
])
|
||||
def test_to_frame_to_lattice(self,lattice,a,b,c,alpha,beta,gamma,vector,keyFrame,keyLattice):
|
||||
L = Orientation(lattice=lattice,
|
||||
a=a,b=b,c=c,
|
||||
alpha=alpha,beta=beta,gamma=gamma)
|
||||
assert np.allclose(vector,
|
||||
L.to_frame(**{keyFrame:L.to_lattice(**{keyLattice:vector})}))
|
||||
|
||||
|
||||
@pytest.mark.parametrize('lattice,a,b,c,alpha,beta,gamma',
|
||||
[
|
||||
|
|
Loading…
Reference in New Issue