distinguish 'family' and 'lattice'
this requires the user to specify a keyword ('*' notation in __init__). Since all 'from_xxx' methods anyway require a keyword, it does not causes much more work (one explicit keyword in case of cube orientation when using __init__ directly).
This commit is contained in:
parent
684016f3e3
commit
e281d8384f
|
@ -30,10 +30,12 @@ lattice_symmetries = {
|
||||||
}
|
}
|
||||||
|
|
||||||
_parameter_doc = \
|
_parameter_doc = \
|
||||||
"""lattice : str
|
"""
|
||||||
Either a crystal family out of {triclinic, monoclinic, orthorhombic, tetragonal, hexagonal, cubic}
|
family : {'triclinic', 'monoclinic', 'orthorhombic', 'tetragonal', 'hexagonal', 'cubic'}
|
||||||
or a Bravais lattice out of {aP, mP, mS, oP, oS, oI, oF, tP, tI, hP, cP, cI, cF}.
|
Crystal family. Mutual exclusive with 'lattice' parameter.
|
||||||
When specifying a Bravais lattice, additional lattice parameters might be required.
|
lattice : {'aP', 'mP', 'mS', 'oP', 'oS', 'oI', 'oF', 'tP', 'tI', 'hP', 'cP', 'cI', 'cF'}.
|
||||||
|
Bravais lattice in Pearson notation.
|
||||||
|
Mutual exclusive with 'family' parameter.
|
||||||
a : float, optional
|
a : float, optional
|
||||||
Length of lattice parameter 'a'.
|
Length of lattice parameter 'a'.
|
||||||
b : float, optional
|
b : float, optional
|
||||||
|
@ -110,7 +112,8 @@ class Orientation(Rotation):
|
||||||
|
|
||||||
@util.extend_docstring(_parameter_doc)
|
@util.extend_docstring(_parameter_doc)
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
rotation = None,
|
rotation = np.array([1.0,0.0,0.0,0.0]), *,
|
||||||
|
family = None,
|
||||||
lattice = None,
|
lattice = None,
|
||||||
a = None,b = None,c = None,
|
a = None,b = None,c = None,
|
||||||
alpha = None,beta = None,gamma = None,
|
alpha = None,beta = None,gamma = None,
|
||||||
|
@ -126,9 +129,16 @@ class Orientation(Rotation):
|
||||||
Defaults to no rotation.
|
Defaults to no rotation.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Rotation.__init__(self) if rotation is None else Rotation.__init__(self,rotation=rotation)
|
Rotation.__init__(self,rotation=rotation)
|
||||||
|
|
||||||
if lattice in lattice_symmetries:
|
if family in set(lattice_symmetries.values()) and lattice is None:
|
||||||
|
self.family = family
|
||||||
|
self.lattice = None
|
||||||
|
|
||||||
|
self.a = self.b = self.c = None
|
||||||
|
self.alpha = self.beta = self.gamma = None
|
||||||
|
|
||||||
|
elif lattice in lattice_symmetries:
|
||||||
self.family = lattice_symmetries[lattice]
|
self.family = lattice_symmetries[lattice]
|
||||||
self.lattice = lattice
|
self.lattice = lattice
|
||||||
|
|
||||||
|
@ -169,14 +179,8 @@ class Orientation(Rotation):
|
||||||
> np.sum(np.roll([self.alpha,self.beta,self.gamma],r)[1:]) for r in range(3)]):
|
> 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')
|
raise ValueError ('Each lattice angle must be less than sum of others')
|
||||||
|
|
||||||
elif lattice in set(lattice_symmetries.values()):
|
|
||||||
self.family = lattice
|
|
||||||
self.lattice = None
|
|
||||||
|
|
||||||
self.a = self.b = self.c = None
|
|
||||||
self.alpha = self.beta = self.gamma = None
|
|
||||||
else:
|
else:
|
||||||
raise KeyError(f'Lattice "{lattice}" is unknown')
|
raise KeyError(f'no valid family or lattice')
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -188,16 +192,16 @@ class Orientation(Rotation):
|
||||||
|
|
||||||
def __copy__(self,**kwargs):
|
def __copy__(self,**kwargs):
|
||||||
"""Create deep copy."""
|
"""Create deep copy."""
|
||||||
return self.__class__(rotation=kwargs['rotation'] if 'rotation' in kwargs else self.quaternion,
|
return self.__class__(rotation= kwargs['rotation'] if 'rotation' in kwargs else self.quaternion,
|
||||||
lattice =kwargs['lattice'] if 'lattice' in kwargs else self.lattice
|
family = kwargs['family'] if 'family' in kwargs else self.family,
|
||||||
if self.lattice is not None else self.family,
|
lattice = kwargs['lattice'] if 'lattice' in kwargs else self.lattice,
|
||||||
a =kwargs['a'] if 'a' in kwargs else self.a,
|
a = kwargs['a'] if 'a' in kwargs else self.a,
|
||||||
b =kwargs['b'] if 'b' in kwargs else self.b,
|
b = kwargs['b'] if 'b' in kwargs else self.b,
|
||||||
c =kwargs['c'] if 'c' in kwargs else self.c,
|
c = kwargs['c'] if 'c' in kwargs else self.c,
|
||||||
alpha =kwargs['alpha'] if 'alpha' in kwargs else self.alpha,
|
alpha = kwargs['alpha'] if 'alpha' in kwargs else self.alpha,
|
||||||
beta =kwargs['beta'] if 'beta' in kwargs else self.beta,
|
beta = kwargs['beta'] if 'beta' in kwargs else self.beta,
|
||||||
gamma =kwargs['gamma'] if 'gamma' in kwargs else self.gamma,
|
gamma = kwargs['gamma'] if 'gamma' in kwargs else self.gamma,
|
||||||
degrees =kwargs['degrees'] if 'degrees' in kwargs else None,
|
degrees = kwargs['degrees'] if 'degrees' in kwargs else None,
|
||||||
)
|
)
|
||||||
|
|
||||||
copy = __copy__
|
copy = __copy__
|
||||||
|
|
|
@ -25,38 +25,42 @@ def set_of_rodrigues(set_of_quaternions):
|
||||||
|
|
||||||
class TestOrientation:
|
class TestOrientation:
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
@pytest.mark.parametrize('shape',[None,5,(4,6)])
|
@pytest.mark.parametrize('shape',[None,5,(4,6)])
|
||||||
def test_equal(self,lattice,shape):
|
def test_equal(self,family,shape):
|
||||||
R = Rotation.from_random(shape)
|
R = Rotation.from_random(shape)
|
||||||
assert Orientation(R,lattice) == Orientation(R,lattice) if shape is None else \
|
assert Orientation(R,family=family) == Orientation(R,family=family) if shape is None else \
|
||||||
(Orientation(R,lattice) == Orientation(R,lattice)).all()
|
(Orientation(R,family=family) == Orientation(R,family=family)).all()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
@pytest.mark.parametrize('shape',[None,5,(4,6)])
|
@pytest.mark.parametrize('shape',[None,5,(4,6)])
|
||||||
def test_unequal(self,lattice,shape):
|
def test_unequal(self,family,shape):
|
||||||
R = Rotation.from_random(shape)
|
R = Rotation.from_random(shape)
|
||||||
assert not ( Orientation(R,lattice) != Orientation(R,lattice) if shape is None else \
|
assert not ( Orientation(R,family=family) != Orientation(R,family=family) if shape is None else \
|
||||||
(Orientation(R,lattice) != Orientation(R,lattice)).any())
|
(Orientation(R,family=family) != Orientation(R,family=family)).any())
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
@pytest.mark.parametrize('shape',[None,5,(4,6)])
|
@pytest.mark.parametrize('shape',[None,5,(4,6)])
|
||||||
def test_close(self,lattice,shape):
|
def test_close(self,family,shape):
|
||||||
R = Orientation.from_random(lattice=lattice,shape=shape)
|
R = Orientation.from_random(family=family,shape=shape)
|
||||||
assert R.isclose(R.reduced).all() and R.allclose(R.reduced)
|
assert R.isclose(R.reduced).all() and R.allclose(R.reduced)
|
||||||
|
|
||||||
@pytest.mark.parametrize('a,b',[
|
@pytest.mark.parametrize('a,b',[
|
||||||
(dict(rotation=[1,0,0,0],lattice='triclinic'),
|
(dict(rotation=[1,0,0,0],family='triclinic'),
|
||||||
dict(rotation=[0.5,0.5,0.5,0.5],lattice='triclinic')),
|
dict(rotation=[0.5,0.5,0.5,0.5],family='triclinic')),
|
||||||
|
|
||||||
(dict(rotation=[1,0,0,0],lattice='cubic'),
|
(dict(rotation=[1,0,0,0],family='cubic'),
|
||||||
dict(rotation=[1,0,0,0],lattice='hexagonal')),
|
dict(rotation=[1,0,0,0],family='hexagonal')),
|
||||||
|
])
|
||||||
|
def test_unequal_family(self,a,b):
|
||||||
|
assert Orientation(**a) != Orientation(**b)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('a,b',[
|
||||||
(dict(rotation=[1,0,0,0],lattice='cF',a=1),
|
(dict(rotation=[1,0,0,0],lattice='cF',a=1),
|
||||||
dict(rotation=[1,0,0,0],lattice='cF',a=2)),
|
dict(rotation=[1,0,0,0],lattice='cF',a=2)),
|
||||||
])
|
])
|
||||||
def test_nonequal(self,a,b):
|
def test_unequal_lattice(self,a,b):
|
||||||
assert Orientation(**a) != Orientation(**b)
|
assert Orientation(**a) != Orientation(**b)
|
||||||
|
|
||||||
@pytest.mark.parametrize('kwargs',[
|
@pytest.mark.parametrize('kwargs',[
|
||||||
|
@ -100,47 +104,47 @@ class TestOrientation:
|
||||||
assert o != p
|
assert o != p
|
||||||
|
|
||||||
def test_from_quaternion(self):
|
def test_from_quaternion(self):
|
||||||
assert np.all(Orientation.from_quaternion(q=np.array([1,0,0,0]),lattice='triclinic').as_matrix()
|
assert np.all(Orientation.from_quaternion(q=np.array([1,0,0,0]),family='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_Euler_angles(self):
|
def test_from_Euler_angles(self):
|
||||||
assert np.all(Orientation.from_Euler_angles(phi=np.zeros(3),lattice='triclinic').as_matrix()
|
assert np.all(Orientation.from_Euler_angles(phi=np.zeros(3),family='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_axis_angle(self):
|
def test_from_axis_angle(self):
|
||||||
assert np.all(Orientation.from_axis_angle(axis_angle=[1,0,0,0],lattice='triclinic').as_matrix()
|
assert np.all(Orientation.from_axis_angle(axis_angle=[1,0,0,0],family='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_basis(self):
|
def test_from_basis(self):
|
||||||
assert np.all(Orientation.from_basis(basis=np.eye(3),lattice='triclinic').as_matrix()
|
assert np.all(Orientation.from_basis(basis=np.eye(3),family='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_matrix(self):
|
def test_from_matrix(self):
|
||||||
assert np.all(Orientation.from_matrix(R=np.eye(3),lattice='triclinic').as_matrix()
|
assert np.all(Orientation.from_matrix(R=np.eye(3),family='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_Rodrigues_vector(self):
|
def test_from_Rodrigues_vector(self):
|
||||||
assert np.all(Orientation.from_Rodrigues_vector(rho=np.array([0,0,1,0]),lattice='triclinic').as_matrix()
|
assert np.all(Orientation.from_Rodrigues_vector(rho=np.array([0,0,1,0]),family='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_homochoric(self):
|
def test_from_homochoric(self):
|
||||||
assert np.all(Orientation.from_homochoric(h=np.zeros(3),lattice='triclinic').as_matrix()
|
assert np.all(Orientation.from_homochoric(h=np.zeros(3),family='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_cubochoric(self):
|
def test_from_cubochoric(self):
|
||||||
assert np.all(Orientation.from_cubochoric(x=np.zeros(3),lattice='triclinic').as_matrix()
|
assert np.all(Orientation.from_cubochoric(x=np.zeros(3),family='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_spherical_component(self):
|
def test_from_spherical_component(self):
|
||||||
assert np.all(Orientation.from_spherical_component(center=Rotation(),
|
assert np.all(Orientation.from_spherical_component(center=Rotation(),
|
||||||
sigma=0.0,N=1,lattice='triclinic').as_matrix()
|
sigma=0.0,N=1,family='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_fiber_component(self):
|
def test_from_fiber_component(self):
|
||||||
r = Rotation.from_fiber_component(alpha=np.zeros(2),beta=np.zeros(2),
|
r = Rotation.from_fiber_component(alpha=np.zeros(2),beta=np.zeros(2),
|
||||||
sigma=0.0,N=1,rng_seed=0)
|
sigma=0.0,N=1,rng_seed=0)
|
||||||
assert np.all(Orientation.from_fiber_component(alpha=np.zeros(2),beta=np.zeros(2),
|
assert np.all(Orientation.from_fiber_component(alpha=np.zeros(2),beta=np.zeros(2),
|
||||||
sigma=0.0,N=1,rng_seed=0,lattice='triclinic').quaternion
|
sigma=0.0,N=1,rng_seed=0,family='triclinic').quaternion
|
||||||
== r.quaternion)
|
== r.quaternion)
|
||||||
|
|
||||||
@pytest.mark.parametrize('kwargs',[
|
@pytest.mark.parametrize('kwargs',[
|
||||||
|
@ -185,26 +189,26 @@ class TestOrientation:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
Orientation(lattice='aP',a=1,b=2,c=3,alpha=45,beta=45,gamma=90.0001,degrees=True) # noqa
|
Orientation(lattice='aP',a=1,b=2,c=3,alpha=45,beta=45,gamma=90.0001,degrees=True) # noqa
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
@pytest.mark.parametrize('angle',[10,20,30,40])
|
@pytest.mark.parametrize('angle',[10,20,30,40])
|
||||||
def test_average(self,angle,lattice):
|
def test_average(self,angle,family):
|
||||||
o = Orientation.from_axis_angle(lattice=lattice,axis_angle=[[0,0,1,10],[0,0,1,angle]],degrees=True)
|
o = Orientation.from_axis_angle(family=family,axis_angle=[[0,0,1,10],[0,0,1,angle]],degrees=True)
|
||||||
avg_angle = o.average().as_axis_angle(degrees=True,pair=True)[1]
|
avg_angle = o.average().as_axis_angle(degrees=True,pair=True)[1]
|
||||||
assert np.isclose(avg_angle,10+(angle-10)/2.)
|
assert np.isclose(avg_angle,10+(angle-10)/2.)
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
def test_reduced_equivalent(self,lattice):
|
def test_reduced_equivalent(self,family):
|
||||||
i = Orientation(lattice=lattice)
|
i = Orientation(family=family)
|
||||||
o = Orientation.from_random(lattice=lattice)
|
o = Orientation.from_random(family=family)
|
||||||
eq = o.equivalent
|
eq = o.equivalent
|
||||||
FZ = np.argmin(abs(eq.misorientation(i.broadcast_to(len(eq))).as_axis_angle(pair=True)[1]))
|
FZ = np.argmin(abs(eq.misorientation(i.broadcast_to(len(eq))).as_axis_angle(pair=True)[1]))
|
||||||
assert o.reduced == eq[FZ]
|
assert o.reduced == eq[FZ]
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
@pytest.mark.parametrize('N',[1,8,32])
|
@pytest.mark.parametrize('N',[1,8,32])
|
||||||
def test_disorientation(self,lattice,N):
|
def test_disorientation(self,family,N):
|
||||||
o = Orientation.from_random(lattice=lattice,shape=N)
|
o = Orientation.from_random(family=family,shape=N)
|
||||||
p = Orientation.from_random(lattice=lattice,shape=N)
|
p = Orientation.from_random(family=family,shape=N)
|
||||||
|
|
||||||
d,ops = o.disorientation(p,return_operators=True)
|
d,ops = o.disorientation(p,return_operators=True)
|
||||||
|
|
||||||
|
@ -218,72 +222,72 @@ class TestOrientation:
|
||||||
.misorientation(p[n].equivalent[ops[n][1]])
|
.misorientation(p[n].equivalent[ops[n][1]])
|
||||||
.as_quaternion())
|
.as_quaternion())
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
@pytest.mark.parametrize('a,b',[
|
@pytest.mark.parametrize('a,b',[
|
||||||
((2,3,2),(2,3,2)),
|
((2,3,2),(2,3,2)),
|
||||||
((2,2),(4,4)),
|
((2,2),(4,4)),
|
||||||
((3,1),(1,3)),
|
((3,1),(1,3)),
|
||||||
(None,None),
|
(None,None),
|
||||||
])
|
])
|
||||||
def test_disorientation_blending(self,lattice,a,b):
|
def test_disorientation_blending(self,family,a,b):
|
||||||
o = Orientation.from_random(lattice=lattice,shape=a)
|
o = Orientation.from_random(family=family,shape=a)
|
||||||
p = Orientation.from_random(lattice=lattice,shape=b)
|
p = Orientation.from_random(family=family,shape=b)
|
||||||
blend = util.shapeblender(o.shape,p.shape)
|
blend = util.shapeblender(o.shape,p.shape)
|
||||||
for loc in np.random.randint(0,blend,(10,len(blend))):
|
for loc in np.random.randint(0,blend,(10,len(blend))):
|
||||||
assert o[tuple(loc[:len(o.shape)])].disorientation(p[tuple(loc[-len(p.shape):])]) \
|
assert o[tuple(loc[:len(o.shape)])].disorientation(p[tuple(loc[-len(p.shape):])]) \
|
||||||
.isclose(o.disorientation(p)[tuple(loc)])
|
.isclose(o.disorientation(p)[tuple(loc)])
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
def test_disorientation360(self,lattice):
|
def test_disorientation360(self,family):
|
||||||
o_1 = Orientation(Rotation(),lattice)
|
o_1 = Orientation(Rotation(),family=family)
|
||||||
o_2 = Orientation.from_Euler_angles(lattice=lattice,phi=[360,0,0],degrees=True)
|
o_2 = Orientation.from_Euler_angles(family=family,phi=[360,0,0],degrees=True)
|
||||||
assert np.allclose((o_1.disorientation(o_2)).as_matrix(),np.eye(3))
|
assert np.allclose((o_1.disorientation(o_2)).as_matrix(),np.eye(3))
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
@pytest.mark.parametrize('shape',[(1),(2,3),(4,3,2)])
|
@pytest.mark.parametrize('shape',[(1),(2,3),(4,3,2)])
|
||||||
def test_reduced_vectorization(self,lattice,shape):
|
def test_reduced_vectorization(self,family,shape):
|
||||||
o = Orientation.from_random(lattice=lattice,shape=shape)
|
o = Orientation.from_random(family=family,shape=shape)
|
||||||
for r, theO in zip(o.reduced.flatten(),o.flatten()):
|
for r, theO in zip(o.reduced.flatten(),o.flatten()):
|
||||||
assert r == theO.reduced
|
assert r == theO.reduced
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
def test_reduced_corner_cases(self,lattice):
|
def test_reduced_corner_cases(self,family):
|
||||||
# test whether there is always a sym-eq rotation that falls into the FZ
|
# test whether there is always a sym-eq rotation that falls into the FZ
|
||||||
N = np.random.randint(10,40)
|
N = np.random.randint(10,40)
|
||||||
size = np.ones(3)*np.pi**(2./3.)
|
size = np.ones(3)*np.pi**(2./3.)
|
||||||
grid = grid_filters.coordinates0_node([N+1,N+1,N+1],size,-size*.5)
|
grid = grid_filters.coordinates0_node([N+1,N+1,N+1],size,-size*.5)
|
||||||
evenly_distributed = Orientation.from_cubochoric(x=grid[:-2,:-2,:-2],lattice=lattice)
|
evenly_distributed = Orientation.from_cubochoric(x=grid[:-2,:-2,:-2],family=family)
|
||||||
assert evenly_distributed.shape == evenly_distributed.reduced.shape
|
assert evenly_distributed.shape == evenly_distributed.reduced.shape
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
@pytest.mark.parametrize('shape',[(1),(2,3),(4,3,2)])
|
@pytest.mark.parametrize('shape',[(1),(2,3),(4,3,2)])
|
||||||
@pytest.mark.parametrize('vector',np.array([[1,0,0],[1,2,3],[-1,1,-1]]))
|
@pytest.mark.parametrize('vector',np.array([[1,0,0],[1,2,3],[-1,1,-1]]))
|
||||||
@pytest.mark.parametrize('proper',[True,False])
|
@pytest.mark.parametrize('proper',[True,False])
|
||||||
def test_to_SST_vectorization(self,lattice,shape,vector,proper):
|
def test_to_SST_vectorization(self,family,shape,vector,proper):
|
||||||
o = Orientation.from_random(lattice=lattice,shape=shape)
|
o = Orientation.from_random(family=family,shape=shape)
|
||||||
for r, theO in zip(o.to_SST(vector=vector,proper=proper).reshape((-1,3)),o.flatten()):
|
for r, theO in zip(o.to_SST(vector=vector,proper=proper).reshape((-1,3)),o.flatten()):
|
||||||
assert np.allclose(r,theO.to_SST(vector=vector,proper=proper))
|
assert np.allclose(r,theO.to_SST(vector=vector,proper=proper))
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
@pytest.mark.parametrize('shape',[(1),(2,3),(4,3,2)])
|
@pytest.mark.parametrize('shape',[(1),(2,3),(4,3,2)])
|
||||||
@pytest.mark.parametrize('vector',np.array([[1,0,0],[1,2,3],[-1,1,-1]]))
|
@pytest.mark.parametrize('vector',np.array([[1,0,0],[1,2,3],[-1,1,-1]]))
|
||||||
@pytest.mark.parametrize('proper',[True,False])
|
@pytest.mark.parametrize('proper',[True,False])
|
||||||
@pytest.mark.parametrize('in_SST',[True,False])
|
@pytest.mark.parametrize('in_SST',[True,False])
|
||||||
def test_IPF_color_vectorization(self,lattice,shape,vector,proper,in_SST):
|
def test_IPF_color_vectorization(self,family,shape,vector,proper,in_SST):
|
||||||
o = Orientation.from_random(lattice=lattice,shape=shape)
|
o = Orientation.from_random(family=family,shape=shape)
|
||||||
for r, theO in zip(o.IPF_color(vector,in_SST=in_SST,proper=proper).reshape((-1,3)),o.flatten()):
|
for r, theO in zip(o.IPF_color(vector,in_SST=in_SST,proper=proper).reshape((-1,3)),o.flatten()):
|
||||||
assert np.allclose(r,theO.IPF_color(vector,in_SST=in_SST,proper=proper))
|
assert np.allclose(r,theO.IPF_color(vector,in_SST=in_SST,proper=proper))
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
@pytest.mark.parametrize('a,b',[
|
@pytest.mark.parametrize('a,b',[
|
||||||
((2,3,2),(2,3,2)),
|
((2,3,2),(2,3,2)),
|
||||||
((2,2),(4,4)),
|
((2,2),(4,4)),
|
||||||
((3,1),(1,3)),
|
((3,1),(1,3)),
|
||||||
(None,(3,)),
|
(None,(3,)),
|
||||||
])
|
])
|
||||||
def test_to_SST_blending(self,lattice,a,b):
|
def test_to_SST_blending(self,family,a,b):
|
||||||
o = Orientation.from_random(lattice=lattice,shape=a)
|
o = Orientation.from_random(family=family,shape=a)
|
||||||
v = np.random.random(b+(3,))
|
v = np.random.random(b+(3,))
|
||||||
blend = util.shapeblender(o.shape,b)
|
blend = util.shapeblender(o.shape,b)
|
||||||
for loc in np.random.randint(0,blend,(10,len(blend))):
|
for loc in np.random.randint(0,blend,(10,len(blend))):
|
||||||
|
@ -298,55 +302,55 @@ class TestOrientation:
|
||||||
{'label':'blue', 'RGB':[0,0,1],'direction':[1,1,1]}])
|
{'label':'blue', 'RGB':[0,0,1],'direction':[1,1,1]}])
|
||||||
@pytest.mark.parametrize('proper',[True,False])
|
@pytest.mark.parametrize('proper',[True,False])
|
||||||
def test_IPF_cubic(self,color,proper):
|
def test_IPF_cubic(self,color,proper):
|
||||||
cube = Orientation(lattice='cubic')
|
cube = Orientation(family='cubic')
|
||||||
for direction in set(permutations(np.array(color['direction']))):
|
for direction in set(permutations(np.array(color['direction']))):
|
||||||
assert np.allclose(np.array(color['RGB']),
|
assert np.allclose(np.array(color['RGB']),
|
||||||
cube.IPF_color(vector=np.array(direction),proper=proper))
|
cube.IPF_color(vector=np.array(direction),proper=proper))
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
@pytest.mark.parametrize('proper',[True,False])
|
@pytest.mark.parametrize('proper',[True,False])
|
||||||
def test_IPF_equivalent(self,set_of_quaternions,lattice,proper):
|
def test_IPF_equivalent(self,set_of_quaternions,family,proper):
|
||||||
direction = np.random.random(3)*2.0-1.0
|
direction = np.random.random(3)*2.0-1.0
|
||||||
o = Orientation(rotation=set_of_quaternions,lattice=lattice).equivalent
|
o = Orientation(rotation=set_of_quaternions,family=family).equivalent
|
||||||
color = o.IPF_color(vector=direction,proper=proper)
|
color = o.IPF_color(vector=direction,proper=proper)
|
||||||
assert np.allclose(np.broadcast_to(color[0,...],color.shape),color)
|
assert np.allclose(np.broadcast_to(color[0,...],color.shape),color)
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
def test_in_FZ_vectorization(self,set_of_rodrigues,lattice):
|
def test_in_FZ_vectorization(self,set_of_rodrigues,family):
|
||||||
result = Orientation.from_Rodrigues_vector(rho=set_of_rodrigues.reshape((-1,4,4)),lattice=lattice).in_FZ.reshape(-1)
|
result = Orientation.from_Rodrigues_vector(rho=set_of_rodrigues.reshape((-1,4,4)),family=family).in_FZ.reshape(-1)
|
||||||
for r,rho in zip(result,set_of_rodrigues[:len(result)]):
|
for r,rho in zip(result,set_of_rodrigues[:len(result)]):
|
||||||
assert r == Orientation.from_Rodrigues_vector(rho=rho,lattice=lattice).in_FZ
|
assert r == Orientation.from_Rodrigues_vector(rho=rho,family=family).in_FZ
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
def test_in_disorientation_FZ_vectorization(self,set_of_rodrigues,lattice):
|
def test_in_disorientation_FZ_vectorization(self,set_of_rodrigues,family):
|
||||||
result = Orientation.from_Rodrigues_vector(rho=set_of_rodrigues.reshape((-1,4,4)),
|
result = Orientation.from_Rodrigues_vector(rho=set_of_rodrigues.reshape((-1,4,4)),
|
||||||
lattice=lattice).in_disorientation_FZ.reshape(-1)
|
family=family).in_disorientation_FZ.reshape(-1)
|
||||||
for r,rho in zip(result,set_of_rodrigues[:len(result)]):
|
for r,rho in zip(result,set_of_rodrigues[:len(result)]):
|
||||||
assert r == Orientation.from_Rodrigues_vector(rho=rho,lattice=lattice).in_disorientation_FZ
|
assert r == Orientation.from_Rodrigues_vector(rho=rho,family=family).in_disorientation_FZ
|
||||||
|
|
||||||
@pytest.mark.parametrize('proper',[True,False])
|
@pytest.mark.parametrize('proper',[True,False])
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
def test_in_SST_vectorization(self,lattice,proper):
|
def test_in_SST_vectorization(self,family,proper):
|
||||||
vecs = np.random.rand(20,4,3)
|
vecs = np.random.rand(20,4,3)
|
||||||
result = Orientation(lattice=lattice).in_SST(vecs,proper).flatten()
|
result = Orientation(family=family).in_SST(vecs,proper).flatten()
|
||||||
for r,v in zip(result,vecs.reshape((-1,3))):
|
for r,v in zip(result,vecs.reshape((-1,3))):
|
||||||
assert np.all(r == Orientation(lattice=lattice).in_SST(v,proper))
|
assert np.all(r == Orientation(family=family).in_SST(v,proper))
|
||||||
|
|
||||||
@pytest.mark.parametrize('invalid_lattice',['fcc','bcc','hello'])
|
@pytest.mark.parametrize('invalid_family',['fcc','bcc','hello'])
|
||||||
def test_invalid_lattice_init(self,invalid_lattice):
|
def test_invalid_lattice_init(self,invalid_family):
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(KeyError):
|
||||||
Orientation(lattice=invalid_lattice) # noqa
|
Orientation(family=invalid_family) # noqa
|
||||||
|
|
||||||
@pytest.mark.parametrize('invalid_family',[None,'fcc','bcc','hello'])
|
@pytest.mark.parametrize('invalid_family',[None,'fcc','bcc','hello'])
|
||||||
def test_invalid_symmetry_family(self,invalid_family):
|
def test_invalid_symmetry_family(self,invalid_family):
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(KeyError):
|
||||||
o = Orientation(lattice='cubic')
|
o = Orientation(family='cubic')
|
||||||
o.family = invalid_family
|
o.family = invalid_family
|
||||||
o.symmetry_operations # noqa
|
o.symmetry_operations # noqa
|
||||||
|
|
||||||
def test_invalid_rot(self):
|
def test_invalid_rot(self):
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
Orientation.from_random(lattice='cubic') * np.ones(3)
|
Orientation.from_random(family='cubic') * np.ones(3)
|
||||||
|
|
||||||
def test_missing_symmetry_immutable(self):
|
def test_missing_symmetry_immutable(self):
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(KeyError):
|
||||||
|
@ -388,14 +392,14 @@ class TestOrientation:
|
||||||
a=a,b=b,c=c,
|
a=a,b=b,c=c,
|
||||||
alpha=alpha,beta=beta,gamma=gamma).related(relation) # noqa
|
alpha=alpha,beta=beta,gamma=gamma).related(relation) # noqa
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',crystal_families)
|
@pytest.mark.parametrize('family',crystal_families)
|
||||||
@pytest.mark.parametrize('proper',[True,False])
|
@pytest.mark.parametrize('proper',[True,False])
|
||||||
def test_in_SST(self,lattice,proper):
|
def test_in_SST(self,family,proper):
|
||||||
assert Orientation(lattice=lattice).in_SST(np.zeros(3),proper)
|
assert Orientation(family=family).in_SST(np.zeros(3),proper)
|
||||||
|
|
||||||
@pytest.mark.parametrize('function',['in_SST','IPF_color'])
|
@pytest.mark.parametrize('function',['in_SST','IPF_color'])
|
||||||
def test_invalid_argument(self,function):
|
def test_invalid_argument(self,function):
|
||||||
o = Orientation(lattice='cubic') # noqa
|
o = Orientation(family='cubic') # noqa
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
eval(f'o.{function}(np.ones(4))')
|
eval(f'o.{function}(np.ones(4))')
|
||||||
|
|
||||||
|
@ -409,7 +413,7 @@ class TestOrientation:
|
||||||
def test_relationship_vectorize(self,set_of_quaternions,lattice,model):
|
def test_relationship_vectorize(self,set_of_quaternions,lattice,model):
|
||||||
r = Orientation(rotation=set_of_quaternions[:200].reshape((50,4,4)),lattice=lattice).related(model)
|
r = Orientation(rotation=set_of_quaternions[:200].reshape((50,4,4)),lattice=lattice).related(model)
|
||||||
for i in range(200):
|
for i in range(200):
|
||||||
assert (r.reshape((-1,200))[:,i] == Orientation(set_of_quaternions[i],lattice).related(model)).all()
|
assert (r.reshape((-1,200))[:,i] == Orientation(set_of_quaternions[i],lattice=lattice).related(model)).all()
|
||||||
|
|
||||||
@pytest.mark.parametrize('model',['Bain','KS','GT','GT_prime','NW','Pitsch'])
|
@pytest.mark.parametrize('model',['Bain','KS','GT','GT_prime','NW','Pitsch'])
|
||||||
@pytest.mark.parametrize('lattice',['cF','cI'])
|
@pytest.mark.parametrize('lattice',['cF','cI'])
|
||||||
|
@ -512,12 +516,12 @@ class TestOrientation:
|
||||||
== o.shape + (o.symmetry_operations.shape if with_symmetry else ()) + vector.shape
|
== o.shape + (o.symmetry_operations.shape if with_symmetry else ()) + vector.shape
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',['hP','cI','cF'])
|
@pytest.mark.parametrize('lattice',['hP','cI','cF'])
|
||||||
@pytest.mark.parametrize('mode',['slip','twin'])
|
def test_Schmid(self,update,ref_path,lattice):
|
||||||
def test_Schmid(self,update,ref_path,lattice,mode):
|
|
||||||
L = Orientation(lattice=lattice)
|
L = Orientation(lattice=lattice)
|
||||||
reference = ref_path/f'{lattice}_{mode}.txt'
|
for mode in ['slip','twin']: # ToDo test tI
|
||||||
P = L.Schmid(mode)
|
reference = ref_path/f'{lattice}_{mode}.txt'
|
||||||
if update:
|
P = L.Schmid(mode)
|
||||||
table = Table(P.reshape(-1,9),{'Schmid':(3,3,)})
|
if update:
|
||||||
table.save(reference)
|
table = Table(P.reshape(-1,9),{'Schmid':(3,3,)})
|
||||||
assert np.allclose(P,Table.load(reference).get('Schmid'))
|
table.save(reference)
|
||||||
|
assert np.allclose(P,Table.load(reference).get('Schmid'))
|
||||||
|
|
Loading…
Reference in New Issue