Unsure how to correctly index variables in a while loop to ensure interp1() has unique points.

1 view (last 30 days)
Hello,
I am wanting my code to read force elongation data from a CSV file and then loop through each test to calculte the relevant mechanical test data such as tensile strength, elongation etc.
My code runs perfectly when I have data from one test in the CSV but as soon as I add a second or more test it runs into problems with the variables in the while loop and then not having unique points in the interp1() function.
Thanks in advance!
Here is the error code:
Warning: Column headers from the file were modified to make them valid MATLAB identifiers before creating variable names for the table. The original column headers are
saved in the VariableDescriptions property.
Set 'VariableNamingRule' to 'preserve' to use the original column headers as table variable names.
Error using matlab.internal.math.interp1
Sample points must be unique.
Error in interp1 (line 188)
VqLite = matlab.internal.math.interp1(X,V,method,method,Xqcol);
Error in Stress_StrainLoop>Analysis (line 85)
Xint = interp1((Stress2 - stress), strain, 0); % Intersecpt of 0.2% offset line and stress-strain curve
Error in Stress_StrainLoop (line 33)
[area, UTS, Elong, E, YS] = Analysis(elongation, force, d0);
Here is a picture of the CSV data:
Here is the while loop to iterate through the CSV data:
path = 'C:/Users/...CSVs/';
filename = 'Tensile.csv'; % CSV file with strain data in the first column and stress data in the second
M = csvread(strcat(path,filename), 2); % Read CSV file from the third row to eliminate headings
table = readtable(strcat(path,filename), 'ReadVariableNames', true); % Count the number of columns in CSV
ncol = width(table);
i = 1;
k = 1;
while k < ncol % Loop until all data read from CSV
elongation = M(:,k); % PRETTY SURE MY PROBLEM IS WITH THESE VARIABLES, I am unsure how to declare/instantiate them?
force = M(:,k+1);
gauge = M(1,k+2);
d0 = M(1,k+3);
df = M(1,k+4);
[area, UTS, Elong, E, YS] = Analysis(elongation, force, d0);
fid = fopen(strcat(path,sprintf('TestData%d.txt', i)),'wt');
fprintf(fid, strcat('Test Data of Specimen:', '\t\t', num2str(k), '\nUltimate Tensile Strength: ', '\t ', num2str(round(UTS, 0)), '', '\t\t ', 'MPa \nYield Strength: ', '\t\t\t ', num2str(round(YS, 0)), '', '\t\t ', 'MPa \nElongation at Fracture: ', '\t\t ', num2str(round(Elong, 2))));
fclose(fid);
i = i+1;
k = k+5;
end
Here is the Analysis() function code:
function [area, UTS, Elong, E, YS] = Analysis(elongation, force, d0)
area = (pi*((d0/2)^2));
stress = (force*1000)/area;
strain = elongation/100;
UTS = max(stress); % MPa
Elong = max(elongation); % %
Coeff = polyfit(strain(1000:6000), stress(1000:6000), 1); % Best fit line of elastic region
E = Coeff(1); % MPa, Young's Modulus
OffsetStrain = strain+0.002;
OffsetStress = E*strain;
OffsetLine = polyfit(OffsetStrain, OffsetStress, 1);
Stress2 = polyval(OffsetLine, strain);
Xint = interp1((Stress2 - stress), strain, 0); % Intersecpt of 0.2% offset line and stress-strain curve
Yint = polyval(OffsetLine, Xint);
YS = Yint; % MPa
end

Accepted Answer

David Hill
David Hill on 7 Apr 2022
Did you inspect M? is the matrix M consistent in its columns? You could try readmatrix() and see if there is any difference. Attach data if you want additional help. Why not just save the entire matrix of answers after completing the loop only once?
path = 'C:/Users/...CSVs/';
filename = 'Tensile.csv';
M = csvread(strcat(path,filename), 2);
table = readtable(strcat(path,filename), 'ReadVariableNames', true);
ncol = width(table);
i = 1;
k = 1;
while k < ncol
elongation = M(:,k);
force = M(:,k+1);
gauge = M(1,k+2);
d0 = M(1,k+3);
df = M(1,k+4);
[area(i), UTS(i), Elong(i), E(i), YS(i)] = Analysis(elongation, force, d0);
i = i+1;
k = k+5;
end
testData=[area,UTS,Elong,E,YS];
save('testData.mat',testData);
  3 Comments
David Hill
David Hill on 7 Apr 2022
Found your problem
function [area, UTS, Elong, E, YS] = Analysis(elongation, force, d0)
elongation(isnan(elongation))=[];%add these lines
force(isnan(force))=[];%add these lines
area = (pi*((d0/2)^2));
stress = (force*1000)/area;
strain = elongation/100;
UTS = max(stress);
Elong = max(elongation);
Coeff = polyfit(strain(1000:6000), stress(1000:6000), 1);
E = Coeff(1);
OffsetStrain = strain+0.002;
OffsetStress = E*strain;
OffsetLine = polyfit(OffsetStrain, OffsetStress, 1);
Stress2 = polyval(OffsetLine, strain);
Xint = interp1((Stress2 - stress), strain, 0);
Yint = polyval(OffsetLine, Xint);
YS = Yint;
end
I used the following script:
M=readmatrix('Tensile.csv');
i=1;
for k=1:5:size(M,2)
elongation = M(:,k);
force = M(:,k+1);
gauge = M(1,k+2);
d0 = M(1,k+3);
df = M(1,k+4);
[area(i), UTS(i), Elong(i), E(i), YS(i)] = Analysis(elongation, force, d0);
i=i+1;
end
testData=[area',UTS',Elong',E',YS'];
writematrix(testData,'testData');

Sign in to comment.

More Answers (0)

Categories

Find more on Stress and Strain in Help Center and File Exchange

Products


Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!