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.
@@ -1,30 +1,11 @@
1
- from Elasticipy.tensors.fourth_order import SymmetricFourthOrderTensor, KELVIN_MAPPING_MATRIX
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='Voigt', **kwargs):
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.matrix)
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.matrix)
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.matrix:
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
- def compute_young_modulus(n):
555
- eps = _compute_unit_strain_along_direction(self, n, n)
556
- return 1 / eps
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
- def compute_shear_modulus(m, n):
572
- eps = _compute_unit_strain_along_direction(self, m, n)
573
- return 1 / (4 * eps)
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
- def compute_PoissonRatio(m, n):
589
- eps1 = _compute_unit_strain_along_direction(self, m, m)
590
- eps2 = _compute_unit_strain_along_direction(self, m, n, direction='transverse')
591
- return -eps2 / eps1
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
- def compute_linear_compressibility(n):
611
- return _compute_unit_strain_along_direction(self, n, n, direction='spherical')
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.matrix
658
- C11 = (c[0, 0] + c[1, 1] + c[2, 2]) / 5 \
659
- + (c[0, 1] + c[0, 2] + c[1, 2]) * 2 / 15 \
660
- + (c[3, 3] + c[4, 4] + c[5, 5]) * 4 / 15
661
- C12 = (c[0, 0] + c[1, 1] + c[2, 2]) / 15 \
662
- + (c[0, 1] + c[0, 2] + c[1, 2]) * 4 / 15 \
663
- - (c[3, 3] + c[4, 4] + c[5, 5]) * 2 / 15
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, nu_yx, nu_zx, nu_zy, Gxy, Gxz, Gyz, **kwargs):
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, Gxz, **kwargs):
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 transverse isotropic symmetry, given the engineering constants.
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
- ChristoffelTensor : Computes the Christoffel tensor along a given direction
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.matrix for C in Cs])
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.matrix[3, 3]
1106
- Gr = Creuss.matrix[3, 3]
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 discussed in [4]_.
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
- return self.matrix /self.mapping_matrix * KELVIN_MAPPING_MATRIX
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
- t = cls(matrix / KELVIN_MAPPING_MATRIX, **kwargs)
1320
- t.matrix *= t.mapping_matrix
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
- ([51.99999999999997, 154.0, 454.0], [2, 3, 1])
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=_compliance_mapping_voigt, **kwargs):
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.matrix)
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.matrix
1516
- S11 = (s[0, 0] + s[1, 1] + s[2, 2]) / 5 \
1517
- + (s[0, 1] + s[0, 2] + s[1, 2]) * 2 / 15 \
1518
- + (s[3, 3] + s[4, 4] + s[5, 5]) * 1 / 15
1519
- S12 = (s[0, 0] + s[1, 1] + s[2, 2]) / 15 \
1520
- + (s[0, 1] + s[0, 2] + s[1, 2]) * 4 / 15 \
1521
- - (s[3, 3] + s[4, 4] + s[5, 5]) * 1 / 30
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.matrix.T
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