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.