每天,我都花时间深入研究用Python类编写的2种不同方法。 第一个使用向量,第二个使用向量,每次都使用步进器来计算值……但是这里的类是相同的。
class LeapFrog(Multistep):
'''
perform the solution of a SODE using 2 step
'''
solved = False
um1 = 0.0
stepper_start = True
def __init__(self, dydt : Rhs, filename: str=None, save: bool= True ):
self.save = save
self.file = filename
super().__init__(dydt)
def solve(self):
'''
Perform the leap-frog (mid point scheme)
'''
self.time , self.u = self.dydt.createArray()
# start-up the method
k1 = self.dydt.f(self.time[0],self.u[0])
k2 = self.dydt.f(self.time[0]+ self.dt , self.u[0]+ self.dt*k1 )
self.u[1] = self.u[0] + self.dt/2.*(k1+k2)
for i in range(1,len(self.time)-1):
self.u[i+1] = self.u[i-1] + 2. * self.dt * self.dydt.f(self.time[i],self.u[i])
if self.save:
return self.time,self.u
LeapFrog.solved = True
@classmethod
def step(cls ,func , t : np.float , u : np.float , dt ):
def f(ti,ui):
return np.array([function(ti,ui) for function in func])
# start-up the method
if LeapFrog.stepper_start == True:
LeapFrog.um1 = u.copy()
u = rungekutta.RK2.Heun.step(func,t,u,dt)
LeapFrog.stepper_start = False
#yield
unext = LeapFrog.um1 + 2. * dt * f(t,u)
LeapFrog.um1 = u
return unext
在两种情况下EDIT ,我都使用dt = 2/100 对不起!我忘了说迭代方法的名称如下:
dt = 2/100
t,u = t0,u0
with open('LeapFrog_p1.dat', 'w') as f:
while True:
f.write('%10.4f %14.10f \n' %(t, u[0]) )
u = multistep.LeapFrog.step(func0,t,u,dt)
t += dt
if t >= tf:
break
lft = np.genfromtxt('LeapFrog_p1.dat',usecols=(0,))
lfu = np.genfromtxt('LeapFrog_p1.dat',usecols=(1,))
编辑 @Iguananaut谢谢您的提示! t0 = 0 tf = 2.0 u0 = np.exp(-5)
龙格·库塔(Runge Kutta)是他的另一种选择:
@classmethod
def step(cls,func , t : np.float , u : np.float , dt ):
def f(ti,ui):
return np.array([function(ti,ui) for function in func])
k1 = f(t,u)
k2 = f(t+dt , u + dt*k1)
unext = u + dt/2.*(k1+k2)
return unext
您的代码还有我担心的其他几个设计问题,因此很难准确地找出问题所在。
您能告诉我哪个吗?我想改善它