elasticipy 4.0.0__py3-none-any.whl → 4.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Elasticipy/gui.py +1 -1
- Elasticipy/interfaces/FEPX.py +119 -0
- Elasticipy/interfaces/PRISMS.py +103 -0
- Elasticipy/plasticity.py +34 -1
- Elasticipy/polefigure.py +21 -0
- Elasticipy/spherical_function.py +2 -14
- Elasticipy/tensors/elasticity.py +171 -79
- Elasticipy/tensors/fourth_order.py +126 -55
- Elasticipy/tensors/mapping.py +44 -0
- Elasticipy/tensors/second_order.py +107 -3
- Elasticipy/tensors/stress_strain.py +20 -4
- {elasticipy-4.0.0.dist-info → elasticipy-4.1.0.dist-info}/METADATA +22 -4
- elasticipy-4.1.0.dist-info/RECORD +23 -0
- {elasticipy-4.0.0.dist-info → elasticipy-4.1.0.dist-info}/WHEEL +1 -1
- elasticipy-4.0.0.dist-info/RECORD +0 -20
- {elasticipy-4.0.0.dist-info → elasticipy-4.1.0.dist-info}/licenses/LICENSE +0 -0
- {elasticipy-4.0.0.dist-info → elasticipy-4.1.0.dist-info}/top_level.txt +0 -0
Elasticipy/tensors/elasticity.py
CHANGED
|
@@ -1,30 +1,11 @@
|
|
|
1
|
-
from Elasticipy.tensors.fourth_order import SymmetricFourthOrderTensor
|
|
1
|
+
from Elasticipy.tensors.fourth_order import SymmetricFourthOrderTensor
|
|
2
2
|
from Elasticipy.spherical_function import SphericalFunction, HyperSphericalFunction
|
|
3
3
|
from Elasticipy.crystal_symmetries import SYMMETRIES
|
|
4
4
|
from Elasticipy.tensors.stress_strain import StrainTensor, StressTensor
|
|
5
|
+
from Elasticipy.tensors.mapping import VoigtMapping, KelvinMapping
|
|
5
6
|
import numpy as np
|
|
6
7
|
import re
|
|
7
8
|
|
|
8
|
-
_compliance_mapping_voigt = np.array([[1., 1., 1., 2., 2., 2.],
|
|
9
|
-
[1., 1., 1., 2., 2., 2.],
|
|
10
|
-
[1., 1., 1., 2., 2., 2.],
|
|
11
|
-
[2., 2., 2., 4., 4., 4.],
|
|
12
|
-
[2., 2., 2., 4., 4., 4.],
|
|
13
|
-
[2., 2., 2., 4., 4., 4.]])
|
|
14
|
-
|
|
15
|
-
def _compute_unit_strain_along_direction(S, m, n, direction='longitudinal'):
|
|
16
|
-
if not isinstance(S, ComplianceTensor):
|
|
17
|
-
S = S.inv()
|
|
18
|
-
if direction == 'transverse':
|
|
19
|
-
ein_str = 'ijkl,pi,pj,pk,pl->p'
|
|
20
|
-
return np.einsum(ein_str, S.full_tensor(), m, m, n, n)
|
|
21
|
-
elif direction == 'longitudinal':
|
|
22
|
-
ein_str = 'ijkl,pi,pk,pj,pl->p'
|
|
23
|
-
return np.einsum(ein_str, S.full_tensor(), m, m, n, n)
|
|
24
|
-
else:
|
|
25
|
-
ein_str = 'ijkk,pi,pj->p'
|
|
26
|
-
return np.einsum(ein_str, S.full_tensor(), m, m)
|
|
27
|
-
|
|
28
9
|
def _parse_tensor_components(prefix, **kwargs):
|
|
29
10
|
pattern = r'^{}(\d{{2}})$'.format(prefix)
|
|
30
11
|
value = dict()
|
|
@@ -53,6 +34,14 @@ def _check_definite_positive(mat):
|
|
|
53
34
|
eigen_val = np.linalg.eigvals(mat)
|
|
54
35
|
raise ValueError('The input matrix is not definite positive (eigenvalues: {})'.format(eigen_val))
|
|
55
36
|
|
|
37
|
+
def _switch_poisson_ratios(nu_xy, nu_yx, Ex, Ey, indices):
|
|
38
|
+
if nu_yx is None and nu_xy is not None:
|
|
39
|
+
return nu_xy * Ey / Ex
|
|
40
|
+
elif nu_yx is not None and nu_xy is None:
|
|
41
|
+
return nu_yx
|
|
42
|
+
else:
|
|
43
|
+
raise ValueError('Either nu_{0}{1} or nu_{1}{0} must be provided'.format(*indices))
|
|
44
|
+
|
|
56
45
|
class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
57
46
|
"""
|
|
58
47
|
Class for manipulating fourth-order stiffness tensors.
|
|
@@ -62,7 +51,7 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
62
51
|
C46_C56_factor = 1.0
|
|
63
52
|
component_prefix = 'C'
|
|
64
53
|
|
|
65
|
-
def __init__(self, M, symmetry='Triclinic', check_positive_definite=True, phase_name= None, mapping=
|
|
54
|
+
def __init__(self, M, symmetry='Triclinic', check_positive_definite=True, phase_name= None, mapping=VoigtMapping(), **kwargs):
|
|
66
55
|
"""
|
|
67
56
|
Construct of stiffness tensor from a (6,6) matrix.
|
|
68
57
|
|
|
@@ -81,10 +70,19 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
81
70
|
Whether to check or not that the input matrix is symmetric.
|
|
82
71
|
force_symmetry : bool, optional
|
|
83
72
|
If true, the major symmetry of the tensor is forces
|
|
73
|
+
mapping : str or MappingConvention
|
|
74
|
+
mapping convention to use. Default is VoigtMapping.
|
|
75
|
+
|
|
76
|
+
Notes
|
|
77
|
+
-----
|
|
78
|
+
The units used when building the stiffness tensor are up to the user (GPa, MPa, psi etc.). Therefor, the
|
|
79
|
+
results you will get when performing operations (Young's modulus, "product" with strain tensor etc.) will be
|
|
80
|
+
consistent with these units. For instance, if the stiffness tensor is defined in GPa, the computed stress will
|
|
81
|
+
be given in GPa as well.
|
|
84
82
|
"""
|
|
85
83
|
super().__init__(M, mapping=mapping, **kwargs)
|
|
86
84
|
if check_positive_definite:
|
|
87
|
-
_check_definite_positive(self.
|
|
85
|
+
_check_definite_positive(self._matrix)
|
|
88
86
|
self.symmetry = symmetry
|
|
89
87
|
self.phase_name = phase_name
|
|
90
88
|
|
|
@@ -113,7 +111,7 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
113
111
|
ComplianceTensor
|
|
114
112
|
Reciprocal tensor
|
|
115
113
|
"""
|
|
116
|
-
C = np.linalg.inv(self.
|
|
114
|
+
C = np.linalg.inv(self._matrix)
|
|
117
115
|
return ComplianceTensor(C, symmetry=self.symmetry, phase_name=self.phase_name)
|
|
118
116
|
|
|
119
117
|
@classmethod
|
|
@@ -183,7 +181,7 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
183
181
|
if self.phase_name is not None:
|
|
184
182
|
f.write(f"Phase Name: {self.phase_name}\n")
|
|
185
183
|
f.write(f"Symmetry: {self.symmetry}\n")
|
|
186
|
-
for row in self.
|
|
184
|
+
for row in self._matrix:
|
|
187
185
|
f.write(" " + " ".join(f"{value:8.2f}" for value in row) + "\n")
|
|
188
186
|
|
|
189
187
|
@classmethod
|
|
@@ -551,9 +549,13 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
551
549
|
Young's modulus
|
|
552
550
|
"""
|
|
553
551
|
self._single_tensor_only('Young_modulus')
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
552
|
+
if isinstance(self, ComplianceTensor):
|
|
553
|
+
S = self
|
|
554
|
+
else:
|
|
555
|
+
S = self.inv()
|
|
556
|
+
def compute_young_modulus(u):
|
|
557
|
+
a = np.einsum('ijkl,...i,...j,...k,...l->...', S.full_tensor(), u, u, u, u)
|
|
558
|
+
return 1 / a
|
|
557
559
|
|
|
558
560
|
return SphericalFunction(compute_young_modulus)
|
|
559
561
|
|
|
@@ -568,9 +570,13 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
568
570
|
Shear modulus
|
|
569
571
|
"""
|
|
570
572
|
self._single_tensor_only('shear_modulus')
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
573
|
+
if isinstance(self, ComplianceTensor):
|
|
574
|
+
S = self
|
|
575
|
+
else:
|
|
576
|
+
S = self.inv()
|
|
577
|
+
def compute_shear_modulus(u, v):
|
|
578
|
+
G = 0.25/np.einsum('ijkl,...i,...j,...k,...l->...',S.full_tensor(),u,v,u,v)
|
|
579
|
+
return G
|
|
574
580
|
|
|
575
581
|
return HyperSphericalFunction(compute_shear_modulus)
|
|
576
582
|
|
|
@@ -583,12 +589,27 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
583
589
|
-------
|
|
584
590
|
HyperSphericalFunction
|
|
585
591
|
Poisson's ratio
|
|
592
|
+
|
|
593
|
+
Notes
|
|
594
|
+
-----
|
|
595
|
+
If the material undergoes tensile strain :math:`\\varepsilon_{ii}` along the i-th direction, the Poisson ratios
|
|
596
|
+
are defined as:
|
|
597
|
+
|
|
598
|
+
.. math::
|
|
599
|
+
|
|
600
|
+
\\nu_{ij}=-\\frac{\\partial \\varepsilon_{jj}}{\\partial \\varepsilon_{ii}}
|
|
601
|
+
|
|
602
|
+
where :math:`\\varepsilon_{jj}` denotes the (compressive) longitudinal strain along the j-th direction.
|
|
586
603
|
"""
|
|
587
604
|
self._single_tensor_only('Poisson_ratio')
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
605
|
+
if isinstance(self, ComplianceTensor):
|
|
606
|
+
Sfull = self.full_tensor()
|
|
607
|
+
else:
|
|
608
|
+
Sfull = self.inv().full_tensor()
|
|
609
|
+
def compute_PoissonRatio(u, v):
|
|
610
|
+
numer = np.einsum('ijkl,...i,...j,...k,...l->...',Sfull,v,v,u,u)
|
|
611
|
+
denom = np.einsum('ijkl,...i,...j,...k,...l->...',Sfull,u,u,u,u)
|
|
612
|
+
return -numer / denom
|
|
592
613
|
|
|
593
614
|
return HyperSphericalFunction(compute_PoissonRatio)
|
|
594
615
|
|
|
@@ -607,8 +628,12 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
607
628
|
bulk_modulus : bulk modulus of the material
|
|
608
629
|
"""
|
|
609
630
|
self._single_tensor_only('linear_compressibility')
|
|
610
|
-
|
|
611
|
-
|
|
631
|
+
if isinstance(self, ComplianceTensor):
|
|
632
|
+
S = self
|
|
633
|
+
else:
|
|
634
|
+
S = self.inv()
|
|
635
|
+
def compute_linear_compressibility(u):
|
|
636
|
+
return np.einsum('ijkk,...i,...j->...',S.full_tensor(),u,u)
|
|
612
637
|
|
|
613
638
|
return SphericalFunction(compute_linear_compressibility)
|
|
614
639
|
|
|
@@ -654,14 +679,13 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
654
679
|
if self.ndim:
|
|
655
680
|
return self.mean(axis=axis)
|
|
656
681
|
else:
|
|
657
|
-
c = self.
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
C44 = (c[0, 0] + c[1, 1] + c[2, 2] - c[0, 1] - c[0, 2] - c[1, 2]) / 15 + (c[3, 3] + c[4, 4] + c[5, 5]) / 5
|
|
682
|
+
c = self._matrix
|
|
683
|
+
A = c[0, 0] + c[1, 1] + c[2, 2]
|
|
684
|
+
B = c[0, 1] + c[0, 2] + c[1, 2]
|
|
685
|
+
C = c[3, 3] + c[4, 4] + c[5, 5]
|
|
686
|
+
C11 = 1 / 5 * A + 2 / 15 * B + 4 / 15 * C
|
|
687
|
+
C12 = 1 / 15 * A + 4 / 15 * B - 2 / 15 * C
|
|
688
|
+
C44 = (A - B) / 15 + C / 5
|
|
665
689
|
mat = _isotropic_matrix(C11, C12, C44)
|
|
666
690
|
return StiffnessTensor(mat, symmetry='isotropic', phase_name=self.phase_name)
|
|
667
691
|
|
|
@@ -770,6 +794,12 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
770
794
|
--------
|
|
771
795
|
transverse_isotropic : create a transverse-isotropic tensor
|
|
772
796
|
|
|
797
|
+
Notes
|
|
798
|
+
-----
|
|
799
|
+
The units you use when passing the elastic moduli must be consistent with that of the stress tensor. For
|
|
800
|
+
instance, if you expect to work in MPa, the Young's modulus and the Lamé's coefficient must be given in MPa as
|
|
801
|
+
well.
|
|
802
|
+
|
|
773
803
|
Examples
|
|
774
804
|
--------
|
|
775
805
|
On can check that the shear modulus for steel is around 82 GPa:
|
|
@@ -808,10 +838,14 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
808
838
|
return StiffnessTensor(np.array(matrix), symmetry='isotropic', phase_name=phase_name)
|
|
809
839
|
|
|
810
840
|
@classmethod
|
|
811
|
-
def orthotropic(cls, *, Ex, Ey, Ez,
|
|
841
|
+
def orthotropic(cls, *, Ex, Ey, Ez, Gxy, Gxz, Gyz,
|
|
842
|
+
nu_yx=None, nu_zx=None, nu_zy=None,
|
|
843
|
+
nu_xy=None, nu_xz=None, nu_yz=None, **kwargs):
|
|
812
844
|
"""
|
|
813
845
|
Create a stiffness tensor corresponding to orthotropic symmetry, given the engineering constants.
|
|
814
846
|
|
|
847
|
+
Exactly three Poisson ratios must be provided. See Notes for details.
|
|
848
|
+
|
|
815
849
|
Parameters
|
|
816
850
|
----------
|
|
817
851
|
Ex : float
|
|
@@ -820,18 +854,18 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
820
854
|
Young modulus along the y axis
|
|
821
855
|
Ez : float
|
|
822
856
|
Young modulus along the z axis
|
|
823
|
-
nu_yx : float
|
|
824
|
-
Poisson ratio between x and y axes
|
|
825
|
-
nu_zx : float
|
|
826
|
-
Poisson ratio between x and z axes
|
|
827
|
-
nu_zy : float
|
|
828
|
-
Poisson ratio between y and z axes
|
|
829
857
|
Gxy : float
|
|
830
858
|
Shear modulus in the x-y plane
|
|
831
859
|
Gxz : float
|
|
832
860
|
Shear modulus in the x-z plane
|
|
833
861
|
Gyz : float
|
|
834
862
|
Shear modulus in the y-z plane
|
|
863
|
+
nu_xy, nu_yx : float, optional
|
|
864
|
+
Poisson ratio along x and y axes. Either nu_xy or nu_yx must be provided, not both.
|
|
865
|
+
nu_xz, nu_zx : float, optional
|
|
866
|
+
Poisson ratio along x and z axes. Either nu_xz or nu_zx must be provided, not both.
|
|
867
|
+
nu_yz, nu_zy : float, optional
|
|
868
|
+
Poisson ratio along y and z axes. Either nu_yz or nu_zy must be provided, not both.
|
|
835
869
|
kwargs : dict, optional
|
|
836
870
|
Keyword arguments to pass to the StiffnessTensor constructor
|
|
837
871
|
|
|
@@ -842,7 +876,27 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
842
876
|
See Also
|
|
843
877
|
--------
|
|
844
878
|
transverse_isotropic : create a stiffness tensor for transverse-isotropic symmetry
|
|
879
|
+
|
|
880
|
+
Notes
|
|
881
|
+
-----
|
|
882
|
+
If the material undergoes tensile strain :math:`\\varepsilon_{ii}` along the i-th direction, the Poisson ratios
|
|
883
|
+
are defined as:
|
|
884
|
+
|
|
885
|
+
.. math::
|
|
886
|
+
|
|
887
|
+
\\nu_{ij}=-\\frac{\\partial \\varepsilon_{jj}}{\\partial \\varepsilon_{ii}}
|
|
888
|
+
|
|
889
|
+
where :math:`\\varepsilon_{jj}` denotes the (compressive) longitudinal strain along the j-th direction. If
|
|
890
|
+
:math:`E_x` and :math:`E_y` are the Young moduli along `x` and `y`, we have:
|
|
891
|
+
|
|
892
|
+
.. math::
|
|
893
|
+
|
|
894
|
+
\\frac{\\nu_{xy}}{E_x} = \\frac{\\nu_{yx}}{E_y}
|
|
895
|
+
|
|
845
896
|
"""
|
|
897
|
+
nu_yx = _switch_poisson_ratios(nu_xy, nu_yx, Ex, Ey,'xy')
|
|
898
|
+
nu_zx = _switch_poisson_ratios(nu_xz, nu_zx, Ex, Ez,'xz')
|
|
899
|
+
nu_zy = _switch_poisson_ratios(nu_yz, nu_zy, Ey, Ez,'yz')
|
|
846
900
|
tri_sup = np.array([[1 / Ex, -nu_yx / Ey, -nu_zx / Ez, 0, 0, 0],
|
|
847
901
|
[0, 1 / Ey, -nu_zy / Ez, 0, 0, 0],
|
|
848
902
|
[0, 0, 1 / Ez, 0, 0, 0],
|
|
@@ -853,9 +907,12 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
853
907
|
return StiffnessTensor(np.linalg.inv(S), symmetry='orthotropic', **kwargs)
|
|
854
908
|
|
|
855
909
|
@classmethod
|
|
856
|
-
def transverse_isotropic(cls, *, Ex, Ez, nu_yx, nu_zx,
|
|
910
|
+
def transverse_isotropic(cls, *, Ex, Ez, Gxz, nu_yx=None, nu_xy=None, nu_zx=None, nu_xz=None, **kwargs):
|
|
857
911
|
"""
|
|
858
|
-
Create a stiffness tensor corresponding to the
|
|
912
|
+
Create a stiffness tensor corresponding to the transversely isotropic symmetry with respect to Z axis, given the
|
|
913
|
+
engineering constants.
|
|
914
|
+
|
|
915
|
+
Exactly two Poisson ratios must be provided (nu_xy or nu_yx, and nu_xz or nu_zx). See Notes for details.
|
|
859
916
|
|
|
860
917
|
Parameters
|
|
861
918
|
----------
|
|
@@ -863,12 +920,12 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
863
920
|
Young modulus along the x axis
|
|
864
921
|
Ez : float
|
|
865
922
|
Young modulus along the y axis
|
|
866
|
-
nu_yx : float
|
|
867
|
-
Poisson ratio between x and y axes
|
|
868
|
-
nu_zx : float
|
|
869
|
-
Poisson ratio between x and z axes
|
|
870
923
|
Gxz : float
|
|
871
924
|
Shear modulus in the x-z plane
|
|
925
|
+
nu_xy, nu_yx : float, optional
|
|
926
|
+
Poisson ratio along x and y. Either nu_xy or nu_yx must be provided, not both.
|
|
927
|
+
nu_xz, nu_zx : float, optional
|
|
928
|
+
Poisson ratio along x and z. Either nu_xz or nu_zx must be provided, not both.
|
|
872
929
|
kwargs : dict
|
|
873
930
|
Keyword arguments to pass to the StiffnessTensor constructor
|
|
874
931
|
|
|
@@ -879,10 +936,28 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
879
936
|
See Also
|
|
880
937
|
--------
|
|
881
938
|
orthotropic : create a stiffness tensor for orthotropic symmetry
|
|
939
|
+
|
|
940
|
+
Notes
|
|
941
|
+
-----
|
|
942
|
+
If the material undergoes tensile strain :math:`\\varepsilon_{ii}` along the i-th direction, the Poisson ratios
|
|
943
|
+
are defined as:
|
|
944
|
+
|
|
945
|
+
.. math::
|
|
946
|
+
|
|
947
|
+
\\nu_{ij}=-\\frac{\\partial \\varepsilon_{jj}}{\\partial \\varepsilon_{ii}}
|
|
948
|
+
|
|
949
|
+
where :math:`\\varepsilon_{jj}` denotes the (compressive) longitudinal strain along the j-th direction. If
|
|
950
|
+
:math:`E_x` and :math:`E_y` are the Young moduli along `x` and `y`, we have:
|
|
951
|
+
|
|
952
|
+
.. math::
|
|
953
|
+
|
|
954
|
+
\\frac{\\nu_{xy}}{E_x} = \\frac{\\nu_{yx}}{E_y}
|
|
882
955
|
"""
|
|
956
|
+
nu_yx = _switch_poisson_ratios(nu_xy, nu_yx, Ex, Ex,'xy')
|
|
883
957
|
Gxy = Ex / (2 * (1 + nu_yx))
|
|
884
958
|
C = StiffnessTensor.orthotropic(Ex=Ex, Ey=Ex, Ez=Ez,
|
|
885
959
|
nu_yx=nu_yx, nu_zx=nu_zx, nu_zy=nu_zx,
|
|
960
|
+
nu_xz=nu_xz, nu_yz=nu_xz,
|
|
886
961
|
Gxy=Gxy, Gxz=Gxz, Gyz=Gxz, **kwargs)
|
|
887
962
|
C.symmetry = 'transverse-isotropic'
|
|
888
963
|
return C
|
|
@@ -928,7 +1003,7 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
928
1003
|
|
|
929
1004
|
See Also
|
|
930
1005
|
--------
|
|
931
|
-
|
|
1006
|
+
Christoffel_tensor : Computes the Christoffel tensor along a given direction
|
|
932
1007
|
|
|
933
1008
|
Returns
|
|
934
1009
|
-------
|
|
@@ -1055,7 +1130,7 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
1055
1130
|
if np.all([isinstance(a, ComplianceTensor) for a in Cs]):
|
|
1056
1131
|
Cs = [C.inv() for C in Cs]
|
|
1057
1132
|
if np.all([isinstance(a, StiffnessTensor) for a in Cs]):
|
|
1058
|
-
C_stack = np.array([C.
|
|
1133
|
+
C_stack = np.array([C._matrix for C in Cs])
|
|
1059
1134
|
method = method.capitalize()
|
|
1060
1135
|
if method == 'Voigt':
|
|
1061
1136
|
C_avg = np.average(C_stack, weights=volume_fractions, axis=0)
|
|
@@ -1102,8 +1177,8 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
1102
1177
|
self._single_tensor_only('universal_anisotropy')
|
|
1103
1178
|
Cvoigt = self.Voigt_average()
|
|
1104
1179
|
Creuss = self.Reuss_average()
|
|
1105
|
-
Gv = Cvoigt.
|
|
1106
|
-
Gr = Creuss.
|
|
1180
|
+
Gv = Cvoigt._matrix[3, 3]
|
|
1181
|
+
Gr = Creuss._matrix[3, 3]
|
|
1107
1182
|
Kv = Cvoigt.bulk_modulus
|
|
1108
1183
|
Kr = Creuss.bulk_modulus
|
|
1109
1184
|
return 5 * Gv / Gr + Kv / Kr - 6
|
|
@@ -1217,14 +1292,27 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
1217
1292
|
|
|
1218
1293
|
Notes
|
|
1219
1294
|
-----
|
|
1220
|
-
This mapping convention is
|
|
1295
|
+
This mapping convention is defined as follows [4]_:
|
|
1296
|
+
|
|
1297
|
+
.. math::
|
|
1298
|
+
|
|
1299
|
+
C_K = \\begin{bmatrix}
|
|
1300
|
+
C_{11} & C_{12} & C_{13} & \\sqrt{2}C_{14} & \\sqrt{2}C_{15} & \\sqrt{2}C_{16}\\\\
|
|
1301
|
+
C_{12} & C_{22} & C_{23} & \\sqrt{2}C_{24} & \\sqrt{2}C_{25} & \\sqrt{2}C_{26}\\\\
|
|
1302
|
+
C_{13} & C_{23} & C_{33} & \\sqrt{2}C_{34} & \\sqrt{2}C_{35} & \\sqrt{2}C_{36}\\\\
|
|
1303
|
+
\\sqrt{2}C_{14} & \\sqrt{2}C_{24} & \\sqrt{2}C_{34} & 2C_{44} & 2C_{45} & 2C_{46}\\\\
|
|
1304
|
+
\\sqrt{2}C_{15} & \\sqrt{2}C_{25} & \\sqrt{2}C_{35} & 2C_{45} & 2C_{55} & 2C_{56}\\\\
|
|
1305
|
+
\\sqrt{2}C_{16} & \\sqrt{2}C_{26} & \\sqrt{2}C_{36} & 2C_{46} & 2C_{56} & 2C_{66}\\\\
|
|
1306
|
+
\\end{bmatrix}
|
|
1307
|
+
|
|
1221
1308
|
|
|
1222
1309
|
References
|
|
1223
1310
|
----------
|
|
1224
1311
|
.. [4] Helbig, K. (2013). What Kelvin might have written about Elasticity. Geophysical Prospecting, 61(1), 1-20.
|
|
1225
1312
|
doi: 10.1111/j.1365-2478.2011.01049.x
|
|
1226
1313
|
"""
|
|
1227
|
-
|
|
1314
|
+
kelvin_mapping = KelvinMapping()
|
|
1315
|
+
return self._matrix /self.mapping.matrix * kelvin_mapping.matrix
|
|
1228
1316
|
|
|
1229
1317
|
def eig(self):
|
|
1230
1318
|
"""
|
|
@@ -1312,12 +1400,18 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
1312
1400
|
(6,6) matrix of components
|
|
1313
1401
|
kwargs
|
|
1314
1402
|
keyword arguments passed to the constructor
|
|
1403
|
+
|
|
1315
1404
|
Returns
|
|
1316
1405
|
-------
|
|
1317
1406
|
StiffnessTensor
|
|
1407
|
+
|
|
1408
|
+
See Also
|
|
1409
|
+
--------
|
|
1410
|
+
to_Kelvin : return the components as a (6,6) matrix following the Kelvin convention
|
|
1318
1411
|
"""
|
|
1319
|
-
|
|
1320
|
-
t
|
|
1412
|
+
kelvin_mapping = KelvinMapping()
|
|
1413
|
+
t = cls(matrix / kelvin_mapping.matrix, **kwargs)
|
|
1414
|
+
t._matrix *= t.mapping.matrix
|
|
1321
1415
|
return t
|
|
1322
1416
|
|
|
1323
1417
|
def eig_stiffnesses_multiplicity(self, tol=1e-4):
|
|
@@ -1350,7 +1444,7 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
|
|
|
1350
1444
|
>>> C.eig_stiffnesses
|
|
1351
1445
|
array([ 52., 52., 154., 154., 154., 454.])
|
|
1352
1446
|
>>> C.eig_stiffnesses_multiplicity()
|
|
1353
|
-
([
|
|
1447
|
+
(array([ 52., 154., 454.]), array([2, 3, 1]))
|
|
1354
1448
|
"""
|
|
1355
1449
|
eig = self.eig_stiffnesses
|
|
1356
1450
|
counts = []
|
|
@@ -1483,7 +1577,7 @@ class ComplianceTensor(StiffnessTensor):
|
|
|
1483
1577
|
component_prefix = 'S'
|
|
1484
1578
|
C46_C56_factor = 2.0
|
|
1485
1579
|
|
|
1486
|
-
def __init__(self, C, check_positive_definite=True, mapping=
|
|
1580
|
+
def __init__(self, C, check_positive_definite=True, mapping=VoigtMapping(tensor='Compliance'), **kwargs):
|
|
1487
1581
|
super().__init__(C, check_positive_definite=check_positive_definite, mapping=mapping, **kwargs)
|
|
1488
1582
|
self.mapping_name = 'Voigt'
|
|
1489
1583
|
|
|
@@ -1505,22 +1599,20 @@ class ComplianceTensor(StiffnessTensor):
|
|
|
1505
1599
|
StiffnessTensor
|
|
1506
1600
|
Reciprocal tensor
|
|
1507
1601
|
"""
|
|
1508
|
-
S = np.linalg.inv(self.
|
|
1602
|
+
S = np.linalg.inv(self._matrix)
|
|
1509
1603
|
return StiffnessTensor(S, symmetry=self.symmetry, phase_name=self.phase_name)
|
|
1510
1604
|
|
|
1511
1605
|
def Reuss_average(self, axis=None):
|
|
1512
1606
|
if self.ndim:
|
|
1513
1607
|
return self.mean(axis=axis)
|
|
1514
1608
|
else:
|
|
1515
|
-
s = self.
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
S44 = ((s[0, 0] + s[1, 1] + s[2, 2] - s[0, 1] - s[0, 2] - s[1, 2]) * 4 / 15 +
|
|
1523
|
-
(s[3, 3] + s[4, 4] + s[5, 5]) / 5)
|
|
1609
|
+
s = self._matrix
|
|
1610
|
+
A = s[0, 0] + s[1, 1] + s[2, 2]
|
|
1611
|
+
B = s[0, 1] + s[0, 2] + s[1, 2]
|
|
1612
|
+
C = s[3, 3] + s[4, 4] + s[5, 5]
|
|
1613
|
+
S11 = 1 / 5 * A + 2 / 15 * B + 1 / 15 * C
|
|
1614
|
+
S12 = 1 / 15 * A + 4 / 15 * B - 1 / 30 * C
|
|
1615
|
+
S44 = 4 / 15 * (A - B) + 1 / 5 * C
|
|
1524
1616
|
mat = _isotropic_matrix(S11, S12, S44)
|
|
1525
1617
|
return ComplianceTensor(mat, symmetry='isotropic', phase_name=self.phase_name)
|
|
1526
1618
|
|
|
@@ -1548,7 +1640,7 @@ class ComplianceTensor(StiffnessTensor):
|
|
|
1548
1640
|
|
|
1549
1641
|
@property
|
|
1550
1642
|
def bulk_modulus(self):
|
|
1551
|
-
matrix_t = self.
|
|
1643
|
+
matrix_t = self._matrix.T
|
|
1552
1644
|
sub_matrix = matrix_t[0:3, 0:3]
|
|
1553
1645
|
return 1 / np.sum(sub_matrix, axis=(0,1))
|
|
1554
1646
|
|