使用scipy.fsolve求解Blasius问题时遇ValueError报错求助
Blasius问题求解中fsolve触发ValueError的原因及解决方法
问题背景
求解Blasius问题时,使用某YouTube教程8:35处的代码,所有print语句均可正常输出结果,但调用fsolve时触发如下ValueError:
xpp0 = fsolve(blas0, x0=0.1, args=(eta), xtol=1e-6) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (3,) + inhomogeneous part.
尝试过降级numpy/scipy、给eta添加dtype=object、改用root函数等方法,均未解决问题。当前环境依赖版本:
Package Version --------------- ----------- contourpy 1.3.0 CoolProp 6.6.0 cycler 0.12.1 fonttools 4.53.1 kiwisolver 1.4.7 matplotlib 3.9.2 numpy 2.1.1 packaging 24.1 pandas 2.2.2 pillow 10.4.0 pip 24.2 pyparsing 3.1.4 PyQt6 6.7.1 PyQt6-Qt6 6.7.2 PyQt6_sip 13.8.0 python-dateutil 2.9.0.post0 pytz 2024.2 scipy 1.14.1 six 1.16.0 tzdata 2024.1
问题原因
- 标量参数的数组化处理:在numpy 2.x + scipy 1.14.1的组合下,
fsolve会将标量初始值x0=0.1包装为数组传递给目标函数blas0。而blas0函数中,初始条件f0=(0., 0., x)会因x是数组,变成包含标量和数组的混合序列,导致odeint返回的结果形状异常,最终触发形状不匹配的错误。 args参数写法错误:args=(eta)未添加逗号,Python会将其解析为eta数组本身而非包含eta的元组。虽然print调用时参数传递正常,但fsolve对额外参数的解析逻辑可能引发潜在的参数传递错位,加剧形状异常问题。
解决方法
方法1:适配数组输入,向量化目标函数
修改blas0函数,使其支持处理数组类型的x参数:
def blas0(x, ts): x = np.asarray(x) results = [] for xi in x: f0 = (0., 0., xi) f = odeint(blas, f0, ts) results.append(1. - f[-1, 1]) return np.array(results)
同时修正args写法:
xpp0 = fsolve(blas0, x0=0.1, args=(eta,), xtol=1e-6)
方法2:改用标量优化专用函数
由于这是标量优化问题,使用root_scalar替代fsolve更合适,无需适配数组输入:
from scipy.optimize import root_scalar sol = root_scalar(blas0, args=(eta,), x0=0.1, method='newton') xpp0 = sol.root
方法3:强制传递标量参数
通过lambda包装blas0,确保x始终以标量形式传递:
xpp0 = fsolve(lambda x: blas0(float(x), eta), x0=0.1, xtol=1e-6)
内容的提问来源于stack exchange,提问作者Heat Transfer
相关产品推荐
相关产品推荐

