-
Notifications
You must be signed in to change notification settings - Fork 12
4.3 Crack detection (Line Intercept Method)
We developed the 'Line Intercept Method' for automatically detecting cracks in digital image correlation (DIC) data. This method utilizes the characteristic displacements of an open crack (see Melching et al. '24). Example scripts are located in the folder scripts/crack_detection.
The features of the algorithm are as follows:
- Crack path reconstruction
- Estimation of crack tip using Von Mises strain threshold
- Iterative correction of crack tip using Williams coefficients
To detect the crack path and crack tip for one nodemap, we need to import the following modules:
import os
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np
from crackpy.crack_detection.line_intercept import CrackDetectionLineIntercept
from crackpy.fracture_analysis.data_processing import InputData
from crackpy.structure_elements.data_files import Nodemap
from crackpy.structure_elements.material import Material
The detection is based on the core module CrackDetectionLineIntercept
.
Plot parameters:
# Set colormap
plt.rcParams['image.cmap'] = 'coolwarm'
plt.rcParams['figure.dpi'] = 300
Set the input and output paths:
# Settings
NODEMAP_FILE = 'Dummy2_WPXXX_DummyVersuch_2_dic_results_1_52.txt'
DATA_PATH = os.path.join('..', '..', 'test_data', 'crack_detection', 'Nodemaps')
Read the data:
# Get nodemap data
nodemap = Nodemap(name=NODEMAP_FILE, folder=DATA_PATH)
data = InputData(nodemap)
data.read_header()
material = Material(E=72000, nu_xy=0.33, sig_yield=350)
data.calc_stresses(material)
Initialize the crack detection:
cd = CrackDetectionLineIntercept(
x_min=0.0,
x_max=25.0,
y_min=-10.0,
y_max=10.0,
data=data,
tick_size_x=0.1,
tick_size_y=0.1,
grid_component='uy',
eps_vm_threshold=0.5/100,
window_size=3,
angle_estimation_mm_radius=5.0
)
cd.run()
The following figure illustrates the CrackDetectionLineIntercept
parameters and the result:
The detection window in the global coordinate system is defined by the parameters x_min
, x_max
, y_min
and y_max
. Within this window, vertical slices are defined with a grid spacing of tick_size_x
and tick_size_y
. The grid_component
displacement is mapped onto the grid. For a pre-dominant mode I crack, we use the displacement component perpendicular to the crack path, which in this case is
This function can adequately approximate the characteristic displacements. The crack path is then reconstructed based on
Then, the von Mises equivalent strain is mapped onto the reconstructed crack path. The crack tip is then simply estimated by the threshold eps_vm_threshold
. Here, we recommend using the yield strength as a first approach (
Finally, we can plot the results together:
fmin = 0
fmax = 0.5
num_colors = 120
contour_vector = np.linspace(fmin, fmax, num_colors, endpoint=True)
label_vector = np.linspace(fmin, fmax, 6, endpoint=True)
plt.clf()
fig = plt.figure(1)
ax = fig.add_subplot(111)
plot = ax.tricontourf(data.coor_x, data.coor_y, data.eps_vm * 100.0, contour_vector, cmap='jet', extend='max')
# final crack path
ax.plot(cd.crack_path[:, 0], cd.crack_path[:, 1], 'k--', linewidth=2, label='Crack path')
# reconstructed path
ax.plot(cd.x_coords[cd.tip_index:], cd.y_path[cd.tip_index:], 'r--', linewidth=2, label='Line segments')
indexes = [100, 150, 200]
# plot slices
for i, index in enumerate(indexes):
if i == 0:
ax.plot(cd.x_grid[:, index], cd.y_grid[:, index], color='grey', linestyle='dashed', linewidth=2, label='slices')
else:
ax.plot(cd.x_grid[:, index], cd.y_grid[:, index], color='grey', linestyle='dashed', linewidth=2)
# plot crack tip
ax.scatter(cd.crack_tip[0], cd.crack_tip[1], marker='X', color='orange', s=80, label='Crack tip', zorder=99)
# plot a box around the detection window
ax.plot([cd.x_min, cd.x_min, cd.x_max, cd.x_max, cd.x_min],
[cd.y_min, cd.y_max, cd.y_max, cd.y_min, cd.y_min],
color='beige', linewidth=3)
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.2)
fig.colorbar(plot, ticks=label_vector, cax=cax, label='Von Mises eqv. strain [%]')
ax.set_xlabel('x [mm]')
ax.set_ylabel('y [mm]')
ax.legend(loc='upper left', ncol=2)
ax.axis('image')
ax.set_xlim(cd.x_min - 5, cd.x_max + 5)
ax.set_ylim(cd.y_min - 5, cd.y_max + 7)
ax.tick_params(axis='x', pad=15)
plt.savefig(os.path.join(OUTPUT_PATH, f"{NODEMAP_FILE[:-4]}.png"), bbox_inches='tight', dpi=300)
print(f'Crack tip: {cd.crack_tip}, Crack angle: {cd.crack_angle} deg')