Area of the hysteresis loops
30 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Viswajit Talluru
el 22 de En. de 2025
Comentada: Star Strider
el 5 de Feb. de 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 comentarios
Respuesta aceptada
Star Strider
el 22 de En. de 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 comentarios
Star Strider
el 22 de En. de 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.
.
Más respuestas (1)
Viswajit Talluru
el 4 de Feb. de 2025
1 comentario
Star Strider
el 5 de Feb. de 2025
II do not understand that approach, however if it works for you, then use it!
imshow(imread('area calculations.jpeg'))
.
Ver también
Categorías
Más información sobre Stress and Strain en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!











