elasticipy 4.1.1__py3-none-any.whl → 4.2.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.
@@ -5,6 +5,7 @@ from Elasticipy.tensors.stress_strain import StrainTensor, StressTensor
5
5
  from Elasticipy.tensors.mapping import VoigtMapping, KelvinMapping
6
6
  import numpy as np
7
7
  import re
8
+ from warnings import warn
8
9
 
9
10
  def _parse_tensor_components(prefix, **kwargs):
10
11
  pattern = r'^{}(\d{{2}})$'.format(prefix)
@@ -47,9 +48,9 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
47
48
  Class for manipulating fourth-order stiffness tensors.
48
49
  """
49
50
  tensor_name = 'Stiffness'
50
- C11_C12_factor = 0.5
51
- C46_C56_factor = 1.0
52
- component_prefix = 'C'
51
+ _C11_C12_factor = 0.5
52
+ _C46_C56_factor = 1.0
53
+ _component_prefix = 'C'
53
54
 
54
55
  def __init__(self, M, symmetry='Triclinic', check_positive_definite=True, phase_name= None, mapping=VoigtMapping(), **kwargs):
55
56
  """
@@ -187,7 +188,7 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
187
188
  @classmethod
188
189
  def _matrixFromCrystalSymmetry(cls, symmetry='Triclinic', point_group=None, diad='y', prefix=None, **kwargs):
189
190
  if prefix is None:
190
- prefix = cls.component_prefix
191
+ prefix = cls._component_prefix
191
192
  values = _parse_tensor_components(prefix, **kwargs)
192
193
  C = np.zeros((6, 6))
193
194
  symmetry = symmetry.capitalize()
@@ -228,17 +229,17 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
228
229
  C11_C12 = symmetry_description.C11_C12
229
230
  if C11_C12:
230
231
  for index in C11_C12:
231
- C[index] = (C[0, 0] - C[0, 1]) * cls.C11_C12_factor
232
+ C[index] = (C[0, 0] - C[0, 1]) * cls._C11_C12_factor
232
233
 
233
234
  if symmetry == 'Trigonal':
234
- C[3, 5] = cls.C46_C56_factor * C[3, 5]
235
- C[4, 5] = cls.C46_C56_factor * C[4, 5]
235
+ C[3, 5] = cls._C46_C56_factor * C[3, 5]
236
+ C[4, 5] = cls._C46_C56_factor * C[4, 5]
236
237
 
237
238
  return C + np.tril(C.T, -1)
238
239
 
239
240
  @classmethod
240
241
  def fromCrystalSymmetry(cls, symmetry='Triclinic', point_group=None, diad='y', phase_name=None, prefix=None,
241
- **kwargs):
242
+ **kwargs):
242
243
  """
243
244
  Create a fourth-order tensor from limited number of components, taking advantage of crystallographic symmetries
244
245
 
@@ -311,8 +312,13 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
311
312
  Phase: TiNi
312
313
  Symmetry: monoclinic
313
314
  """
314
- matrix = cls._matrixFromCrystalSymmetry(point_group=point_group, diad=diad, symmetry=symmetry, prefix=prefix,
315
- **kwargs)
315
+ warn('This function will be removed in a future release. Use {}.{}() instead'.format(cls.__name__,symmetry), DeprecationWarning, stacklevel=2)
316
+ return cls._fromCrystalSymmetry(symmetry=symmetry, point_group=point_group, diad=diad, phase_name=phase_name,
317
+ prefix=prefix, **kwargs)
318
+
319
+ @classmethod
320
+ def _fromCrystalSymmetry(cls, symmetry, phase_name, **kwargs):
321
+ matrix = cls._matrixFromCrystalSymmetry(symmetry=symmetry, **kwargs)
316
322
  return cls(matrix, phase_name=phase_name, symmetry=symmetry)
317
323
 
318
324
 
@@ -337,7 +343,7 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
337
343
  cubic : create a tensor from cubic symmetry
338
344
  tetragonal : create a tensor from tetragonal symmetry
339
345
  """
340
- return cls.fromCrystalSymmetry(symmetry='hexagonal', C11=C11, C12=C12, C13=C13, C33=C33, C44=C44,
346
+ return cls._fromCrystalSymmetry(symmetry='hexagonal', C11=C11, C12=C12, C13=C13, C33=C33, C44=C44,
341
347
  phase_name=phase_name, prefix='C')
342
348
 
343
349
  @classmethod
@@ -362,8 +368,9 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
362
368
  tetragonal : create a tensor from tetragonal symmetry
363
369
  orthorhombic : create a tensor from orthorhombic symmetry
364
370
  """
365
- return cls.fromCrystalSymmetry(point_group='3', C11=C11, C12=C12, C13=C13, C14=C14, C15=C15,
366
- C33=C33, C44=C44, phase_name=phase_name, prefix='C')
371
+ return cls._fromCrystalSymmetry(symmetry='trigonal', point_group='3',
372
+ C11=C11, C12=C12, C13=C13, C14=C14, C15=C15,
373
+ C33=C33, C44=C44, phase_name=phase_name, prefix='C')
367
374
 
368
375
  @classmethod
369
376
  def tetragonal(cls, *, C11=0., C12=0., C13=0., C33=0., C44=0., C16=0., C66=0., phase_name=None):
@@ -388,8 +395,9 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
388
395
  trigonal : create a tensor from trigonal symmetry
389
396
  orthorhombic : create a tensor from orthorhombic symmetry
390
397
  """
391
- return cls.fromCrystalSymmetry(point_group='4', C11=C11, C12=C12, C13=C13, C16=C16,
392
- C33=C33, C44=C44, C66=C66, phase_name=phase_name, prefix='C')
398
+ return cls._fromCrystalSymmetry(symmetry='tetragonal', point_group='4',
399
+ C11=C11, C12=C12, C13=C13, C16=C16,
400
+ C33=C33, C44=C44, C66=C66, phase_name=phase_name, prefix='C')
393
401
 
394
402
  @classmethod
395
403
  def cubic(cls, *, C11=0., C12=0., C44=0., phase_name=None):
@@ -411,7 +419,7 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
411
419
  hexagonal : create a tensor from hexagonal symmetry
412
420
  orthorhombic : create a tensor from orthorhombic symmetry
413
421
  """
414
- return cls.fromCrystalSymmetry(symmetry='cubic', C11=C11, C12=C12, C44=C44, phase_name=phase_name, prefix='C')
422
+ return cls._fromCrystalSymmetry(symmetry='cubic', C11=C11, C12=C12, C44=C44, phase_name=phase_name, prefix='C')
415
423
 
416
424
  @classmethod
417
425
  def orthorhombic(cls, *, C11=0., C12=0., C13=0., C22=0., C23=0., C33=0., C44=0., C55=0., C66=0., phase_name=None):
@@ -434,7 +442,7 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
434
442
  monoclinic : create a tensor from monoclinic symmetry
435
443
  orthorhombic : create a tensor from orthorhombic symmetry
436
444
  """
437
- return cls.fromCrystalSymmetry(symmetry='orthorhombic',
445
+ return cls._fromCrystalSymmetry(symmetry='orthorhombic',
438
446
  C11=C11, C12=C12, C13=C13, C22=C22, C23=C23, C33=C33, C44=C44, C55=C55, C66=C66,
439
447
  phase_name=phase_name, prefix='C')
440
448
 
@@ -487,12 +495,12 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
487
495
  if diad_y and diad_z:
488
496
  raise KeyError('Ambiguous diad. Provide either C15, C25, C35 and C46; or C16, C26, C36 and C45')
489
497
  elif diad_y:
490
- return cls.fromCrystalSymmetry(symmetry='monoclinic', diad='y',
498
+ return cls._fromCrystalSymmetry(symmetry='monoclinic', diad='y',
491
499
  C11=C11, C12=C12, C13=C13, C22=C22, C23=C23, C33=C33, C44=C44, C55=C55,
492
500
  C66=C66,
493
501
  C15=C15, C25=C25, C35=C35, C46=C46, phase_name=phase_name, prefix='C')
494
502
  elif diad_z:
495
- return cls.fromCrystalSymmetry(symmetry='monoclinic', diad='z',
503
+ return cls._fromCrystalSymmetry(symmetry='monoclinic', diad='z',
496
504
  C11=C11, C12=C12, C13=C13, C22=C22, C23=C23, C33=C33, C44=C44, C55=C55,
497
505
  C66=C66,
498
506
  C16=C16, C26=C26, C36=C36, C45=C45, phase_name=phase_name, prefix='C')
@@ -653,6 +661,51 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
653
661
  """
654
662
  return self.inv().bulk_modulus
655
663
 
664
+ @property
665
+ def lame1(self):
666
+ """"
667
+ Compute the first Lamé's parameter (only for isotropic materials).
668
+
669
+ If the stiffness/compliance tensor is not isotropic, NaN is returned.
670
+
671
+ Returns
672
+ -------
673
+ float
674
+ First Lamé's parameter
675
+
676
+ See Also
677
+ --------
678
+ lame2 : second Lamé's parameter
679
+ """
680
+ self._single_tensor_only('lame1')
681
+ if self.is_isotropic():
682
+ C11 = (self.C11 + self.C22 + self.C33) / 3
683
+ return C11 - 2 * self.lame2
684
+ else:
685
+ return np.nan
686
+
687
+ @property
688
+ def lame2(self):
689
+ """"
690
+ Compute the second Lamé's parameter (only for isotropic materials).
691
+
692
+ If the stiffness/compliance tensor is not isotropic, NaN is returned.
693
+
694
+ Returns
695
+ -------
696
+ float
697
+ Second Lamé's parameter
698
+
699
+ See Also
700
+ --------
701
+ lame1 : first Lamé's parameter
702
+ """
703
+ self._single_tensor_only('lame2')
704
+ if self.is_isotropic():
705
+ return (self.C44 + self.C55 + self.C66) / 3
706
+ else:
707
+ return np.nan
708
+
656
709
  def Voigt_average(self, axis=None):
657
710
  """
658
711
  Compute the Voigt average of the stiffness tensor.
@@ -768,10 +821,10 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
768
821
  raise NotImplementedError('Only Voigt, Reus, and Hill are implemented.')
769
822
 
770
823
  @classmethod
771
- def isotropic(cls, E=None, nu=None, lame1=None, lame2=None, phase_name=None):
824
+ def isotropic(cls, E=None, nu=None, G=None, lame1=None, lame2=None, K=None, phase_name=None):
772
825
  """
773
- Create an isotropic stiffness tensor from two elasticity coefficients, namely: E, nu, lame1, or lame2. Exactly
774
- two of these coefficients must be provided.
826
+ Create an isotropic stiffness tensor from two elasticity coefficients, namely: E, nu, G, lame1, or lame2.
827
+ Exactly two of these coefficients must be provided. Note that lame2 is just an alias for G.
775
828
 
776
829
  Parameters
777
830
  ----------
@@ -779,10 +832,14 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
779
832
  Young modulus
780
833
  nu : float, None
781
834
  Poisson ratio
835
+ G : float, None
836
+ Shear modulus
782
837
  lame1 : float, None
783
838
  First Lamé coefficient
784
839
  lame2 : float, None
785
- Second Lamé coefficient
840
+ Second Lamé coefficient (alias for G)
841
+ K : float, None
842
+ Bulk modulus
786
843
  phase_name : str, None
787
844
  Name to print
788
845
 
@@ -808,34 +865,9 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
808
865
  >>> C=StiffnessTensor.isotropic(E=210e3, nu=0.28)
809
866
  >>> C.shear_modulus
810
867
  Hyperspherical function
811
- Min=82031.24999999997, Max=82031.25000000006
812
- """
813
- argument_vector = np.array([E, nu, lame1, lame2])
814
- if np.count_nonzero(argument_vector) != 2:
815
- raise ValueError("Exactly two values are required among E, nu, lame1 and lame2.")
816
- if E is not None:
817
- if nu is not None:
818
- lame1 = E * nu / ((1 + nu) * (1 - 2 * nu))
819
- lame2 = E / (1 + nu) / 2
820
- elif lame1 is not None:
821
- R = np.sqrt(E ** 2 + 9 * lame1 ** 2 + 2 * E * lame1)
822
- lame2 = (E - 3 * lame1 + R) / 4
823
- elif lame2 is not None:
824
- lame1 = lame2 * (E - 2 * lame2) / (3 * lame2 - E)
825
- else:
826
- raise ValueError('Either nu, lame1 or lame2 must be provided.')
827
- elif nu is not None:
828
- if lame1 is not None:
829
- lame2 = lame1 * (1 - 2 * nu) / (2 * nu)
830
- elif lame2 is not None:
831
- lame1 = 2 * lame2 * nu / (1 - 2 * nu)
832
- else:
833
- raise ValueError('Either lame1 or lame2 must be provided.')
834
- C11 = lame1 + 2 * lame2
835
- C12 = lame1
836
- C44 = lame2
837
- matrix = _isotropic_matrix(C11, C12, C44)
838
- return StiffnessTensor(np.array(matrix), symmetry='isotropic', phase_name=phase_name)
868
+ Min=82031.24999999991, Max=82031.25000000006
869
+ """
870
+ return ComplianceTensor.isotropic(E=E, nu=nu, G=G, lame1=lame1, lame2=lame2, K=K, phase_name=phase_name).inv()
839
871
 
840
872
  @classmethod
841
873
  def orthotropic(cls, *, Ex, Ey, Ez, Gxy, Gxz, Gyz,
@@ -894,17 +926,9 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
894
926
  \\frac{\\nu_{xy}}{E_x} = \\frac{\\nu_{yx}}{E_y}
895
927
 
896
928
  """
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')
900
- tri_sup = np.array([[1 / Ex, -nu_yx / Ey, -nu_zx / Ez, 0, 0, 0],
901
- [0, 1 / Ey, -nu_zy / Ez, 0, 0, 0],
902
- [0, 0, 1 / Ez, 0, 0, 0],
903
- [0, 0, 0, 1 / Gyz, 0, 0],
904
- [0, 0, 0, 0, 1 / Gxz, 0],
905
- [0, 0, 0, 0, 0, 1 / Gxy]])
906
- S = tri_sup + np.tril(tri_sup.T, -1)
907
- return StiffnessTensor(np.linalg.inv(S), symmetry='orthotropic', **kwargs)
929
+ return ComplianceTensor.orthotropic(Ex=Ex, Ey=Ey, Ez=Ez, Gxy=Gxy, Gxz=Gxz, Gyz=Gyz,
930
+ nu_yx=nu_yx, nu_zx=nu_zx, nu_zy=nu_zy,
931
+ nu_xy=nu_xy, nu_xz=nu_xz, nu_yz=nu_yz).inv()
908
932
 
909
933
  @classmethod
910
934
  def transverse_isotropic(cls, *, Ex, Ez, Gxz, nu_yx=None, nu_xy=None, nu_zx=None, nu_xz=None, **kwargs):
@@ -1045,13 +1069,8 @@ class StiffnessTensor(SymmetricFourthOrderTensor):
1045
1069
  def make_fun(index):
1046
1070
  def fun(n):
1047
1071
  Gamma = self.Christoffel_tensor(n)
1048
- eig, _ = np.linalg.eig(Gamma)
1049
- if index == 0:
1050
- eig_of_interest = np.max(eig, axis=-1)
1051
- elif index == 1:
1052
- eig_of_interest = np.median(eig, axis=-1)
1053
- else:
1054
- eig_of_interest = np.min(eig, axis=-1)
1072
+ eig, _ = np.linalg.eigh(Gamma)
1073
+ eig_of_interest = eig[...,2-index] # Switch ordering (descending order)
1055
1074
  return np.sqrt(eig_of_interest / rho)
1056
1075
 
1057
1076
  return fun
@@ -1573,9 +1592,9 @@ class ComplianceTensor(StiffnessTensor):
1573
1592
  Class for manipulating compliance tensors
1574
1593
  """
1575
1594
  tensor_name = 'Compliance'
1576
- C11_C12_factor = 2.0
1577
- component_prefix = 'S'
1578
- C46_C56_factor = 2.0
1595
+ _C11_C12_factor = 2.0
1596
+ _component_prefix = 'S'
1597
+ _C46_C56_factor = 2.0
1579
1598
 
1580
1599
  def __init__(self, C, check_positive_definite=True, mapping=VoigtMapping(tensor='Compliance'), **kwargs):
1581
1600
  super().__init__(C, check_positive_definite=check_positive_definite, mapping=mapping, **kwargs)
@@ -1623,12 +1642,68 @@ class ComplianceTensor(StiffnessTensor):
1623
1642
  return self.inv().Hill_average(axis=axis).inv()
1624
1643
 
1625
1644
  @classmethod
1626
- def isotropic(cls, E=None, nu=None, lame1=None, lame2=None, phase_name=None):
1627
- return super().isotropic(E=E, nu=nu, lame1=lame1, lame2=lame2, phase_name=None).inv()
1645
+ def isotropic(cls, E=None, nu=None, G=None, lame1=None, lame2=None, K=None, phase_name=None):
1646
+ if lame2 is not None:
1647
+ if G is None:
1648
+ G = lame2
1649
+ else:
1650
+ raise ValueError('G and lame2 cannot be provided together.')
1651
+ n_specified = sum(v is not None for v in [E, nu, lame1, G, K])
1652
+ if n_specified != 2:
1653
+ raise ValueError("Exactly two values are required among E, nu, G, K, lame1 and lame2.")
1654
+ if K is not None:
1655
+ if E is not None:
1656
+ G = 3 * K * E / (9 * K - E)
1657
+ nu = (3 * K - E) / 6 / K
1658
+ elif lame1 is not None:
1659
+ E = 9 * K * (K - lame1) / (3 * K -lame1)
1660
+ G= 3 * (K - lame1) / 2
1661
+ nu = lame1 / (3*K-lame1)
1662
+ elif G is not None:
1663
+ E = 9 * K * G / (3 * K + G)
1664
+ nu = (3 * K - 2 * G) / 2 / (3 * K + G)
1665
+ elif nu is not None:
1666
+ E = 3 * K * (1 - 2 * nu)
1667
+ G = E / 2 / (1 + nu)
1668
+ elif E is not None:
1669
+ if lame1 is not None:
1670
+ R = np.sqrt(E**2 + 9*lame1**2+2*E*lame1)
1671
+ G = (E - 3 * lame1 + R) / 4
1672
+ nu = 2 * lame1 / (E + lame1 + R)
1673
+ elif G is not None:
1674
+ nu = E / 2 / G - 1
1675
+ elif nu is not None:
1676
+ G = E / 2 / (1 + nu)
1677
+ elif lame1 is not None:
1678
+ if G is not None:
1679
+ E = G * (3 * lame1 + 2 * G) / (lame1 + G)
1680
+ nu = lame1 / 2 / (lame1 + G)
1681
+ elif nu is not None:
1682
+ E = lame1 * ( 1 + nu) * (1 - 2 * nu) / nu
1683
+ G = lame1 * (1 - 2 * nu) / 2 / nu
1684
+ elif (nu is not None) and (G is not None):
1685
+ E = 2 * G * (1 + nu)
1686
+ S11 = 1/E
1687
+ S12 = -nu/E
1688
+ S44 = 1 / G
1689
+ S_mat = _isotropic_matrix(S11, S12, S44)
1690
+ return ComplianceTensor(S_mat, symmetry='isotropic', phase_name=phase_name)
1628
1691
 
1629
1692
  @classmethod
1630
- def orthotropic(cls, *args, **kwargs):
1631
- return super().orthotropic(*args, **kwargs).inv()
1693
+ def orthotropic(cls, *, Ex, Ey, Ez, Gxy, Gxz, Gyz,
1694
+ nu_yx=None, nu_zx=None, nu_zy=None,
1695
+ nu_xy=None, nu_xz=None, nu_yz=None, **kwargs):
1696
+ nu_yx = _switch_poisson_ratios(nu_xy, nu_yx, Ex, Ey,'xy')
1697
+ nu_zx = _switch_poisson_ratios(nu_xz, nu_zx, Ex, Ez,'xz')
1698
+ nu_zy = _switch_poisson_ratios(nu_yz, nu_zy, Ey, Ez,'yz')
1699
+ tri_sup = np.array([[1 / Ex, -nu_yx / Ey, -nu_zx / Ez, 0, 0, 0],
1700
+ [0, 1 / Ey, -nu_zy / Ez, 0, 0, 0],
1701
+ [0, 0, 1 / Ez, 0, 0, 0],
1702
+ [0, 0, 0, 1 / Gyz, 0, 0],
1703
+ [0, 0, 0, 0, 1 / Gxz, 0],
1704
+ [0, 0, 0, 0, 0, 1 / Gxy]])
1705
+ S = tri_sup + np.tril(tri_sup.T, -1)
1706
+ return ComplianceTensor(S, symmetry='orthotropic', **kwargs)
1632
1707
 
1633
1708
  @classmethod
1634
1709
  def transverse_isotropic(cls, *args, **kwargs):
@@ -1745,4 +1820,232 @@ class ComplianceTensor(StiffnessTensor):
1745
1820
  --------
1746
1821
  eig_compliances : compute the eigencompliances from the Kelvin's matrix of compliance
1747
1822
  """
1748
- return 1/self.eig_compliances
1823
+ return 1/self.eig_compliances
1824
+
1825
+ @property
1826
+ def lame1(self):
1827
+ return self.inv().lame1
1828
+
1829
+ @property
1830
+ def lame2(self):
1831
+ return self.inv().lame2
1832
+
1833
+
1834
+ @classmethod
1835
+ def hexagonal(cls, *, S11=0., S12=0., S13=0., S33=0., S44=0., phase_name=None):
1836
+ """
1837
+ Create a fourth-order tensor from hexagonal symmetry.
1838
+
1839
+ Parameters
1840
+ ----------
1841
+ S11, S12 , S13, S33, S44 : float
1842
+ Components of the tensor, using the Voigt notation
1843
+ phase_name : str, optional
1844
+ Phase name to display
1845
+ Returns
1846
+ -------
1847
+ FourthOrderTensor
1848
+
1849
+ See Also
1850
+ --------
1851
+ transverse_isotropic : creates a transverse-isotropic tensor from engineering parameters
1852
+ cubic : create a tensor from cubic symmetry
1853
+ tetragonal : create a tensor from tetragonal symmetry
1854
+ """
1855
+ return cls._fromCrystalSymmetry(symmetry='hexagonal', S11=S11, S12=S12, S13=S13, S33=S33, S44=S44,
1856
+ phase_name=phase_name, prefix='S')
1857
+
1858
+ @classmethod
1859
+ def trigonal(cls, *, S11=0., S12=0., S13=0., S14=0., S33=0., S44=0., S15=0., phase_name=None):
1860
+ """
1861
+ Create a fourth-order tensor from trigonal symmetry.
1862
+
1863
+ Parameters
1864
+ ----------
1865
+ S11, S12, S13, S14, S33, S44 : float
1866
+ Components of the tensor, using the Voigt notation
1867
+ S15 : float, optional
1868
+ S15 component of the tensor, only used for point groups 3 and -3.
1869
+ phase_name : str, optional
1870
+ Phase name to display
1871
+ Returns
1872
+ -------
1873
+ FourthOrderTensor
1874
+
1875
+ See Also
1876
+ --------
1877
+ tetragonal : create a tensor from tetragonal symmetry
1878
+ orthorhombic : create a tensor from orthorhombic symmetry
1879
+ """
1880
+ return cls._fromCrystalSymmetry(symmetry='trigonal', point_group='3',
1881
+ S11=S11, S12=S12, S13=S13, S14=S14, S15=S15,
1882
+ S33=S33, S44=S44, phase_name=phase_name, prefix='S')
1883
+
1884
+ @classmethod
1885
+ def tetragonal(cls, *, S11=0., S12=0., S13=0., S33=0., S44=0., S16=0., S66=0., phase_name=None):
1886
+ """
1887
+ Create a fourth-order tensor from tetragonal symmetry.
1888
+
1889
+ Parameters
1890
+ ----------
1891
+ S11, S12, S13, S33, S44, S66 : float
1892
+ Components of the tensor, using the Voigt notation
1893
+ S16 : float, optional
1894
+ S16 component in Voigt notation (for point groups 4, -4 and 4/m only)
1895
+ phase_name : str, optional
1896
+ Phase name to display
1897
+
1898
+ Returns
1899
+ -------
1900
+ FourthOrderTensor
1901
+
1902
+ See Also
1903
+ --------
1904
+ trigonal : create a tensor from trigonal symmetry
1905
+ orthorhombic : create a tensor from orthorhombic symmetry
1906
+ """
1907
+ return cls._fromCrystalSymmetry(symmetry='tetragonal', point_group='4',
1908
+ S11=S11, S12=S12, S13=S13, S16=S16,
1909
+ S33=S33, S44=S44, S66=S66, phase_name=phase_name, prefix='S')
1910
+
1911
+ @classmethod
1912
+ def cubic(cls, *, S11=0., S12=0., S44=0., phase_name=None):
1913
+ """
1914
+ Create a fourth-order tensor from cubic symmetry.
1915
+
1916
+ Parameters
1917
+ ----------
1918
+ S11 , S12, S44 : float
1919
+ phase_name : str, optional
1920
+ Phase name to display
1921
+
1922
+ Returns
1923
+ -------
1924
+ StiffnessTensor
1925
+
1926
+ See Also
1927
+ --------
1928
+ hexagonal : create a tensor from hexagonal symmetry
1929
+ orthorhombic : create a tensor from orthorhombic symmetry
1930
+ """
1931
+ return cls._fromCrystalSymmetry(symmetry='cubic', S11=S11, S12=S12, S44=S44, phase_name=phase_name, prefix='S')
1932
+
1933
+ @classmethod
1934
+ def orthorhombic(cls, *, S11=0., S12=0., S13=0., S22=0., S23=0., S33=0., S44=0., S55=0., S66=0., phase_name=None):
1935
+ """
1936
+ Create a fourth-order tensor from orthorhombic symmetry.
1937
+
1938
+ Parameters
1939
+ ----------
1940
+ S11, S12, S13, S22, S23, S33, S44, S55, S66 : float
1941
+ Components of the tensor, using the Voigt notation
1942
+ phase_name : str, optional
1943
+ Phase name to display
1944
+
1945
+ Returns
1946
+ -------
1947
+ FourthOrderTensor
1948
+
1949
+ See Also
1950
+ --------
1951
+ monoclinic : create a tensor from monoclinic symmetry
1952
+ orthorhombic : create a tensor from orthorhombic symmetry
1953
+ """
1954
+ return cls._fromCrystalSymmetry(symmetry='orthorhombic',
1955
+ S11=S11, S12=S12, S13=S13, S22=S22, S23=S23, S33=S33, S44=S44, S55=S55, S66=S66,
1956
+ phase_name=phase_name, prefix='S')
1957
+
1958
+ @classmethod
1959
+ def monoclinic(cls, *, S11=0., S12=0., S13=0., S22=0., S23=0., S33=0., S44=0., S55=0., S66=0.,
1960
+ S15=None, S25=None, S35=None, S46=None,
1961
+ S16=None, S26=None, S36=None, S45=None,
1962
+ phase_name=None):
1963
+ """
1964
+ Create a fourth-order tensor from monoclinic symmetry. It automatically detects whether the components are given
1965
+ according to the Y or Z diad, depending on the input arguments.
1966
+
1967
+ For Diad || y, S15, S25, S35 and S46 must be provided.
1968
+ For Diad || z, S16, S26, S36 and S45 must be provided.
1969
+
1970
+ Parameters
1971
+ ----------
1972
+ S11, S12 , S13, S22, S23, S33, S44, S55, S66 : float
1973
+ Components of the tensor, using the Voigt notation
1974
+ S15 : float, optional
1975
+ S15 component of the tensor (if Diad || y)
1976
+ S25 : float, optional
1977
+ S25 component of the tensor (if Diad || y)
1978
+ S35 : float, optional
1979
+ S35 component of the tensor (if Diad || y)
1980
+ S46 : float, optional
1981
+ S46 component of the tensor (if Diad || y)
1982
+ S16 : float, optional
1983
+ S16 component of the tensor (if Diad || z)
1984
+ S26 : float, optional
1985
+ S26 component of the tensor (if Diad || z)
1986
+ S36 : float, optional
1987
+ S36 component of the tensor (if Diad || z)
1988
+ S45 : float, optional
1989
+ S45 component of the tensor (if Diad || z)
1990
+ phase_name : str, optional
1991
+ Name to display
1992
+
1993
+ Returns
1994
+ -------
1995
+ FourthOrderTensor
1996
+
1997
+ See Also
1998
+ --------
1999
+ triclinic : create a tensor from triclinic symmetry
2000
+ orthorhombic : create a tensor from orthorhombic symmetry
2001
+ """
2002
+ diad_y = not (None in (S15, S25, S35, S46))
2003
+ diad_z = not (None in (S16, S26, S36, S45))
2004
+ if diad_y and diad_z:
2005
+ raise KeyError('Ambiguous diad. Provide either S15, S25, S35 and S46; or S16, S26, S36 and S45')
2006
+ elif diad_y:
2007
+ return cls._fromCrystalSymmetry(symmetry='monoclinic', diad='y',
2008
+ S11=S11, S12=S12, S13=S13, S22=S22, S23=S23, S33=S33, S44=S44, S55=S55,
2009
+ S66=S66,
2010
+ S15=S15, S25=S25, S35=S35, S46=S46, phase_name=phase_name, prefix='S')
2011
+ elif diad_z:
2012
+ return cls._fromCrystalSymmetry(symmetry='monoclinic', diad='z',
2013
+ S11=S11, S12=S12, S13=S13, S22=S22, S23=S23, S33=S33, S44=S44, S55=S55,
2014
+ S66=S66,
2015
+ S16=S16, S26=S26, S36=S36, S45=S45, phase_name=phase_name, prefix='S')
2016
+ else:
2017
+ raise KeyError('For monoclinic symmetry, one should provide either S15, S25, S35 and S46, '
2018
+ 'or S16, S26, S36 and S45.')
2019
+
2020
+ @classmethod
2021
+ def triclinic(cls, S11=0., S12=0., S13=0., S14=0., S15=0., S16=0.,
2022
+ S22=0., S23=0., C24=0., S25=0., S26=0.,
2023
+ S33=0., C34=0., S35=0., S36=0.,
2024
+ S44=0., S45=0., S46=0.,
2025
+ S55=0., C56=0.,
2026
+ S66=0., phase_name=None):
2027
+ """
2028
+
2029
+ Parameters
2030
+ ----------
2031
+ S11 , S12 , S13 , S14 , S15 , S16 , S22 , S23 , C24 , S25 , S26 , S33 , C34 , S35 , S36 , S44 , S45 , S46 , S55 , C56 , S66 : float
2032
+ Components of the tensor
2033
+ phase_name : str, optional
2034
+ Name to display
2035
+
2036
+ Returns
2037
+ -------
2038
+ FourthOrderTensor
2039
+
2040
+ See Also
2041
+ --------
2042
+ monoclinic : create a tensor from monoclinic symmetry
2043
+ orthorhombic : create a tensor from orthorhombic symmetry
2044
+ """
2045
+ matrix = np.array([[S11, S12, S13, S14, S15, S16],
2046
+ [S12, S22, S23, C24, S25, S26],
2047
+ [S13, S23, S33, C34, S35, S36],
2048
+ [S14, C24, C34, S44, S45, S46],
2049
+ [S15, S25, S35, S45, S55, C56],
2050
+ [S16, S26, S36, S46, C56, S66]])
2051
+ return cls(matrix, phase_name=phase_name)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: elasticipy
3
- Version: 4.1.1
3
+ Version: 4.2.0
4
4
  Summary: A Python library for elasticity tensor computations
5
5
  Author-email: Dorian Depriester <dorian.dep@gmail.com>
6
6
  License: MIT
@@ -12,7 +12,6 @@ Classifier: Development Status :: 4 - Beta
12
12
  Classifier: Intended Audience :: Science/Research
13
13
  Classifier: License :: OSI Approved :: MIT License
14
14
  Classifier: Programming Language :: Python
15
- Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
17
16
  Classifier: Programming Language :: Python :: 3.12
18
17
  Requires-Python: >=3.11
@@ -40,6 +39,7 @@ Dynamic: license-file
40
39
  [![codecov](https://codecov.io/gh/DorianDepriester/Elasticipy/graph/badge.svg?token=VUZPEUPBH1)](https://codecov.io/gh/DorianDepriester/Elasticipy)
41
40
  ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/Elasticipy)
42
41
  [![status](https://joss.theoj.org/papers/8cce91b782f17f52e9ee30916cd86ad5/status.svg)](https://joss.theoj.org/papers/8cce91b782f17f52e9ee30916cd86ad5)
42
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/DorianDepriester/Elasticipy/HEAD?urlpath=%2Fdoc%2Ftree%2FElasticipy_for_the_Impatient.ipynb)
43
43
 
44
44
  # ![Elasticipy](docs/source/logo/logo_text.svg)
45
45
 
@@ -10,14 +10,14 @@ Elasticipy/spherical_function.py,sha256=Mnb4Cj2eyMCtr7X3mesqESml3BMA_JYT2H3eTZO-
10
10
  Elasticipy/interfaces/FEPX.py,sha256=MleuKz3JvjhvECIcg2q1taV0J1TzoiTrrtLeRRYI9Hs,4234
11
11
  Elasticipy/interfaces/PRISMS.py,sha256=jAHFS2ybbAK2ZcqF9AmnlDTR2JZZMwlgy-FhQIINSAI,3835
12
12
  Elasticipy/tensors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- Elasticipy/tensors/elasticity.py,sha256=vgpPA1FkehKuvSnPq4KEvddXpPgka1wGsp3AdjAdMB8,65000
13
+ Elasticipy/tensors/elasticity.py,sha256=MYJwbk_fjd3Zo8qdIkZ6atBuM5khEWXgPcFqnzACnwM,76393
14
14
  Elasticipy/tensors/fourth_order.py,sha256=ouptzPiWx5W6t9dYWfLY8lTVTj5ahnuB4mmBUIgLycs,23136
15
15
  Elasticipy/tensors/mapping.py,sha256=f-jwvCE2V3bgesIOyeC-vgqVCFJetlUviEAoaBE7yPA,1442
16
16
  Elasticipy/tensors/second_order.py,sha256=6jQiIfGgmW7OsBvhPEXeRXjIcuslqejFHmGjHdYaMsQ,55728
17
17
  Elasticipy/tensors/stress_strain.py,sha256=RysKDHe-PV2dpdrO7cNT1_UBP8bYYCbWxz3H9w9GuPo,3954
18
18
  Elasticipy/tensors/thermal_expansion.py,sha256=XZ9e8Sn9vsLGVh79TrBQoBOkXMg8qF3pShiPSzix4q0,8634
19
- elasticipy-4.1.1.dist-info/licenses/LICENSE,sha256=qNthTMSjVkIDM1_BREgVFQHdn1wVNQi9pwWVfTIazMA,1074
20
- elasticipy-4.1.1.dist-info/METADATA,sha256=3OJs1eydCV7Q_L-vQd57Q1c1x-CmSRst4L5S4QYZKF4,4487
21
- elasticipy-4.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
- elasticipy-4.1.1.dist-info/top_level.txt,sha256=k4zSQzJR5P4vzlHlhWUaxNgvgloq4KIp8oca2X8gQOw,11
23
- elasticipy-4.1.1.dist-info/RECORD,,
19
+ elasticipy-4.2.0.dist-info/licenses/LICENSE,sha256=qNthTMSjVkIDM1_BREgVFQHdn1wVNQi9pwWVfTIazMA,1074
20
+ elasticipy-4.2.0.dist-info/METADATA,sha256=WhpptfQ8jWqIvdoG5ikCnkuhwpwAinRIj6mXFAy6J90,4605
21
+ elasticipy-4.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
+ elasticipy-4.2.0.dist-info/top_level.txt,sha256=k4zSQzJR5P4vzlHlhWUaxNgvgloq4KIp8oca2X8gQOw,11
23
+ elasticipy-4.2.0.dist-info/RECORD,,