mandatory symmetry
if symmetry is not of interest, damask.Rotation should be used
This commit is contained in:
parent
d5806075d4
commit
bc1454970c
|
@ -136,8 +136,7 @@ class Orientation(Rotation):
|
||||||
|
|
||||||
Rotation.__init__(self) if rotation is None else Rotation.__init__(self,rotation=rotation)
|
Rotation.__init__(self) if rotation is None else Rotation.__init__(self,rotation=rotation)
|
||||||
|
|
||||||
if ( lattice is not None
|
if ( lattice not in self.lattice_symmetries
|
||||||
and lattice not in self.lattice_symmetries
|
|
||||||
and lattice not in self.crystal_families):
|
and lattice not in self.crystal_families):
|
||||||
raise KeyError(f'Lattice "{lattice}" is unknown')
|
raise KeyError(f'Lattice "{lattice}" is unknown')
|
||||||
|
|
||||||
|
@ -206,7 +205,7 @@ class Orientation(Rotation):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""Represent."""
|
"""Represent."""
|
||||||
return '\n'.join(([] if self.lattice is None else [f'Bravais lattice {self.lattice}'])
|
return '\n'.join(([] if self.lattice is None else [f'Bravais lattice {self.lattice}'])
|
||||||
+ ([] if self.family is None else [f'Crystal family {self.family}'])
|
+ ([f'Crystal family {self.family}'])
|
||||||
+ [super().__repr__()])
|
+ [super().__repr__()])
|
||||||
|
|
||||||
|
|
||||||
|
@ -239,9 +238,7 @@ class Orientation(Rotation):
|
||||||
"""
|
"""
|
||||||
matching_type = all([hasattr(other,attr) and getattr(self,attr) == getattr(other,attr)
|
matching_type = all([hasattr(other,attr) and getattr(self,attr) == getattr(other,attr)
|
||||||
for attr in ['family','lattice','parameters']])
|
for attr in ['family','lattice','parameters']])
|
||||||
s = self if self.family is None else self.reduced
|
return np.logical_and(super(__class__,self.reduced).__eq__(other.reduced),matching_type)
|
||||||
o = other if other.family is None else other.reduced
|
|
||||||
return np.logical_and(super(__class__,s).__eq__(o),matching_type)
|
|
||||||
|
|
||||||
def __ne__(self,other):
|
def __ne__(self,other):
|
||||||
"""
|
"""
|
||||||
|
@ -279,9 +276,7 @@ class Orientation(Rotation):
|
||||||
"""
|
"""
|
||||||
matching_type = all([hasattr(other,attr) and getattr(self,attr) == getattr(other,attr)
|
matching_type = all([hasattr(other,attr) and getattr(self,attr) == getattr(other,attr)
|
||||||
for attr in ['family','lattice','parameters']])
|
for attr in ['family','lattice','parameters']])
|
||||||
s = self if self.family is None else self.reduced
|
return np.logical_and(super(__class__,self.reduced).isclose(other.reduced),matching_type)
|
||||||
o = other if other.family is None else other.reduced
|
|
||||||
return np.logical_and(super(__class__,s).isclose(o),matching_type)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -546,9 +541,6 @@ class Orientation(Rotation):
|
||||||
is added to the left of the Rotation array.
|
is added to the left of the Rotation array.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.family is None:
|
|
||||||
raise ValueError('Missing crystal symmetry')
|
|
||||||
|
|
||||||
o = self.symmetry_operations.broadcast_to(self.symmetry_operations.shape+self.shape,mode='right')
|
o = self.symmetry_operations.broadcast_to(self.symmetry_operations.shape+self.shape,mode='right')
|
||||||
return self.copy(rotation=o*Rotation(self.quaternion).broadcast_to(o.shape,mode='left'))
|
return self.copy(rotation=o*Rotation(self.quaternion).broadcast_to(o.shape,mode='left'))
|
||||||
|
|
||||||
|
@ -556,9 +548,6 @@ class Orientation(Rotation):
|
||||||
@property
|
@property
|
||||||
def reduced(self):
|
def reduced(self):
|
||||||
"""Select symmetrically equivalent orientation that falls into fundamental zone according to symmetry."""
|
"""Select symmetrically equivalent orientation that falls into fundamental zone according to symmetry."""
|
||||||
if self.family is None:
|
|
||||||
raise ValueError('Missing crystal symmetry')
|
|
||||||
|
|
||||||
eq = self.equivalent
|
eq = self.equivalent
|
||||||
ok = eq.in_FZ
|
ok = eq.in_FZ
|
||||||
ok &= np.cumsum(ok,axis=0) == 1
|
ok &= np.cumsum(ok,axis=0) == 1
|
||||||
|
@ -587,9 +576,6 @@ class Orientation(Rotation):
|
||||||
https://doi.org/10.1107/S0108767391006864
|
https://doi.org/10.1107/S0108767391006864
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.family is None:
|
|
||||||
raise ValueError('Missing crystal symmetry')
|
|
||||||
|
|
||||||
rho_abs = np.abs(self.as_Rodrigues_vector(compact=True))*(1.-1.e-9)
|
rho_abs = np.abs(self.as_Rodrigues_vector(compact=True))*(1.-1.e-9)
|
||||||
|
|
||||||
with np.errstate(invalid='ignore'):
|
with np.errstate(invalid='ignore'):
|
||||||
|
@ -630,9 +616,6 @@ class Orientation(Rotation):
|
||||||
https://doi.org/10.1107/S0108767391006864
|
https://doi.org/10.1107/S0108767391006864
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.family is None:
|
|
||||||
raise ValueError('Missing crystal symmetry')
|
|
||||||
|
|
||||||
rho = self.as_Rodrigues_vector(compact=True)*(1.0-1.0e-9)
|
rho = self.as_Rodrigues_vector(compact=True)*(1.0-1.0e-9)
|
||||||
|
|
||||||
with np.errstate(invalid='ignore'):
|
with np.errstate(invalid='ignore'):
|
||||||
|
@ -783,8 +766,6 @@ class Orientation(Rotation):
|
||||||
'beta': np.pi/2.,
|
'beta': np.pi/2.,
|
||||||
'gamma': np.pi/2.,
|
'gamma': np.pi/2.,
|
||||||
}
|
}
|
||||||
else:
|
|
||||||
raise KeyError(f'Crystal family "{self.family}" is unknown')
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -1081,8 +1062,6 @@ class Orientation(Rotation):
|
||||||
Bunge Eulers / deg: (11.40, 21.86, 0.60)
|
Bunge Eulers / deg: (11.40, 21.86, 0.60)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.family is None or other.family is None:
|
|
||||||
raise ValueError('missing crystal symmetry')
|
|
||||||
if self.family != other.family:
|
if self.family != other.family:
|
||||||
raise NotImplementedError('disorientation between different crystal families')
|
raise NotImplementedError('disorientation between different crystal families')
|
||||||
|
|
||||||
|
@ -1139,9 +1118,6 @@ class Orientation(Rotation):
|
||||||
https://doi.org/10.1107/S0021889801003077
|
https://doi.org/10.1107/S0021889801003077
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.family is None:
|
|
||||||
raise ValueError('Missing crystal symmetry')
|
|
||||||
|
|
||||||
eq = self.equivalent
|
eq = self.equivalent
|
||||||
m = eq.misorientation(self[...,0].reshape((1,)+self.shape[:-1]+(1,))
|
m = eq.misorientation(self[...,0].reshape((1,)+self.shape[:-1]+(1,))
|
||||||
.broadcast_to(eq.shape))\
|
.broadcast_to(eq.shape))\
|
||||||
|
@ -1183,9 +1159,6 @@ class Orientation(Rotation):
|
||||||
Index of symmetrically equivalent orientation that rotated vector to SST.
|
Index of symmetrically equivalent orientation that rotated vector to SST.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self.family is None:
|
|
||||||
raise ValueError('Missing crystal symmetry')
|
|
||||||
|
|
||||||
eq = self.equivalent
|
eq = self.equivalent
|
||||||
blend = util.shapeblender(eq.shape,np.array(vector).shape[:-1])
|
blend = util.shapeblender(eq.shape,np.array(vector).shape[:-1])
|
||||||
poles = eq.broadcast_to(blend,mode='right') @ np.broadcast_to(np.array(vector),blend+(3,))
|
poles = eq.broadcast_to(blend,mode='right') @ np.broadcast_to(np.array(vector),blend+(3,))
|
||||||
|
|
|
@ -54,6 +54,6 @@ class TestConfig:
|
||||||
def test_abstract_is_complete(self):
|
def test_abstract_is_complete(self):
|
||||||
assert Config().is_complete is None
|
assert Config().is_complete is None
|
||||||
|
|
||||||
@pytest.mark.parametrize('data',[Rotation.from_random(),Orientation.from_random()])
|
@pytest.mark.parametrize('data',[Rotation.from_random(),Orientation.from_random(lattice='cI')])
|
||||||
def test_rotation_orientation(self,data):
|
def test_rotation_orientation(self,data):
|
||||||
assert str(Config(a=data)) == str(Config(a=data.as_quaternion()))
|
assert str(Config(a=data)) == str(Config(a=data.as_quaternion()))
|
||||||
|
|
|
@ -37,9 +37,15 @@ class TestOrientation:
|
||||||
assert not ( Orientation(R,lattice) != Orientation(R,lattice) if shape is None else \
|
assert not ( Orientation(R,lattice) != Orientation(R,lattice) if shape is None else \
|
||||||
(Orientation(R,lattice) != Orientation(R,lattice)).any())
|
(Orientation(R,lattice) != Orientation(R,lattice)).any())
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
||||||
|
@pytest.mark.parametrize('shape',[None,5,(4,6)])
|
||||||
|
def test_close(self,lattice,shape):
|
||||||
|
R = Orientation.from_random(lattice=lattice,shape=shape)
|
||||||
|
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]),
|
(dict(rotation=[1,0,0,0],lattice='triclinic'),
|
||||||
dict(rotation=[0.5,0.5,0.5,0.5])),
|
dict(rotation=[0.5,0.5,0.5,0.5],lattice='triclinic')),
|
||||||
|
|
||||||
(dict(rotation=[1,0,0,0],lattice='cubic'),
|
(dict(rotation=[1,0,0,0],lattice='cubic'),
|
||||||
dict(rotation=[1,0,0,0],lattice='hexagonal')),
|
dict(rotation=[1,0,0,0],lattice='hexagonal')),
|
||||||
|
@ -335,33 +341,9 @@ class TestOrientation:
|
||||||
o.family = invalid_family
|
o.family = invalid_family
|
||||||
o.symmetry_operations # noqa
|
o.symmetry_operations # noqa
|
||||||
|
|
||||||
def test_missing_symmetry_equivalent(self):
|
def test_invalid_rot(self):
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(TypeError):
|
||||||
Orientation(lattice=None).equivalent # noqa
|
Orientation.from_random(lattice='cubic') * np.ones(3)
|
||||||
|
|
||||||
def test_missing_symmetry_reduced(self):
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
Orientation(lattice=None).reduced # noqa
|
|
||||||
|
|
||||||
def test_missing_symmetry_in_FZ(self):
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
Orientation(lattice=None).in_FZ # noqa
|
|
||||||
|
|
||||||
def test_missing_symmetry_in_disorientation_FZ(self):
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
Orientation(lattice=None).in_disorientation_FZ # noqa
|
|
||||||
|
|
||||||
def test_missing_symmetry_disorientation(self):
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
Orientation(lattice=None).disorientation(Orientation(lattice=None)) # noqa
|
|
||||||
|
|
||||||
def test_missing_symmetry_average(self):
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
Orientation(lattice=None).average() # noqa
|
|
||||||
|
|
||||||
def test_missing_symmetry_to_SST(self):
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
Orientation(lattice=None).to_SST(np.zeros(3)) # noqa
|
|
||||||
|
|
||||||
def test_missing_symmetry_immutable(self):
|
def test_missing_symmetry_immutable(self):
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(KeyError):
|
||||||
|
|
Loading…
Reference in New Issue