Local stress approach
FE based failure probability calculation
FE Data
we are using VMAP data format and rst file formats. It is also possible to use odb data,
[1]:
import numpy as np
import pandas as pd
import pickle
import pylife.vmap
import pylife.mesh
import pylife.mesh.meshsignal
import pylife.stress.equistress
import pylife.stress
import pylife.strength.fatigue
import pylife.utils.histogram as psh
import pyvista as pv
# from ansys.dpf import post
pv.set_plot_theme('document')
pv.set_jupyter_backend('panel')
VMAP
For plotting of VMAP data we are using pyVista.
[2]:
pyLife_mesh = (pylife.vmap.VMAPImport("plate_with_hole.vmap").make_mesh('1', 'STATE-2')
.join_coordinates()
.join_variable('STRESS_CAUCHY')
.to_frame())
pyLife_mesh['mises'] = pyLife_mesh.equistress.mises()
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')['mises'].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.
Now we want to apply the collectives to the mesh
[3]:
mises = pyLife_mesh.groupby('element_id')[['S11', 'S22', 'S33', 'S12', 'S13', 'S23']].mean().equistress.mises()
mises /= mises.max() # the nominal load level in the FEM analysis is set, that s_max = 1
collectives = pickle.load(open("collectives.p", "rb"))
collectives = collectives.unstack().T.fillna(0)
collectives_sorted = psh.combine_histogram([collectives[col] for col in collectives],
method="sum")
scaled_collectives = collectives_sorted.load_collective.scale(mises)
display(scaled_collectives.to_pandas().sample(5))
range element_id
frequency (22.676746230714638, 34.015119346071955] 214 14740.0
(43.312816955618864, 51.97538034674264] 245 5660.0
(87.60133831753575, 109.50167289691967] 3967 0.0
(135.51184931451127, 154.87068493087006] 697 1218.0
(22.641313026776757, 26.414865197906217] 1604 1654.0
Name: cycles, dtype: float64
Define the material parameters
[4]:
mat = pd.Series({
'k_1': 8.,
'ND': 1.0e6,
'SD': 200.0, # range
'TN': 1./12.,
'TS': 1./1.1
})
Damage Calculation
[5]:
damage = mat.fatigue.miner_haibach().damage(scaled_collectives)
print("Max damage : %f" % damage.max())
damage = damage.groupby(['element_id']).sum()
Max damage : 0.001484
[6]:
grid = pv.UnstructuredGrid(*pyLife_mesh.mesh.vtk_data())
plotter = pv.Plotter(window_size=[1920, 1080])
plotter.add_mesh(grid, scalars=damage.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.
ANSYS
[7]:
#%% Ansys (license is necessary)
# For Ansys *.rst files we are using pymapdl
# from ansys.mapdl import reader as pymapdl_reader
# # for more information please go to pymapdl
# # rst_input = post.load_solution("beam_3d.rst")
# # # pymapdl has some nice features
# # rst_input.plot_nodal_displacement(0)
# # rst_input.plot_nodal_stress(0,"X")
# ansys_mesh = pymapdl_reader.read_binary('beam_3d.rst')
# grid_ansys = ansys_mesh.grid
# plotter = pv.Plotter(window_size=[1920, 1080])
# _, volume, _ = ansys_mesh.element_solution_data(0,"ENG")
# volume = pd.DataFrame(volume)[1]
# nodes, ansys_mesh_mises = ansys_mesh.nodal_stress(0)
# ansys_mesh_mises = pd.DataFrame(data = ansys_mesh_mises,
# columns=['S11', 'S22', 'S33', 'S12', 'S13', 'S23']).equistress.mises()
# test = pd.DataFrame(ansys_mesh.mesh.elem).iloc[:, 8:]
# #%%
# plotter.add_mesh(grid_ansys, scalars=ansys_mesh_mises,
# show_edges=True, cmap='jet')
# plotter.add_scalar_bar()
# plotter.show()