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

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')
               .join_variable('DISPLACEMENT')
               .to_frame())

Calculate and add von Mises stress

[3]:
pyLife_mesh['mises'] = pyLife_mesh.equistress.mises()

Calculate stress gradient on von Mises stress

[4]:
# pyLife_mesh["grad"] = pyLife_mesh.gradient.gradient_of('mises')
grad = pyLife_mesh.gradient.gradient_of('mises')
[5]:
pyLife_nodes = pd.concat([pyLife_mesh.groupby('node_id').mean(), grad], axis=1)
pyLife_nodes["abs_grad"] = np.linalg.norm(grad,axis = 1)
display(pyLife_nodes)

x y z S11 S22 S33 S12 S13 S23 dx dy dz mises dx dy dz abs_grad
node_id
1 7.900000 0.000000 0.0 -0.802995 -68.944250 0.0 -1.869146 0.0 0.0 5.717073e-03 3.114637e-36 0.0 68.842539 -5.616596 5.359001 0.0 7.763056
2 20.000000 0.000000 0.0 30.042272 24.801415 0.0 -0.092955 0.0 0.0 6.448063e-03 6.655135e-38 0.0 27.796941 -0.915970 -0.225004 0.0 0.943201
3 20.000000 9.000000 0.0 30.024656 0.024460 0.0 0.005555 0.0 0.0 5.691581e-03 1.163137e-04 0.0 30.012435 -0.000519 -0.000082 0.0 0.000526
4 0.000000 9.000000 0.0 18.584425 -0.299882 0.0 5.858656 0.0 0.0 -3.303485e-36 -5.751588e-03 0.0 24.948312 0.122343 -0.613853 0.0 0.625926
5 0.000000 6.300000 0.0 216.279488 5.181528 0.0 -6.305715 0.0 0.0 1.365477e-35 -5.435489e-03 0.0 215.130796 16.186186 1.395853 0.0 16.246262
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
14610 -6.424311 -6.312416 0.0 52.471514 -6.999632 0.0 -3.310140 0.0 0.0 -3.627928e-03 1.724823e-03 0.0 56.589972 1.880459 -4.367367 0.0 4.755000
14611 -11.206949 -2.616344 0.0 10.610512 -1.571398 0.0 -10.754698 0.0 0.0 -5.765039e-03 4.447560e-05 0.0 21.879599 -0.800229 -6.246270 0.0 6.297321
14612 -13.101126 -7.120056 0.0 46.328791 1.005923 0.0 -11.133379 0.0 0.0 -4.997560e-03 1.022665e-04 0.0 49.725466 0.651738 -5.209006 0.0 5.249620
14613 -10.574732 -4.750605 0.0 27.268641 -2.193988 0.0 -15.060814 0.0 0.0 -5.150582e-03 1.811491e-04 0.0 38.583754 0.381298 -6.330618 0.0 6.342090
14614 -13.389065 -5.709927 0.0 36.637676 3.454111 0.0 -14.996684 0.0 0.0 -5.329776e-03 2.166348e-05 0.0 43.646014 -0.540695 -6.376289 0.0 6.399172

14614 rows × 17 columns

[6]:
mesh = pv.PolyData(pyLife_nodes[['x', 'y', 'z']].values)
mesh.point_arrays["abs_grad"] = pyLife_nodes["abs_grad"].values
mesh.plot(scalars="abs_grad",log_scale = False)