首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为Scipy的"odeint“的边界条件指定不同的时间点?

为Scipy的"odeint“的边界条件指定不同的时间点?
EN

Stack Overflow用户
提问于 2018-08-08 02:59:59
回答 1查看 1.7K关注 0票数 3

我正在尝试数值求解一个由两个非线性常微分方程组成的系统。我使用的是Scipy的odeint函数。odeint需要指定初始条件的参数y0。然而,它似乎假设y0的初始条件开始于相同的时间点(即两个条件都在t=0)。在我的例子中,我想指定两个不同的边界条件,这两个条件是为不同的时间指定的(即ω(t=0)= 0,θ(t=100)= 0)。我似乎不知道怎么做,非常感谢任何人的帮助!

下面是一些示例代码:

代码语言:javascript
复制
from scipy.integrate import odeint

def pend(y, t, b, c):
    theta, omega = y
    dydt = [omega, -b*omega - c*np.sin(theta)]
    return dydt

b = 0.25
c = 5.0
t = np.linspace(0, 100, 101)

# I want to make these initial conditions specified at different times
y0 = [0, 0]

sol = odeint(pend, y0, t, args=(b, c))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-08 04:19:36

odeint解决了问题。您描述的问题是两点。为此,您可以使用scipy.integrate.solve_bvp

你也可以看看scikits.bvp1lgscikits.bvp_solver,尽管看起来bvp_solver已经很长时间没有更新了。

例如,下面是使用scipy.integrate.solve_bvp的方法。我更改了参数,以便解决方案不会衰减得太快,并且具有较低的频率。当b= 0.25时,衰减足够快,使得θ(100)对所有解≈0,其中ω(0) =0并且|θ(0)|在1的数量级上。

函数bc将在t=0和t=100处传递θ(t)、ω(t)的值。它必须返回两个值,它们是边界条件的“残差”。这只意味着它必须计算必须为0的值。在本例中,只需返回y0[1] (即ω(0))和y1[0] (即θ(100))即可。(如果t=0的边界条件是ω(0) = 1,那么bc返回值的第一个元素将是y0[1] - 1。)

代码语言:javascript
复制
import numpy as np
from scipy.integrate import solve_bvp, odeint
import matplotlib.pyplot as plt


def pend(t, y, b, c):
    theta, omega = y
    dydt = [omega, -b*omega - c*np.sin(theta)]
    return dydt


def bc(y0, y1, b, c):
    # Values at t=0:
    theta0, omega0 = y0

    # Values at t=100:  
    theta1, omega1 = y1

    # These return values are what we want to be 0:
    return [omega0, theta1]


b = 0.02
c = 0.08

t = np.linspace(0, 100, 201)

# Use the solution to the initial value problem as the initial guess
# for the BVP solver. (This is probably not necessary!  Other, simpler
# guesses might also work.)
ystart = odeint(pend, [1, 0], t, args=(b, c,), tfirst=True)


result = solve_bvp(lambda t, y: pend(t, y, b=b, c=c),
                   lambda y0, y1: bc(y0, y1, b=b, c=c),
                   t, ystart.T)


plt.figure(figsize=(6.5, 3.5))
plt.plot(result.x, result.y[0], label=r'$\theta(t)$')
plt.plot(result.x, result.y[1], '--', label=r'$\omega(t)$')
plt.xlabel('t')
plt.grid()
plt.legend(framealpha=1, shadow=True)
plt.tight_layout()

plt.show()

下面是结果图,您可以看到ω( 0 ) =0和θ(100) =0。

请注意,边值问题的解不是唯一的。如果我们将创建ystart修改为

代码语言:javascript
复制
ystart = odeint(pend, [np.pi, 0], t, args=(b, c,), tfirst=True)

找到了不同的解决方案,如下图所示:

在这个解决方案中,钟摆几乎从倒立位置(result.y[0, 0] = 3.141592653578858)开始。它开始非常缓慢地下降;逐渐地,它下降得更快,在t=100时,它达到了直线下降的位置。

平凡解θ(t)≡0和ω(t)≡0也满足边界条件。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51733696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档