I'm trying to create a stress-strain curve in matlab for 2 springs in series, one linear and one non-linear. I have my equation for the energy and have it as a function of the midpoint between the two springs. Fminsearch is used to optimize the springs such that I get the midpoint at which the energy is the smallest. I have already gotten this to work with 2 non-linear springs and 2 linear springs at a set change in length. The problem is I want to do this over a range of lengths from 0:0.20:3.80 in a for loop. When I try to do the same process in the loop, my midpoint [mp] is not changing and my forces are not correct. What mistake am I making in the loop? To me, it looks like I am calling my Energy function every iteration and it should recalculate mp via fminsearch each time with a new total length, Ltot, and yet my midpoint does not change.
a1 = 1; a2 = 1; b2 = 0.1; c2 = 1; mp_0=1;
L=0:0.20:3.80;
F1 = zeros(size(L));
F2 = zeros(size(L));
mp = zeros(size(L));
Energy= @(mp)1/2*(a1*(mp-1).^2+a2*(Ltot-mp-1).^2)+1/3*b2*(Ltot-mp-1).^3+1/4*c2*(Ltot-mp-1).^4;
for k = 1:length(L)
Ltot=L(k);disp(Ltot)
[mp]=fminsearch(Energy,mp_0);
F1(k)=a1*(mp-1);
F2(k)=(a2+b2+c2)*(Ltot-mp-1);
Ftot(k)=F1(k)+F2(k);
end
hold on
plot(L,F1);
plot(L,F2,'r');
plot(L,Ftot,'g');

 Accepted Answer

Alan Weiss
Alan Weiss on 26 Sep 2017
Edited: Alan Weiss on 26 Sep 2017
Your Energy function is defined outside the for loop. Therefore, parameters like Ltot do not change in the function.
Define Energy after all the parameters have been defined, within the body of the loop.
Also, for a 1-D problem, you would probably do better to use fminbnd. I'm sure that you can come up with sensible endpoints for the minimization.
Alan Weiss
MATLAB mathematical toolbox documentation

7 Comments

Okay I'll give it a shot. I was told I wouldn't need Energy inside the loop, but immediately upon putting it in the loop my answer is different. What I can say is that for sure my mp is changing now! I thought that fminsearch would call the Energy function with each iteration of L even though it wasn't inside the loop.
Alternatively, keep the function where it is in your code, and add ‘Ltot’ as a parameter, since only it changes:
Energy= @(mp,Ltot)1/2*(a1*(mp-1).^2+a2*(Ltot-mp-1).^2)+1/3*b2*(Ltot-mp-1).^3+1/4*c2*(Ltot-mp-1).^4;
for k = 1:length(L)
Ltot=L(k); % disp(Ltot)
mp=fminsearch(@(mp)Energy(mp,Ltot),mp_0);
F1(k)=a1*(mp-1);
F2(k)=(a2+b2+c2)*(Ltot-mp-1);
Ftot(k)=F1(k)+F2(k);
end
I think I'll try it the first way. When I do it the second way you mentioned it gives me:
Error using Lab1_part3_retry>@(mp)1/2*(a1*(mp-1).^2+a2*(Ltot-mp-1).^2)+1/3*b2*(Ltot-mp-1).^3+1/4*c2*(Ltot-mp-1).^4
Too many input arguments.
Error in Lab1_part3_retry>@(mp)Energy(mp,Ltot)
It is strange to me because I used this function before and it worked fine with one defined length L, but now even though mp is changing, my curve looks off.
To use my suggestion, you have to add ‘Ltot’ to your ‘Energy’ function as an input argument.
See my previous Comment where I wrote ‘Energy’ as:
Energy = @(mp,Ltot) 1/2*(a1*(mp-1).^2+a2*(Ltot-mp-1).^2)+1/3*b2*(Ltot-mp-1).^3+1/4*c2*(Ltot-mp-1).^4;
Note that before I posted the code in my earlier Comment, I tested it.
It runs without error, and avoids re-defining the function in every iteration of the loop.
Ah yes I see now. I had changed the fminsearch line but not change Energy to Energy = @(mp,Ltot). My stresses still look incorrect, but I'm starting to think it's an error with something else. My fminsearch function is working fine in the loop now so I'll mark it as answered. Thanks for your help!
Our pleasure!

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!