我正在使用不同时间步长的scipy.integrate.odeint进行测试。
具体来说,我设置了一维扩散模拟,一端的粒子扩散到另一侧。对于扩散,我使用有限差分二阶导数近似。
令人惊讶的是,即使总模拟时间相同,我也会根据所采用的时间步长获得不同的模拟结果。
import scipy
import scipy.integrate
import numpy as np
import sys
num_bins=40
bin_size=0.01
bin_size2=bin_size*bin_size
mol_scale=1e-9
def step(y, t, d,dt):
dnorm=(d*dt)/(bin_size2)
dydt=np.zeros([num_bins])
for i in range(1,num_bins-1):
dydt[i]=(y[i-1]-2*y[i]+y[i+1])*dnorm
dydt[0]=(-y[0]+y[1])*dnorm
dydt[num_bins-1]=(y[num_bins-2]-y[num_bins-1])*dnorm
return dydt
y0=np.zeros([num_bins])
y0[1]=1000*mol_scale
d1=0.001
d2=0.01
d3=0.1
#dt1=1
dt=0.01
num_mins=2
t2 = np.linspace(0, num_mins, int((60*num_mins)/dt)+1) #second intervals
sol1 = scipy.integrate.odeint(step, y0, t2, args=(d1,dt))
sol2 = scipy.integrate.odeint(step, y0, t2, args=(d2,dt))
sol3 = scipy.integrate.odeint(step, y0, t2, args=(d3,dt))
import matplotlib.pyplot as plt
tp=-1
plt.plot(range(num_bins), sol1[tp, :]/mol_scale, 'b', label='sol1')
plt.plot(range(num_bins), sol2[tp, :]/mol_scale, 'g', label='sol2')
plt.plot(range(num_bins), sol3[tp, :]/mol_scale, 'r', label='sol3')
plt.legend(loc='best')
plt.xlabel('x')
plt.grid()
plt.show()
当dt = 1(1秒)时,我在2分钟模拟结束时得到以下信号分布。
Signal profile after two minutes simulation with dt=1
然而,当dt = 0.1(0.1秒)时,我得到不同的信号分布。
Signal profile after two minutes simulation with dt=0.1
对我做错了什么的想法?
谢谢,
可人。