elasticipy 3.0.0__tar.gz → 4.0.0__tar.gz

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.
Files changed (106) hide show
  1. {elasticipy-3.0.0 → elasticipy-4.0.0}/Examples/Elasticipy_vs_pymatgen.py +2 -4
  2. {elasticipy-3.0.0 → elasticipy-4.0.0}/Examples/Elate_vs_Elasticipy.py +2 -2
  3. {elasticipy-3.0.0 → elasticipy-4.0.0}/Examples/Example_Stiffness_tensor.py +1 -1
  4. {elasticipy-3.0.0 → elasticipy-4.0.0}/Examples/Example_StressStrain_arrays.py +2 -2
  5. {elasticipy-3.0.0 → elasticipy-4.0.0}/Examples/Example_WaveVelocity.py +1 -2
  6. {elasticipy-3.0.0 → elasticipy-4.0.0}/Examples/Multiple_phases.py +1 -1
  7. elasticipy-4.0.0/Examples/SelfConsistent.py +89 -0
  8. {elasticipy-3.0.0 → elasticipy-4.0.0}/Examples/essai_plasticity.py +3 -3
  9. {elasticipy-3.0.0 → elasticipy-4.0.0}/Examples/example_readwrite.py +1 -1
  10. {elasticipy-3.0.0 → elasticipy-4.0.0}/JOSS/paper.md +8 -5
  11. {elasticipy-3.0.0/src/elasticipy.egg-info → elasticipy-4.0.0}/PKG-INFO +5 -5
  12. {elasticipy-3.0.0 → elasticipy-4.0.0}/README.md +2 -3
  13. elasticipy-4.0.0/docs/source/Elasticipy.plasticity.rst +7 -0
  14. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Elasticipy.rst +7 -5
  15. elasticipy-4.0.0/docs/source/Elasticipy.spherical_function.rst +7 -0
  16. elasticipy-4.0.0/docs/source/Elasticipy.tensors.elasticity.rst +7 -0
  17. elasticipy-4.0.0/docs/source/Elasticipy.tensors.fourth_order.rst +7 -0
  18. elasticipy-4.0.0/docs/source/Elasticipy.tensors.second_order.rst +7 -0
  19. elasticipy-4.0.0/docs/source/Elasticipy.tensors.stress_strain.rst +7 -0
  20. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/Plasticity.rst +30 -3
  21. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/Tutorial_AveragingMethods.rst +2 -2
  22. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/Tutorial_MultiplePhases.rst +1 -1
  23. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/Tutorial_ReadWriteFiles.rst +3 -2
  24. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/Tutorial_StiffnessTensor.rst +1 -1
  25. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/Tutorial_StressStrain.rst +6 -5
  26. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/Tutorial_ThermalExpansion.rst +1 -1
  27. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/Tutorial_wave-velocities.rst +3 -2
  28. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/conf.py +2 -0
  29. elasticipy-4.0.0/docs/source/logo/favicon.png +0 -0
  30. elasticipy-4.0.0/docs/source/logo/logo.png +0 -0
  31. elasticipy-4.0.0/docs/source/logo/logo.svg +100 -0
  32. elasticipy-4.0.0/docs/source/logo/logo_text.png +0 -0
  33. elasticipy-4.0.0/docs/source/logo/logo_text.svg +126 -0
  34. elasticipy-4.0.0/docs/source/logo/logo_text_whitebg.png +0 -0
  35. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/modules.rst +1 -1
  36. elasticipy-4.0.0/src/Elasticipy/FourthOrderTensor.py +16 -0
  37. elasticipy-4.0.0/src/Elasticipy/StressStrainTensors.py +16 -0
  38. elasticipy-4.0.0/src/Elasticipy/ThermalExpansion.py +12 -0
  39. {elasticipy-3.0.0 → elasticipy-4.0.0}/src/Elasticipy/gui.py +2 -2
  40. elasticipy-3.0.0/src/Elasticipy/Plasticity.py → elasticipy-4.0.0/src/Elasticipy/plasticity.py +1 -1
  41. elasticipy-3.0.0/src/Elasticipy/SphericalFunction.py → elasticipy-4.0.0/src/Elasticipy/spherical_function.py +1 -1
  42. elasticipy-3.0.0/src/Elasticipy/FourthOrderTensor.py → elasticipy-4.0.0/src/Elasticipy/tensors/elasticity.py +389 -512
  43. elasticipy-4.0.0/src/Elasticipy/tensors/fourth_order.py +591 -0
  44. elasticipy-3.0.0/src/Elasticipy/SecondOrderTensor.py → elasticipy-4.0.0/src/Elasticipy/tensors/second_order.py +6 -6
  45. elasticipy-3.0.0/src/Elasticipy/StressStrainTensors.py → elasticipy-4.0.0/src/Elasticipy/tensors/stress_strain.py +1 -1
  46. elasticipy-3.0.0/src/Elasticipy/ThermalExpansion.py → elasticipy-4.0.0/src/Elasticipy/tensors/thermal_expansion.py +2 -2
  47. {elasticipy-3.0.0 → elasticipy-4.0.0/src/elasticipy.egg-info}/PKG-INFO +5 -5
  48. {elasticipy-3.0.0 → elasticipy-4.0.0}/src/elasticipy.egg-info/SOURCES.txt +24 -10
  49. elasticipy-4.0.0/tests/__init__.py +0 -0
  50. elasticipy-4.0.0/tests/test_FourthOrderTensors.py +112 -0
  51. {elasticipy-3.0.0 → elasticipy-4.0.0}/tests/test_SphericalFunction.py +2 -2
  52. {elasticipy-3.0.0 → elasticipy-4.0.0}/tests/test_StiffnessTensor.py +214 -80
  53. {elasticipy-3.0.0 → elasticipy-4.0.0}/tests/test_StressStrainTensors.py +13 -6
  54. {elasticipy-3.0.0 → elasticipy-4.0.0}/tests/test_ThermalExpansion.py +7 -1
  55. {elasticipy-3.0.0 → elasticipy-4.0.0}/tests/test_plasticity.py +3 -3
  56. elasticipy-3.0.0/docs/source/Elasticipy.FourthOrderTensor.rst +0 -7
  57. elasticipy-3.0.0/docs/source/Elasticipy.Plasticity.rst +0 -7
  58. elasticipy-3.0.0/docs/source/Elasticipy.SecondOrderTensor.rst +0 -7
  59. elasticipy-3.0.0/docs/source/Elasticipy.SphericalFunction.rst +0 -7
  60. elasticipy-3.0.0/docs/source/Elasticipy.StressStrainTensors.rst +0 -7
  61. {elasticipy-3.0.0 → elasticipy-4.0.0}/.github/workflows/Codecov.yml +0 -0
  62. {elasticipy-3.0.0 → elasticipy-4.0.0}/.github/workflows/JOSS build.yml +0 -0
  63. {elasticipy-3.0.0 → elasticipy-4.0.0}/.github/workflows/cloc.yml +0 -0
  64. {elasticipy-3.0.0 → elasticipy-4.0.0}/.github/workflows/python-publish.yml +0 -0
  65. {elasticipy-3.0.0 → elasticipy-4.0.0}/.readthedocs.yaml +0 -0
  66. {elasticipy-3.0.0 → elasticipy-4.0.0}/CODE_OF_CONDUCT.md +0 -0
  67. {elasticipy-3.0.0 → elasticipy-4.0.0}/CONTRIBUTING.md +0 -0
  68. {elasticipy-3.0.0 → elasticipy-4.0.0}/Examples/MaterialsProject.json +0 -0
  69. {elasticipy-3.0.0 → elasticipy-4.0.0}/JOSS/ElasticipyVSpymatgen.png +0 -0
  70. {elasticipy-3.0.0 → elasticipy-4.0.0}/JOSS/Nye.png +0 -0
  71. {elasticipy-3.0.0 → elasticipy-4.0.0}/JOSS/Plot_E.png +0 -0
  72. {elasticipy-3.0.0 → elasticipy-4.0.0}/JOSS/YoungModulus.png +0 -0
  73. {elasticipy-3.0.0 → elasticipy-4.0.0}/JOSS/paper.bib +0 -0
  74. {elasticipy-3.0.0 → elasticipy-4.0.0}/LICENSE +0 -0
  75. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/_static/images/HyperSphericalCoordinates.png +0 -0
  76. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/index.rst +0 -0
  77. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/GUI.rst +0 -0
  78. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/Cyclic.png +0 -0
  79. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/E_PF.png +0 -0
  80. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/E_VRH_sections.png +0 -0
  81. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/E_hill_fiber.png +0 -0
  82. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/E_plot3D.png +0 -0
  83. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/E_xyz_sections.png +0 -0
  84. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/GUI.png +0 -0
  85. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/G_plot3D.png +0 -0
  86. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/G_plot3D_min.png +0 -0
  87. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/G_xyz_sections.png +0 -0
  88. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/Incremental.png +0 -0
  89. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/Shear.png +0 -0
  90. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/Stress-controlled.png +0 -0
  91. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/StressStrain-controlled.png +0 -0
  92. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/WaveVelocities.png +0 -0
  93. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/plot_volumeFraction.png +0 -0
  94. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/Tutorials.rst +0 -0
  95. {elasticipy-3.0.0 → elasticipy-4.0.0}/docs/source/index.rst +0 -0
  96. {elasticipy-3.0.0 → elasticipy-4.0.0}/pyproject.toml +0 -0
  97. {elasticipy-3.0.0 → elasticipy-4.0.0}/requirements.txt +0 -0
  98. {elasticipy-3.0.0 → elasticipy-4.0.0}/setup.cfg +0 -0
  99. {elasticipy-3.0.0 → elasticipy-4.0.0}/src/Elasticipy/__init__.py +0 -0
  100. /elasticipy-3.0.0/src/Elasticipy/CrystalSymmetries.py → /elasticipy-4.0.0/src/Elasticipy/crystal_symmetries.py +0 -0
  101. /elasticipy-3.0.0/src/Elasticipy/PoleFigure.py → /elasticipy-4.0.0/src/Elasticipy/polefigure.py +0 -0
  102. {elasticipy-3.0.0/tests → elasticipy-4.0.0/src/Elasticipy/tensors}/__init__.py +0 -0
  103. {elasticipy-3.0.0 → elasticipy-4.0.0}/src/elasticipy.egg-info/dependency_links.txt +0 -0
  104. {elasticipy-3.0.0 → elasticipy-4.0.0}/src/elasticipy.egg-info/requires.txt +0 -0
  105. {elasticipy-3.0.0 → elasticipy-4.0.0}/src/elasticipy.egg-info/top_level.txt +0 -0
  106. {elasticipy-3.0.0 → elasticipy-4.0.0}/tests/MaterialsProject.json +0 -0
@@ -1,7 +1,5 @@
1
- from docutils.utils.math.latex2mathml import layout_styles
2
-
3
- from Elasticipy.StressStrainTensors import StrainTensor
4
- from Elasticipy.FourthOrderTensor import StiffnessTensor
1
+ from Elasticipy.tensors.stress_strain import StrainTensor
2
+ from Elasticipy.tensors.elasticity import StiffnessTensor
5
3
  from matplotlib import pyplot as plt
6
4
  import matplotlib as mpl
7
5
  mpl.use('Qt5Agg') # Ensure interactive plot
@@ -1,9 +1,9 @@
1
1
  import numpy as np
2
2
  from elastic import Elastic
3
- from Elasticipy.FourthOrderTensor import StiffnessTensor
3
+ from Elasticipy.tensors.elasticity import StiffnessTensor
4
4
  import matplotlib as mpl
5
5
  mpl.use('Qt5Agg') # Ensure interactive plot
6
- from Elasticipy.SphericalFunction import sph2cart, _plot3D
6
+ from Elasticipy.spherical_function import sph2cart, _plot3D
7
7
  import time
8
8
  import matplotlib.pyplot as plt
9
9
 
@@ -1,4 +1,4 @@
1
- from Elasticipy.FourthOrderTensor import StiffnessTensor
1
+ from Elasticipy.tensors.elasticity import StiffnessTensor
2
2
  from scipy.spatial.transform import Rotation
3
3
  import matplotlib as mpl
4
4
  mpl.use('Qt5Agg') # Ensure interactive plot
@@ -2,7 +2,7 @@
2
2
  # Imports and simple example of stress
3
3
  # ======================================================
4
4
  import numpy as np
5
- from Elasticipy.StressStrainTensors import StressTensor, StrainTensor
5
+ from Elasticipy.tensors.stress_strain import StressTensor, StrainTensor
6
6
 
7
7
 
8
8
  stress = StressTensor([[0, 1, 0],
@@ -23,7 +23,7 @@ print(strain.volumetric_strain())
23
23
  # ======================================================
24
24
  # Linear elasticity
25
25
  # ======================================================
26
- from Elasticipy.FourthOrderTensor import StiffnessTensor
26
+ from Elasticipy.tensors.elasticity import StiffnessTensor
27
27
 
28
28
  C = StiffnessTensor.fromCrystalSymmetry(symmetry='cubic', phase_name='ferrite',
29
29
  C11=274, C12=175, C44=89)
@@ -1,7 +1,6 @@
1
- from Elasticipy.FourthOrderTensor import StiffnessTensor
1
+ from Elasticipy.tensors.elasticity import StiffnessTensor
2
2
  import matplotlib as mpl
3
3
  mpl.use('Qt5Agg') # Ensure interactive plot
4
- from matplotlib import pyplot as plt
5
4
 
6
5
  C = StiffnessTensor.fromCrystalSymmetry(symmetry='orthorombic', phase_name='forsterite',
7
6
  C11=320, C12=68.2, C13=71.6,
@@ -1,4 +1,4 @@
1
- from Elasticipy.FourthOrderTensor import StiffnessTensor
1
+ from Elasticipy.tensors.elasticity import StiffnessTensor
2
2
  import numpy as np
3
3
  from matplotlib import pyplot as plt
4
4
 
@@ -0,0 +1,89 @@
1
+ import numpy as np
2
+ from Elasticipy.tensors.fourth_order import FourthOrderTensor
3
+ from Elasticipy.tensors.elasticity import StiffnessTensor
4
+ from scipy.integrate import trapezoid
5
+ from scipy.spatial.transform import Rotation
6
+
7
+ I = FourthOrderTensor.identity()
8
+
9
+ def gamma(C_macro_local, phi, theta, a1, a2, a3):
10
+ s1 = np.sin(theta)*np.cos(phi) / a1
11
+ s2 = np.sin(theta)*np.sin(phi) / a2
12
+ s3 = np.cos(theta) / a3
13
+ s = np.array([s1, s2, s3])
14
+ D = np.einsum('lmnp,pqr,lqr->qrmn', C_macro_local.full_tensor(), s, s)
15
+ Dinv = np.linalg.inv(D)
16
+ return np.einsum('qrjk,iqr,lqr->qrijkl', Dinv, s, s) # The symmetrization is made afterward (see below)
17
+
18
+ def polarization_tensor(C_macro_local, a1, a2, a3, n_phi, n_theta):
19
+ theta = np.linspace(0, np.pi, n_theta)
20
+ phi = np.linspace(0, 2 * np.pi, n_phi)
21
+ phi_grid, theta_grid = np.meshgrid(phi, theta, indexing='ij')
22
+ g = gamma(C_macro_local, phi_grid, theta_grid, a1, a2, a3)
23
+ gsin = (g.T*np.sin(theta_grid.T)).T
24
+ a = trapezoid(gsin, phi, axis=0)
25
+ b= trapezoid(a, theta, axis=0)/(4*np.pi)
26
+ return FourthOrderTensor(b, force_minor_symmetry=True) # Symmetrization here (see above)
27
+
28
+ def localization_tensor(C_macro_local, C_incl, n_phi, n_theta, a1, a2, a3):
29
+ E = polarization_tensor(C_macro_local, a1, a2, a3, n_phi, n_theta)
30
+ delta = FourthOrderTensor(C_incl.matrix - C_macro_local.matrix)
31
+ Ainv = E.ddot(delta) + I
32
+ return Ainv.inv()
33
+
34
+ def Kroner_Eshelby(Ci, g, method='strain', max_iter=5, atol=1e-3, rtol=1e-3, display=False, n_phi=100, n_theta=100, particle_size=None):
35
+ Ci_rotated = (Ci * g)
36
+ C_macro = Ci_rotated.Hill_average()
37
+ eigen_stiff = C_macro.eig_stiffnesses
38
+ keep_on = True
39
+ k = 0
40
+ message = 'Maximum number of iterations is reached'
41
+ m = len(g)
42
+ A_local = FourthOrderTensor.zeros(m)
43
+ if particle_size is None:
44
+ a1 = a2 = a3 = 1
45
+ else:
46
+ a1, a2, a3 = particle_size
47
+ while keep_on:
48
+ eigen_stiff_old = eigen_stiff
49
+ C_macro_local = C_macro * (g.inv())
50
+ for i in range(m):
51
+ A_local[i] = localization_tensor(C_macro_local[i], Ci, n_phi, n_theta, a1, a2, a3)
52
+ A = A_local * g
53
+ Q = Ci_rotated.ddot(A)
54
+ if method=='stress':
55
+ CiAi_mean = Q.mean()
56
+ C_macro = StiffnessTensor.from_Kelvin(CiAi_mean.matrix, force_symmetries=True)
57
+ err = A.mean() - FourthOrderTensor.identity()
58
+ else:
59
+ B = Q.ddot(C_macro.inv())
60
+ R = Ci_rotated.inv().ddot(B)
61
+ R_mean = R.mean()
62
+ C_macro = StiffnessTensor.from_Kelvin(R_mean.inv().matrix, force_symmetries=True)
63
+ err = B.mean() - FourthOrderTensor.identity()
64
+
65
+ # Stopping criteria
66
+ eigen_stiff = C_macro.eig_stiffnesses
67
+ abs_change = np.abs(eigen_stiff - eigen_stiff_old)
68
+ rel_change = np.max(abs_change / eigen_stiff_old)
69
+ max_abs_change = np.max(abs_change)
70
+ k += 1
71
+ if max_abs_change < atol:
72
+ keep_on = False
73
+ message = 'Absolute change is below threshold value'
74
+ if rel_change < rtol:
75
+ keep_on = False
76
+ message = 'Relative change is below threshold value'
77
+ if k == max_iter:
78
+ keep_on = False
79
+ if display:
80
+ err = np.max(np.abs(err.matrix))
81
+ print('Iter #{}: abs. change={:0.5f}; rel. change={:0.5f}; error={:0.5f}'.format(k, max_abs_change, rel_change,err))
82
+ return C_macro, message
83
+
84
+ Cstrip = StiffnessTensor.transverse_isotropic(Ex= 10.2, Ez=146.8, nu_zx=0.274, nu_yx=0.355, Gxz=7)
85
+ Cstrip = Cstrip * Rotation.from_euler('Y', 90, degrees=True)
86
+ #orientations = Rotation.from_euler('Z', np.linspace(0, 180, 10, endpoint=False), degrees=True)
87
+ orientations = Rotation.random(100, random_state=1234)
88
+ Cstrip = StiffnessTensor.cubic(C11=186, C12=134, C44=77)
89
+ C_stress, reason = Kroner_Eshelby(Cstrip, orientations, display=True, method='strain')
@@ -1,6 +1,6 @@
1
- from Elasticipy.Plasticity import JohnsonCook
2
- from Elasticipy.StressStrainTensors import StressTensor, StrainTensor
3
- from Elasticipy.FourthOrderTensor import StiffnessTensor
1
+ from Elasticipy.plasticity import JohnsonCook
2
+ from Elasticipy.tensors.stress_strain import StressTensor, StrainTensor
3
+ from Elasticipy.tensors.elasticity import StiffnessTensor
4
4
  import numpy as np
5
5
  from matplotlib import pyplot as plt
6
6
  import matplotlib as mpl
@@ -1,4 +1,4 @@
1
- from Elasticipy.FourthOrderTensor import StiffnessTensor
1
+ from Elasticipy.tensors.elasticity import StiffnessTensor
2
2
 
3
3
  C = StiffnessTensor.from_MP("mp-1048")
4
4
  C.save_to_txt("TiNi.txt")
@@ -142,7 +142,9 @@ with ease. It already implements thermal expansion.
142
142
  \autoref{fig:Young}.a) and b) were rendered with the following syntax:
143
143
 
144
144
  ````python
145
- from Elasticipy.FourthOrderTensor import StiffnessTensor
145
+
146
+ from Elasticipy.tensors.elasticity import StiffnessTensor
147
+
146
148
  C = StiffnessTensor.cubic(C11=186, C12=134, C44=77)
147
149
  E = C.Young_modulus
148
150
  E.plot3D(n_phi=500, n_theta=500)
@@ -181,10 +183,11 @@ Efforts have been made to provide out-of-the-box simple syntaxes for common oper
181
183
  will create a tensor array corresponding to evenly-spaced strain along $[1,0,0]$ axis:
182
184
 
183
185
  ````python
184
- from Elasticipy.StressStrainTensors import StrainTensor
185
- m = 1000 # length of tensor array
186
- mag = np.linspace(0, 0.1, m) # Strain magnitude
187
- strain = StrainTensor.tensile([1,0,0], mag)
186
+ from Elasticipy.tensors.stress_strain import StrainTensor
187
+
188
+ m = 1000 # length of tensor array
189
+ mag = np.linspace(0, 0.1, m) # Strain magnitude
190
+ strain = StrainTensor.tensile([1, 0, 0], mag)
188
191
  ````
189
192
 
190
193
  Given the stiffness tensor ``C`` (see above), one can compute the corresponding stress array with:
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: elasticipy
3
- Version: 3.0.0
3
+ Version: 4.0.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
@@ -27,8 +27,8 @@ Requires-Dist: pytest-cov; extra == "dev"
27
27
  Requires-Dist: pymatgen; extra == "dev"
28
28
  Requires-Dist: orix; extra == "dev"
29
29
  Requires-Dist: mp_api; extra == "dev"
30
+ Dynamic: license-file
30
31
 
31
- # Elasticipy
32
32
  [![PyPI - Version](https://img.shields.io/pypi/v/Elasticipy?link=https%3A%2F%2Fpypi.org%2Fproject%2FElasticipy%2F)](https://pypi.org/project/elasticipy/)
33
33
  [![PyPI - Downloads](https://img.shields.io/pypi/dm/Elasticipy?link=https%3A%2F%2Fpypi.org%2Fproject%2FElasticipy%2F)](https://pypistats.org/packages/elasticipy)
34
34
  [![PyPI - License](https://img.shields.io/pypi/l/Elasticipy)](https://github.com/DorianDepriester/Elasticipy/blob/main/LICENSE)
@@ -38,9 +38,9 @@ Requires-Dist: mp_api; extra == "dev"
38
38
  ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/Elasticipy)
39
39
  [![status](https://joss.theoj.org/papers/8cce91b782f17f52e9ee30916cd86ad5/status.svg)](https://joss.theoj.org/papers/8cce91b782f17f52e9ee30916cd86ad5)
40
40
 
41
+ # ![Elasticipy](docs/source/logo/logo_text.svg)
41
42
 
42
-
43
- A python toolkit to manipulate strain and strain tensors, and other linear elasticity-related tensors (e.g. stiffness).
43
+ A python toolkit to manipulate stress and strain tensors, and other linear elasticity-related tensors (e.g. stiffness).
44
44
  This package also provides a collection of easy-to-use and very fast tools to work on stress and strain tensors.
45
45
 
46
46
  ## Main features
@@ -1,4 +1,3 @@
1
- # Elasticipy
2
1
  [![PyPI - Version](https://img.shields.io/pypi/v/Elasticipy?link=https%3A%2F%2Fpypi.org%2Fproject%2FElasticipy%2F)](https://pypi.org/project/elasticipy/)
3
2
  [![PyPI - Downloads](https://img.shields.io/pypi/dm/Elasticipy?link=https%3A%2F%2Fpypi.org%2Fproject%2FElasticipy%2F)](https://pypistats.org/packages/elasticipy)
4
3
  [![PyPI - License](https://img.shields.io/pypi/l/Elasticipy)](https://github.com/DorianDepriester/Elasticipy/blob/main/LICENSE)
@@ -8,9 +7,9 @@
8
7
  ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/Elasticipy)
9
8
  [![status](https://joss.theoj.org/papers/8cce91b782f17f52e9ee30916cd86ad5/status.svg)](https://joss.theoj.org/papers/8cce91b782f17f52e9ee30916cd86ad5)
10
9
 
10
+ # ![Elasticipy](docs/source/logo/logo_text.svg)
11
11
 
12
-
13
- A python toolkit to manipulate strain and strain tensors, and other linear elasticity-related tensors (e.g. stiffness).
12
+ A python toolkit to manipulate stress and strain tensors, and other linear elasticity-related tensors (e.g. stiffness).
14
13
  This package also provides a collection of easy-to-use and very fast tools to work on stress and strain tensors.
15
14
 
16
15
  ## Main features
@@ -0,0 +1,7 @@
1
+ Elasticipy.plasticity module
2
+ ============================
3
+
4
+ .. automodule:: Elasticipy.plasticity
5
+ :members:
6
+ :undoc-members:
7
+ :show-inheritance:
@@ -7,11 +7,13 @@ Submodules
7
7
  .. toctree::
8
8
  :maxdepth: 4
9
9
 
10
- Elasticipy.FourthOrderTensor
11
- Elasticipy.SecondOrderTensor
12
- Elasticipy.SphericalFunction
13
- Elasticipy.StressStrainTensors
14
- Elasticipy.Plasticity
10
+ Elasticipy.tensors.fourth_order
11
+ Elasticipy.tensors.elasticity
12
+ Elasticipy.tensors.second_order
13
+ Elasticipy.tensors.stress_strain
14
+ Elasticipy.spherical_function
15
+ Elasticipy.plasticity
16
+
15
17
 
16
18
  Module contents
17
19
  ---------------
@@ -0,0 +1,7 @@
1
+ Elasticipy.spherical_function module
2
+ ====================================
3
+
4
+ .. automodule:: Elasticipy.spherical_function
5
+ :members:
6
+ :undoc-members:
7
+ :show-inheritance:
@@ -0,0 +1,7 @@
1
+ Elasticipy.tensors.elasticity module
2
+ ====================================
3
+
4
+ .. automodule:: Elasticipy.tensors.elasticity
5
+ :members:
6
+ :undoc-members:
7
+ :show-inheritance:
@@ -0,0 +1,7 @@
1
+ Elasticipy.tensors.fourth_order module
2
+ ======================================
3
+
4
+ .. automodule:: Elasticipy.tensors.fourth_order
5
+ :members:
6
+ :undoc-members:
7
+ :show-inheritance:
@@ -0,0 +1,7 @@
1
+ Elasticipy.tensors.second_order module
2
+ ======================================
3
+
4
+ .. automodule:: Elasticipy.tensors.second_order
5
+ :members:
6
+ :undoc-members:
7
+ :show-inheritance:
@@ -0,0 +1,7 @@
1
+ Elasticipy.tensors.stress_strain module
2
+ =======================================
3
+
4
+ .. automodule:: Elasticipy.tensors.stress_strain
5
+ :members:
6
+ :undoc-members:
7
+ :show-inheritance:
@@ -39,17 +39,44 @@ First, let us create the model:
39
39
 
40
40
  .. doctest::
41
41
 
42
- >>> from Elasticipy.Plasticity import JohnsonCook
42
+ >>> from Elasticipy.plasticity import JohnsonCook
43
43
  >>> JC = JohnsonCook(A=363, B=792.7122, n=0.5756)
44
44
 
45
45
  The parameters are taken from [1]_. As we will also take elastic behaviour into account, we also need:
46
46
 
47
- >>> from Elasticipy.FourthOrderTensor import StiffnessTensor
47
+ >>> from Elasticipy.tensors.elasticity import StiffnessTensor
48
48
  >>> C = StiffnessTensor.isotropic(E=210000, nu=0.27)
49
49
 
50
50
  Now, let say that we want to investigate the material's response for the tensile stress ranging from 0 to 725 MPa:
51
51
 
52
- >>> from Elasticipy.StressStrainTensors import StressTensor, StrainTensor
52
+ >>> from Elasticipy.tensors.stress_strain import StressTensor, StrainTensor
53
+ >>> import numpy as np
54
+ >>> n_step = 100
55
+ >>> stress_mag = np.linspace(0, 725, n_step)
56
+ >>> stress = StressTensor.tensile([1,0,0], stress_mag)
57
+
58
+ At least, we can directly compute the elastic strain for each step:
59
+
60
+ >>> elastic_strain = C.inv() * stress
61
+
62
+ So now, the plastic strain can be computed using an iterative approach:
63
+
64
+ >>> plastic_strain = StrainTensor.zeros(n_step)
65
+ >>> for i in range(1, n_step):
66
+ ... strain_increment = JC.compute_strain_increment(stress[i])
67
+ ... plastic_strain[i] = plastic_strain[i-1] + strain_increment
68
+
69
+ That's all. Finally, let us plot the applied stress as a function of the overall elongation:
70
+
71
+ >>> from matplotlib import pyplot as plt
72
+ >>> elong = elastic_strain.C[0,0]+plastic_strain.C[0,0]
73
+ >>> fig, ax = plt.subplots()
74
+ >>> ax.plot(elong, stress_mag, label='Stress-controlled') # doctest: +SKIP
75
+ >>> ax.set_xlabel(r'$\varepsilon_{xx}$') # doctest: +SKIP
76
+ >>> ax.set_ylabel('Tensile stress (MPa)') # doctest: +SKIP
77
+
78
+ Now, let say that we want to investigate the material's response for the tensile stress ranging from 0 to 725 MPa:
79
+
53
80
  >>> import numpy as np
54
81
  >>> n_step = 100
55
82
  >>> stress_mag = np.linspace(0, 725, n_step)
@@ -17,7 +17,7 @@ As an example, let's consider the stiffness tensor for monoclinic TiNi:
17
17
 
18
18
  .. doctest::
19
19
 
20
- >>> from Elasticipy.FourthOrderTensor import StiffnessTensor
20
+ >>> from Elasticipy.tensors.elasticity import StiffnessTensor
21
21
  >>> C = StiffnessTensor.monoclinic(phase_name='TiNi',
22
22
  ... C11=231, C12=127, C13=104,
23
23
  ... C22=240, C23=131, C33=175,
@@ -36,7 +36,7 @@ behaviour. In this case, the aforementioned averages can be estimated as follows
36
36
  Let's see how ``C_Hill`` looks like:
37
37
 
38
38
  >>> print(C_Hill)
39
- Stiffness tensor (in Voigt notation):
39
+ Stiffness tensor (in Voigt mapping):
40
40
  [[200.92610744 119.59583533 119.59583533 0. 0.
41
41
  0. ]
42
42
  [119.59583533 200.92610744 119.59583533 0. 0.
@@ -42,7 +42,7 @@ Let's start by creating the two stiffness tensors in Python:
42
42
 
43
43
  .. doctest::
44
44
 
45
- >>> from Elasticipy.FourthOrderTensor import StiffnessTensor
45
+ >>> from Elasticipy.tensors.elasticity import StiffnessTensor
46
46
  >>> C_austenite = StiffnessTensor.cubic(C11=204, C12=137, C44=126)
47
47
  >>> C_ferrite = StiffnessTensor.cubic(C11=242, C12=146, C44=116)
48
48
 
@@ -12,7 +12,7 @@ To save a given stiffness tensor to a plain text file, just use the ``save_to_tx
12
12
 
13
13
  .. doctest::
14
14
 
15
- >>> from Elasticipy.FourthOrderTensor import StiffnessTensor
15
+ >>> from Elasticipy.tensors.elasticity import StiffnessTensor
16
16
  >>> C = StiffnessTensor.cubic(C11=186, C12=134, C44=77, phase_name='Cu')
17
17
  >>> C.save_to_txt('Stiffness_Cu.txt')
18
18
 
@@ -25,13 +25,14 @@ To read entries from an existing text file, just run ``StiffnessTensor.from_txt_
25
25
  Using the example above:
26
26
 
27
27
  >>> StiffnessTensor.from_txt_file('Stiffness_Cu.txt')
28
- Stiffness tensor (in Voigt notation) for Cu:
28
+ Stiffness tensor (in Voigt mapping):
29
29
  [[186. 134. 134. 0. 0. 0.]
30
30
  [134. 186. 134. 0. 0. 0.]
31
31
  [134. 134. 186. 0. 0. 0.]
32
32
  [ 0. 0. 0. 77. 0. 0.]
33
33
  [ 0. 0. 0. 0. 77. 0.]
34
34
  [ 0. 0. 0. 0. 0. 77.]]
35
+ Phase: Cu
35
36
  Symmetry: cubic
36
37
 
37
38
 
@@ -12,7 +12,7 @@ First, create a stiffness tensor with a given symmetry (let say, monoclinic):
12
12
 
13
13
  .. doctest::
14
14
 
15
- >>> from Elasticipy.FourthOrderTensor import StiffnessTensor
15
+ >>> from Elasticipy.tensors.elasticity import StiffnessTensor
16
16
  >>> C = StiffnessTensor.monoclinic(phase_name='TiNi',
17
17
  ... C11=231, C12=127, C13=104,
18
18
  ... C22=240, C23=131, C33=175,
@@ -11,7 +11,7 @@ equivalent stresses:
11
11
 
12
12
  .. doctest::
13
13
 
14
- >>> from Elasticipy.StressStrainTensors import StressTensor, StrainTensor
14
+ >>> from Elasticipy.tensors.stress_strain import StressTensor, StrainTensor
15
15
  >>> stress = StressTensor.shear([1, 0, 0], [0, 1, 0], 1.0) # Unit XY shear stress
16
16
  >>> print(stress.vonMises(), stress.Tresca())
17
17
  1.7320508075688772 2.0
@@ -32,10 +32,10 @@ Linear elasticity
32
32
  This section is dedicated to linear elasticity, hence introducing the fourth-order stiffness tensor.
33
33
  As an example, create a stiffness tensor corresponding to steel:
34
34
 
35
- >>> from Elasticipy.FourthOrderTensor import StiffnessTensor
35
+ >>> from Elasticipy.tensors.elasticity import StiffnessTensor
36
36
  >>> C = StiffnessTensor.isotropic(E=210e3, nu=0.28)
37
37
  >>> print(C)
38
- Stiffness tensor (in Voigt notation):
38
+ Stiffness tensor (in Voigt mapping):
39
39
  [[268465.90909091 104403.40909091 104403.40909091 0.
40
40
  0. 0. ]
41
41
  [104403.40909091 268465.90909091 104403.40909091 0.
@@ -64,7 +64,7 @@ Conversely, one can compute the compliance tensor:
64
64
 
65
65
  >>> S = C.inv()
66
66
  >>> print(S)
67
- Compliance tensor (in Voigt notation):
67
+ Compliance tensor (in Voigt mapping):
68
68
  [[ 4.76190476e-06 -1.33333333e-06 -1.33333333e-06 0.00000000e+00
69
69
  0.00000000e+00 0.00000000e+00]
70
70
  [-1.33333333e-06 4.76190476e-06 -1.33333333e-06 0.00000000e+00
@@ -97,13 +97,14 @@ As an illustration, we consider the anisotropic behaviour of ferrite:
97
97
  >>> C = StiffnessTensor.fromCrystalSymmetry(symmetry='cubic', phase_name='ferrite',
98
98
  ... C11=274, C12=175, C44=89)
99
99
  >>> print(C)
100
- Stiffness tensor (in Voigt notation) for ferrite:
100
+ Stiffness tensor (in Voigt mapping):
101
101
  [[274. 175. 175. 0. 0. 0.]
102
102
  [175. 274. 175. 0. 0. 0.]
103
103
  [175. 175. 274. 0. 0. 0.]
104
104
  [ 0. 0. 0. 89. 0. 0.]
105
105
  [ 0. 0. 0. 0. 89. 0.]
106
106
  [ 0. 0. 0. 0. 0. 89.]]
107
+ Phase: ferrite
107
108
  Symmetry: cubic
108
109
 
109
110
  Let's start by creating an array of 10 stresses:
@@ -8,7 +8,7 @@ At first, let's consider steel as an example, assuming an isotropic behaviour:
8
8
 
9
9
  .. doctest::
10
10
 
11
- >>> from Elasticipy.ThermalExpansion import ThermalExpansionTensor as ThEx
11
+ >>> from Elasticipy.tensors.thermal_expansion import ThermalExpansionTensor as ThEx
12
12
  >>> alpha = ThEx.isotropic(11e-6)
13
13
  >>> print(alpha)
14
14
  Thermal expansion tensor
@@ -11,18 +11,19 @@ We thus start by defining the stiffness tensor for forsterite:
11
11
 
12
12
  .. doctest::
13
13
 
14
- >>> from Elasticipy.FourthOrderTensor import StiffnessTensor
14
+ >>> from Elasticipy.tensors.elasticity import StiffnessTensor
15
15
  >>> C = StiffnessTensor.orthorhombic(phase_name='forsterite',
16
16
  ... C11=320, C12=68.2, C13=71.6, C22=196.5, C23=76.8,
17
17
  ... C33=233.5, C44=64, C55=77, C66=78.7)
18
18
  >>> print(C)
19
- Stiffness tensor (in Voigt notation) for forsterite:
19
+ Stiffness tensor (in Voigt mapping):
20
20
  [[320. 68.2 71.6 0. 0. 0. ]
21
21
  [ 68.2 196.5 76.8 0. 0. 0. ]
22
22
  [ 71.6 76.8 233.5 0. 0. 0. ]
23
23
  [ 0. 0. 0. 64. 0. 0. ]
24
24
  [ 0. 0. 0. 0. 77. 0. ]
25
25
  [ 0. 0. 0. 0. 0. 78.7]]
26
+ Phase: forsterite
26
27
  Symmetry: orthorhombic
27
28
 
28
29
  And define the mass density:
@@ -40,6 +40,8 @@ language = 'english'
40
40
 
41
41
  html_theme = "sphinx_rtd_theme"
42
42
  html_static_path = ['../_static']
43
+ html_logo = "logo/logo_text_whitebg.png"
44
+ html_favicon = 'logo/favicon.png'
43
45
  numpydoc_class_members_toctree = False
44
46
  autoclass_content = 'both'
45
47
 
@@ -0,0 +1,100 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+ <svg
5
+ width="35mm"
6
+ height="35mm"
7
+ viewBox="0 0 35 35"
8
+ version="1.1"
9
+ id="svg1"
10
+ sodipodi:docname="logo.svg"
11
+ inkscape:export-filename="favicon.png"
12
+ inkscape:export-xdpi="23.222858"
13
+ inkscape:export-ydpi="23.222858"
14
+ inkscape:version="1.4 (86a8ad7, 2024-10-11)"
15
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
16
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
17
+ xmlns:xlink="http://www.w3.org/1999/xlink"
18
+ xmlns="http://www.w3.org/2000/svg"
19
+ xmlns:svg="http://www.w3.org/2000/svg">
20
+ <sodipodi:namedview
21
+ id="namedview1"
22
+ pagecolor="#ffffff"
23
+ bordercolor="#000000"
24
+ borderopacity="0.25"
25
+ inkscape:showpageshadow="2"
26
+ inkscape:pageopacity="0.0"
27
+ inkscape:pagecheckerboard="0"
28
+ inkscape:deskcolor="#d1d1d1"
29
+ inkscape:document-units="mm"
30
+ inkscape:zoom="4.1071317"
31
+ inkscape:cx="50.887095"
32
+ inkscape:cy="57.339286"
33
+ inkscape:window-width="1920"
34
+ inkscape:window-height="1017"
35
+ inkscape:window-x="1912"
36
+ inkscape:window-y="-8"
37
+ inkscape:window-maximized="1"
38
+ inkscape:current-layer="layer1"
39
+ inkscape:export-bgcolor="#ffffff00" />
40
+ <defs
41
+ id="defs1">
42
+ <linearGradient
43
+ inkscape:collect="always"
44
+ xlink:href="#linearGradient4671"
45
+ id="linearGradient11"
46
+ gradientUnits="userSpaceOnUse"
47
+ gradientTransform="matrix(0.26458333,0,0,-0.26458333,63.222824,140.3324)"
48
+ x1="347.23236"
49
+ y1="-16.795702"
50
+ x2="318.25162"
51
+ y2="-62.776524"
52
+ spreadMethod="pad" />
53
+ <linearGradient
54
+ id="linearGradient4671">
55
+ <stop
56
+ style="stop-color:#ffd43b;stop-opacity:1"
57
+ offset="0"
58
+ id="stop4673" />
59
+ <stop
60
+ style="stop-color:#ffe873;stop-opacity:1"
61
+ offset="1"
62
+ id="stop4675" />
63
+ </linearGradient>
64
+ <linearGradient
65
+ inkscape:collect="always"
66
+ xlink:href="#linearGradient4689"
67
+ id="linearGradient9"
68
+ gradientUnits="userSpaceOnUse"
69
+ gradientTransform="matrix(0.26458333,0,0,0.26458333,80.574734,138.09756)"
70
+ x1="181.30275"
71
+ y1="-17.131027"
72
+ x2="256.79184"
73
+ y2="52.408573" />
74
+ <linearGradient
75
+ id="linearGradient4689">
76
+ <stop
77
+ style="stop-color:#5a9fd4;stop-opacity:1"
78
+ offset="0"
79
+ id="stop4691" />
80
+ <stop
81
+ style="stop-color:#306998;stop-opacity:1"
82
+ offset="1"
83
+ id="stop4693" />
84
+ </linearGradient>
85
+ </defs>
86
+ <g
87
+ inkscape:label="Layer 1"
88
+ inkscape:groupmode="layer"
89
+ id="layer1"
90
+ transform="translate(-126.73542,-133.35)">
91
+ <path
92
+ id="text1-4-5-2-54-3"
93
+ style="font-size:192px;text-align:start;writing-mode:lr-tb;direction:ltr;text-anchor:start;display:inline;fill:url(#linearGradient11);fill-opacity:1;stroke-width:0.264583"
94
+ d="m 150.74998,141.06271 c -0.96996,0 -1.83852,0.007 -2.66237,0.0186 0.52425,0.50605 0.97673,1.07142 1.28261,1.74873 0.50892,1.12689 0.82992,2.28417 0.82992,3.53829 v 1.39991 c 2.66736,0.0162 5.07681,0.0196 8.15455,0.0196 0,-0.87942 0.0155,-1.76812 0.0155,-2.4474 0,-2.51527 -0.32529,-4.27777 -7.62021,-4.27777 z m -11.61583,2.07016 c -0.74411,1.15235 -0.76426,2.93071 -0.76946,5.67458 v 0.0248 c 0,1.14102 0.14056,2.1084 0.42168,2.90215 0.11054,0.30092 0.24218,0.57875 0.39378,0.83406 1.45247,-0.19775 2.71407,-2.31732 2.71404,-4.72736 3e-5,-2.43536 -1.28837,-4.55112 -2.76004,-4.70824 z m 16.1029,0.14314 a 1.3449186,1.3449186 0 0 1 1.34513,1.34514 1.3449186,1.3449186 0 0 1 -1.34513,1.34513 1.3449186,1.3449186 0 0 1 -1.34462,-1.34513 1.3449186,1.3449186 0 0 1 1.34462,-1.34514 z m -5.05448,5.9893 c -0.0858,2.29191 -0.60955,4.25462 -1.45572,5.93038 -0.90878,1.81756 -2.28539,2.88556 -4.03025,3.84887 -1.74485,0.96331 -3.67874,1.21646 -6.13244,1.21646 -0.067,0 -0.12977,-0.004 -0.19585,-0.005 -3.2e-4,0.0383 -0.004,0.0729 -0.004,0.11162 v 0.0248 c 0.0134,7.04478 0.0291,7.74475 12.38529,7.74475 7.29492,0 7.62021,-1.7625 7.62021,-4.27777 0,-0.67928 -0.0155,-1.56798 -0.0155,-2.4474 -4.40154,0 -7.05527,-0.01 -11.76001,0.046 -0.74191,0.01 -0.77069,-0.8692 -0.01,-0.8692 4.27995,0 5.96966,-1.55757 5.96966,-6.01823 0,-2.77849 -0.67428,-4.46657 -2.37195,-5.30562 z" />
95
+ <path
96
+ id="text1-1-5-1"
97
+ style="font-weight:bold;font-size:192px;font-family:Bahnschrift;-inkscape-font-specification:'Bahnschrift Bold';display:inline;fill:url(#linearGradient9);stroke-width:0.705556"
98
+ d="m 143.93283,133.35 c -2.87272,0 -8.44558,0.27355 -10.72338,1.48363 -1.5875,0.84336 -2.80293,2.06706 -3.64629,3.6711 -0.82682,1.60402 -1.24023,3.53053 -1.24023,5.77949 v 4.19199 c 0,2.36472 0.41341,4.39043 1.24023,6.07715 0.84336,1.67018 2.05879,2.94349 3.64629,3.81992 1.5875,0.87644 3.49746,1.31465 5.72988,1.31465 2.23242,0 4.14239,-0.43821 5.72989,-1.31465 1.5875,-0.87643 2.79466,-2.14147 3.62148,-3.79511 0.84336,-1.67019 1.26504,-3.67937 1.26504,-6.02754 v -2.03399 c 0,-1.14101 -0.23151,-2.22415 -0.69453,-3.24941 -0.46302,-1.02526 -1.14102,-1.87689 -2.03399,-2.55488 -0.29302,-0.22791 -0.60567,-0.42439 -0.93431,-0.59532 0,0 6.299,0.0465 8.87181,0 10e-4,-0.72917 0.0207,-1.55216 0.0207,-2.13475 0,-3.69368 -0.73316,-4.63228 -10.85257,-4.63228 z m 7.72666,2.2779 a 1.3383084,1.3383084 0 0 1 1.33841,1.33842 1.3383084,1.3383084 0 0 1 -1.33841,1.3379 1.3383084,1.3383084 0 0 1 -1.33791,-1.3379 1.3383084,1.3383084 0 0 1 1.33791,-1.33842 z m -12.67365,6.68641 c 1.97408,3e-4 3.57433,2.43687 3.57446,5.44257 6e-5,3.00589 -1.60025,5.44278 -3.57446,5.44308 -1.97441,1.4e-4 -3.57503,-2.43688 -3.57497,-5.44308 1.3e-4,-3.00601 1.60069,-5.44271 3.57497,-5.44257 z" />
99
+ </g>
100
+ </svg>