self-explanatory names
This commit is contained in:
parent
5ebde607a2
commit
6bedd84759
|
@ -753,7 +753,7 @@ class Geom:
|
||||||
if fill is None: fill = np.nanmax(self.material) + 1
|
if fill is None: fill = np.nanmax(self.material) + 1
|
||||||
dtype = float if np.isnan(fill) or int(fill) != fill or self.material.dtype==np.float else int
|
dtype = float if np.isnan(fill) or int(fill) != fill or self.material.dtype==np.float else int
|
||||||
|
|
||||||
Eulers = R.as_Eulers(degrees=True)
|
Eulers = R.as_Euler_angles(degrees=True)
|
||||||
material_in = self.material.copy()
|
material_in = self.material.copy()
|
||||||
|
|
||||||
# These rotations are always applied in the reference coordinate system, i.e. (z,x,z) not (z,x',z'')
|
# These rotations are always applied in the reference coordinate system, i.e. (z,x,z) not (z,x',z'')
|
||||||
|
|
|
@ -86,8 +86,8 @@ class Orientation(Rotation):
|
||||||
>>> damask.Orientation.from_random(shape=(3,5),lattice='tetragonal').reduced
|
>>> damask.Orientation.from_random(shape=(3,5),lattice='tetragonal').reduced
|
||||||
|
|
||||||
Disorientation between two specific orientations of hexagonal symmetry:
|
Disorientation between two specific orientations of hexagonal symmetry:
|
||||||
>>> a = damask.Orientation.from_Eulers(phi=[123,32,21],degrees=True,lattice='hexagonal')
|
>>> a = damask.Orientation.from_Euler_angles(phi=[123,32,21],degrees=True,lattice='hexagonal')
|
||||||
>>> b = damask.Orientation.from_Eulers(phi=[104,11,87],degrees=True,lattice='hexagonal')
|
>>> b = damask.Orientation.from_Euler_angles(phi=[104,11,87],degrees=True,lattice='hexagonal')
|
||||||
>>> a.disorientation(b)
|
>>> a.disorientation(b)
|
||||||
|
|
||||||
Inverse pole figure color of the e_3 direction for a crystal in "Cube" orientation with cubic symmetry:
|
Inverse pole figure color of the e_3 direction for a crystal in "Cube" orientation with cubic symmetry:
|
||||||
|
@ -95,7 +95,7 @@ class Orientation(Rotation):
|
||||||
>>> o.IPF_color(o.to_SST(np.array([0,0,1])))
|
>>> o.IPF_color(o.to_SST(np.array([0,0,1])))
|
||||||
|
|
||||||
Schmid matrix (in lab frame) of slip systems of a face-centered cubic crystal in "Goss" orientation:
|
Schmid matrix (in lab frame) of slip systems of a face-centered cubic crystal in "Goss" orientation:
|
||||||
>>> damask.Orientation.from_Eulers(phi=[0,45,0],degrees=True,lattice='cF').Schmid('slip')
|
>>> damask.Orientation.from_Euler_angles(phi=[0,45,0],degrees=True,lattice='cF').Schmid('slip')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -291,9 +291,9 @@ class Orientation(Rotation):
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@extended_docstring(Rotation.from_Eulers)
|
@extended_docstring(Rotation.from_Euler_angles)
|
||||||
def from_Eulers(cls,**kwargs):
|
def from_Euler_angles(cls,**kwargs):
|
||||||
return cls(rotation=Rotation.from_Eulers(**kwargs),**kwargs)
|
return cls(rotation=Rotation.from_Euler_angles(**kwargs),**kwargs)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -315,9 +315,9 @@ class Orientation(Rotation):
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@extended_docstring(Rotation.from_Rodrigues)
|
@extended_docstring(Rotation.from_Rodrigues_vector)
|
||||||
def from_Rodrigues(cls,**kwargs):
|
def from_Rodrigues_vector(cls,**kwargs):
|
||||||
return cls(rotation=Rotation.from_Rodrigues(**kwargs),**kwargs)
|
return cls(rotation=Rotation.from_Rodrigues_vector(**kwargs),**kwargs)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -496,7 +496,7 @@ class Orientation(Rotation):
|
||||||
if self.family is None:
|
if self.family is None:
|
||||||
raise ValueError('Missing crystal symmetry')
|
raise ValueError('Missing crystal symmetry')
|
||||||
|
|
||||||
rho_abs = np.abs(self.as_Rodrigues(vector=True))
|
rho_abs = np.abs(self.as_Rodrigues_vector(vector=True))
|
||||||
|
|
||||||
with np.errstate(invalid='ignore'):
|
with np.errstate(invalid='ignore'):
|
||||||
# using '*'/prod for 'and'
|
# using '*'/prod for 'and'
|
||||||
|
@ -539,7 +539,7 @@ class Orientation(Rotation):
|
||||||
if self.family is None:
|
if self.family is None:
|
||||||
raise ValueError('Missing crystal symmetry')
|
raise ValueError('Missing crystal symmetry')
|
||||||
|
|
||||||
rho = self.as_Rodrigues(vector=True)
|
rho = self.as_Rodrigues_vector(vector=True)
|
||||||
|
|
||||||
with np.errstate(invalid='ignore'):
|
with np.errstate(invalid='ignore'):
|
||||||
if self.family == 'cubic':
|
if self.family == 'cubic':
|
||||||
|
|
|
@ -597,19 +597,19 @@ class Result:
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _add_Cauchy(P,F):
|
def _add_stress_Cauchy(P,F):
|
||||||
return {
|
return {
|
||||||
'data': mechanics.Cauchy(P['data'],F['data']),
|
'data': mechanics.stress_Cauchy(P['data'],F['data']),
|
||||||
'label': 'sigma',
|
'label': 'sigma',
|
||||||
'meta': {
|
'meta': {
|
||||||
'Unit': P['meta']['Unit'],
|
'Unit': P['meta']['Unit'],
|
||||||
'Description': "Cauchy stress calculated "
|
'Description': "Cauchy stress calculated "
|
||||||
f"from {P['label']} ({P['meta']['Description']})"
|
f"from {P['label']} ({P['meta']['Description']})"
|
||||||
f" and {F['label']} ({F['meta']['Description']})",
|
f" and {F['label']} ({F['meta']['Description']})",
|
||||||
'Creator': 'add_Cauchy'
|
'Creator': 'add_stress_Cauchy'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def add_Cauchy(self,P='P',F='F'):
|
def add_stress_Cauchy(self,P='P',F='F'):
|
||||||
"""
|
"""
|
||||||
Add Cauchy stress calculated from first Piola-Kirchhoff stress and deformation gradient.
|
Add Cauchy stress calculated from first Piola-Kirchhoff stress and deformation gradient.
|
||||||
|
|
||||||
|
@ -621,7 +621,7 @@ class Result:
|
||||||
Label of the dataset containing the deformation gradient. Defaults to ‘F’.
|
Label of the dataset containing the deformation gradient. Defaults to ‘F’.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._add_generic_pointwise(self._add_Cauchy,{'P':P,'F':F})
|
self._add_generic_pointwise(self._add_stress_Cauchy,{'P':P,'F':F})
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -798,7 +798,7 @@ class Result:
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _add_Mises(T_sym,kind):
|
def _add_equivalent_Mises(T_sym,kind):
|
||||||
k = kind
|
k = kind
|
||||||
if k is None:
|
if k is None:
|
||||||
if T_sym['meta']['Unit'] == '1':
|
if T_sym['meta']['Unit'] == '1':
|
||||||
|
@ -809,7 +809,8 @@ class Result:
|
||||||
raise ValueError('invalid von Mises kind {kind}')
|
raise ValueError('invalid von Mises kind {kind}')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'data': (mechanics.Mises_strain if k=='strain' else mechanics.Mises_stress)(T_sym['data']),
|
'data': (mechanics.equivalent_strain_Mises if k=='strain' else \
|
||||||
|
mechanics.equivalent_stress_Mises)(T_sym['data']),
|
||||||
'label': f"{T_sym['label']}_vM",
|
'label': f"{T_sym['label']}_vM",
|
||||||
'meta': {
|
'meta': {
|
||||||
'Unit': T_sym['meta']['Unit'],
|
'Unit': T_sym['meta']['Unit'],
|
||||||
|
@ -817,7 +818,7 @@ class Result:
|
||||||
'Creator': 'add_Mises'
|
'Creator': 'add_Mises'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def add_Mises(self,T_sym,kind=None):
|
def add_equivalent_Mises(self,T_sym,kind=None):
|
||||||
"""
|
"""
|
||||||
Add the equivalent Mises stress or strain of a symmetric tensor.
|
Add the equivalent Mises stress or strain of a symmetric tensor.
|
||||||
|
|
||||||
|
@ -830,7 +831,7 @@ class Result:
|
||||||
it is selected based on the unit of the dataset ('1' -> strain, 'Pa' -> stress').
|
it is selected based on the unit of the dataset ('1' -> strain, 'Pa' -> stress').
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._add_generic_pointwise(self._add_Mises,{'T_sym':T_sym},{'kind':kind})
|
self._add_generic_pointwise(self._add_equivalent_Mises,{'T_sym':T_sym},{'kind':kind})
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -872,19 +873,19 @@ class Result:
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _add_PK2(P,F):
|
def _add_stress_second_Piola_Kirchhoff(P,F):
|
||||||
return {
|
return {
|
||||||
'data': mechanics.PK2(P['data'],F['data']),
|
'data': mechanics.stress_second_Piola_Kirchhoff(P['data'],F['data']),
|
||||||
'label': 'S',
|
'label': 'S',
|
||||||
'meta': {
|
'meta': {
|
||||||
'Unit': P['meta']['Unit'],
|
'Unit': P['meta']['Unit'],
|
||||||
'Description': "2. Piola-Kirchhoff stress calculated "
|
'Description': "2. Piola-Kirchhoff stress calculated "
|
||||||
f"from {P['label']} ({P['meta']['Description']})"
|
f"from {P['label']} ({P['meta']['Description']})"
|
||||||
f" and {F['label']} ({F['meta']['Description']})",
|
f" and {F['label']} ({F['meta']['Description']})",
|
||||||
'Creator': 'add_PK2'
|
'Creator': 'add_stress_second_Piola_Kirchhoff'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def add_PK2(self,P='P',F='F'):
|
def add_stress_second_Piola_Kirchhoff(self,P='P',F='F'):
|
||||||
"""
|
"""
|
||||||
Add second Piola-Kirchhoff stress calculated from first Piola-Kirchhoff stress and deformation gradient.
|
Add second Piola-Kirchhoff stress calculated from first Piola-Kirchhoff stress and deformation gradient.
|
||||||
|
|
||||||
|
@ -896,7 +897,7 @@ class Result:
|
||||||
Label of deformation gradient dataset. Defaults to ‘F’.
|
Label of deformation gradient dataset. Defaults to ‘F’.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self._add_generic_pointwise(self._add_PK2,{'P':P,'F':F})
|
self._add_generic_pointwise(self._add_stress_second_Piola_Kirchhoff,{'P':P,'F':F})
|
||||||
|
|
||||||
|
|
||||||
# The add_pole functionality needs discussion.
|
# The add_pole functionality needs discussion.
|
||||||
|
@ -1297,3 +1298,6 @@ class Result:
|
||||||
v.add(u,'u')
|
v.add(u,'u')
|
||||||
|
|
||||||
v.save(f'{self.fname.stem}_inc{inc[3:].zfill(N_digits)}')
|
v.save(f'{self.fname.stem}_inc{inc[3:].zfill(N_digits)}')
|
||||||
|
|
||||||
|
|
||||||
|
Result.add_PK2 = Result.add_stress_second_Piola_Kirchhoff
|
||||||
|
|
|
@ -66,12 +66,12 @@ class Rotation:
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""Represent rotation as unit quaternion, rotation matrix, and Bunge-Euler angles."""
|
"""Represent rotation as unit quaternion, rotation matrix, and Bunge-Euler angles."""
|
||||||
return 'Quaternions:\n'+str(self.quaternion) \
|
return 'As quaternions:\n'+str(self.quaternion) \
|
||||||
if self.quaternion.shape != (4,) else \
|
if self.quaternion.shape != (4,) else \
|
||||||
'\n'.join([
|
'\n'.join([
|
||||||
'Quaternion: (real={:.3f}, imag=<{:+.3f}, {:+.3f}, {:+.3f}>)'.format(*(self.quaternion)),
|
'Quaternion: (real={:.3f}, imag=<{:+.3f}, {:+.3f}, {:+.3f}>)'.format(*(self.quaternion)),
|
||||||
'Matrix:\n{}'.format(np.round(self.as_matrix(),8)),
|
'Matrix:\n{}'.format(np.round(self.as_matrix(),8)),
|
||||||
'Bunge Eulers / deg: ({:3.2f}, {:3.2f}, {:3.2f})'.format(*self.as_Eulers(degrees=True)),
|
'Bunge Eulers / deg: ({:3.2f}, {:3.2f}, {:3.2f})'.format(*self.as_Euler_angles(degrees=True)),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
@ -314,7 +314,7 @@ class Rotation:
|
||||||
"""
|
"""
|
||||||
return self.quaternion.copy()
|
return self.quaternion.copy()
|
||||||
|
|
||||||
def as_Eulers(self,
|
def as_Euler_angles(self,
|
||||||
degrees = False):
|
degrees = False):
|
||||||
"""
|
"""
|
||||||
Represent as Bunge-Euler angles.
|
Represent as Bunge-Euler angles.
|
||||||
|
@ -372,7 +372,7 @@ class Rotation:
|
||||||
"""
|
"""
|
||||||
return Rotation._qu2om(self.quaternion)
|
return Rotation._qu2om(self.quaternion)
|
||||||
|
|
||||||
def as_Rodrigues(self,
|
def as_Rodrigues_vector(self,
|
||||||
vector = False):
|
vector = False):
|
||||||
"""
|
"""
|
||||||
Represent as Rodrigues-Frank vector with separated axis and angle argument.
|
Represent as Rodrigues-Frank vector with separated axis and angle argument.
|
||||||
|
@ -462,7 +462,7 @@ class Rotation:
|
||||||
return Rotation(qu)
|
return Rotation(qu)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_Eulers(phi,
|
def from_Euler_angles(phi,
|
||||||
degrees = False,
|
degrees = False,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -606,7 +606,7 @@ class Rotation:
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_Rodrigues(rho,
|
def from_Rodrigues_vector(rho,
|
||||||
normalize = False,
|
normalize = False,
|
||||||
P = -1,
|
P = -1,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
|
@ -784,7 +784,7 @@ class Rotation:
|
||||||
dg = 1.0 if fractions else _dg(Eulers,degrees)
|
dg = 1.0 if fractions else _dg(Eulers,degrees)
|
||||||
dV_V = dg * np.maximum(0.0,weights.squeeze())
|
dV_V = dg * np.maximum(0.0,weights.squeeze())
|
||||||
|
|
||||||
return Rotation.from_Eulers(Eulers[util.hybrid_IA(dV_V,N,seed)],degrees)
|
return Rotation.from_Euler_angles(Eulers[util.hybrid_IA(dV_V,N,seed)],degrees)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -5,7 +5,7 @@ from . import tensor
|
||||||
import numpy as _np
|
import numpy as _np
|
||||||
|
|
||||||
|
|
||||||
def Cauchy_Green_deformation_left(F):
|
def deformation_Cauchy_Green_left(F):
|
||||||
"""
|
"""
|
||||||
Calculate left Cauchy-Green deformation tensor (Finger deformation tensor).
|
Calculate left Cauchy-Green deformation tensor (Finger deformation tensor).
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ def Cauchy_Green_deformation_left(F):
|
||||||
return _np.matmul(F,tensor.transpose(F))
|
return _np.matmul(F,tensor.transpose(F))
|
||||||
|
|
||||||
|
|
||||||
def Cauchy_Green_deformation_right(F):
|
def deformation_Cauchy_Green_right(F):
|
||||||
"""
|
"""
|
||||||
Calculate right Cauchy-Green deformation tensor.
|
Calculate right Cauchy-Green deformation tensor.
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ def Cauchy_Green_deformation_right(F):
|
||||||
return _np.matmul(tensor.transpose(F),F)
|
return _np.matmul(tensor.transpose(F),F)
|
||||||
|
|
||||||
|
|
||||||
def Cauchy(P,F):
|
def stress_Cauchy(P,F):
|
||||||
"""
|
"""
|
||||||
Calculate the Cauchy stress (true stress).
|
Calculate the Cauchy stress (true stress).
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ def maximum_shear(T_sym):
|
||||||
return (w[...,0] - w[...,2])*0.5
|
return (w[...,0] - w[...,2])*0.5
|
||||||
|
|
||||||
|
|
||||||
def Mises_strain(epsilon):
|
def equivalent_strain_Mises(epsilon):
|
||||||
"""
|
"""
|
||||||
Calculate the Mises equivalent of a strain tensor.
|
Calculate the Mises equivalent of a strain tensor.
|
||||||
|
|
||||||
|
@ -116,10 +116,10 @@ def Mises_strain(epsilon):
|
||||||
Von Mises equivalent strain of epsilon.
|
Von Mises equivalent strain of epsilon.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return _Mises(epsilon,2.0/3.0)
|
return _equivalent_Mises(epsilon,2.0/3.0)
|
||||||
|
|
||||||
|
|
||||||
def Mises_stress(sigma):
|
def equivalent_stress_Mises(sigma):
|
||||||
"""
|
"""
|
||||||
Calculate the Mises equivalent of a stress tensor.
|
Calculate the Mises equivalent of a stress tensor.
|
||||||
|
|
||||||
|
@ -134,10 +134,10 @@ def Mises_stress(sigma):
|
||||||
Von Mises equivalent stress of sigma.
|
Von Mises equivalent stress of sigma.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return _Mises(sigma,3.0/2.0)
|
return _equivalent_Mises(sigma,3.0/2.0)
|
||||||
|
|
||||||
|
|
||||||
def PK2(P,F):
|
def stress_second_Piola_Kirchhoff(P,F):
|
||||||
"""
|
"""
|
||||||
Calculate the second Piola-Kirchhoff stress.
|
Calculate the second Piola-Kirchhoff stress.
|
||||||
|
|
||||||
|
@ -226,9 +226,9 @@ def strain(F,t,m):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if t == 'V':
|
if t == 'V':
|
||||||
w,n = _np.linalg.eigh(Cauchy_Green_deformation_left(F))
|
w,n = _np.linalg.eigh(deformation_Cauchy_Green_left(F))
|
||||||
elif t == 'U':
|
elif t == 'U':
|
||||||
w,n = _np.linalg.eigh(Cauchy_Green_deformation_right(F))
|
w,n = _np.linalg.eigh(deformation_Cauchy_Green_right(F))
|
||||||
|
|
||||||
if m > 0.0:
|
if m > 0.0:
|
||||||
eps = 1.0/(2.0*abs(m)) * (+ _np.einsum('...j,...kj,...lj',w**m,n,n) - _np.eye(3))
|
eps = 1.0/(2.0*abs(m)) * (+ _np.einsum('...j,...kj,...lj',w**m,n,n) - _np.eye(3))
|
||||||
|
@ -304,7 +304,7 @@ def _polar_decomposition(T,requested):
|
||||||
return tuple(output)
|
return tuple(output)
|
||||||
|
|
||||||
|
|
||||||
def _Mises(T_sym,s):
|
def _equivalent_Mises(T_sym,s):
|
||||||
"""
|
"""
|
||||||
Base equation for Mises equivalent of a stress or strain tensor.
|
Base equation for Mises equivalent of a stress or strain tensor.
|
||||||
|
|
||||||
|
|
|
@ -223,7 +223,7 @@ class TestGeom:
|
||||||
@pytest.mark.parametrize('Eulers',[[32.0,68.0,21.0],
|
@pytest.mark.parametrize('Eulers',[[32.0,68.0,21.0],
|
||||||
[0.0,32.0,240.0]])
|
[0.0,32.0,240.0]])
|
||||||
def test_rotate(self,default,update,reference_dir,Eulers):
|
def test_rotate(self,default,update,reference_dir,Eulers):
|
||||||
modified = default.rotate(Rotation.from_Eulers(Eulers,degrees=True))
|
modified = default.rotate(Rotation.from_Euler_angles(Eulers,degrees=True))
|
||||||
tag = f'Eulers_{util.srepr(Eulers,"-")}'
|
tag = f'Eulers_{util.srepr(Eulers,"-")}'
|
||||||
reference = reference_dir/f'rotate_{tag}.vtr'
|
reference = reference_dir/f'rotate_{tag}.vtr'
|
||||||
if update: modified.save(reference)
|
if update: modified.save(reference)
|
||||||
|
|
|
@ -16,7 +16,7 @@ def reference_dir(reference_dir_base):
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def set_of_rodrigues(set_of_quaternions):
|
def set_of_rodrigues(set_of_quaternions):
|
||||||
return Rotation(set_of_quaternions).as_Rodrigues()[:200]
|
return Rotation(set_of_quaternions).as_Rodrigues_vector()[:200]
|
||||||
|
|
||||||
|
|
||||||
class TestOrientation:
|
class TestOrientation:
|
||||||
|
@ -90,8 +90,8 @@ class TestOrientation:
|
||||||
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]),lattice='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_Eulers(self):
|
def test_from_Euler_angles(self):
|
||||||
assert np.all(Orientation.from_Eulers(phi=np.zeros(3),lattice='triclinic').as_matrix()
|
assert np.all(Orientation.from_Euler_angles(phi=np.zeros(3),lattice='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_axis_angle(self):
|
def test_from_axis_angle(self):
|
||||||
|
@ -106,8 +106,8 @@ class TestOrientation:
|
||||||
assert np.all(Orientation.from_matrix(R=np.eye(3),lattice='triclinic').as_matrix()
|
assert np.all(Orientation.from_matrix(R=np.eye(3),lattice='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_Rodrigues(self):
|
def test_from_Rodrigues_vector(self):
|
||||||
assert np.all(Orientation.from_Rodrigues(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]),lattice='triclinic').as_matrix()
|
||||||
== np.eye(3))
|
== np.eye(3))
|
||||||
|
|
||||||
def test_from_homochoric(self):
|
def test_from_homochoric(self):
|
||||||
|
@ -208,7 +208,7 @@ class TestOrientation:
|
||||||
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
||||||
def test_disorientation360(self,lattice):
|
def test_disorientation360(self,lattice):
|
||||||
o_1 = Orientation(Rotation(),lattice)
|
o_1 = Orientation(Rotation(),lattice)
|
||||||
o_2 = Orientation.from_Eulers(lattice=lattice,phi=[360,0,0],degrees=True)
|
o_2 = Orientation.from_Euler_angles(lattice=lattice,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',Orientation.crystal_families)
|
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
||||||
|
@ -275,16 +275,16 @@ class TestOrientation:
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
||||||
def test_in_FZ_vectorization(self,set_of_rodrigues,lattice):
|
def test_in_FZ_vectorization(self,set_of_rodrigues,lattice):
|
||||||
result = Orientation.from_Rodrigues(rho=set_of_rodrigues.reshape((50,4,-1)),lattice=lattice).in_FZ.reshape(-1)
|
result = Orientation.from_Rodrigues_vector(rho=set_of_rodrigues.reshape((50,4,-1)),lattice=lattice).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(rho=rho,lattice=lattice).in_FZ
|
assert r == Orientation.from_Rodrigues_vector(rho=rho,lattice=lattice).in_FZ
|
||||||
|
|
||||||
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
||||||
def test_in_disorientation_FZ_vectorization(self,set_of_rodrigues,lattice):
|
def test_in_disorientation_FZ_vectorization(self,set_of_rodrigues,lattice):
|
||||||
result = Orientation.from_Rodrigues(rho=set_of_rodrigues.reshape((50,4,-1)),
|
result = Orientation.from_Rodrigues_vector(rho=set_of_rodrigues.reshape((50,4,-1)),
|
||||||
lattice=lattice).in_disorientation_FZ.reshape(-1)
|
lattice=lattice).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(rho=rho,lattice=lattice).in_disorientation_FZ
|
assert r == Orientation.from_Rodrigues_vector(rho=rho,lattice=lattice).in_disorientation_FZ
|
||||||
|
|
||||||
@pytest.mark.parametrize('proper',[True,False])
|
@pytest.mark.parametrize('proper',[True,False])
|
||||||
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
@pytest.mark.parametrize('lattice',Orientation.crystal_families)
|
||||||
|
@ -417,7 +417,7 @@ class TestOrientation:
|
||||||
def test_relationship_reference(self,update,reference_dir,model,lattice):
|
def test_relationship_reference(self,update,reference_dir,model,lattice):
|
||||||
reference = reference_dir/f'{lattice}_{model}.txt'
|
reference = reference_dir/f'{lattice}_{model}.txt'
|
||||||
o = Orientation(lattice=lattice)
|
o = Orientation(lattice=lattice)
|
||||||
eu = o.related(model).as_Eulers(degrees=True)
|
eu = o.related(model).as_Euler_angles(degrees=True)
|
||||||
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(eu,{'Eulers':(3,)})\
|
Table(eu,{'Eulers':(3,)})\
|
||||||
|
|
|
@ -121,13 +121,13 @@ class TestResult:
|
||||||
in_file = default.read_dataset(loc['x'],0)
|
in_file = default.read_dataset(loc['x'],0)
|
||||||
assert np.allclose(in_memory,in_file)
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
def test_add_Cauchy(self,default):
|
def test_add_stress_Cauchy(self,default):
|
||||||
default.add_Cauchy('P','F')
|
default.add_stress_Cauchy('P','F')
|
||||||
loc = {'F': default.get_dataset_location('F'),
|
loc = {'F': default.get_dataset_location('F'),
|
||||||
'P': default.get_dataset_location('P'),
|
'P': default.get_dataset_location('P'),
|
||||||
'sigma':default.get_dataset_location('sigma')}
|
'sigma':default.get_dataset_location('sigma')}
|
||||||
in_memory = mechanics.Cauchy(default.read_dataset(loc['P'],0),
|
in_memory = mechanics.stress_Cauchy(default.read_dataset(loc['P'],0),
|
||||||
default.read_dataset(loc['F'],0))
|
default.read_dataset(loc['F'],0))
|
||||||
in_file = default.read_dataset(loc['sigma'],0)
|
in_file = default.read_dataset(loc['sigma'],0)
|
||||||
assert np.allclose(in_memory,in_file)
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ class TestResult:
|
||||||
|
|
||||||
@pytest.mark.parametrize('eigenvalue,function',[('max',np.amax),('min',np.amin)])
|
@pytest.mark.parametrize('eigenvalue,function',[('max',np.amax),('min',np.amin)])
|
||||||
def test_add_eigenvalue(self,default,eigenvalue,function):
|
def test_add_eigenvalue(self,default,eigenvalue,function):
|
||||||
default.add_Cauchy('P','F')
|
default.add_stress_Cauchy('P','F')
|
||||||
default.add_eigenvalue('sigma',eigenvalue)
|
default.add_eigenvalue('sigma',eigenvalue)
|
||||||
loc = {'sigma' :default.get_dataset_location('sigma'),
|
loc = {'sigma' :default.get_dataset_location('sigma'),
|
||||||
'lambda':default.get_dataset_location(f'lambda_{eigenvalue}(sigma)')}
|
'lambda':default.get_dataset_location(f'lambda_{eigenvalue}(sigma)')}
|
||||||
|
@ -159,7 +159,7 @@ class TestResult:
|
||||||
|
|
||||||
@pytest.mark.parametrize('eigenvalue,idx',[('max',2),('mid',1),('min',0)])
|
@pytest.mark.parametrize('eigenvalue,idx',[('max',2),('mid',1),('min',0)])
|
||||||
def test_add_eigenvector(self,default,eigenvalue,idx):
|
def test_add_eigenvector(self,default,eigenvalue,idx):
|
||||||
default.add_Cauchy('P','F')
|
default.add_stress_Cauchy('P','F')
|
||||||
default.add_eigenvector('sigma',eigenvalue)
|
default.add_eigenvector('sigma',eigenvalue)
|
||||||
loc = {'sigma' :default.get_dataset_location('sigma'),
|
loc = {'sigma' :default.get_dataset_location('sigma'),
|
||||||
'v(sigma)':default.get_dataset_location(f'v_{eigenvalue}(sigma)')}
|
'v(sigma)':default.get_dataset_location(f'v_{eigenvalue}(sigma)')}
|
||||||
|
@ -183,7 +183,7 @@ class TestResult:
|
||||||
assert np.allclose(in_memory,in_file)
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
def test_add_maximum_shear(self,default):
|
def test_add_maximum_shear(self,default):
|
||||||
default.add_Cauchy('P','F')
|
default.add_stress_Cauchy('P','F')
|
||||||
default.add_maximum_shear('sigma')
|
default.add_maximum_shear('sigma')
|
||||||
loc = {'sigma' :default.get_dataset_location('sigma'),
|
loc = {'sigma' :default.get_dataset_location('sigma'),
|
||||||
'max_shear(sigma)':default.get_dataset_location('max_shear(sigma)')}
|
'max_shear(sigma)':default.get_dataset_location('max_shear(sigma)')}
|
||||||
|
@ -196,34 +196,34 @@ class TestResult:
|
||||||
m = np.random.random()*2.0 - 1.0
|
m = np.random.random()*2.0 - 1.0
|
||||||
default.add_strain('F',t,m)
|
default.add_strain('F',t,m)
|
||||||
label = f'epsilon_{t}^{m}(F)'
|
label = f'epsilon_{t}^{m}(F)'
|
||||||
default.add_Mises(label)
|
default.add_equivalent_Mises(label)
|
||||||
loc = {label :default.get_dataset_location(label),
|
loc = {label :default.get_dataset_location(label),
|
||||||
label+'_vM':default.get_dataset_location(label+'_vM')}
|
label+'_vM':default.get_dataset_location(label+'_vM')}
|
||||||
in_memory = mechanics.Mises_strain(default.read_dataset(loc[label],0)).reshape(-1,1)
|
in_memory = mechanics.equivalent_strain_Mises(default.read_dataset(loc[label],0)).reshape(-1,1)
|
||||||
in_file = default.read_dataset(loc[label+'_vM'],0)
|
in_file = default.read_dataset(loc[label+'_vM'],0)
|
||||||
assert np.allclose(in_memory,in_file)
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
def test_add_Mises_stress(self,default):
|
def test_add_Mises_stress(self,default):
|
||||||
default.add_Cauchy('P','F')
|
default.add_stress_Cauchy('P','F')
|
||||||
default.add_Mises('sigma')
|
default.add_equivalent_Mises('sigma')
|
||||||
loc = {'sigma' :default.get_dataset_location('sigma'),
|
loc = {'sigma' :default.get_dataset_location('sigma'),
|
||||||
'sigma_vM':default.get_dataset_location('sigma_vM')}
|
'sigma_vM':default.get_dataset_location('sigma_vM')}
|
||||||
in_memory = mechanics.Mises_stress(default.read_dataset(loc['sigma'],0)).reshape(-1,1)
|
in_memory = mechanics.equivalent_stress_Mises(default.read_dataset(loc['sigma'],0)).reshape(-1,1)
|
||||||
in_file = default.read_dataset(loc['sigma_vM'],0)
|
in_file = default.read_dataset(loc['sigma_vM'],0)
|
||||||
assert np.allclose(in_memory,in_file)
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
def test_add_Mises_invalid(self,default):
|
def test_add_Mises_invalid(self,default):
|
||||||
default.add_Cauchy('P','F')
|
default.add_stress_Cauchy('P','F')
|
||||||
default.add_calculation('sigma_y','#sigma#',unit='y')
|
default.add_calculation('sigma_y','#sigma#',unit='y')
|
||||||
default.add_Mises('sigma_y')
|
default.add_equivalent_Mises('sigma_y')
|
||||||
assert default.get_dataset_location('sigma_y_vM') == []
|
assert default.get_dataset_location('sigma_y_vM') == []
|
||||||
|
|
||||||
def test_add_Mises_stress_strain(self,default):
|
def test_add_Mises_stress_strain(self,default):
|
||||||
default.add_Cauchy('P','F')
|
default.add_stress_Cauchy('P','F')
|
||||||
default.add_calculation('sigma_y','#sigma#',unit='y')
|
default.add_calculation('sigma_y','#sigma#',unit='y')
|
||||||
default.add_calculation('sigma_x','#sigma#',unit='x')
|
default.add_calculation('sigma_x','#sigma#',unit='x')
|
||||||
default.add_Mises('sigma_y',kind='strain')
|
default.add_equivalent_Mises('sigma_y',kind='strain')
|
||||||
default.add_Mises('sigma_x',kind='stress')
|
default.add_equivalent_Mises('sigma_x',kind='stress')
|
||||||
loc = {'y' :default.get_dataset_location('sigma_y_vM'),
|
loc = {'y' :default.get_dataset_location('sigma_y_vM'),
|
||||||
'x' :default.get_dataset_location('sigma_x_vM')}
|
'x' :default.get_dataset_location('sigma_x_vM')}
|
||||||
assert not np.allclose(default.read_dataset(loc['y'],0),default.read_dataset(loc['x'],0))
|
assert not np.allclose(default.read_dataset(loc['y'],0),default.read_dataset(loc['x'],0))
|
||||||
|
@ -236,13 +236,13 @@ class TestResult:
|
||||||
in_file = default.read_dataset(loc['|F|_1'],0)
|
in_file = default.read_dataset(loc['|F|_1'],0)
|
||||||
assert np.allclose(in_memory,in_file)
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
def test_add_PK2(self,default):
|
def test_add_stress_second_Piola_Kirchhoff(self,default):
|
||||||
default.add_PK2('P','F')
|
default.add_stress_second_Piola_Kirchhoff('P','F')
|
||||||
loc = {'F':default.get_dataset_location('F'),
|
loc = {'F':default.get_dataset_location('F'),
|
||||||
'P':default.get_dataset_location('P'),
|
'P':default.get_dataset_location('P'),
|
||||||
'S':default.get_dataset_location('S')}
|
'S':default.get_dataset_location('S')}
|
||||||
in_memory = mechanics.PK2(default.read_dataset(loc['P'],0),
|
in_memory = mechanics.stress_second_Piola_Kirchhoff(default.read_dataset(loc['P'],0),
|
||||||
default.read_dataset(loc['F'],0))
|
default.read_dataset(loc['F'],0))
|
||||||
in_file = default.read_dataset(loc['S'],0)
|
in_file = default.read_dataset(loc['S'],0)
|
||||||
assert np.allclose(in_memory,in_file)
|
assert np.allclose(in_memory,in_file)
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ class TestResult:
|
||||||
def test_add_overwrite(self,default,overwrite):
|
def test_add_overwrite(self,default,overwrite):
|
||||||
default.pick('times',default.times_in_range(0,np.inf)[-1])
|
default.pick('times',default.times_in_range(0,np.inf)[-1])
|
||||||
|
|
||||||
default.add_Cauchy()
|
default.add_stress_Cauchy()
|
||||||
loc = default.get_dataset_location('sigma')
|
loc = default.get_dataset_location('sigma')
|
||||||
with h5py.File(default.fname,'r') as f:
|
with h5py.File(default.fname,'r') as f:
|
||||||
# h5py3 compatibility
|
# h5py3 compatibility
|
||||||
|
|
|
@ -522,7 +522,7 @@ class TestRotation:
|
||||||
def test_Eulers_internal(self,set_of_rotations,forward,backward):
|
def test_Eulers_internal(self,set_of_rotations,forward,backward):
|
||||||
"""Ensure invariance of conversion from Euler angles and back."""
|
"""Ensure invariance of conversion from Euler angles and back."""
|
||||||
for rot in set_of_rotations:
|
for rot in set_of_rotations:
|
||||||
m = rot.as_Eulers()
|
m = rot.as_Euler_angles()
|
||||||
o = backward(forward(m))
|
o = backward(forward(m))
|
||||||
u = np.array([np.pi*2,np.pi,np.pi*2])
|
u = np.array([np.pi*2,np.pi,np.pi*2])
|
||||||
ok = np.allclose(m,o,atol=atol)
|
ok = np.allclose(m,o,atol=atol)
|
||||||
|
@ -559,7 +559,7 @@ class TestRotation:
|
||||||
"""Ensure invariance of conversion from Rodrigues-Frank vector and back."""
|
"""Ensure invariance of conversion from Rodrigues-Frank vector and back."""
|
||||||
cutoff = np.tan(np.pi*.5*(1.-1e-4))
|
cutoff = np.tan(np.pi*.5*(1.-1e-4))
|
||||||
for rot in set_of_rotations:
|
for rot in set_of_rotations:
|
||||||
m = rot.as_Rodrigues()
|
m = rot.as_Rodrigues_vector()
|
||||||
o = backward(forward(m))
|
o = backward(forward(m))
|
||||||
ok = np.allclose(np.clip(m,None,cutoff),np.clip(o,None,cutoff),atol=atol)
|
ok = np.allclose(np.clip(m,None,cutoff),np.clip(o,None,cutoff),atol=atol)
|
||||||
ok = ok or np.isclose(m[3],0.0,atol=atol)
|
ok = ok or np.isclose(m[3],0.0,atol=atol)
|
||||||
|
@ -626,7 +626,7 @@ class TestRotation:
|
||||||
(Rotation._eu2ro,eu2ro)])
|
(Rotation._eu2ro,eu2ro)])
|
||||||
def test_Eulers_vectorization(self,set_of_rotations,vectorized,single):
|
def test_Eulers_vectorization(self,set_of_rotations,vectorized,single):
|
||||||
"""Check vectorized implementation for Euler angles against single point calculation."""
|
"""Check vectorized implementation for Euler angles against single point calculation."""
|
||||||
eu = np.array([rot.as_Eulers() for rot in set_of_rotations])
|
eu = np.array([rot.as_Euler_angles() for rot in set_of_rotations])
|
||||||
vectorized(eu.reshape(eu.shape[0]//2,-1,3))
|
vectorized(eu.reshape(eu.shape[0]//2,-1,3))
|
||||||
co = vectorized(eu)
|
co = vectorized(eu)
|
||||||
for e,c in zip(eu,co):
|
for e,c in zip(eu,co):
|
||||||
|
@ -649,7 +649,7 @@ class TestRotation:
|
||||||
(Rotation._ro2ho,ro2ho)])
|
(Rotation._ro2ho,ro2ho)])
|
||||||
def test_Rodrigues_vectorization(self,set_of_rotations,vectorized,single):
|
def test_Rodrigues_vectorization(self,set_of_rotations,vectorized,single):
|
||||||
"""Check vectorized implementation for Rodrigues-Frank vector against single point calculation."""
|
"""Check vectorized implementation for Rodrigues-Frank vector against single point calculation."""
|
||||||
ro = np.array([rot.as_Rodrigues() for rot in set_of_rotations])
|
ro = np.array([rot.as_Rodrigues_vector() for rot in set_of_rotations])
|
||||||
vectorized(ro.reshape(ro.shape[0]//2,-1,4))
|
vectorized(ro.reshape(ro.shape[0]//2,-1,4))
|
||||||
co = vectorized(ro)
|
co = vectorized(ro)
|
||||||
for r,c in zip(ro,co):
|
for r,c in zip(ro,co):
|
||||||
|
@ -687,7 +687,7 @@ class TestRotation:
|
||||||
def test_Eulers(self,set_of_rotations,degrees):
|
def test_Eulers(self,set_of_rotations,degrees):
|
||||||
for rot in set_of_rotations:
|
for rot in set_of_rotations:
|
||||||
m = rot.as_quaternion()
|
m = rot.as_quaternion()
|
||||||
o = Rotation.from_Eulers(rot.as_Eulers(degrees),degrees).as_quaternion()
|
o = Rotation.from_Euler_angles(rot.as_Euler_angles(degrees),degrees).as_quaternion()
|
||||||
ok = np.allclose(m,o,atol=atol)
|
ok = np.allclose(m,o,atol=atol)
|
||||||
if np.isclose(rot.as_quaternion()[0],0.0,atol=atol):
|
if np.isclose(rot.as_quaternion()[0],0.0,atol=atol):
|
||||||
ok |= np.allclose(m*-1.,o,atol=atol)
|
ok |= np.allclose(m*-1.,o,atol=atol)
|
||||||
|
@ -699,8 +699,8 @@ class TestRotation:
|
||||||
def test_axis_angle(self,set_of_rotations,degrees,normalize,P):
|
def test_axis_angle(self,set_of_rotations,degrees,normalize,P):
|
||||||
c = np.array([P*-1,P*-1,P*-1,1.])
|
c = np.array([P*-1,P*-1,P*-1,1.])
|
||||||
for rot in set_of_rotations:
|
for rot in set_of_rotations:
|
||||||
m = rot.as_Eulers()
|
m = rot.as_Euler_angles()
|
||||||
o = Rotation.from_axis_angle(rot.as_axis_angle(degrees)*c,degrees,normalize,P).as_Eulers()
|
o = Rotation.from_axis_angle(rot.as_axis_angle(degrees)*c,degrees,normalize,P).as_Euler_angles()
|
||||||
u = np.array([np.pi*2,np.pi,np.pi*2])
|
u = np.array([np.pi*2,np.pi,np.pi*2])
|
||||||
ok = np.allclose(m,o,atol=atol)
|
ok = np.allclose(m,o,atol=atol)
|
||||||
ok |= np.allclose(np.where(np.isclose(m,u),m-u,m),np.where(np.isclose(o,u),o-u,o),atol=atol)
|
ok |= np.allclose(np.where(np.isclose(m,u),m-u,m),np.where(np.isclose(o,u),o-u,o),atol=atol)
|
||||||
|
@ -726,7 +726,7 @@ class TestRotation:
|
||||||
c = np.array([P*-1,P*-1,P*-1,1.])
|
c = np.array([P*-1,P*-1,P*-1,1.])
|
||||||
for rot in set_of_rotations:
|
for rot in set_of_rotations:
|
||||||
m = rot.as_matrix()
|
m = rot.as_matrix()
|
||||||
o = Rotation.from_Rodrigues(rot.as_Rodrigues()*c,normalize,P).as_matrix()
|
o = Rotation.from_Rodrigues_vector(rot.as_Rodrigues_vector()*c,normalize,P).as_matrix()
|
||||||
ok = np.allclose(m,o,atol=atol)
|
ok = np.allclose(m,o,atol=atol)
|
||||||
assert ok and np.isclose(np.linalg.det(o),1.0), f'{m},{o}'
|
assert ok and np.isclose(np.linalg.det(o),1.0), f'{m},{o}'
|
||||||
|
|
||||||
|
@ -734,8 +734,8 @@ class TestRotation:
|
||||||
def test_homochoric(self,set_of_rotations,P):
|
def test_homochoric(self,set_of_rotations,P):
|
||||||
cutoff = np.tan(np.pi*.5*(1.-1e-4))
|
cutoff = np.tan(np.pi*.5*(1.-1e-4))
|
||||||
for rot in set_of_rotations:
|
for rot in set_of_rotations:
|
||||||
m = rot.as_Rodrigues()
|
m = rot.as_Rodrigues_vector()
|
||||||
o = Rotation.from_homochoric(rot.as_homochoric()*P*-1,P).as_Rodrigues()
|
o = Rotation.from_homochoric(rot.as_homochoric()*P*-1,P).as_Rodrigues_vector()
|
||||||
ok = np.allclose(np.clip(m,None,cutoff),np.clip(o,None,cutoff),atol=atol)
|
ok = np.allclose(np.clip(m,None,cutoff),np.clip(o,None,cutoff),atol=atol)
|
||||||
ok = ok or np.isclose(m[3],0.0,atol=atol)
|
ok = ok or np.isclose(m[3],0.0,atol=atol)
|
||||||
assert ok and np.isclose(np.linalg.norm(o[:3]),1.0), f'{m},{o},{rot.as_quaternion()}'
|
assert ok and np.isclose(np.linalg.norm(o[:3]),1.0), f'{m},{o},{rot.as_quaternion()}'
|
||||||
|
@ -819,10 +819,10 @@ class TestRotation:
|
||||||
assert r == r.flatten(order).reshape(shape,order)
|
assert r == r.flatten(order).reshape(shape,order)
|
||||||
|
|
||||||
@pytest.mark.parametrize('function',[Rotation.from_quaternion,
|
@pytest.mark.parametrize('function',[Rotation.from_quaternion,
|
||||||
Rotation.from_Eulers,
|
Rotation.from_Euler_angles,
|
||||||
Rotation.from_axis_angle,
|
Rotation.from_axis_angle,
|
||||||
Rotation.from_matrix,
|
Rotation.from_matrix,
|
||||||
Rotation.from_Rodrigues,
|
Rotation.from_Rodrigues_vector,
|
||||||
Rotation.from_homochoric,
|
Rotation.from_homochoric,
|
||||||
Rotation.from_cubochoric])
|
Rotation.from_cubochoric])
|
||||||
def test_invalid_shape(self,function):
|
def test_invalid_shape(self,function):
|
||||||
|
@ -832,7 +832,7 @@ class TestRotation:
|
||||||
|
|
||||||
@pytest.mark.parametrize('fr,to',[(Rotation.from_quaternion,'as_quaternion'),
|
@pytest.mark.parametrize('fr,to',[(Rotation.from_quaternion,'as_quaternion'),
|
||||||
(Rotation.from_axis_angle,'as_axis_angle'),
|
(Rotation.from_axis_angle,'as_axis_angle'),
|
||||||
(Rotation.from_Rodrigues, 'as_Rodrigues'),
|
(Rotation.from_Rodrigues_vector, 'as_Rodrigues_vector'),
|
||||||
(Rotation.from_homochoric,'as_homochoric'),
|
(Rotation.from_homochoric,'as_homochoric'),
|
||||||
(Rotation.from_cubochoric,'as_cubochoric')])
|
(Rotation.from_cubochoric,'as_cubochoric')])
|
||||||
def test_invalid_P(self,fr,to):
|
def test_invalid_P(self,fr,to):
|
||||||
|
@ -852,13 +852,13 @@ class TestRotation:
|
||||||
|
|
||||||
@pytest.mark.parametrize('function,invalid',[(Rotation.from_quaternion, np.array([-1,0,0,0])),
|
@pytest.mark.parametrize('function,invalid',[(Rotation.from_quaternion, np.array([-1,0,0,0])),
|
||||||
(Rotation.from_quaternion, np.array([1,1,1,0])),
|
(Rotation.from_quaternion, np.array([1,1,1,0])),
|
||||||
(Rotation.from_Eulers, np.array([1,4,0])),
|
(Rotation.from_Euler_angles, np.array([1,4,0])),
|
||||||
(Rotation.from_axis_angle, np.array([1,0,0,4])),
|
(Rotation.from_axis_angle, np.array([1,0,0,4])),
|
||||||
(Rotation.from_axis_angle, np.array([1,1,0,1])),
|
(Rotation.from_axis_angle, np.array([1,1,0,1])),
|
||||||
(Rotation.from_matrix, np.random.rand(3,3)),
|
(Rotation.from_matrix, np.random.rand(3,3)),
|
||||||
(Rotation.from_matrix, np.array([[1,1,0],[1,2,0],[0,0,1]])),
|
(Rotation.from_matrix, np.array([[1,1,0],[1,2,0],[0,0,1]])),
|
||||||
(Rotation.from_Rodrigues, np.array([1,0,0,-1])),
|
(Rotation.from_Rodrigues_vector, np.array([1,0,0,-1])),
|
||||||
(Rotation.from_Rodrigues, np.array([1,1,0,1])),
|
(Rotation.from_Rodrigues_vector, np.array([1,1,0,1])),
|
||||||
(Rotation.from_homochoric, np.array([2,2,2])),
|
(Rotation.from_homochoric, np.array([2,2,2])),
|
||||||
(Rotation.from_cubochoric, np.array([1.1,0,0])) ])
|
(Rotation.from_cubochoric, np.array([1.1,0,0])) ])
|
||||||
def test_invalid_value(self,function,invalid):
|
def test_invalid_value(self,function,invalid):
|
||||||
|
@ -904,8 +904,8 @@ class TestRotation:
|
||||||
def test_rotate_360deg(self,data):
|
def test_rotate_360deg(self,data):
|
||||||
phi_1 = np.random.random() * np.pi
|
phi_1 = np.random.random() * np.pi
|
||||||
phi_2 = 2*np.pi - phi_1
|
phi_2 = 2*np.pi - phi_1
|
||||||
R_1 = Rotation.from_Eulers(np.array([phi_1,0.,0.]))
|
R_1 = Rotation.from_Euler_angles(np.array([phi_1,0.,0.]))
|
||||||
R_2 = Rotation.from_Eulers(np.array([0.,0.,phi_2]))
|
R_2 = Rotation.from_Euler_angles(np.array([0.,0.,phi_2]))
|
||||||
assert np.allclose(data,R_2@(R_1@data))
|
assert np.allclose(data,R_2@(R_1@data))
|
||||||
|
|
||||||
@pytest.mark.parametrize('pwr',[-10,0,1,2.5,np.pi,np.random.random()])
|
@pytest.mark.parametrize('pwr',[-10,0,1,2.5,np.pi,np.random.random()])
|
||||||
|
@ -951,7 +951,7 @@ class TestRotation:
|
||||||
|
|
||||||
def test_misorientation360(self):
|
def test_misorientation360(self):
|
||||||
R_1 = Rotation()
|
R_1 = Rotation()
|
||||||
R_2 = Rotation.from_Eulers([360,0,0],degrees=True)
|
R_2 = Rotation.from_Euler_angles([360,0,0],degrees=True)
|
||||||
assert np.allclose(R_1.misorientation(R_2).as_matrix(),np.eye(3))
|
assert np.allclose(R_1.misorientation(R_2).as_matrix(),np.eye(3))
|
||||||
|
|
||||||
@pytest.mark.parametrize('angle',[10,20,30,40,50,60,70,80,90,100,120])
|
@pytest.mark.parametrize('angle',[10,20,30,40,50,60,70,80,90,100,120])
|
||||||
|
@ -1014,7 +1014,7 @@ class TestRotation:
|
||||||
Eulers = grid_filters.cell_coord0(steps,limits)
|
Eulers = grid_filters.cell_coord0(steps,limits)
|
||||||
Eulers = np.radians(Eulers) if not degrees else Eulers
|
Eulers = np.radians(Eulers) if not degrees else Eulers
|
||||||
|
|
||||||
Eulers_r = Rotation.from_ODF(weights,Eulers.reshape(-1,3,order='F'),N,degrees,fractions).as_Eulers(True)
|
Eulers_r = Rotation.from_ODF(weights,Eulers.reshape(-1,3,order='F'),N,degrees,fractions).as_Euler_angles(True)
|
||||||
weights_r = np.histogramdd(Eulers_r,steps,rng)[0].flatten(order='F')/N * np.sum(weights)
|
weights_r = np.histogramdd(Eulers_r,steps,rng)[0].flatten(order='F')/N * np.sum(weights)
|
||||||
|
|
||||||
if fractions: assert np.sqrt(((weights_r - weights) ** 2).mean()) < 4
|
if fractions: assert np.sqrt(((weights_r - weights) ** 2).mean()) < 4
|
||||||
|
@ -1032,7 +1032,7 @@ class TestRotation:
|
||||||
Eulers = grid_filters.node_coord0(steps,limits)[:-1,:-1,:-1]
|
Eulers = grid_filters.node_coord0(steps,limits)[:-1,:-1,:-1]
|
||||||
Eulers = np.radians(Eulers) if not degrees else Eulers
|
Eulers = np.radians(Eulers) if not degrees else Eulers
|
||||||
|
|
||||||
Eulers_r = Rotation.from_ODF(weights,Eulers.reshape(-1,3,order='F'),N,degrees).as_Eulers(True)
|
Eulers_r = Rotation.from_ODF(weights,Eulers.reshape(-1,3,order='F'),N,degrees).as_Euler_angles(True)
|
||||||
weights_r = np.histogramdd(Eulers_r,steps,rng)[0].flatten(order='F')/N * np.sum(weights)
|
weights_r = np.histogramdd(Eulers_r,steps,rng)[0].flatten(order='F')/N * np.sum(weights)
|
||||||
|
|
||||||
assert np.sqrt(((weights_r - weights) ** 2).mean()) < 5
|
assert np.sqrt(((weights_r - weights) ** 2).mean()) < 5
|
||||||
|
|
|
@ -4,7 +4,7 @@ import numpy as np
|
||||||
from damask import tensor
|
from damask import tensor
|
||||||
from damask import mechanics
|
from damask import mechanics
|
||||||
|
|
||||||
def Cauchy(P,F):
|
def stress_Cauchy(P,F):
|
||||||
sigma = 1.0/np.linalg.det(F) * np.dot(P,F.T)
|
sigma = 1.0/np.linalg.det(F) * np.dot(P,F.T)
|
||||||
return symmetric(sigma)
|
return symmetric(sigma)
|
||||||
|
|
||||||
|
@ -22,15 +22,15 @@ def maximum_shear(T_sym):
|
||||||
return (w[0] - w[2])*0.5
|
return (w[0] - w[2])*0.5
|
||||||
|
|
||||||
|
|
||||||
def Mises_strain(epsilon):
|
def equivalent_strain_Mises(epsilon):
|
||||||
return Mises(epsilon,2.0/3.0)
|
return equivalent_Mises(epsilon,2.0/3.0)
|
||||||
|
|
||||||
|
|
||||||
def Mises_stress(sigma):
|
def equivalent_stress_Mises(sigma):
|
||||||
return Mises(sigma,3.0/2.0)
|
return equivalent_Mises(sigma,3.0/2.0)
|
||||||
|
|
||||||
|
|
||||||
def PK2(P,F):
|
def stress_second_Piola_Kirchhoff(P,F):
|
||||||
S = np.dot(np.linalg.inv(F),P)
|
S = np.dot(np.linalg.inv(F),P)
|
||||||
return symmetric(S)
|
return symmetric(S)
|
||||||
|
|
||||||
|
@ -91,9 +91,8 @@ def polar_decomposition(T,requested):
|
||||||
|
|
||||||
return tuple(output)
|
return tuple(output)
|
||||||
|
|
||||||
def Mises(T_sym,s):
|
def equivalent_Mises(T_sym,s):
|
||||||
d = deviatoric_part(T_sym)
|
return np.sqrt(s*(np.sum(deviatoric_part(T_sym)**2.0)))
|
||||||
return np.sqrt(s*(np.sum(d**2.0)))
|
|
||||||
|
|
||||||
|
|
||||||
class TestMechanics:
|
class TestMechanics:
|
||||||
|
@ -112,14 +111,14 @@ class TestMechanics:
|
||||||
for i,v in enumerate(np.reshape(vectorized(test_data),vectorized(test_data_flat).shape)):
|
for i,v in enumerate(np.reshape(vectorized(test_data),vectorized(test_data_flat).shape)):
|
||||||
assert np.allclose(single(test_data_flat[i]),v)
|
assert np.allclose(single(test_data_flat[i]),v)
|
||||||
|
|
||||||
@pytest.mark.parametrize('vectorized,single',[(mechanics.deviatoric_part, deviatoric_part),
|
@pytest.mark.parametrize('vectorized,single',[(mechanics.deviatoric_part, deviatoric_part),
|
||||||
(mechanics.maximum_shear , maximum_shear ),
|
(mechanics.maximum_shear, maximum_shear),
|
||||||
(mechanics.Mises_strain , Mises_strain ),
|
(mechanics.equivalent_stress_Mises, equivalent_stress_Mises),
|
||||||
(mechanics.Mises_stress , Mises_stress ),
|
(mechanics.equivalent_strain_Mises, equivalent_strain_Mises),
|
||||||
(mechanics.rotational_part, rotational_part),
|
(mechanics.rotational_part, rotational_part),
|
||||||
(mechanics.spherical_part , spherical_part ),
|
(mechanics.spherical_part, spherical_part),
|
||||||
(mechanics.stretch_left , stretch_left ),
|
(mechanics.stretch_left, stretch_left),
|
||||||
(mechanics.stretch_right , stretch_right ),
|
(mechanics.stretch_right, stretch_right),
|
||||||
])
|
])
|
||||||
def test_vectorize_1_arg(self,vectorized,single):
|
def test_vectorize_1_arg(self,vectorized,single):
|
||||||
epsilon = np.random.rand(self.n,3,3)
|
epsilon = np.random.rand(self.n,3,3)
|
||||||
|
@ -127,8 +126,8 @@ class TestMechanics:
|
||||||
for i,v in enumerate(np.reshape(vectorized(epsilon_vec),vectorized(epsilon).shape)):
|
for i,v in enumerate(np.reshape(vectorized(epsilon_vec),vectorized(epsilon).shape)):
|
||||||
assert np.allclose(single(epsilon[i]),v)
|
assert np.allclose(single(epsilon[i]),v)
|
||||||
|
|
||||||
@pytest.mark.parametrize('vectorized,single',[(mechanics.Cauchy,Cauchy),
|
@pytest.mark.parametrize('vectorized,single',[(mechanics.stress_Cauchy, stress_Cauchy),
|
||||||
(mechanics.PK2 ,PK2 )
|
(mechanics.stress_second_Piola_Kirchhoff, stress_second_Piola_Kirchhoff)
|
||||||
])
|
])
|
||||||
def test_vectorize_2_arg(self,vectorized,single):
|
def test_vectorize_2_arg(self,vectorized,single):
|
||||||
P = np.random.rand(self.n,3,3)
|
P = np.random.rand(self.n,3,3)
|
||||||
|
@ -148,8 +147,8 @@ class TestMechanics:
|
||||||
for i,v in enumerate(np.reshape(vectorized(F_vec,t,m),vectorized(F,t,m).shape)):
|
for i,v in enumerate(np.reshape(vectorized(F_vec,t,m),vectorized(F,t,m).shape)):
|
||||||
assert np.allclose(single(F[i],t,m),v)
|
assert np.allclose(single(F[i],t,m),v)
|
||||||
|
|
||||||
@pytest.mark.parametrize('function',[mechanics.Cauchy,
|
@pytest.mark.parametrize('function',[mechanics.stress_Cauchy,
|
||||||
mechanics.PK2,
|
mechanics.stress_second_Piola_Kirchhoff,
|
||||||
])
|
])
|
||||||
def test_stress_measures(self,function):
|
def test_stress_measures(self,function):
|
||||||
"""Ensure that all stress measures are equivalent for no deformation."""
|
"""Ensure that all stress measures are equivalent for no deformation."""
|
||||||
|
@ -212,8 +211,8 @@ class TestMechanics:
|
||||||
def test_deviatoric_Mises(self):
|
def test_deviatoric_Mises(self):
|
||||||
"""Ensure that Mises equivalent stress depends only on deviatoric part."""
|
"""Ensure that Mises equivalent stress depends only on deviatoric part."""
|
||||||
x = np.random.rand(self.n,3,3)
|
x = np.random.rand(self.n,3,3)
|
||||||
full = mechanics.Mises_stress(x)
|
full = mechanics.equivalent_stress_Mises(x)
|
||||||
dev = mechanics.Mises_stress(mechanics.deviatoric_part(x))
|
dev = mechanics.equivalent_stress_Mises(mechanics.deviatoric_part(x))
|
||||||
assert np.allclose(full,
|
assert np.allclose(full,
|
||||||
dev)
|
dev)
|
||||||
|
|
||||||
|
@ -229,14 +228,14 @@ class TestMechanics:
|
||||||
"""Ensure that Mises equivalent strain of spherical strain is 0."""
|
"""Ensure that Mises equivalent strain of spherical strain is 0."""
|
||||||
x = np.random.rand(self.n,3,3)
|
x = np.random.rand(self.n,3,3)
|
||||||
sph = mechanics.spherical_part(x,True)
|
sph = mechanics.spherical_part(x,True)
|
||||||
assert np.allclose(mechanics.Mises_strain(sph),
|
assert np.allclose(mechanics.equivalent_strain_Mises(sph),
|
||||||
0.0)
|
0.0)
|
||||||
|
|
||||||
|
|
||||||
def test_Mises(self):
|
def test_Mises(self):
|
||||||
"""Ensure that equivalent stress is 3/2 of equivalent strain."""
|
"""Ensure that equivalent stress is 3/2 of equivalent strain."""
|
||||||
x = np.random.rand(self.n,3,3)
|
x = np.random.rand(self.n,3,3)
|
||||||
assert np.allclose(mechanics.Mises_stress(x)/mechanics.Mises_strain(x),
|
assert np.allclose(mechanics.equivalent_stress_Mises(x)/mechanics.equivalent_strain_Mises(x),
|
||||||
1.5)
|
1.5)
|
||||||
|
|
||||||
def test_spherical_no_shear(self):
|
def test_spherical_no_shear(self):
|
||||||
|
|
Loading…
Reference in New Issue