Detecting and removing data (faulty data) from stress-strain curve after rupture
23 views (last 30 days)
Show older comments
Dogan Akcakaya
on 7 Jul 2023
Commented: Star Strider
on 8 Jul 2023
Hi everyone,
Iam writing a script/app which automates syncing and cleaning of stress (from testing machine) and strain (from gages). After the rupture of the specimen, data is still collected so I get something like below.

Unfortunately I don't have access to my code at the moment, so i won't be able to share it right now but my first attempt was just using the largest derivative of the dataset both on stress-time and strain-time datas to detect largest jump (rupture) and delete the data after this point.
While first derivative works on small sets, large/noisy sets with very high sampling rates create some problems and make it impossible to work. Do you have any idea/suggestions? By the way on the figure, drop happens after the global peak. But this is not the case always. (Consider a general stress strain curve).
Basically what I need is a way to detect a huge jump happening over a few or a few hundred datapoints relative to the size of the data.
All the help is appreciated.
Thanks.
1 Comment
Jonas
on 7 Jul 2023
maybe the biggest maximum given by islocalmax with minimum prominence of 50% of the highest value in your measurement?
Accepted Answer
Star Strider
on 7 Jul 2023
Without the data to refer to, see if the ischange function (introduced in R2017b) will do what you want —
strain = linspace(0, 0.2, 250).'; % Assume Column Vectors
stress = 100*(1-exp(-10*strain));
stress(strain>=0.15) = exp(-50*strain(strain>=0.15));
figure
plot(strain, stress)
xlabel('Strain')
ylabel('Stress')
title('Original Data')
[Lv,S1,S2] = ischange(stress, 'linear','Threshold',100);
cp = find(Lv, 1, 'last') - 1; % Change Point (Numeric Index)
Changes = table(strain(Lv),S1(Lv),S2(Lv), 'VariableNames',{'Strain','Slope','Intercept'})
figure
plot(strain, stress, 'LineWidth',3, 'DisplayName','Original Data')
hold on
plot(strain(cp), stress(cp), 'sr', 'DisplayName','Identified Changes')
plot(strain(1:cp), stress(1:cp), '-r', 'LineWidth',1.5, 'DisplayName','Truncated Data')
hold off
xlabel('Strain')
ylabel('Stress')
title('Data Demonstrating ‘ischange’ Results')
legend('Location','best')
Experiment with the ischange parameters to get the result you want.
.
2 Comments
Star Strider
on 8 Jul 2023
The 'Threshold' value essentially inversely proportional to the number of points returned. The way I usually use ischange is to use the second and third outputs to determine the point of interest.
An alternative is to compute the slope and intercept at every point, and then select the maximum intercept (that should be close to a vertical line), and determine its index —
strain = linspace(0, 0.2, 250).'; % Assume Column Vectors
stress = 100*(1-exp(-10*strain));
stress(strain>=0.15) = exp(-50*strain(strain>=0.15));
figure
plot(strain, stress)
xlabel('Strain')
ylabel('Stress')
title('Original Data')
dydx = gradient(stress) ./ gradient(strain); % Numerical Derivative (Slope)
incp = stress - dydx.*strain; % Corresponding Intercept
figure
yyaxis left
plot(strain, dydx, '.-')
ylabel('Slope At Change Points')
yyaxis right
plot(strain, incp,'.-')
ylabel('Intercept At Change Points')
grid
xlabel('Strain')
figure
plot(strain, stress)
hold on
for k = 1:50:numel(dydx)
x = strain(k)+[-1:0.1:1]/75;
y = dydx(k)*x + incp(k);
plot(x, y, '-r')
end
hold off
grid
yline(0, ':k')
title('Data With Tangent Lines')
[cp,cpix] = max(incp) % Maximum Intercept & Index
figure
plot(strain, stress, 'LineWidth',3, 'DisplayName','Original Data')
hold on
plot(strain(cpix), stress(cpix), 'sr', 'DisplayName','Identified Changes')
plot(strain(1:cpix), stress(1:cpix), '-r', 'LineWidth',1.5, 'DisplayName','Truncated Data')
hold off
xlabel('Strain')
ylabel('Stress')
title('Data Demonstrating ‘ischange’ Results')
legend('Location','best')
This apporach of course works flawlessly on smooth, synthetic data. With a noisy signal, computing the numerical derivative is going to be much less certain, since taking the derivative amplifies the noise, so ideally some sort of filtering would need to be performed first. My choice for this would be sgolayfilt, using a 3-degree polynomial and a small value for ‘framelen’, since larger values would make the rupture point location less certain. You will likely need to experiment with this with your data to make it work correctly.
.
More Answers (0)
See Also
Categories
Find more on Stress and Strain in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!




