Python 开发一种ode积分步进器

Python 开发一种ode积分步进器,python,differential-equations,Python,Differential Equations,我正在创建一个类,以便对一个微分问题执行若干操作(如求解、绘图、将解决方案保存到文件中) 步进器是更重要的部分,我想将我的代码从简单的classmethod修改为生成器 下面是我的代码片段: import numpy as np first_startup , second_startup, third_startup = True, True, True um1,um2,um3 = 0.,0.,0. def step(f , t : np.float , u : np.float

我正在创建一个类,以便对一个微分问题执行若干操作(如求解、绘图、将解决方案保存到文件中) 步进器是更重要的部分,我想将我的代码从简单的classmethod修改为生成器

下面是我的代码片段:

import numpy as np  

first_startup , second_startup, third_startup = True, True, True


um1,um2,um3 = 0.,0.,0.

def step(f , t : np.float , u : np.float , dt):
    global first_startup , second_startup, third_startup
    global um1,um2,um3    

    if first_startup:
        um3 = u.copy()
        unext = u + dt*f(t,u)  #rungekutta.RK4.step(func,t,um2,dt)
        t += dt
        first_startup = False
    elif second_startup:
        um2 = u.copy()
        unext = unext = u + dt*f(t,u) #rungekutta.RK4.step(func,t,um2,dt) 
        t+= dt
        second_startup = False
    elif third_startup:  
        um1 = u.copy()
        unext = u + dt*f(t,u) #rungekutta.RK4.step(func,t,um1,dt)
        t += dt 
        third_step = False
    else:  # compute AB 4th order    
        unext = u + dt/24.* ( 55.*f(t,u) - 59.*f(t-dt,um1) + 37.*f(t-dt-dt,um2) \
                                                               - 9.*f(t-dt-dt,um3 )) 
        um3 = um2.copy()
        um2 = um1.copy()
        um1 = u.copy() 
    return unext   

def main():

    func = lambda t,u : -10*(t-1)*u
    t0 = 0. 
    tf = 2.      
    dt = 2/50 
    u = np.exp(-5)   
    t = t0
    with open('output.dat', 'w') as f:
        while True:
            f.write('%f %f \n' %(t, u) )
            u = step(func,t,u,dt)
            t += dt
            if t > tf:
              break

if __name__ == '__main__':
    main()
如果yoes是一个好主意,那么可以创建一个生成器,用于在步进机上为3个调用返回if、elif、else块内的值计算(这里我编写了一个简单的方法,但在步进机中我对调用进行了注释),我该怎么做

EDITjdowner我已经注释掉了对runge kutta的调用,因为我只提供了一个最小的工作代码。对runge kutta的调用是为了启动多步骤而完成的(4步,所以我需要计算3点以启动该方法)

编辑Ilia L,但在多步骤方法运行期间,我也需要这3个变量。。在房间里找

编辑 我得到了这个错误:

Traceback (most recent call last):
  File "drive.py", line 377, in <module>
    main()
  File "drive.py", line 224, in main
    f.write('%f %f \n' %(t, u) ) # u[0]) )
TypeError: must be real number, not generator
回溯(最近一次呼叫最后一次):
文件“drive.py”,第377行,在
main()
文件“drive.py”,第224行,在main中
f、 写入(“%f%f\n”%(t,u))#u[0]))
TypeError:必须是实数,而不是生成器

如果您想使用生成器执行上述计算,我会这样写:

def step(f, t, u, dt):

    um3 = u
    yield u + dt * f(t, u)

    um2 = u
    yield u + dt * f(t, u)

    um1 = u
    yield u + dt * f(t, u)

    while True:
        k1 = 55.0 * f(t, u)
        k2 = 59.0 * f(t - dt, um1)
        k3 = 37.0 * f(t - 2 * dt, um2)
        k4 = 9.0 * f(t - 2 * dt, um3)

        yield u + dt * (k1 - k2 + k3 - k4) / 24.0

        um3 = um2
        um2 = um1
        um1 = u

我不确定RK4的这个推导是从哪里来的,但它看起来完全错了。看起来您将其视为一个多步骤方法,但事实并非如此。您好,我只是python的初学者,但我认为如果您为启动使用计数器而不是3个不同的变量,则可以稍微改进代码,以startup=1开始,更正if语句,可以增加启动计数器,而不是将变量变为false