18 views (last 30 days)

Show older comments

Hi all, I've been trying to use matlab's fsolve function to solve a fluid pipe problem where I have narrowed down the unknown variables into 5. I have run into the error that 'fsolve stopped because it exceeded the function evaluation limit' and gives me complex answers. Can anyone see something wrong with the code itself? Assuming equations are right?

I have used a function handle, and called it in another script. (I do not have much programming background in advance)

function F=fluidssolver(X)

dV = X(1);

V1 = X(2);

f1 = X(3);

f2 = X(4);

f3 = X(5);

rho = 999.1;

mu = 1.138 * 10^-3;

g = 9.81;

Za = 2.1;

Zb = 9.1;

L1 = 25.1;

L2 = 25.1;

L3 = 25.1;

D1 = 3/100;

D2 = 4/100;

D3 = 5/100;

n = 0.68;

dW = 8000;

epsilon = 0;

A1 = pi*D1^2*0.25;

A2 = pi*D2^2*0.25;

A3 = pi*D3^2*0.25;

Re1 = (rho*V1*D1)/mu;

V2 = sqrt((f1*L1*D2)/(f2*L2*D1))*V1;

V3 = sqrt((f1*L1*D3)/(f3*L3*D1))*V1;

Re2 = (rho*V2*D2)/mu;

Re3 = (rho*V3*D3)/mu;

F(1) = dW*n - rho * g * dV * ((Zb-Za) + f1 * (L1/D1) * (V1^2/(2*g))) ;

F(2) = 1/(sqrt(f1)) + 2 * log10 (((epsilon/D1)/3.7) + (2.51/((Re1*sqrt(f1)))));

F(3) = 1/(sqrt(f2)) + 2 * log10 (((epsilon/D2)/3.7) + (2.51/((Re2*sqrt(f2)))));

F(4) = 1/(sqrt(f2)) + 2 * log10 (((epsilon/D3)/3.7) + (2.51/((Re3*sqrt(f3)))));

F(5) = dV - V1*A1 - V2*A2 - V3*A3;

% F(5) = dV - V1*A1 - (sqrt((V1*f1*L1*D2)/f2*L2*D1) * V1)*A2 - (sqrt((V1*f1*L1*D3)/f3*L3*D1) * V1)*A3

end

and as for the function, I have initial guesses in the following different script:

fun = @fluidssolver

fsolve(fun,[0.5, 5, 0.12, 0.12, 0.12])

Alex Sha
on 6 May 2020

Hi, Anahita, if you don't want complex answers, then there are problems in your eauqtions, here taking second equation as an example:

1/(sqrt(f1)) + 2 * log(((epsilon/D1)/3.7) + (2.51/((Re1*sqrt(f1)))))=0

the above equation can simpliy written as:

1/(sqrt(f1)) + 2 * log(s)=0

where s=((epsilon/D1)/3.7) + (2.51/((Re1*sqrt(f1))))

it is:

1/(sqrt(f1)) = -2 * log(s)

obviously, both "1/(sqrt(f1))" and "2 * log(s)" are impossible to be negetive values, this would make the equation untenable.

Same problems for your third and fourth equations。

Matt J
on 5 May 2020

Edited: Matt J
on 5 May 2020

You should get rid of all the square roots on the unknown parameters. Write the equations in terms of new variables like z1=sqrt(f1), z2=sqrt(f2), so that the computations don't involve any square roots.

Also, if you know that some of the parameters are supposed to be non-negative, you should also use lsqnonlin, instead of fsolve, which would alllow you to put lower bounds (and upper bounds, if desired) on the unknowns.

Matt J
on 5 May 2020

That is part of it - if the values go below 0 during the search, the sqrt and log operations will generate complex values.

There is an additional problem, however. Even if you bound the parameters to be positive, the sqrt(f) operations are non-differentiable at f=0, whereas fsolve assumes that your objective function is smooth. Therefore, the change of variables that I mentioned is important as well.

Walter Roberson
on 5 May 2020

your variables are going negative as fsolve makes projections to calculate gradients. Your objective expects several variables to be positive and gives complex results if not.

You cannot proceed with fsolve.

If you have the symbolic toolbox then vpasolve permits bounds.

consider forming the sum of squares of your functions, and minimizing using fmincon with lb.

Walter Roberson
on 5 May 2020

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

Start Hunting!