You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python调用root_scalar求解fCf函数报math domain error错误

问题描述

程序除fCf函数相关逻辑外其余部分运行正常。整体采用双层for循环结构:外层循环中i值逐次递增,内层循环以ii遍历tau_analysis完成迭代计算,单个i值会对应多组由内层迭代生成的V_ratio、Re取值,但循环内求解fCf函数时持续触发报错。

第二层for循环实现代码如下:

for ii in tau_analysis:

    fLam = root_scalar(fLambda, args=(ii, C_v, Clo), method='toms748', bracket=[0.0, 10.0])
    #print("lambda = ", fLam.root)

    Cld = 0.012 * pow(fLam.root, 0.5) * pow(ii, 1.1)
    #print("Cld =", Cld)

    V_ratio = sqrt(1 - (Cld - 0.0065 * beta * pow(Cld, 0.6)) / (fLam.root * 
              cos(math.radians(ii))))
    #print("V_ratio =", V_ratio)

    Fn = i/sqrt(g*pow(delta_volume, 1/3))                                                                  
    Re = (V_ratio*i*fLam.root*b)/visco                                                                     
    #print("Fn =", Fn)
    #print("Reynolds =", Re)

    Cf = root_scalar(fCf, args = Re, method='toms748', bracket=[0,0.01])
    print("Cf = ", Cf.root)

fCf函数定义代码如下:

def fCf(x, Re):
    return log10(Re*x) - 0.02/sqrt(x)

相同计算逻辑在MATLAB中运行无任何错误,Python运行时触发的完整报错回溯信息如下:

Traceback (most recent call last):
  File "C:\Users\27835\PycharmProjects\pythonProject\Savitsky (3).py", line 87, in <module>
    Cf = root_scalar(fCf, args = Re, method='toms748', bracket=[0,0.01])
  File "C:\Users\27835\PycharmProjects\pythonProject\venv\lib\site-packages\scipy\optimize\_root_scalar.py", line 249, in root_scalar
    r, sol = methodc(f, a, b, args=args, **kwargs)
  File "C:\Users\27835\PycharmProjects\pythonProject\venv\lib\site-packages\scipy\optimize\_zeros_py.py", line 1373, in toms748
    result = solver.solve(f, a, b, args=args, k=k, xtol=xtol, rtol=rtol,
  File "C:\Users\27835\PycharmProjects\pythonProject\venv\lib\site-packages\scipy\optimize\_zeros_py.py", line 1220, in solve
    status, xn = self.start(f, a, b, args)
  File "C:\Users\27835\PycharmProjects\pythonProject\venv\lib\site-packages\scipy\optimize\_zeros_py.py", line 1108, in start
    fa = self._callf(a)
  File "C:\Users\27835\PycharmProjects\pythonProject\venv\lib\site-packages\scipy\optimize\_zeros_py.py", line 1082, in _callf
    fx = self.f(x, *self.args)
  File "C:\Users\27835\PycharmProjects\pythonProject\Savitsky (3).py", line 40, in fCf
    return log10(Re*x) - 0.02/sqrt(x)
ValueError: math domain error

报错核心为执行fCf函数内log10(Re*x) - 0.02/sqrt(x)计算时抛出ValueError: math domain error异常,需要定位问题触发原因并给出修复方案。

报错触发原因
  • 求解区间左端点非法:传入root_scalar的求解括号为[0, 0.01],toms748算法初始化时会先计算区间两个端点的函数值。当x=0时:
    • sqrt(0)=0,0.02/sqrt(x)触发除零运算
    • Re*0=0,实数域内log10(0)无定义,直接抛出数学域错误
  • 传参格式不符合接口要求:root_scalar的args参数要求传入可迭代的元组类型,原代码写args = Re直接传入单个数值,后续参数解包时也会触发错误,只是当前端点计算错误先抛出了异常。
  • 跨平台求解逻辑差异:MATLAB的求根函数(如fzero)不会直接计算用户传入的端点0的函数值,会自动在区间内偏移取合法点计算,所以相同区间设置在MATLAB下不会报错。
修复方案
  • 调整求解区间,将左端点从0替换为极小的合法正数,避开无定义点。摩擦系数Cf的物理取值范围通常在1e-5~0.01之间,可将区间设置为[1e-8, 0.01]
  • 修正args传参格式,将单个Re值包装为元组,即写为args=(Re,)
  • 可选优化:调用求解器前可先计算区间两端的fCf返回值,确认两端函数值符号相反(toms748算法要求区间两端点函数值异号才能正常收敛),避免无意义报错。

修复后的求解代码如下:

Cf = root_scalar(fCf, args=(Re,), method='toms748', bracket=[1e-8, 0.01])
print("Cf = ", Cf.root)

内容的提问来源于stack exchange,提问作者david

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 12:51:31