simplifications + more tests
This commit is contained in:
parent
de8e9b5fc1
commit
e18a5b8a1b
|
@ -1,7 +1,5 @@
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from . import Rotation
|
|
||||||
|
|
||||||
|
|
||||||
class Symmetry:
|
class Symmetry:
|
||||||
"""
|
"""
|
||||||
|
@ -29,7 +27,6 @@ class Symmetry:
|
||||||
raise KeyError(f'Crystal system "{system}" is unknown')
|
raise KeyError(f'Crystal system "{system}" is unknown')
|
||||||
|
|
||||||
self.system = system.lower() if isinstance(system,str) else system
|
self.system = system.lower() if isinstance(system,str) else system
|
||||||
self.lattice = self.system # ToDo: for compatibility
|
|
||||||
|
|
||||||
|
|
||||||
def __copy__(self):
|
def __copy__(self):
|
||||||
|
@ -219,6 +216,7 @@ class Symmetry:
|
||||||
return np.ones_like(rho[...,0],dtype=bool)
|
return np.ones_like(rho[...,0],dtype=bool)
|
||||||
|
|
||||||
|
|
||||||
|
#ToDo: IPF color in separate function
|
||||||
def in_SST(self,vector,proper=False,color=False):
|
def in_SST(self,vector,proper=False,color=False):
|
||||||
"""
|
"""
|
||||||
Check whether given vector falls into standard stereographic triangle of own symmetry.
|
Check whether given vector falls into standard stereographic triangle of own symmetry.
|
||||||
|
@ -311,9 +309,9 @@ class Symmetry:
|
||||||
# ******************************************************************************************
|
# ******************************************************************************************
|
||||||
class Lattice: # ToDo: Make a subclass of Symmetry!
|
class Lattice: # ToDo: Make a subclass of Symmetry!
|
||||||
"""
|
"""
|
||||||
Lattice system.
|
Bravais lattice.
|
||||||
|
|
||||||
Currently, this contains only a mapping from Bravais lattice to symmetry
|
This contains only a mapping from Bravais lattice to symmetry
|
||||||
and orientation relationships. It could include twin and slip systems.
|
and orientation relationships. It could include twin and slip systems.
|
||||||
|
|
||||||
References
|
References
|
||||||
|
@ -331,7 +329,7 @@ class Lattice: # ToDo: Make a subclass of Symmetry!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, lattice):
|
def __init__(self,lattice,c_over_a=None):
|
||||||
"""
|
"""
|
||||||
New lattice of given type.
|
New lattice of given type.
|
||||||
|
|
||||||
|
@ -345,20 +343,20 @@ class Lattice: # ToDo: Make a subclass of Symmetry!
|
||||||
self.symmetry = Symmetry(self.lattices[lattice]['system'])
|
self.symmetry = Symmetry(self.lattices[lattice]['system'])
|
||||||
|
|
||||||
# transition to subclass
|
# transition to subclass
|
||||||
self.system = self.symmetry.system
|
self.system = self.symmetry.system
|
||||||
self.in_SST = self.symmetry.in_SST
|
self.in_SST = self.symmetry.in_SST
|
||||||
self.in_FZ = self.symmetry.in_FZ
|
self.in_FZ = self.symmetry.in_FZ
|
||||||
|
self.in_disorientation_SST = self.symmetry.in_disorientation_SST
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""Report basic lattice information."""
|
"""Report basic lattice information."""
|
||||||
return 'Bravais lattice {} ({} symmetry)'.format(self.lattice,self.symmetry)
|
return 'Bravais lattice {} ({} crystal system)'.format(self.lattice,self.symmetry)
|
||||||
|
|
||||||
|
|
||||||
# Kurdjomov--Sachs orientation relationship for fcc <-> bcc transformation
|
# Kurdjomov--Sachs orientation relationship for fcc <-> bcc transformation
|
||||||
# from S. Morito et al., Journal of Alloys and Compounds 577:s587-s592, 2013
|
# 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
|
# also see K. Kitahara et al., Acta Materialia 54:1279-1288, 2006
|
||||||
KS = {'mapping':{'fcc':0,'bcc':1},
|
_KS = {'mapping':{'fcc':0,'bcc':1},
|
||||||
'planes': np.array([
|
'planes': 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]],
|
||||||
|
@ -412,7 +410,7 @@ class Lattice: # ToDo: Make a subclass of Symmetry!
|
||||||
|
|
||||||
# Greninger--Troiano orientation relationship for fcc <-> bcc transformation
|
# Greninger--Troiano orientation relationship for fcc <-> bcc transformation
|
||||||
# from Y. He et al., Journal of Applied Crystallography 39:72-81, 2006
|
# from Y. He et al., Journal of Applied Crystallography 39:72-81, 2006
|
||||||
GT = {'mapping':{'fcc':0,'bcc':1},
|
_GT = {'mapping':{'fcc':0,'bcc':1},
|
||||||
'planes': np.array([
|
'planes': np.array([
|
||||||
[[ 1, 1, 1],[ 1, 0, 1]],
|
[[ 1, 1, 1],[ 1, 0, 1]],
|
||||||
[[ 1, 1, 1],[ 1, 1, 0]],
|
[[ 1, 1, 1],[ 1, 1, 0]],
|
||||||
|
@ -466,7 +464,7 @@ class Lattice: # ToDo: Make a subclass of Symmetry!
|
||||||
|
|
||||||
# Greninger--Troiano' orientation relationship for fcc <-> bcc transformation
|
# Greninger--Troiano' orientation relationship for fcc <-> bcc transformation
|
||||||
# from Y. He et al., Journal of Applied Crystallography 39:72-81, 2006
|
# from Y. He et al., Journal of Applied Crystallography 39:72-81, 2006
|
||||||
GTprime = {'mapping':{'fcc':0,'bcc':1},
|
_GTprime = {'mapping':{'fcc':0,'bcc':1},
|
||||||
'planes': np.array([
|
'planes': np.array([
|
||||||
[[ 7, 17, 17],[ 12, 5, 17]],
|
[[ 7, 17, 17],[ 12, 5, 17]],
|
||||||
[[ 17, 7, 17],[ 17, 12, 5]],
|
[[ 17, 7, 17],[ 17, 12, 5]],
|
||||||
|
@ -520,7 +518,7 @@ class Lattice: # ToDo: Make a subclass of Symmetry!
|
||||||
|
|
||||||
# Nishiyama--Wassermann orientation relationship for fcc <-> bcc transformation
|
# Nishiyama--Wassermann orientation relationship for fcc <-> bcc transformation
|
||||||
# from H. Kitahara et al., Materials Characterization 54:378-386, 2005
|
# from H. Kitahara et al., Materials Characterization 54:378-386, 2005
|
||||||
NW = {'mapping':{'fcc':0,'bcc':1},
|
_NW = {'mapping':{'fcc':0,'bcc':1},
|
||||||
'planes': np.array([
|
'planes': 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]],
|
||||||
|
@ -550,7 +548,7 @@ class Lattice: # ToDo: Make a subclass of Symmetry!
|
||||||
|
|
||||||
# Pitsch orientation relationship for fcc <-> bcc transformation
|
# Pitsch orientation relationship for fcc <-> bcc transformation
|
||||||
# from Y. He et al., Acta Materialia 53:1179-1190, 2005
|
# from Y. He et al., Acta Materialia 53:1179-1190, 2005
|
||||||
Pitsch = {'mapping':{'fcc':0,'bcc':1},
|
_Pitsch = {'mapping':{'fcc':0,'bcc':1},
|
||||||
'planes': np.array([
|
'planes': np.array([
|
||||||
[[ 0, 1, 0],[ -1, 0, 1]],
|
[[ 0, 1, 0],[ -1, 0, 1]],
|
||||||
[[ 0, 0, 1],[ 1, -1, 0]],
|
[[ 0, 0, 1],[ 1, -1, 0]],
|
||||||
|
@ -580,7 +578,7 @@ class Lattice: # ToDo: Make a subclass of Symmetry!
|
||||||
|
|
||||||
# Bain orientation relationship for fcc <-> bcc transformation
|
# Bain orientation relationship for fcc <-> bcc transformation
|
||||||
# from Y. He et al., Journal of Applied Crystallography 39:72-81, 2006
|
# from Y. He et al., Journal of Applied Crystallography 39:72-81, 2006
|
||||||
Bain = {'mapping':{'fcc':0,'bcc':1},
|
_Bain = {'mapping':{'fcc':0,'bcc':1},
|
||||||
'planes': np.array([
|
'planes': np.array([
|
||||||
[[ 1, 0, 0],[ 1, 0, 0]],
|
[[ 1, 0, 0],[ 1, 0, 0]],
|
||||||
[[ 0, 1, 0],[ 0, 1, 0]],
|
[[ 0, 1, 0],[ 0, 1, 0]],
|
||||||
|
@ -590,7 +588,8 @@ class Lattice: # ToDo: Make a subclass of Symmetry!
|
||||||
[[ 0, 0, 1],[ 1, 0, 1]],
|
[[ 0, 0, 1],[ 1, 0, 1]],
|
||||||
[[ 1, 0, 0],[ 1, 1, 0]]],dtype='float')}
|
[[ 1, 0, 0],[ 1, 1, 0]]],dtype='float')}
|
||||||
|
|
||||||
def relationOperations(self,model):
|
|
||||||
|
def relation_operations(self,model):
|
||||||
"""
|
"""
|
||||||
Crystallographic orientation relationships for phase transformations.
|
Crystallographic orientation relationships for phase transformations.
|
||||||
|
|
||||||
|
@ -612,8 +611,8 @@ class Lattice: # ToDo: Make a subclass of Symmetry!
|
||||||
https://doi.org/10.1016/j.actamat.2004.11.021
|
https://doi.org/10.1016/j.actamat.2004.11.021
|
||||||
|
|
||||||
"""
|
"""
|
||||||
models={'KS':self.KS, 'GT':self.GT, 'GT_prime':self.GTprime,
|
models={'KS':self._KS, 'GT':self._GT, 'GT_prime':self._GTprime,
|
||||||
'NW':self.NW, 'Pitsch': self.Pitsch, 'Bain':self.Bain}
|
'NW':self._NW, 'Pitsch': self._Pitsch, 'Bain':self._Bain}
|
||||||
try:
|
try:
|
||||||
relationship = models[model]
|
relationship = models[model]
|
||||||
except KeyError :
|
except KeyError :
|
||||||
|
@ -639,6 +638,8 @@ class Lattice: # ToDo: Make a subclass of Symmetry!
|
||||||
otherDir = miller[otherDir_id]/ np.linalg.norm(miller[otherDir_id])
|
otherDir = miller[otherDir_id]/ np.linalg.norm(miller[otherDir_id])
|
||||||
otherMatrix = np.array([otherDir,np.cross(otherPlane,otherDir),otherPlane])
|
otherMatrix = np.array([otherDir,np.cross(otherPlane,otherDir),otherPlane])
|
||||||
|
|
||||||
r['rotations'].append(Rotation.from_matrix(np.dot(otherMatrix.T,myMatrix)))
|
r['rotations'].append(np.dot(otherMatrix.T,myMatrix))
|
||||||
|
|
||||||
|
r['rotations'] = np.array(r['rotations'])
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
|
|
@ -71,8 +71,8 @@ class Orientation: # ToDo: make subclass of lattice and Rotation?
|
||||||
r = b*aInv
|
r = b*aInv
|
||||||
for k in range(2):
|
for k in range(2):
|
||||||
r.inverse()
|
r.inverse()
|
||||||
breaker = self.in_FZ \
|
breaker = self.lattice.in_FZ(r.as_Rodrigues(vector=True)) \
|
||||||
and (not SST or other.lattice.symmetry.inDisorientationSST(r.as_Rodrigues(vector=True)))
|
and (not SST or other.lattice.in_disorientation_SST(r.as_Rodrigues(vector=True)))
|
||||||
if breaker: break
|
if breaker: break
|
||||||
if breaker: break
|
if breaker: break
|
||||||
if breaker: break
|
if breaker: break
|
||||||
|
@ -90,40 +90,36 @@ class Orientation: # ToDo: make subclass of lattice and Rotation?
|
||||||
@property
|
@property
|
||||||
def equivalent(self):
|
def equivalent(self):
|
||||||
"""
|
"""
|
||||||
Return orientations which are symmetrically equivalent.
|
Orientations which are symmetrically equivalent.
|
||||||
|
|
||||||
One dimension (length according to symmetrically equivalent orientations)
|
One dimension (length according to number of symmetrically equivalent orientations)
|
||||||
is added to the left of the Rotation array.
|
is added to the left of the Rotation array.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
s = self.lattice.symmetry.symmetry_operations
|
o = self.lattice.symmetry.symmetry_operations
|
||||||
s = s.reshape(s.shape[:1]+(1,)*len(self.rotation.shape)+(4,))
|
o = o.reshape(o.shape[:1]+(1,)*len(self.rotation.shape)+(4,))
|
||||||
s = Rotation(np.broadcast_to(s,s.shape[:1]+self.rotation.quaternion.shape))
|
o = Rotation(np.broadcast_to(o,o.shape[:1]+self.rotation.quaternion.shape))
|
||||||
|
|
||||||
r = np.broadcast_to(self.rotation.quaternion,s.shape[:1]+self.rotation.quaternion.shape)
|
s = np.broadcast_to(self.rotation.quaternion,o.shape[:1]+self.rotation.quaternion.shape)
|
||||||
|
|
||||||
return self.__class__(s@Rotation(r),self.lattice)
|
return self.__class__(o@Rotation(s),self.lattice)
|
||||||
|
|
||||||
|
|
||||||
def relatedOrientations_vec(self,model):
|
def related(self,model):
|
||||||
"""List of orientations related by the given orientation relationship."""
|
"""
|
||||||
h = self.lattice.relationOperations(model)
|
Orientations related by the given orientation relationship.
|
||||||
rot= h['rotations']
|
|
||||||
op=np.array([o.as_quaternion() for o in rot])
|
|
||||||
|
|
||||||
s = op.reshape(op.shape[:1]+(1,)*len(self.rotation.shape)+(4,))
|
One dimension (length according to number of related orientations)
|
||||||
s = Rotation(np.broadcast_to(s,s.shape[:1]+self.rotation.quaternion.shape))
|
is added to the left of the Rotation array.
|
||||||
|
|
||||||
r = np.broadcast_to(self.rotation.quaternion,s.shape[:1]+self.rotation.quaternion.shape)
|
"""
|
||||||
r = Rotation(r)
|
o = Rotation.from_matrix(self.lattice.relation_operations(model)['rotations']).as_quaternion()
|
||||||
|
o = o.reshape(o.shape[:1]+(1,)*len(self.rotation.shape)+(4,))
|
||||||
|
o = Rotation(np.broadcast_to(o,o.shape[:1]+self.rotation.quaternion.shape))
|
||||||
|
|
||||||
return self.__class__(s@r,h['lattice'])
|
s = np.broadcast_to(self.rotation.quaternion,o.shape[:1]+self.rotation.quaternion.shape)
|
||||||
|
|
||||||
|
return self.__class__(o@Rotation(s),self.lattice.relation_operations(model)['lattice'])
|
||||||
def relatedOrientations(self,model):
|
|
||||||
"""List of orientations related by the given orientation relationship."""
|
|
||||||
r = self.lattice.relationOperations(model)
|
|
||||||
return [self.__class__(o*self.rotation,r['lattice']) for o in r['rotations']]
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -136,26 +132,31 @@ class Orientation: # ToDo: make subclass of lattice and Rotation?
|
||||||
found = np.zeros_like(in_FZ[0],dtype=bool)
|
found = np.zeros_like(in_FZ[0],dtype=bool)
|
||||||
q = self.rotation.quaternion[0]
|
q = self.rotation.quaternion[0]
|
||||||
for s in range(in_FZ.shape[0]):
|
for s in range(in_FZ.shape[0]):
|
||||||
|
#something fishy... why does q needs to be initialized?
|
||||||
q = np.where(np.expand_dims(np.logical_and(in_FZ[s],~found),-1),eq.rotation.quaternion[s],q)
|
q = np.where(np.expand_dims(np.logical_and(in_FZ[s],~found),-1),eq.rotation.quaternion[s],q)
|
||||||
found = np.logical_or(in_FZ[s],found)
|
found = np.logical_or(in_FZ[s],found)
|
||||||
|
|
||||||
return self.__class__(q,self.lattice)
|
return self.__class__(q,self.lattice)
|
||||||
|
|
||||||
|
|
||||||
# ToDo: vectorize
|
def inverse_pole(self,axis,proper=False,SST=True):
|
||||||
def inversePole(self,
|
|
||||||
axis,
|
|
||||||
proper = False,
|
|
||||||
SST = True):
|
|
||||||
"""Axis rotated according to orientation (using crystal symmetry to ensure location falls into SST)."""
|
"""Axis rotated according to orientation (using crystal symmetry to ensure location falls into SST)."""
|
||||||
if SST: # pole requested to be within SST
|
if SST:
|
||||||
for i,o in enumerate(self.equivalent): # test all symmetric equivalent quaternions
|
eq = self.equivalent
|
||||||
pole = o.rotation@axis # align crystal direction to axis
|
pole = eq.rotation @ np.broadcast_to(axis/np.linalg.norm(axis),eq.rotation.shape+(3,))
|
||||||
if self.lattice.in_SST(pole,proper): break # found SST version
|
in_SST = self.lattice.in_SST(pole,proper=proper)
|
||||||
else:
|
|
||||||
pole = self.rotation@axis # align crystal direction to axis
|
# remove duplicates (occur for highly symmetric orientations)
|
||||||
|
found = np.zeros_like(in_SST[0],dtype=bool)
|
||||||
|
p = pole[0]
|
||||||
|
for s in range(in_SST.shape[0]):
|
||||||
|
p = np.where(np.expand_dims(np.logical_and(in_SST[s],~found),-1),pole[s],p)
|
||||||
|
found = np.logical_or(in_SST[s],found)
|
||||||
|
|
||||||
|
return p
|
||||||
|
else:
|
||||||
|
return self.rotation @ np.broadcast_to(axis/np.linalg.norm(axis),self.rotation.shape+(3,))
|
||||||
|
|
||||||
return (pole,i if SST else 0)
|
|
||||||
|
|
||||||
|
|
||||||
def IPF_color(self,axis): #ToDo axis or direction?
|
def IPF_color(self,axis): #ToDo axis or direction?
|
||||||
|
@ -166,7 +167,7 @@ class Orientation: # ToDo: make subclass of lattice and Rotation?
|
||||||
|
|
||||||
# remove duplicates (occur for highly symmetric orientations)
|
# remove duplicates (occur for highly symmetric orientations)
|
||||||
found = np.zeros_like(in_SST[0],dtype=bool)
|
found = np.zeros_like(in_SST[0],dtype=bool)
|
||||||
c = np.empty(color.shape[1:])
|
c = color[0]
|
||||||
for s in range(in_SST.shape[0]):
|
for s in range(in_SST.shape[0]):
|
||||||
c = np.where(np.expand_dims(np.logical_and(in_SST[s],~found),-1),color[s],c)
|
c = np.where(np.expand_dims(np.logical_and(in_SST[s],~found),-1),color[s],c)
|
||||||
found = np.logical_or(in_SST[s],found)
|
found = np.logical_or(in_SST[s],found)
|
||||||
|
|
|
@ -28,6 +28,22 @@ def reference_dir(reference_dir_base):
|
||||||
|
|
||||||
class TestOrientation:
|
class TestOrientation:
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('model',['Bain','KS','GT','GT_prime','NW','Pitsch'])
|
||||||
|
@pytest.mark.parametrize('lattice',['fcc','bcc'])
|
||||||
|
def test_relationship_vectorize(self,set_of_quaternions,lattice,model):
|
||||||
|
result = Orientation(set_of_quaternions[:200].reshape(50,4,4),lattice).related(model)
|
||||||
|
ref_qu = result.rotation.quaternion.reshape(-1,200,4)
|
||||||
|
for i in range(200):
|
||||||
|
single = Orientation(set_of_quaternions[i],lattice).related(model).rotation.quaternion
|
||||||
|
assert np.allclose(ref_qu[:,i,:],single)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('lattice',Lattice.lattices)
|
||||||
|
def test_IPF_vectorize(self,set_of_quaternions,lattice):
|
||||||
|
direction = np.random.random(3)*2.0-1
|
||||||
|
oris = Orientation(Rotation(set_of_quaternions),lattice)[:200]
|
||||||
|
for i,color in enumerate(oris.IPF_color(direction)):
|
||||||
|
assert np.allclose(color,IPF_color(oris[i],direction))
|
||||||
|
|
||||||
@pytest.mark.parametrize('color',[{'label':'red', 'RGB':[1,0,0],'direction':[0,0,1]},
|
@pytest.mark.parametrize('color',[{'label':'red', 'RGB':[1,0,0],'direction':[0,0,1]},
|
||||||
{'label':'green','RGB':[0,1,0],'direction':[0,1,1]},
|
{'label':'green','RGB':[0,1,0],'direction':[0,1,1]},
|
||||||
{'label':'blue', 'RGB':[0,0,1],'direction':[1,1,1]}])
|
{'label':'blue', 'RGB':[0,0,1],'direction':[1,1,1]}])
|
||||||
|
@ -45,15 +61,6 @@ class TestOrientation:
|
||||||
for equivalent in ori.equivalent:
|
for equivalent in ori.equivalent:
|
||||||
assert np.allclose(color,equivalent.IPF_color(direction))
|
assert np.allclose(color,equivalent.IPF_color(direction))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',Lattice.lattices)
|
|
||||||
def test_IPF_vectorize(self,set_of_quaternions,lattice):
|
|
||||||
direction = np.random.random(3)*2.0-1
|
|
||||||
oris = Orientation(Rotation(set_of_quaternions),lattice)[:200]
|
|
||||||
for i,color in enumerate(oris.IPF_color(direction)):
|
|
||||||
assert np.allclose(color,IPF_color(oris[i],direction))
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',Lattice.lattices)
|
@pytest.mark.parametrize('lattice',Lattice.lattices)
|
||||||
def test_reduced(self,set_of_quaternions,lattice):
|
def test_reduced(self,set_of_quaternions,lattice):
|
||||||
oris = Orientation(Rotation(set_of_quaternions),lattice)
|
oris = Orientation(Rotation(set_of_quaternions),lattice)
|
||||||
|
@ -65,8 +72,8 @@ class TestOrientation:
|
||||||
@pytest.mark.parametrize('lattice',['fcc','bcc'])
|
@pytest.mark.parametrize('lattice',['fcc','bcc'])
|
||||||
def test_relationship_forward_backward(self,model,lattice):
|
def test_relationship_forward_backward(self,model,lattice):
|
||||||
ori = Orientation(Rotation.from_random(),lattice)
|
ori = Orientation(Rotation.from_random(),lattice)
|
||||||
for i,r in enumerate(ori.relatedOrientations(model)):
|
for i,r in enumerate(ori.related(model)):
|
||||||
ori2 = r.relatedOrientations(model)[i]
|
ori2 = r.related(model)[i]
|
||||||
misorientation = ori.rotation.misorientation(ori2.rotation)
|
misorientation = ori.rotation.misorientation(ori2.rotation)
|
||||||
assert misorientation.asAxisAngle(degrees=True)[3]<1.0e-5
|
assert misorientation.asAxisAngle(degrees=True)[3]<1.0e-5
|
||||||
|
|
||||||
|
@ -75,7 +82,7 @@ class TestOrientation:
|
||||||
def test_relationship_reference(self,update,reference_dir,model,lattice):
|
def test_relationship_reference(self,update,reference_dir,model,lattice):
|
||||||
reference = os.path.join(reference_dir,'{}_{}.txt'.format(lattice,model))
|
reference = os.path.join(reference_dir,'{}_{}.txt'.format(lattice,model))
|
||||||
ori = Orientation(Rotation(),lattice)
|
ori = Orientation(Rotation(),lattice)
|
||||||
eu = np.array([o.rotation.as_Eulers(degrees=True) for o in ori.relatedOrientations(model)])
|
eu = np.array([o.rotation.as_Eulers(degrees=True) for o in ori.related(model)])
|
||||||
if update:
|
if update:
|
||||||
coords = np.array([(1,i+1) for i,x in enumerate(eu)])
|
coords = np.array([(1,i+1) for i,x in enumerate(eu)])
|
||||||
table = damask.Table(eu,{'Eulers':(3,)})
|
table = damask.Table(eu,{'Eulers':(3,)})
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
import pytest
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
from damask import Rotation
|
|
||||||
from damask import Orientation
|
|
||||||
from damask import Lattice
|
|
||||||
|
|
||||||
rot0= Rotation.from_random()
|
|
||||||
rot1= Rotation.from_random()
|
|
||||||
rot2= Rotation.from_random()
|
|
||||||
rot3= Rotation.from_random()
|
|
||||||
|
|
||||||
#disorientation
|
|
||||||
|
|
||||||
#fromaverage
|
|
||||||
#average
|
|
||||||
|
|
||||||
class TestOrientation_vec:
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('model',['Bain','KS','GT','GT_prime','NW','Pitsch'])
|
|
||||||
@pytest.mark.parametrize('lattice',['fcc','bcc'])
|
|
||||||
def test_relatedOrientations_vec(self,model,lattice):
|
|
||||||
ori0=Orientation(rot0,lattice)
|
|
||||||
ori1=Orientation(rot1,lattice)
|
|
||||||
ori2=Orientation(rot2,lattice)
|
|
||||||
ori3=Orientation(rot3,lattice)
|
|
||||||
|
|
||||||
quat=np.array([rot0.as_quaternion(),rot1.as_quaternion(),rot2.as_quaternion(),rot3.as_quaternion()])
|
|
||||||
ori_vec=Orientation(quat,lattice)
|
|
||||||
|
|
||||||
|
|
||||||
for s in range(len(ori1.lattice.relationOperations(model)['rotations'])):
|
|
||||||
assert all(ori_vec.relatedOrientations_vec(model).rotation.as_Eulers()[s,0] == \
|
|
||||||
ori0.relatedOrientations(model)[s].rotation.as_Eulers())
|
|
||||||
assert all(ori_vec.relatedOrientations_vec(model).rotation.as_quaternion()[s,1] == \
|
|
||||||
ori1.relatedOrientations(model)[s].rotation.as_quaternion())
|
|
||||||
assert all(ori_vec.relatedOrientations_vec(model).rotation.as_Rodrigues()[s,2] == \
|
|
||||||
ori2.relatedOrientations(model)[s].rotation.as_Rodrigues())
|
|
||||||
assert all(ori_vec.relatedOrientations_vec(model).rotation.as_cubochoric()[s,3] == \
|
|
||||||
ori3.relatedOrientations(model)[s].rotation.as_cubochoric())
|
|
Loading…
Reference in New Issue