有没有办法在 Python 的 ODEINT 中更改我的 ODE?

Is there a way to change my ODE inside ODEINT in Python?

我正在尝试模拟一个略有不同的振荡系统:我希望它在 body 向上移动时使用特定的运动方程(O.D.E。),并且body 向下移动时的另一个运动方程。为了求解这些方程,我使用了 Scypi 的 ODEINT。

例如,让我们考虑经典的mass-spring系统。我试图让系统在 body 向上移动时使用外部激励的运动方程,而在它向下移动时使用简单的方程。

def function (x,t):

    F0 = 10.00
    w = 1.00
    m = 2.00
    c = 1.00
    k = 20.00
    s = x[0]
    dsdt = x[1]

    if x[1] >= 0:
        d2sdt2 = (F0*np.sin(w*t)-c*dsdt-k*s)/m
    else:
        d2sdt2 = (-c*dsdt-k*s)/m

    result = [dsdt,d2sdt2]
    return result

initial = [3.00,0.00]
t = np.linspace(0.00,10.00,101)
y = odeint(function, initial, t)

获得的结果表明只有第二个运动方程对body(Results Obtained)起作用。由于外力,body 向上移动时,我原以为会有更混乱的运动模式。

有没有更好的实现方式?

只是增加一些参数来增加内部步骤的密度和输出的密度

t = np.linspace(0.00,10.00,301)
y = odeint(function, initial, t, hmax=0.1, atol = 1e-8, rtol=1e-10)

不使用虚线给出了情节

下半场的扭结清晰可见。

因此您的代码是正确的,但您需要考虑到 ODE 求解器是为平滑的右侧构造的,从数学方法开始一直到,尤其是对于最佳步长的预测变量。由于此处右侧存在局部不可预测的非平滑变化,因此必须告诉求解器不要使用非常大的步长,因为这可能会跳过模型阶段的变化并返回。

顺便说一句,对于平滑的绘图,整个水平轴上 100 个点的输出密度通常太小了。根据绘图的最终 "in-print" 大小使用 200 到 600 点。