elasticipy 2.9.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.
- {elasticipy-2.9.0 → elasticipy-4.0.0}/Examples/Elasticipy_vs_pymatgen.py +2 -4
- {elasticipy-2.9.0 → elasticipy-4.0.0}/Examples/Elate_vs_Elasticipy.py +2 -2
- {elasticipy-2.9.0 → elasticipy-4.0.0}/Examples/Example_Stiffness_tensor.py +1 -1
- {elasticipy-2.9.0 → elasticipy-4.0.0}/Examples/Example_StressStrain_arrays.py +2 -2
- {elasticipy-2.9.0 → elasticipy-4.0.0}/Examples/Example_WaveVelocity.py +1 -2
- {elasticipy-2.9.0 → elasticipy-4.0.0}/Examples/Multiple_phases.py +1 -1
- elasticipy-4.0.0/Examples/SelfConsistent.py +89 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/Examples/essai_plasticity.py +3 -3
- {elasticipy-2.9.0 → elasticipy-4.0.0}/Examples/example_readwrite.py +1 -1
- {elasticipy-2.9.0 → elasticipy-4.0.0}/JOSS/paper.bib +4 -2
- {elasticipy-2.9.0 → elasticipy-4.0.0}/JOSS/paper.md +8 -5
- {elasticipy-2.9.0/src/elasticipy.egg-info → elasticipy-4.0.0}/PKG-INFO +6 -5
- {elasticipy-2.9.0 → elasticipy-4.0.0}/README.md +3 -3
- elasticipy-4.0.0/docs/source/Elasticipy.plasticity.rst +7 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Elasticipy.rst +7 -5
- elasticipy-4.0.0/docs/source/Elasticipy.spherical_function.rst +7 -0
- elasticipy-4.0.0/docs/source/Elasticipy.tensors.elasticity.rst +7 -0
- elasticipy-4.0.0/docs/source/Elasticipy.tensors.fourth_order.rst +7 -0
- elasticipy-4.0.0/docs/source/Elasticipy.tensors.second_order.rst +7 -0
- elasticipy-4.0.0/docs/source/Elasticipy.tensors.stress_strain.rst +7 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/Plasticity.rst +64 -37
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/Tutorial_AveragingMethods.rst +2 -2
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/Tutorial_MultiplePhases.rst +1 -1
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/Tutorial_ReadWriteFiles.rst +3 -2
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/Tutorial_StiffnessTensor.rst +2 -2
- elasticipy-4.0.0/docs/source/Tutorials/Tutorial_StressStrain.rst +232 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/Tutorial_ThermalExpansion.rst +10 -6
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/Tutorial_wave-velocities.rst +3 -2
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/conf.py +2 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/index.rst +4 -0
- elasticipy-4.0.0/docs/source/logo/favicon.png +0 -0
- elasticipy-4.0.0/docs/source/logo/logo.png +0 -0
- elasticipy-4.0.0/docs/source/logo/logo.svg +100 -0
- elasticipy-4.0.0/docs/source/logo/logo_text.png +0 -0
- elasticipy-4.0.0/docs/source/logo/logo_text.svg +126 -0
- elasticipy-4.0.0/docs/source/logo/logo_text_whitebg.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/modules.rst +1 -1
- elasticipy-4.0.0/src/Elasticipy/FourthOrderTensor.py +16 -0
- elasticipy-4.0.0/src/Elasticipy/StressStrainTensors.py +16 -0
- elasticipy-4.0.0/src/Elasticipy/ThermalExpansion.py +12 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/src/Elasticipy/gui.py +2 -2
- elasticipy-2.9.0/src/Elasticipy/Plasticity.py → elasticipy-4.0.0/src/Elasticipy/plasticity.py +106 -56
- elasticipy-2.9.0/src/Elasticipy/SphericalFunction.py → elasticipy-4.0.0/src/Elasticipy/spherical_function.py +1 -1
- elasticipy-2.9.0/src/Elasticipy/FourthOrderTensor.py → elasticipy-4.0.0/src/Elasticipy/tensors/elasticity.py +590 -397
- elasticipy-4.0.0/src/Elasticipy/tensors/fourth_order.py +591 -0
- elasticipy-2.9.0/src/Elasticipy/SecondOrderTensor.py → elasticipy-4.0.0/src/Elasticipy/tensors/second_order.py +248 -59
- elasticipy-2.9.0/src/Elasticipy/StressStrainTensors.py → elasticipy-4.0.0/src/Elasticipy/tensors/stress_strain.py +10 -6
- elasticipy-2.9.0/src/Elasticipy/ThermalExpansion.py → elasticipy-4.0.0/src/Elasticipy/tensors/thermal_expansion.py +89 -18
- {elasticipy-2.9.0 → elasticipy-4.0.0/src/elasticipy.egg-info}/PKG-INFO +6 -5
- {elasticipy-2.9.0 → elasticipy-4.0.0}/src/elasticipy.egg-info/SOURCES.txt +24 -10
- elasticipy-4.0.0/tests/__init__.py +0 -0
- elasticipy-4.0.0/tests/test_FourthOrderTensors.py +112 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/tests/test_SphericalFunction.py +2 -2
- {elasticipy-2.9.0 → elasticipy-4.0.0}/tests/test_StiffnessTensor.py +349 -77
- {elasticipy-2.9.0 → elasticipy-4.0.0}/tests/test_StressStrainTensors.py +179 -20
- {elasticipy-2.9.0 → elasticipy-4.0.0}/tests/test_ThermalExpansion.py +22 -1
- {elasticipy-2.9.0 → elasticipy-4.0.0}/tests/test_plasticity.py +34 -17
- elasticipy-2.9.0/docs/source/Elasticipy.FourthOrderTensor.rst +0 -7
- elasticipy-2.9.0/docs/source/Elasticipy.Plasticity.rst +0 -7
- elasticipy-2.9.0/docs/source/Elasticipy.SecondOrderTensor.rst +0 -7
- elasticipy-2.9.0/docs/source/Elasticipy.SphericalFunction.rst +0 -7
- elasticipy-2.9.0/docs/source/Elasticipy.StressStrainTensors.rst +0 -7
- elasticipy-2.9.0/docs/source/Tutorials/Tutorial_StressStrain.rst +0 -445
- {elasticipy-2.9.0 → elasticipy-4.0.0}/.github/workflows/Codecov.yml +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/.github/workflows/JOSS build.yml +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/.github/workflows/cloc.yml +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/.github/workflows/python-publish.yml +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/.readthedocs.yaml +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/CODE_OF_CONDUCT.md +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/CONTRIBUTING.md +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/Examples/MaterialsProject.json +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/JOSS/ElasticipyVSpymatgen.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/JOSS/Nye.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/JOSS/Plot_E.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/JOSS/YoungModulus.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/LICENSE +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/_static/images/HyperSphericalCoordinates.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/index.rst +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/GUI.rst +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/Cyclic.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/E_PF.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/E_VRH_sections.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/E_hill_fiber.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/E_plot3D.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/E_xyz_sections.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/GUI.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/G_plot3D.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/G_plot3D_min.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/G_xyz_sections.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/Incremental.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/Shear.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/Stress-controlled.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/StressStrain-controlled.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/WaveVelocities.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials/images/plot_volumeFraction.png +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/docs/source/Tutorials.rst +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/pyproject.toml +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/requirements.txt +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/setup.cfg +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/src/Elasticipy/__init__.py +0 -0
- /elasticipy-2.9.0/src/Elasticipy/CrystalSymmetries.py → /elasticipy-4.0.0/src/Elasticipy/crystal_symmetries.py +0 -0
- /elasticipy-2.9.0/src/Elasticipy/PoleFigure.py → /elasticipy-4.0.0/src/Elasticipy/polefigure.py +0 -0
- {elasticipy-2.9.0/tests → elasticipy-4.0.0/src/Elasticipy/tensors}/__init__.py +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/src/elasticipy.egg-info/dependency_links.txt +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/src/elasticipy.egg-info/requires.txt +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/src/elasticipy.egg-info/top_level.txt +0 -0
- {elasticipy-2.9.0 → elasticipy-4.0.0}/tests/MaterialsProject.json +0 -0
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
from
|
|
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.
|
|
3
|
+
from Elasticipy.tensors.elasticity import StiffnessTensor
|
|
4
4
|
import matplotlib as mpl
|
|
5
5
|
mpl.use('Qt5Agg') # Ensure interactive plot
|
|
6
|
-
from Elasticipy.
|
|
6
|
+
from Elasticipy.spherical_function import sph2cart, _plot3D
|
|
7
7
|
import time
|
|
8
8
|
import matplotlib.pyplot as plt
|
|
9
9
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Imports and simple example of stress
|
|
3
3
|
# ======================================================
|
|
4
4
|
import numpy as np
|
|
5
|
-
from Elasticipy.
|
|
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.
|
|
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.
|
|
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,
|
|
@@ -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.
|
|
2
|
-
from Elasticipy.
|
|
3
|
-
from Elasticipy.
|
|
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
|
|
@@ -6,6 +6,7 @@ pages = {314-319},
|
|
|
6
6
|
year = {2013},
|
|
7
7
|
issn = {0927-0256},
|
|
8
8
|
url = {https://doi.org/10.1016/j.commatsci.2012.10.028},
|
|
9
|
+
doi = {10.1016/j.commatsci.2012.10.028},
|
|
9
10
|
author = {Shyue Ping Ong and William Davidson Richards and Anubhav Jain and Geoffroy Hautier and Michael Kocher and Shreyas Cholia and Dan Gunter and Vincent L. Chevrier and Kristin A. Persson and Gerbrand Ceder},
|
|
10
11
|
keywords = {Materials, Project, Design, Thermodynamics, High-throughput},
|
|
11
12
|
}
|
|
@@ -33,7 +34,8 @@ journal = {Journal of Physics: Condensed Matter},
|
|
|
33
34
|
pages={175--192},
|
|
34
35
|
year={2011},
|
|
35
36
|
publisher={The Geological Society of London London},
|
|
36
|
-
url={http://dx.doi.org/10.1144/SP360.10}
|
|
37
|
+
url={http://dx.doi.org/10.1144/SP360.10},
|
|
38
|
+
doi={10.1144/SP360.10}
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
@book{nye,
|
|
@@ -124,4 +126,4 @@ DOI = {10.5194/se-11-259-2020}
|
|
|
124
126
|
doi = {10.1038/s41586-020-2649-2},
|
|
125
127
|
publisher = {Springer Science and Business Media {LLC}},
|
|
126
128
|
url = {https://doi.org/10.1038/s41586-020-2649-2}
|
|
127
|
-
}
|
|
129
|
+
}
|
|
@@ -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
|
-
|
|
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.
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: elasticipy
|
|
3
|
-
Version:
|
|
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
|
[](https://pypi.org/project/elasticipy/)
|
|
33
33
|
[](https://pypistats.org/packages/elasticipy)
|
|
34
34
|
[](https://github.com/DorianDepriester/Elasticipy/blob/main/LICENSE)
|
|
@@ -36,10 +36,11 @@ Requires-Dist: mp_api; extra == "dev"
|
|
|
36
36
|
[](https://doi.org/10.5281/zenodo.14501849)
|
|
37
37
|
[](https://codecov.io/gh/DorianDepriester/Elasticipy)
|
|
38
38
|

|
|
39
|
+
[](https://joss.theoj.org/papers/8cce91b782f17f52e9ee30916cd86ad5)
|
|
39
40
|
|
|
41
|
+
# 
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
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).
|
|
43
44
|
This package also provides a collection of easy-to-use and very fast tools to work on stress and strain tensors.
|
|
44
45
|
|
|
45
46
|
## Main features
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# Elasticipy
|
|
2
1
|
[](https://pypi.org/project/elasticipy/)
|
|
3
2
|
[](https://pypistats.org/packages/elasticipy)
|
|
4
3
|
[](https://github.com/DorianDepriester/Elasticipy/blob/main/LICENSE)
|
|
@@ -6,10 +5,11 @@
|
|
|
6
5
|
[](https://doi.org/10.5281/zenodo.14501849)
|
|
7
6
|
[](https://codecov.io/gh/DorianDepriester/Elasticipy)
|
|
8
7
|

|
|
8
|
+
[](https://joss.theoj.org/papers/8cce91b782f17f52e9ee30916cd86ad5)
|
|
9
9
|
|
|
10
|
+
# 
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
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).
|
|
13
13
|
This package also provides a collection of easy-to-use and very fast tools to work on stress and strain tensors.
|
|
14
14
|
|
|
15
15
|
## Main features
|
|
@@ -7,11 +7,13 @@ Submodules
|
|
|
7
7
|
.. toctree::
|
|
8
8
|
:maxdepth: 4
|
|
9
9
|
|
|
10
|
-
Elasticipy.
|
|
11
|
-
Elasticipy.
|
|
12
|
-
Elasticipy.
|
|
13
|
-
Elasticipy.
|
|
14
|
-
Elasticipy.
|
|
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
|
---------------
|
|
@@ -39,17 +39,17 @@ First, let us create the model:
|
|
|
39
39
|
|
|
40
40
|
.. doctest::
|
|
41
41
|
|
|
42
|
-
>>> from Elasticipy.
|
|
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.
|
|
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.
|
|
52
|
+
>>> from Elasticipy.tensors.stress_strain import StressTensor, StrainTensor
|
|
53
53
|
>>> import numpy as np
|
|
54
54
|
>>> n_step = 100
|
|
55
55
|
>>> stress_mag = np.linspace(0, 725, n_step)
|
|
@@ -63,17 +63,44 @@ So now, the plastic strain can be computed using an iterative approach:
|
|
|
63
63
|
|
|
64
64
|
>>> plastic_strain = StrainTensor.zeros(n_step)
|
|
65
65
|
>>> for i in range(1, n_step):
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
... strain_increment = JC.compute_strain_increment(stress[i])
|
|
67
|
+
... plastic_strain[i] = plastic_strain[i-1] + strain_increment
|
|
68
68
|
|
|
69
69
|
That's all. Finally, let us plot the applied stress as a function of the overall elongation:
|
|
70
70
|
|
|
71
71
|
>>> from matplotlib import pyplot as plt
|
|
72
72
|
>>> elong = elastic_strain.C[0,0]+plastic_strain.C[0,0]
|
|
73
73
|
>>> fig, ax = plt.subplots()
|
|
74
|
-
>>> ax.plot(elong, stress_mag, label='Stress-controlled')
|
|
75
|
-
>>> ax.set_xlabel(r'$\varepsilon_{xx}$')
|
|
76
|
-
>>> ax.set_ylabel('Tensile stress (MPa)')
|
|
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
|
+
|
|
80
|
+
>>> import numpy as np
|
|
81
|
+
>>> n_step = 100
|
|
82
|
+
>>> stress_mag = np.linspace(0, 725, n_step)
|
|
83
|
+
>>> stress = StressTensor.tensile([1,0,0], stress_mag)
|
|
84
|
+
|
|
85
|
+
At least, we can directly compute the elastic strain for each step:
|
|
86
|
+
|
|
87
|
+
>>> elastic_strain = C.inv() * stress
|
|
88
|
+
|
|
89
|
+
So now, the plastic strain can be computed using an iterative approach:
|
|
90
|
+
|
|
91
|
+
>>> plastic_strain = StrainTensor.zeros(n_step)
|
|
92
|
+
>>> for i in range(1, n_step):
|
|
93
|
+
... strain_increment = JC.compute_strain_increment(stress[i])
|
|
94
|
+
... plastic_strain[i] = plastic_strain[i-1] + strain_increment
|
|
95
|
+
|
|
96
|
+
That's all. Finally, let us plot the applied stress as a function of the overall elongation:
|
|
97
|
+
|
|
98
|
+
>>> from matplotlib import pyplot as plt
|
|
99
|
+
>>> elong = elastic_strain.C[0,0]+plastic_strain.C[0,0]
|
|
100
|
+
>>> fig, ax = plt.subplots()
|
|
101
|
+
>>> ax.plot(elong, stress_mag, label='Stress-controlled') # doctest: +SKIP
|
|
102
|
+
>>> ax.set_xlabel(r'$\varepsilon_{xx}$') # doctest: +SKIP
|
|
103
|
+
>>> ax.set_ylabel('Tensile stress (MPa)') # doctest: +SKIP
|
|
77
104
|
|
|
78
105
|
.. image:: images/Stress-controlled.png
|
|
79
106
|
|
|
@@ -90,22 +117,22 @@ to add a subroutine (optimization loop) to find the tensile stress so that the a
|
|
|
90
117
|
>>> plastic_strain = StrainTensor.zeros(n_step)
|
|
91
118
|
>>> JC.reset_strain()
|
|
92
119
|
>>> for i in range(1, n_step):
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
120
|
+
... def fun(tensile_stress):
|
|
121
|
+
... trial_stress = StressTensor.tensile([1,0,0], tensile_stress)
|
|
122
|
+
... trial_elastic_strain = C.inv() * trial_stress
|
|
123
|
+
... trial_strain_increment = JC.compute_strain_increment(trial_stress, apply_strain=False)
|
|
124
|
+
... trial_plastic_strain = plastic_strain[i - 1] + trial_strain_increment
|
|
125
|
+
... trial_elongation = trial_plastic_strain.C[0,0] + trial_elastic_strain.C[0,0]
|
|
126
|
+
... return (trial_elongation - elong[i])**2
|
|
127
|
+
... s = minimize_scalar(fun)
|
|
128
|
+
... stress.C[0,0][i] = s.x
|
|
129
|
+
... strain_increment = JC.compute_strain_increment(stress[i])
|
|
130
|
+
... plastic_strain[i] = plastic_strain[i-1] + strain_increment
|
|
104
131
|
|
|
105
132
|
Finally, let's plot the corresponding tensile curve ontop of that of the stress-controlled tensile test:
|
|
106
133
|
|
|
107
|
-
>>> ax.plot(elong, stress.C[0,0], label='Strain-controlled', linestyle='dotted')
|
|
108
|
-
>>> ax.legend()
|
|
134
|
+
>>> ax.plot(elong, stress.C[0,0], label='Strain-controlled', linestyle='dotted') # doctest: +SKIP
|
|
135
|
+
>>> ax.legend() # doctest: +SKIP
|
|
109
136
|
|
|
110
137
|
.. image:: images/StressStrain-controlled.png
|
|
111
138
|
|
|
@@ -115,10 +142,10 @@ Incremental loading
|
|
|
115
142
|
Here, we have only considered monotonic loading, but we can also consider different loading path, such as incremental:
|
|
116
143
|
|
|
117
144
|
>>> load_path = [np.linspace(0,0.1),
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
145
|
+
... np.linspace(0.1,0.099),
|
|
146
|
+
... np.linspace(0.099,0.2),
|
|
147
|
+
... np.linspace(0.2,0.199),
|
|
148
|
+
... np.linspace(0.199,0.3)]
|
|
122
149
|
>>> elong = np.concatenate(load_path)
|
|
123
150
|
>>> n_step = len(elong)
|
|
124
151
|
|
|
@@ -128,9 +155,9 @@ or cyclic:
|
|
|
128
155
|
|
|
129
156
|
|
|
130
157
|
>>> load_path = [np.linspace(0,0.1),
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
158
|
+
... np.linspace(0.1,-0.2),
|
|
159
|
+
... np.linspace(-0.2,0.3),
|
|
160
|
+
... np.linspace(0.3,-0.4)]
|
|
134
161
|
>>> elong = np.concatenate(load_path)
|
|
135
162
|
>>> n_step = len(elong)
|
|
136
163
|
|
|
@@ -166,15 +193,15 @@ For instance, one can highlight the difference between the J2 and Tresca plastic
|
|
|
166
193
|
>>> elastic_strain = C.inv() * stress
|
|
167
194
|
>>> fig, ax = plt.subplots()
|
|
168
195
|
>>> for j, model in enumerate(models):
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
>>> ax.set_xlabel(r'$\varepsilon_{xy}$')
|
|
176
|
-
>>> ax.set_ylabel('Shear stress (MPa)')
|
|
177
|
-
>>> ax.legend()
|
|
196
|
+
... plastic_strain = StrainTensor.zeros(n_step)
|
|
197
|
+
... for i in range(1, n_step):
|
|
198
|
+
... strain_increment = model.compute_strain_increment(stress[i])
|
|
199
|
+
... plastic_strain[i] = plastic_strain[i-1] + strain_increment
|
|
200
|
+
... eps_xy = elastic_strain.C[0,1]+plastic_strain.C[0,1]
|
|
201
|
+
... ax.plot(eps_xy, stress_mag, label=labels[j])
|
|
202
|
+
>>> ax.set_xlabel(r'$\varepsilon_{xy}$') # doctest: +SKIP
|
|
203
|
+
>>> ax.set_ylabel('Shear stress (MPa)') # doctest: +SKIP
|
|
204
|
+
>>> ax.legend() # doctest: +SKIP
|
|
178
205
|
|
|
179
206
|
|
|
180
207
|
.. image:: images/Shear.png
|
|
@@ -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.
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
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,
|
|
@@ -55,7 +55,7 @@ deviation of the Young modulus:
|
|
|
55
55
|
Another way to evidence anisotropy is to use the universal anisotropy factor [1]_:
|
|
56
56
|
|
|
57
57
|
>>> C.universal_anisotropy
|
|
58
|
-
5.
|
|
58
|
+
5.1410095516414085
|
|
59
59
|
|
|
60
60
|
Shear moduli and Poisson ratios
|
|
61
61
|
-------------------------------
|