Stress gradient calculation¶
This demo shows the stress gradient calculation module. A gradient is calculated by fitting a plane into a node and its neighbor nodes of an FEM mesh.
See documentation for details on the module.
[1]:
import numpy as np
import pandas as pd
import pylife.stress.equistress
import pylife.mesh.gradient
import pylife.vmap
import pyvista as pv
pv.set_plot_theme('document')
pv.set_jupyter_backend('panel')
Read in demo data and add the stress tensor dimensions for the third dimension.
[2]:
vm_mesh = pylife.vmap.VMAPImport("plate_with_hole.vmap")
pyLife_mesh = (vm_mesh.make_mesh('1', 'STATE-2')
.join_coordinates()
.join_variable('STRESS_CAUCHY')
.to_frame())
Calculate and add von Mises stress
[3]:
pyLife_mesh['mises'] = pyLife_mesh.equistress.mises()
Calculate stress gradient on von Mises stress
[4]:
grad = pyLife_mesh.gradient.gradient_of('mises')
[5]:
grad["abs_grad"] = np.linalg.norm(grad, axis = 1)
pyLife_mesh = pyLife_mesh.join(grad)
display(pyLife_mesh)
x | y | z | S11 | S22 | S33 | S12 | S13 | S23 | mises | dmises_dx | dmises_dy | dmises_dz | abs_grad | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
element_id | node_id | ||||||||||||||
1 | 1734 | 14.897208 | 5.269875 | 0.0 | 27.080811 | 6.927080 | 0.0 | -13.687358 | 0.0 | 0.0 | 33.996987 | -0.693487 | -1.256807 | 0.0 | 1.435440 |
1582 | 14.555333 | 5.355806 | 0.0 | 28.319006 | 1.178649 | 0.0 | -10.732705 | 0.0 | 0.0 | 33.399850 | -3.300877 | -0.779737 | 0.0 | 3.391722 | |
1596 | 14.630658 | 4.908741 | 0.0 | 47.701195 | 5.512213 | 0.0 | -17.866833 | 0.0 | 0.0 | 54.777007 | -4.654205 | 1.511868 | 0.0 | 4.893605 | |
4923 | 14.726271 | 5.312840 | 0.0 | 27.699907 | 4.052865 | 0.0 | -12.210032 | 0.0 | 0.0 | 33.446991 | -1.438945 | -4.702223 | 0.0 | 4.917465 | |
4924 | 14.592996 | 5.132274 | 0.0 | 38.010101 | 3.345431 | 0.0 | -14.299768 | 0.0 | 0.0 | 44.070962 | 35.610803 | -51.987913 | 0.0 | 63.014858 | |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
4770 | 3812 | -13.189782 | -5.691876 | 0.0 | 36.527439 | 2.470588 | 0.0 | -14.706686 | 0.0 | 0.0 | 43.577209 | -0.154659 | -6.003801 | 0.0 | 6.005793 |
12418 | -13.560289 | -5.278386 | 0.0 | 32.868889 | 3.320898 | 0.0 | -14.260107 | 0.0 | 0.0 | 39.903508 | 0.174451 | -3.892492 | 0.0 | 3.896399 | |
14446 | -13.673285 | -5.569107 | 0.0 | 34.291058 | 3.642457 | 0.0 | -13.836027 | 0.0 | 0.0 | 40.478974 | 2.091836 | 4.804640 | 0.0 | 5.240262 | |
14614 | -13.389065 | -5.709927 | 0.0 | 36.063541 | 2.828889 | 0.0 | -13.774759 | 0.0 | 0.0 | 42.140169 | -0.540695 | -6.376289 | 0.0 | 6.399172 | |
14534 | -13.276068 | -5.419206 | 0.0 | 33.804211 | 2.829817 | 0.0 | -14.580153 | 0.0 | 0.0 | 41.143837 | -0.141019 | -4.978514 | 0.0 | 4.980511 |
37884 rows × 14 columns
[6]:
grid = pv.UnstructuredGrid(*pyLife_mesh.mesh.vtk_data())
plotter = pv.Plotter(window_size=[1920, 1080])
plotter.add_mesh(grid, scalars=pyLife_mesh.groupby('element_id')["abs_grad"].mean().to_numpy(),
show_edges=True, cmap='jet')
plotter.add_scalar_bar()
plotter.show()