Area of the hysteresis loops
22 views (last 30 days)
Show older comments
Viswajit Talluru
on 22 Jan 2025
Commented: Star Strider
on 5 Feb 2025
Hi Community,
I have a stress vs. strain plot with approximately 30 different loops, and I need to calculate the area enclosed by each loop. I've attached a file containing the stress vs. strain data.
Any help or guidance would be greatly appreciated!
Thank you!
0 Comments
Accepted Answer
Star Strider
on 22 Jan 2025
These do not look like hysteresis curves to me. At least, I do not see any that form loops. (I am not certain what the ‘Cycle count’ does, so I used it to segregate the individual records.)
Try this —
T1 = readtable('stress_strain_cycle_count.csv', VariableNamingRule='preserve');
% disp(T1)
[Ucc,~,ix] = unique(T1.('Cycle count'));
cycles = accumarray(ix, (1:numel(ix)).', [], @(x){T1(x,:)})
% cycles{1}
figure
tiledlayout(5,4)
for k = 1:numel(cycles)
x = cycles{k}.Strain;
y = cycles{k}.Stress;
a(k) = trapz(x, y);
nexttile
plot(x, y)
grid
title(["Loop "+k "Area = "+round(a(k),3)])
end
Something is missing from these data that would form them into loops. Please provide it.
.
4 Comments
Star Strider
on 22 Jan 2025
Many of the plot do not have those ’loops’, for example 1, 5, 9 annd 13, so it would be impossible to calculate the area of a loop that doesn’t exist.
Beyond that, for curves that cross, I outlined a way to determine the point of intersection and then calculate the enclosed area. (The indices are reversed, going from high to low rather than low to high, so the areas might appear to be negative. They aren’t. Just take the absolute values of the areas as I did to make them all positive.)
imshow(imread('output (1).png'))
T1 = readtable('stress_strain_cycle_count.csv', VariableNamingRule='preserve');
% disp(T1)
[Ucc,~,ix] = unique(T1.('Cycle count'));
cycles = accumarray(ix, (1:numel(ix)).', [], @(x){T1(x,:)})
% cycles{1}
figure
tiledlayout(2,2)
for k = 1:4:14
x = cycles{k}.Strain;
y = cycles{k}.Stress;
a(k) = trapz(x, y); % Area Between Vector And X-Axis
nexttile
plot(x, y)
grid
xlabel('Strain')
ylabel('Stress')
title(["Segment "+k "Area = "+round(a(k),3)])
end
sgtitle('These Vectors Don’t Display Any Loops')
figure
k = 2;
x = cycles{k}.Strain;
y = cycles{k}.Stress;
a(k) = trapz(x, y);
plot(x, y, '.-')
grid
xlabel('Strain')
ylabel('Stress')
title(["Loop "+k "Area = "+round(a(k),3)])
[pks,locs] = findpeaks(y, MinPeakProminence=0.8);
locs(1) = 1;
pks(1) = y(1);
Bline = [min(x) 1; max(x) 1] \ [min(y); max(y)] % Slope & Intercept Of The two-Point Linear Segment At The End
idxrng = locs(1):locs(2);
sl = [x(idxrng) ones(numel(idxrng),1)] * Bline; % Evaluate Straight Line
isxidx = find(diff(sign(sl-y(idxrng)))) % Intersection Indices
loopix = isxidx(1) : isxidx(end);
a = trapz(x(loopix),sl(loopix)) - trapz(x(loopix),y(loopix)) % Area Calculation
figure
plot(x(idxrng), y(idxrng), '.-', DisplayName='Segment Data')
hold on
plot(x(idxrng(1)), y(idxrng(1)), 'pc', MarkerSize=10, DisplayName='Segment Start')
plot(x(idxrng(end)), y(idxrng(end)), 'pm', MarkerSize=10, DisplayName='Segment End')
plot(x(idxrng), sl, '.-', DisplayName='Segment Straight Line')
plot(x(isxidx), y(isxidx), 'rs', DisplayName='Line & Curve Intersections')
hold off
grid
xlabel('Strain')
ylabel('Stress')
text(0.07, 0.25, sprintf('\\leftarrow Area = %.6f', abs(a)))
legend(Location='best')
t = linspace(0, 1, 500);
x = 2*cos(2*pi*t);
y = 2*sin(2*pi*t);
a(k) = trapz(x, y);
plot(x, y)
grid
axis('equal','padded')
title(["Circle With Radius = 2" "Area = "+round(-a(k),6) "Area = "+round(-a(k),2)/pi+" \times \pi"])
You will likely have to manually segment the data with ‘pseudo-loops’ and data, and then use the code I provided you to calculate the areas in the ‘pseudo-loops’. You can probably use either findpeaks or islocalmax for to detect the peaks separating them, and adding 1 and the end values (for example 1 and numel(x)) of each vector to provide the beginning and end reference indices. It would be easiest to visually determine which data have loops, rather than write rather complicated code to detect them. Then just use my code to find the areas. I
t might be best to put my area-finding code in a function, select the ‘pseudo-loops’ by their beginning and ending index values (from findpeaks or islocalmax), and then call the function for each set of stress-strain vectors that you previously identified.
Once you write it, I can probably help you get that code running if you have problems with it.
.
More Answers (1)
Viswajit Talluru
on 4 Feb 2025
1 Comment
Star Strider
on 5 Feb 2025
II do not understand that approach, however if it works for you, then use it!
imshow(imread('area calculations.jpeg'))
.
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!










