我有一个由3个微分方程组成的系统(从我认为的代码中可以明显看出)有3个边界条件。我设法在MATLAB中使用循环来解决它,一点一点地改变初始猜测,如果要返回错误,则不会终止程序。但是,在scipy
的{{1}}上,我总是得到一些答案,尽管这是错误的。所以我一直在改变我的猜测(不断改变答案)并且给出了我从实际解决方案中得到的非常接近的数字,它仍然无法正常工作。代码是否还有其他问题,因为它不起作用?我刚编辑了他们文档的代码。
solve_bvp
实际解决方案如下图所示。
BVP的MATLAB解决方案
答案 0 :(得分:2)
显然你需要一个更好的初始猜测,否则solve_bvp
使用的迭代方法可以在y[1]
中创建使表达式exp(-19846/y[1])
溢出的值。当发生这种情况时,算法可能会失败。该表达式中的溢出意味着y[1]
中的某些值为负;也就是说,解算器离杂草很远,它几乎没有机会收敛到正确的解决方案。您将看到警告,有时该函数仍会返回合理的解决方案,但通常会在发生溢出时返回垃圾。
您可以通过查看solve_bvp
来确定sol.status
是否未能收敛。如果它不是0,则表示失败。 sol.message
包含描述状态的文本消息。
我能够通过使用它来创建初始猜测来获得Matlab解决方案:
n = 25
x = np.linspace(0, 1, n)
y = np.array([x, np.full_like(x, 673), np.linspace(800, 200, n)])
n
的较小值也有效,但当n
太小时,可能会出现溢出警告。
这是我修改过的脚本版本,然后是它生成的图表:
import numpy as np
from scipy.integrate import solve_bvp
import matplotlib.pyplot as plt
def fun(x, y):
t1 = np.exp(-19846/y[1])*(1 - y[0])
dy21 = y[2] - y[1]
return np.vstack((3.769911184e12*t1,
0.2056315191*dy21 + 6.511664773e14*t1,
1.696460033*dy21))
def bc(ya, yb):
return np.array([ya[0], ya[1] - 673, yb[2] - 200])
n = 25
x = np.linspace(0, 1, n)
y = np.array([x, np.full_like(x, 673), np.linspace(800, 200, n)])
sol = solve_bvp(fun, bc, x, y)
if sol.status != 0:
print("WARNING: sol.status is %d" % sol.status)
print(sol.message)
plt.subplot(2, 1, 1)
plt.plot(sol.x, sol.y[0], color='#801010', label='$y_0(x)$')
plt.grid(alpha=0.5)
plt.legend(framealpha=1, shadow=True)
plt.subplot(2, 1, 2)
plt.plot(sol.x, sol.y[1], '-', color='C0', label='$y_1(x)$')
plt.plot(sol.x, sol.y[2], '--', color='C0', label='$y_2(x)$')
plt.xlabel('$x$')
plt.grid(alpha=0.5)
plt.legend(framealpha=1, shadow=True)
plt.show()