简体   繁体   中英

I had a problem solving nonlinear system of equations numerically in python

I'm currently trying to solve my fluid mechanics problem that results in three different equations by Python. After some research, I tried to make it as simple as I could, which resulted in the following code:

from scipy.optimize import fsolve 
import math

def equations(p):
    d, Re, f = p
    return (d**5 - 0.0165*f, 97200 - Re*d, f**(-0.5) + 2*math.log10(0.00015/(3.7*d) + 2.51/(Re*f**(0.5))))
 
d, Re, f =  fsolve(equations, (0.22, 0.0213, 490000))

print(equations((d, Re, f)))

Which gives a long error:

> ValueError                                Traceback (most recent call
> last) <ipython-input-19-dcc7fc844bb6> in <module>()
>       6     return (d**5 - 0.0165*f, 97200 - Re*d, f**(-0.5) + 2*math.log10(0.00015/(3.7*d) + 2.51/(Re*f**(0.5))))
>       7 
> ----> 8 d, Re, f =  fsolve(equations, (0.22, 0.0213, 490000))
>       9 
>      10 print(equations((d, Re, f)))
> 
> ~\Anaconda3\lib\site-packages\scipy\optimize\minpack.py in
> fsolve(func, x0, args, fprime, full_output, col_deriv, xtol, maxfev,
> band, epsfcn, factor, diag)
>     146                'diag': diag}
>     147 
> --> 148     res = _root_hybr(func, x0, args, jac=fprime, **options)
>     149     if full_output:
>     150         x = res['x']
> 
> ~\Anaconda3\lib\site-packages\scipy\optimize\minpack.py in
> _root_hybr(func, x0, args, jac, col_deriv, xtol, maxfev, band, eps, factor, diag, **unknown_options)
>     225         with _MINPACK_LOCK:
>     226             retval = _minpack._hybrd(func, x0, args, 1, xtol, maxfev,
> --> 227                                      ml, mu, epsfcn, factor, diag)
>     228     else:
>     229         _check_func('fsolve', 'fprime', Dfun, x0, args, n, (n, n))
> 
> <ipython-input-19-dcc7fc844bb6> in equations(p)
>       4 def equations(p):
>       5     d, Re, f = p
> ----> 6     return (d**5 - 0.0165*f, 97200 - Re*d, f**(-0.5) + 2*math.log10(0.00015/(3.7*d) + 2.51/(Re*f**(0.5))))
>       7 
>       8 d, Re, f =  fsolve(equations, (0.22, 0.0213, 490000))
> 
> ValueError: math domain error

Now, I understand that it must be related to log value, but I think the complexity of the equation also may play a role here.

You can add a print(d, Re, f) in your equations(p) function and see how the value changes over each iteration.

I did a run on it and these are the results before the error

0.22 0.0213 490000.0
0.22 0.0213 490000.0
0.22 0.0213 490000.0
0.22000000327825547 0.0213 490000.0
0.22 0.02130000031739473 490000.0
0.22 0.0213 490000.007301569
4384243.368454826 -464.7214227491007 3096116.988633934

As you can see, as it evaluates, the last row of values are actually invalid for the f**(-0.5) + 2*math.log10(0.00015/(3.7*d) + 2.51/(Re*f**(0.5))) operation since 0.00015/(3.7*d) + 2.51/(Re*f**(0.5)) evaluates to -3.069524039032724e-06 , which is close to 0 and thus be recognized as 0. Therefore, since log(0) is invalid itself, it returns Domain Error

To fix this, you may want to revisit your formula or extend the number of significate figures to hold more number and stop it from being 0.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM