简体   繁体   English

我在 python 中数值求解非线性方程组时遇到了一个问题

[英]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.我目前正在尝试解决我的流体力学问题,该问题导致 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.您可以在您的equations(p)函数中添加一个print(d, Re, f)并查看值在每次迭代中如何变化。

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如您所见,在评估时,最后一行值实际上对f**(-0.5) + 2*math.log10(0.00015/(3.7*d) + 2.51/(Re*f**(0.5)))操作,因为0.00015/(3.7*d) + 2.51/(Re*f**(0.5))计算结果为-3.069524039032724e-06 ,它接近于 0,因此被识别为 0。因此,由于log(0)本身无效,它返回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.要解决此问题,您可能需要重新访问您的公式或扩展有效数字的数量以容纳更多数字并阻止其为 0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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