158 lines
6.9 KiB
Python
158 lines
6.9 KiB
Python
import random
|
|
|
|
import pytest
|
|
import numpy as np
|
|
|
|
from damask import Rotation
|
|
from damask import Symmetry
|
|
|
|
def in_FZ(system,rho):
|
|
"""Non-vectorized version of 'in_FZ'."""
|
|
rho_abs = abs(rho)
|
|
|
|
if system == 'cubic':
|
|
return np.sqrt(2.0)-1.0 >= rho_abs[0] \
|
|
and np.sqrt(2.0)-1.0 >= rho_abs[1] \
|
|
and np.sqrt(2.0)-1.0 >= rho_abs[2] \
|
|
and 1.0 >= rho_abs[0] + rho_abs[1] + rho_abs[2]
|
|
elif system == 'hexagonal':
|
|
return 1.0 >= rho_abs[0] and 1.0 >= rho_abs[1] and 1.0 >= rho_abs[2] \
|
|
and 2.0 >= np.sqrt(3)*rho_abs[0] + rho_abs[1] \
|
|
and 2.0 >= np.sqrt(3)*rho_abs[1] + rho_abs[0] \
|
|
and 2.0 >= np.sqrt(3) + rho_abs[2]
|
|
elif system == 'tetragonal':
|
|
return 1.0 >= rho_abs[0] and 1.0 >= rho_abs[1] \
|
|
and np.sqrt(2.0) >= rho_abs[0] + rho_abs[1] \
|
|
and np.sqrt(2.0) >= rho_abs[2] + 1.0
|
|
elif system == 'orthorhombic':
|
|
return 1.0 >= rho_abs[0] and 1.0 >= rho_abs[1] and 1.0 >= rho_abs[2]
|
|
else:
|
|
return np.all(np.isfinite(rho_abs))
|
|
|
|
|
|
def in_disorientation_SST(system,rho):
|
|
"""Non-vectorized version of 'in_Disorientation_SST'."""
|
|
epsilon = 0.0
|
|
if system == 'cubic':
|
|
return rho[0] >= rho[1]+epsilon and rho[1] >= rho[2]+epsilon and rho[2] >= epsilon
|
|
elif system == 'hexagonal':
|
|
return rho[0] >= np.sqrt(3)*(rho[1]-epsilon) and rho[1] >= epsilon and rho[2] >= epsilon
|
|
elif system == 'tetragonal':
|
|
return rho[0] >= rho[1]-epsilon and rho[1] >= epsilon and rho[2] >= epsilon
|
|
elif system == 'orthorhombic':
|
|
return rho[0] >= epsilon and rho[1] >= epsilon and rho[2] >= epsilon
|
|
else:
|
|
return True
|
|
|
|
|
|
def in_SST(system,vector,proper = False):
|
|
"""Non-vectorized version of 'in_SST'."""
|
|
if system == 'cubic':
|
|
basis = {'improper':np.array([ [-1. , 0. , 1. ],
|
|
[ np.sqrt(2.) , -np.sqrt(2.) , 0. ],
|
|
[ 0. , np.sqrt(3.) , 0. ] ]),
|
|
'proper':np.array([ [ 0. , -1. , 1. ],
|
|
[-np.sqrt(2.) , np.sqrt(2.) , 0. ],
|
|
[ np.sqrt(3.) , 0. , 0. ] ]),
|
|
}
|
|
elif system == 'hexagonal':
|
|
basis = {'improper':np.array([ [ 0. , 0. , 1. ],
|
|
[ 1. , -np.sqrt(3.) , 0. ],
|
|
[ 0. , 2. , 0. ] ]),
|
|
'proper':np.array([ [ 0. , 0. , 1. ],
|
|
[-1. , np.sqrt(3.) , 0. ],
|
|
[ np.sqrt(3.) , -1. , 0. ] ]),
|
|
}
|
|
elif system == 'tetragonal':
|
|
basis = {'improper':np.array([ [ 0. , 0. , 1. ],
|
|
[ 1. , -1. , 0. ],
|
|
[ 0. , np.sqrt(2.) , 0. ] ]),
|
|
'proper':np.array([ [ 0. , 0. , 1. ],
|
|
[-1. , 1. , 0. ],
|
|
[ np.sqrt(2.) , 0. , 0. ] ]),
|
|
}
|
|
elif system == 'orthorhombic':
|
|
basis = {'improper':np.array([ [ 0., 0., 1.],
|
|
[ 1., 0., 0.],
|
|
[ 0., 1., 0.] ]),
|
|
'proper':np.array([ [ 0., 0., 1.],
|
|
[-1., 0., 0.],
|
|
[ 0., 1., 0.] ]),
|
|
}
|
|
else:
|
|
return True
|
|
|
|
v = np.array(vector,dtype=float)
|
|
if proper:
|
|
theComponents = np.around(np.dot(basis['improper'],v),12)
|
|
inSST = np.all(theComponents >= 0.0)
|
|
if not inSST:
|
|
theComponents = np.around(np.dot(basis['proper'],v),12)
|
|
inSST = np.all(theComponents >= 0.0)
|
|
else:
|
|
v[2] = abs(v[2])
|
|
theComponents = np.around(np.dot(basis['improper'],v),12)
|
|
inSST = np.all(theComponents >= 0.0)
|
|
|
|
return inSST
|
|
|
|
|
|
@pytest.fixture
|
|
def set_of_rodrigues(set_of_quaternions):
|
|
return Rotation(set_of_quaternions).as_Rodrigues(vector=True)[:200]
|
|
|
|
class TestSymmetry:
|
|
|
|
@pytest.mark.parametrize('system',Symmetry.crystal_systems)
|
|
def test_in_FZ_vectorize(self,set_of_rodrigues,system):
|
|
result = Symmetry(system).in_FZ(set_of_rodrigues.reshape(50,4,3)).reshape(200)
|
|
for i,r in enumerate(result):
|
|
assert r == in_FZ(system,set_of_rodrigues[i])
|
|
|
|
@pytest.mark.parametrize('system',Symmetry.crystal_systems)
|
|
def test_in_disorientation_SST_vectorize(self,set_of_rodrigues,system):
|
|
result = Symmetry(system).in_disorientation_SST(set_of_rodrigues.reshape(50,4,3)).reshape(200)
|
|
for i,r in enumerate(result):
|
|
assert r == in_disorientation_SST(system,set_of_rodrigues[i])
|
|
|
|
@pytest.mark.parametrize('proper',[True,False])
|
|
@pytest.mark.parametrize('system',Symmetry.crystal_systems)
|
|
def test_in_SST_vectorize(self,system,proper):
|
|
vecs = np.random.rand(20,4,3)
|
|
result = Symmetry(system).in_SST(vecs,proper).reshape(20*4)
|
|
for i,r in enumerate(result):
|
|
assert r == in_SST(system,vecs.reshape(20*4,3)[i],proper)
|
|
|
|
@pytest.mark.parametrize('invalid_symmetry',['fcc','bcc','hello'])
|
|
def test_invalid_symmetry(self,invalid_symmetry):
|
|
with pytest.raises(KeyError):
|
|
s = Symmetry(invalid_symmetry) # noqa
|
|
|
|
def test_equal(self):
|
|
symmetry = random.choice(Symmetry.crystal_systems)
|
|
print(symmetry)
|
|
assert Symmetry(symmetry) == Symmetry(symmetry)
|
|
|
|
def test_not_equal(self):
|
|
symmetries = random.sample(Symmetry.crystal_systems,k=2)
|
|
assert Symmetry(symmetries[0]) != Symmetry(symmetries[1])
|
|
|
|
@pytest.mark.parametrize('system',Symmetry.crystal_systems)
|
|
def test_in_FZ(self,system):
|
|
assert Symmetry(system).in_FZ(np.zeros(3))
|
|
|
|
@pytest.mark.parametrize('system',Symmetry.crystal_systems)
|
|
def test_in_disorientation_SST(self,system):
|
|
assert Symmetry(system).in_disorientation_SST(np.zeros(3))
|
|
|
|
@pytest.mark.parametrize('system',Symmetry.crystal_systems)
|
|
@pytest.mark.parametrize('proper',[True,False])
|
|
def test_in_SST(self,system,proper):
|
|
assert Symmetry(system).in_SST(np.zeros(3),proper)
|
|
|
|
@pytest.mark.parametrize('function',['in_FZ','in_disorientation_SST','in_SST'])
|
|
def test_invalid_argument(self,function):
|
|
s = Symmetry() # noqa
|
|
with pytest.raises(ValueError):
|
|
eval(f's.{function}(np.ones(4))')
|