elasticipy 3.0.0__py3-none-any.whl → 4.0.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.
@@ -0,0 +1,138 @@
1
+ import numpy as np
2
+ from Elasticipy.tensors.second_order import SymmetricSecondOrderTensor
3
+
4
+
5
+ class StrainTensor(SymmetricSecondOrderTensor):
6
+ """
7
+ Class for manipulating symmetric strain tensors or arrays of symmetric strain tensors.
8
+
9
+ """
10
+ name = 'Strain tensor'
11
+ voigt_map = [1, 1, 1, 2, 2, 2]
12
+
13
+ def principal_strains(self):
14
+ """
15
+ Values of the principals strains.
16
+
17
+ If the tensor array is of shape [m,n,...], the results will be of shape [m,n,...,3].
18
+
19
+ Returns
20
+ -------
21
+ np.ndarray
22
+ Principal strain values
23
+ """
24
+ return self.eigvals()
25
+
26
+ def volumetric_strain(self):
27
+ """
28
+ Volumetric change (1st invariant of the strain tensor)
29
+
30
+ Returns
31
+ -------
32
+ numpy.ndarray or float
33
+ Volumetric change
34
+ """
35
+ return self.I1
36
+
37
+ def eq_strain(self):
38
+ """von Mises equivalent strain"""
39
+ return np.sqrt(2/3 * self.ddot(self))
40
+
41
+ def elastic_energy(self, stress):
42
+ """
43
+ Compute the elastic energy.
44
+
45
+ Parameters
46
+ ----------
47
+ stress : StressTensor
48
+ Corresponding stress tensor
49
+
50
+ Returns
51
+ -------
52
+ Volumetric elastic energy
53
+ """
54
+ return 0.5 * self.ddot(stress)
55
+
56
+
57
+ class StressTensor(SymmetricSecondOrderTensor):
58
+ """
59
+ Class for manipulating stress tensors or arrays of stress tensors.
60
+ """
61
+ name = 'Stress tensor'
62
+
63
+ def principal_stresses(self):
64
+ """
65
+ Values of the principals stresses.
66
+
67
+ If the tensor array is of shape [m,n,...], the results will be of shape [m,n,...,3].
68
+
69
+ Returns
70
+ -------
71
+ np.ndarray
72
+ Principal stresses
73
+ """
74
+ return self.eigvals()
75
+
76
+ def vonMises(self):
77
+ """
78
+ von Mises equivalent stress.
79
+
80
+ Returns
81
+ -------
82
+ np.ndarray or float
83
+ von Mises equivalent stress
84
+
85
+ See Also
86
+ --------
87
+ Tresca : Tresca equivalent stress
88
+ """
89
+ return np.sqrt(3 * self.J2)
90
+
91
+ def Tresca(self):
92
+ """
93
+ Tresca(-Guest) equivalent stress.
94
+
95
+ Returns
96
+ -------
97
+ np.ndarray or float
98
+ Tresca equivalent stress
99
+
100
+ See Also
101
+ --------
102
+ vonMises : von Mises equivalent stress
103
+ """
104
+ ps = self.principal_stresses()
105
+ return ps[...,0] - ps[...,-1]
106
+
107
+ def hydrostatic_pressure(self):
108
+ """
109
+ Hydrostatic pressure
110
+
111
+ Returns
112
+ -------
113
+ np.ndarray or float
114
+
115
+ See Also
116
+ --------
117
+ sphericalPart : spherical part of the stress
118
+ """
119
+ return -self.I1/3
120
+
121
+ def elastic_energy(self, strain, mode='pair'):
122
+ """
123
+ Compute the elastic energy.
124
+
125
+ Parameters
126
+ ----------
127
+ strain : StrainTensor
128
+ Corresponding elastic strain tensor
129
+ mode : str, optional
130
+ If 'pair' (default), the elastic energies are computed element-wise. Broadcasting rule applies.
131
+ If 'cross', each cross-combination of stress and strain are considered.
132
+
133
+ Returns
134
+ -------
135
+ numpy.ndarray
136
+ Volumetric elastic energy
137
+ """
138
+ return 0.5 * self.ddot(strain, mode=mode)
@@ -0,0 +1,249 @@
1
+ import warnings
2
+
3
+ from Elasticipy.tensors.second_order import SymmetricSecondOrderTensor, ALPHABET, is_orix_rotation
4
+ from Elasticipy.tensors.stress_strain import StrainTensor
5
+ import numpy as np
6
+ from scipy.spatial.transform import Rotation
7
+
8
+ class ThermalExpansionTensor(SymmetricSecondOrderTensor):
9
+ name = 'Thermal expansion tensor'
10
+
11
+ def __mul__(self, other):
12
+ if isinstance(other, Rotation) or is_orix_rotation(other):
13
+ return super().__mul__(other)
14
+ else:
15
+ other = np.asarray(other)
16
+ other_expanded = other[..., None, None]
17
+ other_with_eye = other_expanded * np.ones(3)
18
+ new_mat = self.matrix * other_with_eye
19
+ return StrainTensor(new_mat)
20
+
21
+ def apply_temperature(self, temperature, mode='pair'):
22
+ """
23
+ Apply temperature increase to the thermal expansion tensor, or to the array.
24
+
25
+ Application can be made pair-wise, or considering all cross-combinations (see below).
26
+
27
+ Parameters
28
+ ----------
29
+ temperature : float or numpy.ndarray
30
+ mode : str, optional
31
+ If "pair" (default), the temperatures are applied pair-wise on the tensor array. Broadcasting rule applies
32
+ If "cross", all cross combinations are considered. Therefore, if ``C=A.apply_temperature(T, mode="cross")``,
33
+ then ``C.shape=A.shape + T.shape``.
34
+
35
+ Returns
36
+ -------
37
+ StrainTensor
38
+ Strain corresponding to the applied temperature increase(s).
39
+
40
+ Examples
41
+ --------
42
+ Let consider a transverse isotropic case (e.g. carbon fibers):
43
+ >>> from Elasticipy.ThermalExpansion import ThermalExpansionTensor as ThEx
44
+ >>> alpha = ThEx.transverse_isotropic(alpha_11=5.6e-6, alpha_33=-0.4e-6)
45
+
46
+ Now apply temperature increases:
47
+ >>> T = [0, 1, 2]
48
+ >>> eps = alpha.apply_temperature(T)
49
+
50
+ We get a strain tensor of the same shape as the applied temperatures:
51
+ >>> eps
52
+ Strain tensor
53
+ Shape=(3,)
54
+ >>> eps[-1]
55
+ Strain tensor
56
+ [[ 1.12e-05 0.00e+00 0.00e+00]
57
+ [ 0.00e+00 1.12e-05 0.00e+00]
58
+ [ 0.00e+00 0.00e+00 -8.00e-07]]
59
+
60
+ Now let's rotate the thermal expansions:
61
+ >>> from scipy.spatial.transform import Rotation
62
+ >>> rot = Rotation.random(3) # Set of 3 random 3D rotations
63
+ >>> alpha_rotated = alpha * rot
64
+
65
+ If we want to combine each rotated thermal expansion with the corresponding temperature increase:
66
+ >>> eps_rotated_pair = alpha_rotated * T # Equivalent to alpha_rotated.apply_temperature(T)
67
+ >>> eps_rotated_pair
68
+ Strain tensor
69
+ Shape=(3,)
70
+
71
+ Conversely, if we want to evaluate all cross-combinations of thermal expansions and temperature increases:
72
+
73
+ >>> eps_rotated_cross = alpha_rotated.apply_temperature(T, mode='cross')
74
+ >>> eps_rotated_cross
75
+ Strain tensor
76
+ Shape=(3, 3)
77
+
78
+ """
79
+ temperature = np.asarray(temperature)
80
+ if mode == 'pair':
81
+ matrix = self.matrix*temperature[...,np.newaxis,np.newaxis]
82
+ elif mode == 'cross':
83
+ indices_self = ALPHABET[:self.ndim]
84
+ indices_temp = ALPHABET[:len(temperature.shape)].upper()
85
+ ein_str = indices_self + 'ij,' + indices_temp + '->' + indices_self + indices_temp + 'ij'
86
+ matrix = np.einsum(ein_str, self.matrix, temperature)
87
+ else:
88
+ raise ValueError('Invalid mode. It could be either "pair" or "cross".')
89
+ return StrainTensor(matrix)
90
+
91
+
92
+ def matmul(self, other):
93
+ """
94
+ Matrix like product with array of float, resulting either in StrainTensor.
95
+
96
+ Compute the product between the tensor and a numpy array in a "matrix-product" way,*
97
+ that is by computing each of the products. If T.shape=(m,n,o,...) and other.shape=(p,q,r,...), then::
98
+
99
+ T.matmul(other).shape = (m,n,o,...,p,q,r,...)
100
+
101
+ Parameters
102
+ ----------
103
+ other : np.ndarray
104
+ Value to multiply by.
105
+ Returns
106
+ -------
107
+ StrainTensor
108
+ Array fo strain tensors corresponding to all cross-combinations between Thermal expansions and temperature
109
+ increases.
110
+ """
111
+ warnings.warn(
112
+ 'matmul() is deprecated and will be removed in a future version. Use dot(tensor,mode="cross") or '
113
+ 'rotate(rotation,mode="cross") instead.',
114
+ DeprecationWarning,
115
+ stacklevel=2)
116
+ if isinstance(other, Rotation) or is_orix_rotation(other):
117
+ return super().matmul(other)
118
+ else:
119
+ return self.apply_temperature(other, mode='cross')
120
+
121
+
122
+ @classmethod
123
+ def isotropic(cls, alpha):
124
+ """
125
+ Create an isotropic thermal expansion tensor.
126
+
127
+ Parameters
128
+ ----------
129
+ alpha : float
130
+ Thermal expansion coefficient.
131
+
132
+ Returns
133
+ -------
134
+ ThermalExpansionTensor
135
+ """
136
+ return cls(np.eye(3)*alpha)
137
+
138
+ @classmethod
139
+ def orthotropic(cls, alpha_11, alpha_22, alpha_33):
140
+ """
141
+ Create an orthotropic thermal expansion tensor.
142
+
143
+ Parameters
144
+ ----------
145
+ alpha_11, alpha_22, alpha_33 : float
146
+ Thermal expansion coefficients along the first, second and third axes, respectively.
147
+
148
+ Returns
149
+ -------
150
+ ThermalExpansionTensor
151
+ """
152
+ return cls(np.diag([alpha_11, alpha_22, alpha_33]))
153
+
154
+ @classmethod
155
+ def orthorhombic(cls, *args):
156
+ """
157
+ Create a thermal expansion tensor corresponding to an orthotropic thermal expansion coefficient.
158
+
159
+ This function is an alias for orthotropic().
160
+
161
+ Parameters
162
+ ----------
163
+ args : list
164
+ Orthotropic thermal expansion coefficient.
165
+
166
+ Returns
167
+ -------
168
+ ThermalExpansionTensor
169
+
170
+ See Also
171
+ --------
172
+ orthotropic
173
+ """
174
+ return cls.orthotropic(*args)
175
+
176
+ @classmethod
177
+ def monoclinic(cls, alpha_11, alpha_22, alpha_33, alpha_13=None, alpha_12=None):
178
+ """
179
+ Create a thermal expansion tensor for monoclinic symmetry.
180
+
181
+ If alpha_13, the Diad || z is assumed. If alpha_12, the Diad || z is assumed. Therefore, these two parameters
182
+ are exclusive.
183
+
184
+ Parameters
185
+ ----------
186
+ alpha_11, alpha_22, alpha_33 : float
187
+ Thermal expansion coefficient along the first, second and third axes, respectively.
188
+ alpha_13 : float, optional
189
+ Thermal expansion coefficient corresponding to XZ shear (for Diad || y)
190
+ alpha_12: float, optional
191
+ Thermal expansion coefficient corresponding to XY shear (for Diad || z)
192
+
193
+ Returns
194
+ -------
195
+ ThermalExpansionTensor
196
+ """
197
+ matrix = np.diag([alpha_11, alpha_22, alpha_33])
198
+ if (alpha_13 is not None) and (alpha_12 is None):
199
+ matrix[0, 2] = matrix[2, 0]= alpha_13
200
+ elif (alpha_12 is not None) and (alpha_13 is None):
201
+ matrix[0, 1] = matrix[1, 0]= alpha_12
202
+ elif (alpha_13 is not None) and (alpha_12 is not None):
203
+ raise ValueError('alpha_13 and alpha_12 cannot be used together.')
204
+ else:
205
+ raise ValueError('Either alpha_13 or alpha_12 must be provided.')
206
+ return cls(matrix)
207
+
208
+
209
+ @classmethod
210
+ def triclinic(cls, alpha_11=0., alpha_12=0., alpha_13=0., alpha_22=0., alpha_23=0., alpha_33=0.):
211
+ """
212
+ Create a thermal expansion tensor for triclinic symmetry.
213
+
214
+ Parameters
215
+ ----------
216
+ alpha_11, alpha_12, alpha_13, alpha_22, alpha_23, alpha_33 : float
217
+ Values of the thermal expansion coefficients
218
+
219
+ Returns
220
+ -------
221
+ ThermalExpansionTensor
222
+ """
223
+ mat = [[alpha_11, alpha_12, alpha_13],
224
+ [alpha_12, alpha_22, alpha_23],
225
+ [alpha_13, alpha_23, alpha_33]]
226
+ return cls(mat)
227
+
228
+ @classmethod
229
+ def transverse_isotropic(cls, alpha_11, alpha_33):
230
+ """
231
+ Create a thermal expansion tensor for transverse isotropic symmetry.
232
+
233
+ Parameters
234
+ ----------
235
+ alpha_11 : float
236
+ Thermal expansion coefficient along the first and second axes
237
+ alpha_33 : float
238
+ Thermal expansion coefficient along the third axis
239
+
240
+ Returns
241
+ -------
242
+ ThermalExpansionTensor
243
+ """
244
+ return cls(np.diag([alpha_11, alpha_11, alpha_33]))
245
+
246
+ @property
247
+ def volumetric_coefficient(self):
248
+ """ Returns the volumetric thermal expansion coefficient."""
249
+ return self.I1
@@ -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
@@ -0,0 +1,20 @@
1
+ Elasticipy/FourthOrderTensor.py,sha256=jKXGD69Zas5CKQfeSz-AgLfeYX2XN-O6Q6lGtBKuoiU,508
2
+ Elasticipy/StressStrainTensors.py,sha256=xs4wgG1ohx3pT-X5GZUlm511SazHPsD_-okn822NqCA,491
3
+ Elasticipy/ThermalExpansion.py,sha256=O7VlU_8prjUzlVhQ4N-J66Zhs89S7TqllepUOQ-psJM,411
4
+ Elasticipy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ Elasticipy/crystal_symmetries.py,sha256=DAX-XPgYqI2nFvf6anCVvZ5fLM0CNSDJ7r2h15l3Hoc,3958
6
+ Elasticipy/gui.py,sha256=ta_EqjwI_HqIl-Sqtrnbj0lwZ818UmA0It5gC2MS87k,11249
7
+ Elasticipy/plasticity.py,sha256=G8r9v51iD4g3szRe7IdTXE1wiXQzsGr3wlMGOYbtTPc,11377
8
+ Elasticipy/polefigure.py,sha256=G3Sz7ssX2KKY96g3XEvcaOYFmEat9JUCdb2A91XbA6w,3531
9
+ Elasticipy/spherical_function.py,sha256=vSV8zOqk3w4PIImQd4sKeQgn-j9oha1WQtSL2AmPEaw,41244
10
+ Elasticipy/tensors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ Elasticipy/tensors/elasticity.py,sha256=NpgDuGLgCtHQh-orihNDh6Oc5Qw9O-jveML8pVCqUTY,61074
12
+ Elasticipy/tensors/fourth_order.py,sha256=uuQSIhbuG17Y7iSwdujwSbGKvF8BTDb-5yEXXCEo5Dk,20741
13
+ Elasticipy/tensors/second_order.py,sha256=GOLNriRPL8BqxNyZpcpOsy1GGDBrOHozojl4G8fnwaE,52278
14
+ Elasticipy/tensors/stress_strain.py,sha256=TC6L1IsuJh53ZCEEMXumOhRHl0w1wiNI25Jwudqv7bs,3264
15
+ Elasticipy/tensors/thermal_expansion.py,sha256=XZ9e8Sn9vsLGVh79TrBQoBOkXMg8qF3pShiPSzix4q0,8634
16
+ elasticipy-4.0.0.dist-info/licenses/LICENSE,sha256=qNthTMSjVkIDM1_BREgVFQHdn1wVNQi9pwWVfTIazMA,1074
17
+ elasticipy-4.0.0.dist-info/METADATA,sha256=wvXEyiXxjUKAK83oc1Yw6iZGJ8JMYpaDDM2g6yk6Ol0,4016
18
+ elasticipy-4.0.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
19
+ elasticipy-4.0.0.dist-info/top_level.txt,sha256=k4zSQzJR5P4vzlHlhWUaxNgvgloq4KIp8oca2X8gQOw,11
20
+ elasticipy-4.0.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.1)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,15 +0,0 @@
1
- Elasticipy/CrystalSymmetries.py,sha256=DAX-XPgYqI2nFvf6anCVvZ5fLM0CNSDJ7r2h15l3Hoc,3958
2
- Elasticipy/FourthOrderTensor.py,sha256=slRB4WL5JZKA8YP7jXMaQs9PRkhi1-RWDGhVNL2VuYA,63944
3
- Elasticipy/Plasticity.py,sha256=vfL4Ckpk-GgpxXjGXEd4dTSIZJDr28wh_Za5S7PM3WI,11375
4
- Elasticipy/PoleFigure.py,sha256=G3Sz7ssX2KKY96g3XEvcaOYFmEat9JUCdb2A91XbA6w,3531
5
- Elasticipy/SecondOrderTensor.py,sha256=USsX2Jg_H8t67P10csPFVxmXJ40PPH7D94Kod_pdD7Y,52261
6
- Elasticipy/SphericalFunction.py,sha256=X6hrjwCiZkLjiUQ8WO2W4vLNOlbQ4jLWsloOg33IlL4,41244
7
- Elasticipy/StressStrainTensors.py,sha256=gEPo69Bnu4qBEeyYc4Rn-T213E-fTmTh_QNwAdVCX_U,3261
8
- Elasticipy/ThermalExpansion.py,sha256=pXAa6CJ7_Yr02ZfUNcjFL7l6o0Bc-O1E3IjEM7yfYy4,8629
9
- Elasticipy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- Elasticipy/gui.py,sha256=zyVnvp6IIi3FDR5hWfIJrOP28Y7XkP4wc71XXMyGpeo,11247
11
- elasticipy-3.0.0.dist-info/LICENSE,sha256=qNthTMSjVkIDM1_BREgVFQHdn1wVNQi9pwWVfTIazMA,1074
12
- elasticipy-3.0.0.dist-info/METADATA,sha256=-aOaNihsY1m4e1NANFp-EMtTWgQ63vPNS0AlbWRAkLk,3961
13
- elasticipy-3.0.0.dist-info/WHEEL,sha256=nn6H5-ilmfVryoAQl3ZQ2l8SH5imPWFpm1A5FgEuFV4,91
14
- elasticipy-3.0.0.dist-info/top_level.txt,sha256=k4zSQzJR5P4vzlHlhWUaxNgvgloq4KIp8oca2X8gQOw,11
15
- elasticipy-3.0.0.dist-info/RECORD,,
File without changes