Detecting and removing data (faulty data) from stress-strain curve after rupture

23 views (last 30 days)
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
Jonas on 7 Jul 2023
maybe the biggest maximum given by islocalmax with minimum prominence of 50% of the highest value in your measurement?

Sign in to comment.

Accepted Answer

Star Strider
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'})
Changes = 3×3 table
Strain Slope Intercept ________ ___________ _________ 0.040964 0.42158 12.734 0.08996 0.24491 32.588 0.1502 -7.4044e-06 0.0018248
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
Dogan Akcakaya
Dogan Akcakaya on 8 Jul 2023
Hey star strider,
First of all thanks for the answer. Iam already using ischange function to determine linear portion of stress-strain curve (thanks to your previous answers). The problem is determination of threshold. I had a few problems with treshold value since I don't know the exact meaning of the value. Is it graident/slope or something like that? I am asking because while I was experimenting with it, I noticed I lose all my linear region even if I change it from 5e6 from lets say 4e6. I know it depends on dataset, but not knowing what it is exactly makes it harder for me to follow. I am going to use my script on both metals and composites. For that I expect threshold value needs to be configured for every test. Maybe I can switch to max number of change points. Anyways if you any other methodology or a solution for variable threshold, any help is appreciated.
Otherwise, thanks for the helps. Best regards.
Star Strider
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
cp = 7.2730e+03
cpix = 187
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.
.

Sign in to comment.

More Answers (0)

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!