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 | -1.893361 | 3.568289 | 0.0 | 4.039493 |
1582 | 14.555333 | 5.355806 | 0.0 | 28.319006 | 1.178649 | 0.0 | -10.732705 | 0.0 | 0.0 | 33.399850 | -1.508279 | 3.797076 | 0.0 | 4.085669 | |
1596 | 14.630658 | 4.908741 | 0.0 | 47.701195 | 5.512213 | 0.0 | -17.866833 | 0.0 | 0.0 | 54.777007 | -1.442228 | 5.469620 | 0.0 | 5.656568 | |
4923 | 14.726271 | 5.312840 | 0.0 | 27.699907 | 4.052865 | 0.0 | -12.210032 | 0.0 | 0.0 | 33.446991 | 1.381062 | 6.028931 | 0.0 | 6.185091 | |
4924 | 14.592996 | 5.132274 | 0.0 | 38.010101 | 3.345431 | 0.0 | -14.299768 | 0.0 | 0.0 | 44.070962 | -0.538004 | -5.162114 | 0.0 | 5.190074 | |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
4770 | 3812 | -13.189782 | -5.691876 | 0.0 | 36.527439 | 2.470588 | 0.0 | -14.706686 | 0.0 | 0.0 | 43.577209 | 0.489075 | -5.247270 | 0.0 | 5.270013 |
12418 | -13.560289 | -5.278386 | 0.0 | 32.868889 | 3.320898 | 0.0 | -14.260107 | 0.0 | 0.0 | 39.903508 | -0.352899 | -9.819771 | 0.0 | 9.826110 | |
14446 | -13.673285 | -5.569107 | 0.0 | 34.291058 | 3.642457 | 0.0 | -13.836027 | 0.0 | 0.0 | 40.478974 | 3.865992 | -7.135043 | 0.0 | 8.115093 | |
14614 | -13.389065 | -5.709927 | 0.0 | 36.063541 | 2.828889 | 0.0 | -13.774759 | 0.0 | 0.0 | 42.140169 | 0.252531 | -5.859227 | 0.0 | 5.864667 | |
14534 | -13.276068 | -5.419206 | 0.0 | 33.804211 | 2.829817 | 0.0 | -14.580153 | 0.0 | 0.0 | 41.143837 | -0.134343 | -10.059937 | 0.0 | 10.060834 |
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()
WARNING:param.VTKRenderWindowSynchronized: Providing a width-responsive sizing_mode ('stretch_width') and a fixed width is not supported. Converting fixed width to min_width. If you intended the component to be fully width-responsive remove the heightsetting, otherwise change it to min_height. To error on the incorrect specification disable the config.layout_compatibility option.
WARNING:param.Row: Providing a width-responsive sizing_mode ('stretch_width') and a fixed width is not supported. Converting fixed width to min_width. If you intended the component to be fully width-responsive remove the heightsetting, otherwise change it to min_height. To error on the incorrect specification disable the config.layout_compatibility option.