elasticipy 2.8.9__py3-none-any.whl → 2.9.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Elasticipy/Plasticity.py +172 -15
- Elasticipy/SecondOrderTensor.py +99 -15
- Elasticipy/StressStrainTensors.py +4 -3
- {elasticipy-2.8.9.dist-info → elasticipy-2.9.0.dist-info}/METADATA +1 -1
- {elasticipy-2.8.9.dist-info → elasticipy-2.9.0.dist-info}/RECORD +8 -8
- {elasticipy-2.8.9.dist-info → elasticipy-2.9.0.dist-info}/LICENSE +0 -0
- {elasticipy-2.8.9.dist-info → elasticipy-2.9.0.dist-info}/WHEEL +0 -0
- {elasticipy-2.8.9.dist-info → elasticipy-2.9.0.dist-info}/top_level.txt +0 -0
Elasticipy/Plasticity.py
CHANGED
|
@@ -1,9 +1,74 @@
|
|
|
1
1
|
import numpy as np
|
|
2
|
+
from Elasticipy.StressStrainTensors import StrainTensor, StressTensor
|
|
2
3
|
|
|
4
|
+
class IsotropicHardening:
|
|
5
|
+
"""
|
|
6
|
+
Template class for isotropic hardening plasticity models
|
|
7
|
+
"""
|
|
8
|
+
def __init__(self, criterion='von Mises'):
|
|
9
|
+
"""
|
|
10
|
+
Create an instance of a plastic model, assuming isotropic hardening
|
|
11
|
+
|
|
12
|
+
Parameters
|
|
13
|
+
----------
|
|
14
|
+
criterion : str, optional
|
|
15
|
+
Plasticity criterion to use. Can be 'von Mises', 'Tresca' or 'J2'. J2 is the same as von Mises.
|
|
16
|
+
"""
|
|
17
|
+
criterion = criterion.lower()
|
|
18
|
+
if criterion in ('von mises', 'mises', 'vonmises', 'j2'):
|
|
19
|
+
criterion = 'j2'
|
|
20
|
+
elif criterion != 'tresca':
|
|
21
|
+
raise ValueError('The criterion can be "Tresca", "von Mises" or "J2".')
|
|
22
|
+
self.criterion = criterion.lower()
|
|
23
|
+
self.plastic_strain = 0.0
|
|
3
24
|
|
|
25
|
+
def flow_stress(self, strain, **kwargs):
|
|
26
|
+
pass
|
|
4
27
|
|
|
5
|
-
|
|
6
|
-
|
|
28
|
+
def apply_strain(self, strain, **kwargs):
|
|
29
|
+
"""
|
|
30
|
+
Apply strain to the current JC model.
|
|
31
|
+
|
|
32
|
+
This function updates the internal variable to store hardening state.
|
|
33
|
+
|
|
34
|
+
Parameters
|
|
35
|
+
----------
|
|
36
|
+
strain : float or StrainTensor
|
|
37
|
+
kwargs : dict
|
|
38
|
+
Keyword arguments passed to flow_stress()
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
float
|
|
43
|
+
Associated flow stress (positive)
|
|
44
|
+
|
|
45
|
+
See Also
|
|
46
|
+
--------
|
|
47
|
+
flow_stress : compute the flow stress, given a cumulative equivalent strain
|
|
48
|
+
"""
|
|
49
|
+
if isinstance(strain, float):
|
|
50
|
+
self.plastic_strain += np.abs(strain)
|
|
51
|
+
elif isinstance(strain, StrainTensor):
|
|
52
|
+
self.plastic_strain += strain.eq_strain()
|
|
53
|
+
else:
|
|
54
|
+
raise ValueError('The applied strain must be float of StrainTensor')
|
|
55
|
+
return self.flow_stress(self.plastic_strain, **kwargs)
|
|
56
|
+
|
|
57
|
+
def compute_strain_increment(self, stress, **kwargs):
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
def reset_strain(self):
|
|
61
|
+
self.plastic_strain = 0.0
|
|
62
|
+
|
|
63
|
+
def eq_stress(self, stress):
|
|
64
|
+
if self.criterion == 'j2':
|
|
65
|
+
return stress.vonMises()
|
|
66
|
+
else:
|
|
67
|
+
return stress.Tresca()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class JohnsonCook(IsotropicHardening):
|
|
71
|
+
def __init__(self, A, B, n, C=None, eps_dot_ref=1.0, m=None, T0=25, Tm=None, criterion='von Mises'):
|
|
7
72
|
"""
|
|
8
73
|
Constructor for a Jonhson-Cook (JC) model.
|
|
9
74
|
|
|
@@ -28,6 +93,8 @@ class JohnsonCook:
|
|
|
28
93
|
Reference temperature
|
|
29
94
|
Tm : float, optional
|
|
30
95
|
Melting temperature (at which the flow stress is zero)
|
|
96
|
+
criterion : str, optional
|
|
97
|
+
Plasticity criterion to use. It can be 'von Mises' or 'Tresca'.
|
|
31
98
|
|
|
32
99
|
Notes
|
|
33
100
|
-----
|
|
@@ -50,6 +117,7 @@ class JohnsonCook:
|
|
|
50
117
|
1 & \\text{otherwise}
|
|
51
118
|
\\end{cases}
|
|
52
119
|
"""
|
|
120
|
+
super().__init__(criterion=criterion)
|
|
53
121
|
self.A = A
|
|
54
122
|
self.B = B
|
|
55
123
|
self.C = C
|
|
@@ -74,7 +142,7 @@ class JohnsonCook:
|
|
|
74
142
|
Temperature. If float, the temperature is supposed to be homogeneous for every value of eps_p.
|
|
75
143
|
Returns
|
|
76
144
|
-------
|
|
77
|
-
numpy.ndarray
|
|
145
|
+
float or numpy.ndarray
|
|
78
146
|
Flow stress
|
|
79
147
|
"""
|
|
80
148
|
eps_p = np.asarray(eps_p)
|
|
@@ -97,29 +165,118 @@ class JohnsonCook:
|
|
|
97
165
|
return stress
|
|
98
166
|
|
|
99
167
|
|
|
100
|
-
|
|
168
|
+
|
|
169
|
+
def compute_strain_increment(self, stress, T=None, apply_strain=True, criterion='von Mises'):
|
|
101
170
|
"""
|
|
102
|
-
Given the equivalent stress, compute the strain
|
|
171
|
+
Given the equivalent stress, compute the strain increment with respect to the normality rule.
|
|
103
172
|
|
|
104
173
|
Parameters
|
|
105
174
|
----------
|
|
106
|
-
stress : float or
|
|
107
|
-
Equivalent stress
|
|
108
|
-
T : float
|
|
175
|
+
stress : float or StressTensor
|
|
176
|
+
Equivalent stress to compute the stress from, or full stress tensor.
|
|
177
|
+
T : float
|
|
109
178
|
Temperature
|
|
179
|
+
apply_strain : bool, optional
|
|
180
|
+
If true, the JC model will be updated to account for the applied strain (hardening)
|
|
181
|
+
criterion : str, optional
|
|
182
|
+
Plasticity criterion to consider to compute the equivalent stress and apply the normality rule.
|
|
183
|
+
It can be 'von Mises', 'Tresca' or 'J2'. 'J2' is equivalent to 'von Mises'.
|
|
110
184
|
|
|
111
185
|
Returns
|
|
112
186
|
-------
|
|
113
|
-
|
|
114
|
-
|
|
187
|
+
StrainTensor or float
|
|
188
|
+
Increment of plastic strain. If the input stress is float, only the magnitude of the increment will be
|
|
189
|
+
returned (float value). If the stress is of type StressTensor, the returned value will be a full
|
|
190
|
+
StrainTensor.
|
|
191
|
+
|
|
192
|
+
See Also
|
|
193
|
+
--------
|
|
194
|
+
apply_strain : apply strain to the JC model and updates its hardening value
|
|
115
195
|
"""
|
|
116
|
-
|
|
196
|
+
if isinstance(stress, StressTensor):
|
|
197
|
+
eq_stress = self.eq_stress(stress)
|
|
198
|
+
else:
|
|
199
|
+
eq_stress = stress
|
|
117
200
|
if T is None:
|
|
118
|
-
|
|
201
|
+
if eq_stress > self.A:
|
|
202
|
+
k = eq_stress - self.A
|
|
203
|
+
total_strain = (1 / self.B * k) ** (1 / self.n)
|
|
204
|
+
strain_increment = np.max((total_strain - self.plastic_strain, 0))
|
|
205
|
+
else:
|
|
206
|
+
strain_increment = 0.0
|
|
119
207
|
else:
|
|
120
208
|
if self.T0 is None or self.Tm is None or self.m is None:
|
|
121
209
|
raise ValueError('T0, Tm and m must be defined for using a temperature-dependent model')
|
|
122
210
|
else:
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
211
|
+
if T >= self.Tm:
|
|
212
|
+
strain_increment = np.inf
|
|
213
|
+
else:
|
|
214
|
+
theta = (T - self.T0) / (self.Tm - self.T0)
|
|
215
|
+
theta_m = theta**self.m
|
|
216
|
+
k = (eq_stress / (1 - theta_m) - self.A)
|
|
217
|
+
if k<0:
|
|
218
|
+
strain_increment = 0.0
|
|
219
|
+
else:
|
|
220
|
+
total_strain = (1/self.B * k)**(1/self.n)
|
|
221
|
+
strain_increment = np.max((total_strain - self.plastic_strain, 0))
|
|
222
|
+
if apply_strain:
|
|
223
|
+
self.apply_strain(strain_increment)
|
|
224
|
+
|
|
225
|
+
if isinstance(stress, StressTensor):
|
|
226
|
+
n = normality_rule(stress, criterion=criterion)
|
|
227
|
+
return n * strain_increment
|
|
228
|
+
else:
|
|
229
|
+
return strain_increment
|
|
230
|
+
|
|
231
|
+
def reset_strain(self):
|
|
232
|
+
"""
|
|
233
|
+
Reinitialize the plastic strain to 0
|
|
234
|
+
"""
|
|
235
|
+
self.plastic_strain = 0.0
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def normality_rule(stress, criterion='von Mises'):
|
|
239
|
+
"""
|
|
240
|
+
Apply the normality rule for plastic flow, given a yield criterion.
|
|
241
|
+
|
|
242
|
+
The stress can be a single tensor, or an array of tensors.
|
|
243
|
+
|
|
244
|
+
Parameters
|
|
245
|
+
----------
|
|
246
|
+
stress : StressTensor
|
|
247
|
+
Stress tensor to apply the normality rule from
|
|
248
|
+
criterion : str, optional
|
|
249
|
+
Name of the criterion to use. Can be either 'von Mises' or 'Tresca'
|
|
250
|
+
|
|
251
|
+
Returns
|
|
252
|
+
-------
|
|
253
|
+
StrainTensor
|
|
254
|
+
If a single stress tensor is passed, the returned array will be of shape
|
|
255
|
+
|
|
256
|
+
Notes
|
|
257
|
+
-----
|
|
258
|
+
The singular points for the Tresca criterion are treated as the von Mises criterion, which is equivalent to the
|
|
259
|
+
average of the two adjacent normals of the domain.
|
|
260
|
+
"""
|
|
261
|
+
if criterion.lower()=='von mises':
|
|
262
|
+
eq_stress = stress.vonMises()
|
|
263
|
+
dev_stress= stress.deviatoric_part()
|
|
264
|
+
gradient_tensor = dev_stress / eq_stress
|
|
265
|
+
return StrainTensor(3/2 * gradient_tensor.matrix)
|
|
266
|
+
elif criterion.lower()=='tresca':
|
|
267
|
+
vals, dirs = stress.eig()
|
|
268
|
+
u1 = dirs[...,0]
|
|
269
|
+
u3 = dirs[...,2]
|
|
270
|
+
s1 = vals[...,0]
|
|
271
|
+
s2 = vals[..., 1]
|
|
272
|
+
s3 = vals[...,2]
|
|
273
|
+
A = np.einsum('...i,...j->...ij',u1, u1)
|
|
274
|
+
B = np.einsum('...i,...j->...ij',u3, u3)
|
|
275
|
+
normal = A - B
|
|
276
|
+
singular_points = np.logical_or(s2==s1, s2==s3)
|
|
277
|
+
normal[singular_points] = normality_rule(stress[singular_points], criterion='von Mises').matrix
|
|
278
|
+
normal[np.logical_and(s2==s1, s2==s3)] = 0.0
|
|
279
|
+
strain = StrainTensor(normal)
|
|
280
|
+
return strain / strain.eq_strain()
|
|
281
|
+
else:
|
|
282
|
+
raise NotImplementedError('The normality rule is only implemented for von Mises (J2) and Tresca criteria.')
|
Elasticipy/SecondOrderTensor.py
CHANGED
|
@@ -290,7 +290,7 @@ class SecondOrderTensor:
|
|
|
290
290
|
@property
|
|
291
291
|
def J2(self):
|
|
292
292
|
"""
|
|
293
|
-
Second invariant of the deviatoric part of the
|
|
293
|
+
Second invariant of the deviatoric part of the tensor.
|
|
294
294
|
|
|
295
295
|
Returns
|
|
296
296
|
-------
|
|
@@ -302,7 +302,7 @@ class SecondOrderTensor:
|
|
|
302
302
|
@property
|
|
303
303
|
def J3(self):
|
|
304
304
|
"""
|
|
305
|
-
Third invariant of the deviatoric part of the
|
|
305
|
+
Third invariant of the deviatoric part of the tensor.
|
|
306
306
|
|
|
307
307
|
Returns
|
|
308
308
|
-------
|
|
@@ -311,6 +311,48 @@ class SecondOrderTensor:
|
|
|
311
311
|
"""
|
|
312
312
|
return self.deviatoric_part().I3
|
|
313
313
|
|
|
314
|
+
def Lode_angle(self, degrees=False):
|
|
315
|
+
"""
|
|
316
|
+
Computes the Lode angle of the tensor.
|
|
317
|
+
|
|
318
|
+
The returned value is defined from the positive cosine (see Notes).
|
|
319
|
+
|
|
320
|
+
Parameters
|
|
321
|
+
----------
|
|
322
|
+
degrees : bool, optional
|
|
323
|
+
Whether to return the angle in degrees or not
|
|
324
|
+
|
|
325
|
+
Returns
|
|
326
|
+
-------
|
|
327
|
+
float or numpy.ndarray
|
|
328
|
+
|
|
329
|
+
See Also
|
|
330
|
+
--------
|
|
331
|
+
J2 : Second invariant of the deviatoric part
|
|
332
|
+
J3 : Third invariant of the deviatoric part
|
|
333
|
+
|
|
334
|
+
Notes
|
|
335
|
+
-----
|
|
336
|
+
The Lode angle is defined such that:
|
|
337
|
+
|
|
338
|
+
.. math::
|
|
339
|
+
|
|
340
|
+
\\cos(3\\theta)= \\frac{J_3}{2}\\left(\\frac{3}{J_2}\\right)^{3/2}
|
|
341
|
+
"""
|
|
342
|
+
J2 = np.atleast_1d(self.J2)
|
|
343
|
+
J3 = np.atleast_1d(self.J3)
|
|
344
|
+
non_hydro = J2 !=0.
|
|
345
|
+
cosine = np.ones(shape=J3.shape) * np.nan
|
|
346
|
+
cosine[non_hydro] = J3[non_hydro] / 2 * (3 / J2[non_hydro] )**(3 / 2)
|
|
347
|
+
if degrees:
|
|
348
|
+
theta = np.arccos(cosine) * 60 / np.pi
|
|
349
|
+
else:
|
|
350
|
+
theta = np.arccos(cosine) / 3
|
|
351
|
+
if self.shape:
|
|
352
|
+
return theta
|
|
353
|
+
else:
|
|
354
|
+
return theta[0]
|
|
355
|
+
|
|
314
356
|
def trace(self):
|
|
315
357
|
"""
|
|
316
358
|
Return the traces of the tensor array
|
|
@@ -377,6 +419,18 @@ class SecondOrderTensor:
|
|
|
377
419
|
else:
|
|
378
420
|
raise NotImplementedError('Left multiplication is only implemented for scalar values.')
|
|
379
421
|
|
|
422
|
+
def __truediv__(self, other):
|
|
423
|
+
new_mat = np.zeros(self.matrix.shape)
|
|
424
|
+
non_zero = np.any(self.matrix, axis=(-1, -2))
|
|
425
|
+
if isinstance(other, (float, int)):
|
|
426
|
+
new_mat[non_zero] = self.matrix[non_zero] / other # Hack to force 0/0 = 0
|
|
427
|
+
elif isinstance(other, np.ndarray) and (self.shape == other.shape):
|
|
428
|
+
new_mat[non_zero] = np.einsum('pij,p->pij', self.matrix[non_zero], 1/other[non_zero])
|
|
429
|
+
return self.__class__(new_mat)
|
|
430
|
+
else:
|
|
431
|
+
raise NotImplementedError('Tensors can only be divided by scalar values or by arrays of the same shape.')
|
|
432
|
+
return self.__class__(new_mat)
|
|
433
|
+
|
|
380
434
|
def __eq__(self, other) -> np.ndarray:
|
|
381
435
|
"""
|
|
382
436
|
Check whether the tensors in the tensor array are equal
|
|
@@ -719,7 +773,7 @@ class SecondOrderTensor:
|
|
|
719
773
|
|
|
720
774
|
Returns
|
|
721
775
|
-------
|
|
722
|
-
|
|
776
|
+
SkewSymmetricSecondOrderTensor
|
|
723
777
|
Skew-symmetric tensor
|
|
724
778
|
"""
|
|
725
779
|
new_mat = 0.5 * (self.matrix - self._transposeTensor())
|
|
@@ -731,7 +785,7 @@ class SecondOrderTensor:
|
|
|
731
785
|
|
|
732
786
|
Returns
|
|
733
787
|
-------
|
|
734
|
-
|
|
788
|
+
self
|
|
735
789
|
Spherical part
|
|
736
790
|
|
|
737
791
|
See Also
|
|
@@ -748,7 +802,7 @@ class SecondOrderTensor:
|
|
|
748
802
|
|
|
749
803
|
Returns
|
|
750
804
|
-------
|
|
751
|
-
|
|
805
|
+
self
|
|
752
806
|
|
|
753
807
|
See Also
|
|
754
808
|
--------
|
|
@@ -769,7 +823,7 @@ class SecondOrderTensor:
|
|
|
769
823
|
|
|
770
824
|
Returns
|
|
771
825
|
-------
|
|
772
|
-
|
|
826
|
+
cls
|
|
773
827
|
Array of identity tensors
|
|
774
828
|
|
|
775
829
|
See Also
|
|
@@ -798,7 +852,7 @@ class SecondOrderTensor:
|
|
|
798
852
|
|
|
799
853
|
Returns
|
|
800
854
|
-------
|
|
801
|
-
|
|
855
|
+
cls
|
|
802
856
|
Array of ones tensors
|
|
803
857
|
|
|
804
858
|
See Also
|
|
@@ -826,7 +880,7 @@ class SecondOrderTensor:
|
|
|
826
880
|
|
|
827
881
|
Returns
|
|
828
882
|
-------
|
|
829
|
-
|
|
883
|
+
cls
|
|
830
884
|
Array of ones tensors
|
|
831
885
|
|
|
832
886
|
See Also
|
|
@@ -855,7 +909,7 @@ class SecondOrderTensor:
|
|
|
855
909
|
will be of the same shape as magnitude.
|
|
856
910
|
Returns
|
|
857
911
|
-------
|
|
858
|
-
|
|
912
|
+
cls
|
|
859
913
|
tensor or tensor array
|
|
860
914
|
"""
|
|
861
915
|
mat = _tensor_from_direction_magnitude(u, u, magnitude)
|
|
@@ -875,7 +929,7 @@ class SecondOrderTensor:
|
|
|
875
929
|
|
|
876
930
|
Returns
|
|
877
931
|
-------
|
|
878
|
-
|
|
932
|
+
cls
|
|
879
933
|
Tensor or tensor array of uniform random value
|
|
880
934
|
|
|
881
935
|
See Also
|
|
@@ -930,7 +984,7 @@ class SecondOrderTensor:
|
|
|
930
984
|
|
|
931
985
|
Returns
|
|
932
986
|
-------
|
|
933
|
-
|
|
987
|
+
cls
|
|
934
988
|
Tensor or tensor array of normal random value
|
|
935
989
|
"""
|
|
936
990
|
if shape is None:
|
|
@@ -964,7 +1018,7 @@ class SecondOrderTensor:
|
|
|
964
1018
|
will be of the same shape as magnitude.
|
|
965
1019
|
Returns
|
|
966
1020
|
-------
|
|
967
|
-
|
|
1021
|
+
cls
|
|
968
1022
|
tensor or tensor array
|
|
969
1023
|
"""
|
|
970
1024
|
if np.abs(np.dot(u, v)) > 1e-5:
|
|
@@ -1281,10 +1335,39 @@ class SymmetricSecondOrderTensor(SecondOrderTensor):
|
|
|
1281
1335
|
raise ValueError("array must be of shape (6,) or (...,6) with Voigt vector")
|
|
1282
1336
|
|
|
1283
1337
|
def eig(self):
|
|
1284
|
-
|
|
1338
|
+
"""
|
|
1339
|
+
Compute the principal values (eigenvaleues) and principal direction (eigenvectors) of the tensor, sorted in
|
|
1340
|
+
descending order of principal values
|
|
1341
|
+
|
|
1342
|
+
Returns
|
|
1343
|
+
-------
|
|
1344
|
+
numpy.ndarray
|
|
1345
|
+
Principal values
|
|
1346
|
+
numpy.ndarray
|
|
1347
|
+
Principal directions
|
|
1348
|
+
|
|
1349
|
+
See Also
|
|
1350
|
+
--------
|
|
1351
|
+
eigvals : compute the principal values only
|
|
1352
|
+
"""
|
|
1353
|
+
eigvals, eigdir = np.linalg.eigh(self.matrix)
|
|
1354
|
+
return np.flip(eigvals,axis=-1), np.flip(eigdir,axis=-1)
|
|
1285
1355
|
|
|
1286
1356
|
def eigvals(self):
|
|
1287
|
-
|
|
1357
|
+
"""
|
|
1358
|
+
Compute the principal values (eigenvalues), sorted in descending order.
|
|
1359
|
+
|
|
1360
|
+
Returns
|
|
1361
|
+
-------
|
|
1362
|
+
numpy.ndarray
|
|
1363
|
+
Principal values
|
|
1364
|
+
|
|
1365
|
+
See Also
|
|
1366
|
+
--------
|
|
1367
|
+
eig : return the principal values and principal directions
|
|
1368
|
+
"""
|
|
1369
|
+
eigvals = np.linalg.eigvalsh(self.matrix)
|
|
1370
|
+
return np.flip(eigvals,axis=-1)
|
|
1288
1371
|
|
|
1289
1372
|
|
|
1290
1373
|
class SkewSymmetricSecondOrderTensor(SecondOrderTensor):
|
|
@@ -1352,7 +1435,8 @@ def rotation_to_matrix(rotation, return_transpose=False):
|
|
|
1352
1435
|
if isinstance(rotation, Rotation):
|
|
1353
1436
|
matrix = rotation.as_matrix()
|
|
1354
1437
|
elif is_orix_rotation(rotation):
|
|
1355
|
-
|
|
1438
|
+
inv_rotation = ~rotation
|
|
1439
|
+
matrix = inv_rotation.to_matrix()
|
|
1356
1440
|
else:
|
|
1357
1441
|
raise TypeError('The input argument must be of class scipy.transform.Rotation or '
|
|
1358
1442
|
'orix.quaternion.rotation.Rotation')
|
|
@@ -29,13 +29,14 @@ class StrainTensor(SymmetricSecondOrderTensor):
|
|
|
29
29
|
|
|
30
30
|
Returns
|
|
31
31
|
-------
|
|
32
|
-
|
|
32
|
+
numpy.ndarray or float
|
|
33
33
|
Volumetric change
|
|
34
34
|
"""
|
|
35
35
|
return self.I1
|
|
36
36
|
|
|
37
37
|
def eq_strain(self):
|
|
38
|
-
|
|
38
|
+
"""von Mises equivalent strain"""
|
|
39
|
+
return np.sqrt(2/3 * self.ddot(self))
|
|
39
40
|
|
|
40
41
|
def elastic_energy(self, stress):
|
|
41
42
|
"""
|
|
@@ -101,7 +102,7 @@ class StressTensor(SymmetricSecondOrderTensor):
|
|
|
101
102
|
vonMises : von Mises equivalent stress
|
|
102
103
|
"""
|
|
103
104
|
ps = self.principal_stresses()
|
|
104
|
-
return ps[
|
|
105
|
+
return ps[...,0] - ps[...,-1]
|
|
105
106
|
|
|
106
107
|
def hydrostaticPressure(self):
|
|
107
108
|
"""
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
Elasticipy/CrystalSymmetries.py,sha256=DAX-XPgYqI2nFvf6anCVvZ5fLM0CNSDJ7r2h15l3Hoc,3958
|
|
2
2
|
Elasticipy/FourthOrderTensor.py,sha256=LuqLxcWeonumxgVCjTIvcIjCkAqMK4ZNBlpGLvXGPeA,54105
|
|
3
|
-
Elasticipy/Plasticity.py,sha256=
|
|
3
|
+
Elasticipy/Plasticity.py,sha256=K6ml5Lfezt-9F2PJvuAUdxsQksZV3bkWYj9GdVTt9gw,10189
|
|
4
4
|
Elasticipy/PoleFigure.py,sha256=G3Sz7ssX2KKY96g3XEvcaOYFmEat9JUCdb2A91XbA6w,3531
|
|
5
|
-
Elasticipy/SecondOrderTensor.py,sha256=
|
|
5
|
+
Elasticipy/SecondOrderTensor.py,sha256=0dTZZ6rw9E9ctnyto6cuRajsXk2LmxCcJUOB2YO-u-E,46288
|
|
6
6
|
Elasticipy/SphericalFunction.py,sha256=X6hrjwCiZkLjiUQ8WO2W4vLNOlbQ4jLWsloOg33IlL4,41244
|
|
7
|
-
Elasticipy/StressStrainTensors.py,sha256=
|
|
7
|
+
Elasticipy/StressStrainTensors.py,sha256=WdElPvSl3kpPVF3MNfbQsHtkmm0edqi4Tb2DoE9dD7k,2981
|
|
8
8
|
Elasticipy/ThermalExpansion.py,sha256=nfPTXuqI4fJe14YLzYn8zfSjpYaep8URRYawj8xzjfo,6012
|
|
9
9
|
Elasticipy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
Elasticipy/gui.py,sha256=zyVnvp6IIi3FDR5hWfIJrOP28Y7XkP4wc71XXMyGpeo,11247
|
|
11
|
-
elasticipy-2.
|
|
12
|
-
elasticipy-2.
|
|
13
|
-
elasticipy-2.
|
|
14
|
-
elasticipy-2.
|
|
15
|
-
elasticipy-2.
|
|
11
|
+
elasticipy-2.9.0.dist-info/LICENSE,sha256=qNthTMSjVkIDM1_BREgVFQHdn1wVNQi9pwWVfTIazMA,1074
|
|
12
|
+
elasticipy-2.9.0.dist-info/METADATA,sha256=ydDKE8dp7qNcCiQhduU_HIrgIrgWE5YF3_1F7fpx6L0,3810
|
|
13
|
+
elasticipy-2.9.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
14
|
+
elasticipy-2.9.0.dist-info/top_level.txt,sha256=k4zSQzJR5P4vzlHlhWUaxNgvgloq4KIp8oca2X8gQOw,11
|
|
15
|
+
elasticipy-2.9.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|