将Neumann边界条件应用于扩散方程

时间:2018-11-28 14:10:52

标签: python numpy matplotlib math numerical-methods

我为扩散方程du / dt = D(d ^ 2 u / dx ^ 2)+ Cu绘制了数值解代码,其中u是x和t的函数-我已经解决了它数值计算并用direchtlet边界条件u(-L / 2,t)= u(L / 2,t)= 0绘制,临界长度是函数爆炸前的值,我已经得出成为pi。我正在尝试将正确的边界条件更改为Neumann边界条件u_x(L / 2)= 0,这应减小临界长度并导致函数呈指数增加,但是我不太确定该怎么做我的工作似乎不太正确-有人可以看看他们是否能确定我哪里出问题了吗?谢谢!

L=np.pi # value chosen for the critical length
s=101 # number of steps in x
t=10002 # number of timesteps
ds=L/(s-1) # step in x
dt=0.0001 # time step
D=1 # diffusion constant, set equal to 1
C=1 # creation rate of neutrons, set equal to 1
Alpha=(D*dt)/(ds*ds) # constant for diffusion term
Beta=C*dt # constant for u term

x = np.linspace(-L/2, 0, num=51)
x = np.concatenate([x, np.linspace(x[-1] - x[-2], L/2, num=50)]) # setting x in the specified interval

u=np.zeros(shape=(s,t))
u[50,0]=1/ds # delta function
for k in range(0,t-1):
    u[0,k]=0 #direchtlet boundary condition
    for i in range(1,s-1):
        u[i,k+1]=(1+Beta-2*Alpha)*u[i,k]+Alpha*u[i+1,k]+Alpha*u[i-1,k] # numerical solution 
    u[s-1,k+1]=u[s-2,k+1] # neumann boundary condition
    if k == 50 or k == 100 or k == 250 or k == 500 or k == 1000 or k == 10000: # plotting at times
        plt.plot(x,u[:,k])

plt.show()

1 个答案:

答案 0 :(得分:1)

首先,您需要在时间循环的开始和当前时间步分别应用 左右边界条件(而不是像在右边那样在k+1上)公元前)。

import numpy as np
import matplotlib.pyplot as plt
L=np.pi # value chosen for the critical length
s=101 # number of steps in x
t=10002 # number of timesteps
ds=L/(s-1) # step in x
dt=0.0001 # time step
D=1 # diffusion constant, set equal to 1
C=1 # creation rate of neutrons, set equal to 1
Alpha=(D*dt)/(ds*ds) # constant for diffusion term
Beta=C*dt # constant for u term

x = np.linspace(-L/2, 0, num=51)
x = np.concatenate([x, np.linspace(x[-1] - x[-2], L/2, num=50)]) # setting x in the specified interval

u=np.zeros(shape=(s,t))
u[50,0]=1/ds # delta function
for k in range(0,t-1):
    u[0,k] = 0 # left direchtlet boundary condition
    u[s-1,k] = 0 # right dirichlet boundary condition

    for i in range(1,s-1):
        u[i,k+1]=(1+Beta-2*Alpha)*u[i,k]+Alpha*u[i+1,k]+Alpha*u[i-1,k] # numerical solution 
    if k == 50 or k == 100 or k == 250 or k == 500 or k == 1000 or k == 10000: # plotting at times
        plt.plot(x,u[:,k])

plt.savefig('test1.png')
plt.close()

对于狄利克莱特BC,您可以获得: enter image description here (可能与以前相同,因为对于扩散问题,它不会产生太大的变化,但是无论如何都是不正确的)。然后,您可以更改Von-Neumann BC的右边界条件

u[s-1,k] = u[s-3,k] # right von-neumann boundary condition

因为我看到您使用的是中心差分方案,所以Von-Neumann BC指出边界处du / dx = 0。使用右边界处的中心差分方案离散该导数为(u[s-1,k]-u[s-3,k])/dx = 0,因此u[s-1,k]=u[s-3,k]。有了这个改变,你得到 enter image description here