您的初始条件不是,因为它们在两个不同点给出值。这些都是边界条件。
def bc1(u1,u2): return [u1[0]-2.0,u2[1]-0.5]
def bc2(u1,u2): return [u1[1]-1.0,u2[1]-0.8]
def bc3(u1,u2): return [u1[0]-0.0,u2[0]-1.0]
您需要一个 BVP 求解器来解决这些边界值问题。
您可以使用拍摄方法制作自己的求解器,以防万一
def shoot(b): return odeint(dU_dx,[2,b],[1,2])[-1,1]-0.5
b = fsolve(shoot,0)
T = linspace(1,2,N)
U = odeint(dU_dx,[2,b],T)
或使用割线法而不是scipy.optimize.fsolve,因为问题是线性的,所以应该收敛于 1,最多 2 步。
或者您可以使用scipy.integrate.solve_bvp 求解器(这可能比问题更新?)。您的任务类似于记录的示例。请注意,ODE 函数中的参数顺序在所有其他求解器中都会切换,即使在 odeint 中,您也可以提供选项 tfirst=True。
def dudx(x,u): return [u[1], np.cos(2*x)-2*(u[1]+u[0])]
使用solve_bvp 生成的解,节点是积分区间的自动生成的细分,它们的密度表明 ODE 在该区域中的“不平坦”程度。
xplot=np.linspace(1,2,161)
for k,bc in enumerate([bc1,bc2,bc3]):
res = solve_bvp(dudx, bc, [1.0,2.0], [[0,0],[0,0]], tol=1e-5)
print res.message
l,=plt.plot(res.x,res.y[0],'x')
c = l.get_color()
plt.plot(xplot, res.sol(xplot)[0],c=c, label="%d."%(k+1))
以x=0处的初始值作为未知参数的射击方法生成的解,然后得到区间[0,3]的解轨迹。
x = np.linspace(0,3,301)
for k,bc in enumerate([bc1,bc2,bc3]):
def shoot(u0): u = odeint(dudx,u0,[0,1,2],tfirst=True); return bc(u[1],u[2])
u0 = fsolve(shoot,[0,0])
u = odeint(dudx,u0,x,tfirst=True);
l, = plt.plot(x, u[:,0], label="%d."%(k+1))
c = l.get_color()
plt.plot(x[::100],u[::100,0],'x',c=c)