DAMASK_EICMD/python/tests/test_Rotation.py

204 lines
8.9 KiB
Python
Raw Normal View History

import os
2019-11-24 10:59:00 +05:30
import pytest
2019-11-22 01:31:01 +05:30
import numpy as np
2019-11-24 10:59:00 +05:30
2019-11-22 01:31:01 +05:30
from damask import Rotation
2020-04-08 17:11:46 +05:30
2020-04-09 11:10:20 +05:30
n = 1100
atol=1.e-4
scatter=1.e-2
2019-11-24 10:59:00 +05:30
@pytest.fixture
def default():
"""A set of n random rotations."""
specials = np.array(
[np.array([ 1.0, 0.0, 0.0, 0.0]),
2020-04-08 17:11:46 +05:30
#-----------------------------------------------
np.array([0.0, 1.0, 0.0, 0.0]),
np.array([0.0, 0.0, 1.0, 0.0]),
np.array([0.0, 0.0, 0.0, 1.0]),
np.array([0.0,-1.0, 0.0, 0.0]),
np.array([0.0, 0.0,-1.0, 0.0]),
np.array([0.0, 0.0, 0.0,-1.0]),
2020-04-08 17:11:46 +05:30
#-----------------------------------------------
np.array([1.0, 1.0, 0.0, 0.0])/np.sqrt(2.),
np.array([1.0, 0.0, 1.0, 0.0])/np.sqrt(2.),
np.array([1.0, 0.0, 0.0, 1.0])/np.sqrt(2.),
np.array([0.0, 1.0, 1.0, 0.0])/np.sqrt(2.),
np.array([0.0, 1.0, 0.0, 1.0])/np.sqrt(2.),
np.array([0.0, 0.0, 1.0, 1.0])/np.sqrt(2.),
2020-04-08 17:11:46 +05:30
#-----------------------------------------------
np.array([1.0,-1.0, 0.0, 0.0])/np.sqrt(2.),
np.array([1.0, 0.0,-1.0, 0.0])/np.sqrt(2.),
np.array([1.0, 0.0, 0.0,-1.0])/np.sqrt(2.),
np.array([0.0, 1.0,-1.0, 0.0])/np.sqrt(2.),
np.array([0.0, 1.0, 0.0,-1.0])/np.sqrt(2.),
np.array([0.0, 0.0, 1.0,-1.0])/np.sqrt(2.),
2020-04-08 17:11:46 +05:30
#-----------------------------------------------
np.array([0.0, 1.0,-1.0, 0.0])/np.sqrt(2.),
np.array([0.0, 1.0, 0.0,-1.0])/np.sqrt(2.),
np.array([0.0, 0.0, 1.0,-1.0])/np.sqrt(2.),
2020-04-08 17:11:46 +05:30
#-----------------------------------------------
np.array([0.0,-1.0,-1.0, 0.0])/np.sqrt(2.),
np.array([0.0,-1.0, 0.0,-1.0])/np.sqrt(2.),
np.array([0.0, 0.0,-1.0,-1.0])/np.sqrt(2.),
#-----------------------------------------------
np.array([1.0, 1.0, 1.0, 0.0])/np.sqrt(3.),
np.array([1.0, 1.0, 0.0, 1.0])/np.sqrt(3.),
np.array([1.0, 0.0, 1.0, 1.0])/np.sqrt(3.),
np.array([1.0,-1.0, 1.0, 0.0])/np.sqrt(3.),
np.array([1.0,-1.0, 0.0, 1.0])/np.sqrt(3.),
np.array([1.0, 0.0,-1.0, 1.0])/np.sqrt(3.),
np.array([1.0, 1.0,-1.0, 0.0])/np.sqrt(3.),
np.array([1.0, 1.0, 0.0,-1.0])/np.sqrt(3.),
np.array([1.0, 0.0, 1.0,-1.0])/np.sqrt(3.),
np.array([1.0,-1.0,-1.0, 0.0])/np.sqrt(3.),
np.array([1.0,-1.0, 0.0,-1.0])/np.sqrt(3.),
np.array([1.0, 0.0,-1.0,-1.0])/np.sqrt(3.),
#-----------------------------------------------
np.array([0.0, 1.0, 1.0, 1.0])/np.sqrt(3.),
np.array([0.0, 1.0,-1.0, 1.0])/np.sqrt(3.),
np.array([0.0, 1.0, 1.0,-1.0])/np.sqrt(3.),
np.array([0.0,-1.0, 1.0, 1.0])/np.sqrt(3.),
np.array([0.0,-1.0,-1.0, 1.0])/np.sqrt(3.),
np.array([0.0,-1.0, 1.0,-1.0])/np.sqrt(3.),
np.array([0.0,-1.0,-1.0,-1.0])/np.sqrt(3.),
#-----------------------------------------------
np.array([1.0, 1.0, 1.0, 1.0])/2.,
np.array([1.0,-1.0, 1.0, 1.0])/2.,
np.array([1.0, 1.0,-1.0, 1.0])/2.,
np.array([1.0, 1.0, 1.0,-1.0])/2.,
np.array([1.0,-1.0,-1.0, 1.0])/2.,
np.array([1.0,-1.0, 1.0,-1.0])/2.,
np.array([1.0, 1.0,-1.0,-1.0])/2.,
np.array([1.0,-1.0,-1.0,-1.0])/2.,
])
2020-04-09 11:10:20 +05:30
specials_scatter = specials + np.broadcast_to(np.random.rand(4)*scatter,specials.shape)
specials_scatter /= np.linalg.norm(specials_scatter,axis=1).reshape(-1,1)
specials_scatter[specials_scatter[:,0]<0]*=-1
2020-04-08 17:11:46 +05:30
return [Rotation.fromQuaternion(s) for s in specials] + \
2020-04-09 11:10:20 +05:30
[Rotation.fromQuaternion(s) for s in specials_scatter] + \
2020-04-09 17:50:43 +05:30
[Rotation.fromRandom() for _ in range(n-len(specials)-len(specials_scatter))]
2019-11-24 10:59:00 +05:30
@pytest.fixture
def reference_dir(reference_dir_base):
"""Directory containing reference results."""
return os.path.join(reference_dir_base,'Rotation')
2019-11-22 01:31:01 +05:30
class TestRotation:
2019-11-24 10:59:00 +05:30
def test_Eulers(self,default):
for rot in default:
m = rot.asQuaternion()
o = Rotation.fromEulers(rot.asEulers()).asQuaternion()
ok = np.allclose(m,o,atol=atol)
if np.isclose(rot.asQuaternion()[0],0.0,atol=atol):
ok = ok or np.allclose(m*-1.,o,atol=atol)
print(m,o,rot.asQuaternion())
2020-04-08 17:11:46 +05:30
assert ok
2019-11-22 01:31:01 +05:30
2019-11-24 10:59:00 +05:30
def test_AxisAngle(self,default):
for rot in default:
m = rot.asEulers()
o = Rotation.fromAxisAngle(rot.asAxisAngle()).asEulers()
u = np.array([np.pi*2,np.pi,np.pi*2])
ok = np.allclose(m,o,atol=atol)
ok = ok or np.allclose(np.where(np.isclose(m,u),m-u,m),np.where(np.isclose(o,u),o-u,o),atol=atol)
if np.isclose(m[1],0.0,atol=atol) or np.isclose(m[1],np.pi,atol=atol):
sum_phi = np.unwrap([m[0]+m[2],o[0]+o[2]])
ok = ok or np.isclose(sum_phi[0],sum_phi[1],atol=atol)
print(m,o,rot.asQuaternion())
assert ok
2019-11-22 01:31:01 +05:30
2019-11-24 10:59:00 +05:30
def test_Matrix(self,default):
for rot in default:
m = rot.asAxisAngle()
o = Rotation.fromAxisAngle(rot.asAxisAngle()).asAxisAngle()
ok = np.allclose(m,o,atol=atol)
if np.isclose(m[3],np.pi,atol=atol):
ok = ok or np.allclose(m*np.array([-1.,-1.,-1.,1.]),o,atol=atol)
print(m,o,rot.asQuaternion())
2020-04-08 17:11:46 +05:30
assert ok
2019-11-22 01:31:01 +05:30
2019-11-24 10:59:00 +05:30
def test_Rodriques(self,default):
for rot in default:
m = rot.asMatrix()
o = Rotation.fromRodrigues(rot.asRodrigues()).asMatrix()
print(m,o)
assert np.allclose(m,o,atol=atol)
2019-11-22 01:31:01 +05:30
2019-11-24 10:59:00 +05:30
def test_Homochoric(self,default):
for rot in default:
m = rot.asRodrigues()
o = Rotation.fromHomochoric(rot.asHomochoric()).asRodrigues()
ok = np.allclose(np.clip(m,None,1.e9),np.clip(o,None,1.e9),atol=atol)
print(m,o,rot.asQuaternion())
ok = ok or np.isclose(m[3],0.0,atol=atol)
2019-11-22 01:31:01 +05:30
2019-11-24 10:59:00 +05:30
def test_Cubochoric(self,default):
for rot in default:
m = rot.asHomochoric()
o = Rotation.fromCubochoric(rot.asCubochoric()).asHomochoric()
print(m,o,rot.asQuaternion())
2020-04-08 23:53:05 +05:30
assert np.allclose(m,o,atol=atol)
2019-11-22 01:31:01 +05:30
2019-11-24 10:59:00 +05:30
def test_Quaternion(self,default):
for rot in default:
m = rot.asCubochoric()
o = Rotation.fromQuaternion(rot.asQuaternion()).asCubochoric()
print(m,o,rot.asQuaternion())
assert np.allclose(m,o,atol=atol)
@pytest.mark.parametrize('conversion',[Rotation.qu2om,
Rotation.qu2eu,
Rotation.qu2ax,
Rotation.qu2ro,
Rotation.qu2ho])
def test_quaternion_vectorization(self,default,conversion):
qu = np.array([rot.asQuaternion() for rot in default])
2020-04-09 17:50:43 +05:30
#dev_null = conversion(qu.reshape(qu.shape[0]//2,-1,4))
co = conversion(qu)
for q,c in zip(qu,co):
2020-04-09 17:50:43 +05:30
print(q,c)
assert np.allclose(conversion(q),c)
@pytest.mark.parametrize('conversion',[Rotation.om2eu,
Rotation.om2ax,
])
def test_matrix_vectorization(self,default,conversion):
2020-04-09 17:50:43 +05:30
om = np.array([rot.asMatrix() for rot in default])
#dev_null = conversion(om.reshape(om.shape[0]//2,-1,3,3))
co = conversion(om)
for o,c in zip(om,co):
print(o,c)
assert np.allclose(conversion(o),c)
@pytest.mark.parametrize('conversion',[Rotation.eu2qu,
Rotation.eu2om,
Rotation.eu2ax,
Rotation.eu2ro,
])
def test_Euler_vectorization(self,default,conversion):
2020-04-09 17:50:43 +05:30
eu = np.array([rot.asEulers() for rot in default])
#dev_null = conversion(eu.reshape(eu.shape[0]//2,-1,3))
co = conversion(eu)
for e,c in zip(eu,co):
print(e,c)
assert np.allclose(conversion(e),c)
@pytest.mark.parametrize('conversion',[Rotation.ax2qu,
Rotation.ax2om,
Rotation.ax2ro,
Rotation.ax2ho,
])
def test_axisAngle_vectorization(self,default,conversion):
ax = np.array([rot.asAxisAngle() for rot in default])
dev_null = conversion(ax.reshape(ax.shape[0]//2,-1,4))
co = conversion(ax)
for a,c in zip(ax,co):
2020-04-09 17:50:43 +05:30
print(a,c)
assert np.allclose(conversion(a),c)