簡體   English   中英

使用scipy的solve_bvp解決BVP問題

[英]Solving a BVP with scipy's solve_bvp

我有一個3個微分方程組(從我認為的代碼中可以明顯看出)有3個邊界條件。 我設法在MATLAB中使用循環來解決它,一點一點地改變初始猜測,如果要返回錯誤,則不會終止程序。 但是,在scipysolve_bvp ,我總能得到一些答案,盡管這是錯誤的。 所以我一直在改變我的猜測(不斷改變答案)並且給出了我從實際解決方案中得到的非常接近的數字,它仍然無法正常工作。 代碼是否還有其他問題,因為它不起作用? 我剛剛編輯了他們的文檔代碼。

import numpy as np
def fun(x, y):
    return np.vstack((3.769911184e12*np.exp(-19846/y[1])*(1-y[0]), 0.2056315191*(y[2]-y[1])+6.511664773e14*np.exp(-19846/y[1])*(1-y[0]), 1.696460033*(y[2]-y[1])))
def bc(ya, yb):
    return np.array([ya[0], ya[1]-673, yb[2]-200])
x = np.linspace(0, 1, 5)
#y = np.ones((3, x.size))
y = np.array([[1, 1, 1, 1, 1], [670, 670, 670, 670, 670], [670, 670, 670, 670, 670] ])
from scipy.integrate import solve_bvp
sol = solve_bvp(fun, bc, x, y)

實際的解決方案如下圖所示。

BVP的MATLAB解決方案

顯然你需要一個更好的初始猜測,否則solve_bvp使用的迭代方法可以在y[1]中創建使表達式exp(-19846/y[1])溢出的值。 當發生這種情況時,算法可能會失敗。 該表達式中的溢出意味着y[1]中的某些值為負; 也就是說,解算器離雜草很遠,它幾乎沒有機會收斂到正確的解決方案。 你會看到警告,有時函數仍會返回一個合理的解決方案,但通常它會在溢出發生時返回垃圾。

您可以通過檢查sol.status來確定solve_bvp是否未能收斂。 如果它不是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()

情節

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM