求解扩散方程时的高频噪声

计算科学 有限元 Python 麻木的 扩散
2021-11-30 22:28:20

我正在尝试基于Fick's 2nd law模拟一个简单的扩散。

from pylab import *
import numpy as np
gridpoints = 128

def profile(x):
    range = 2.
    straggle = .1576
    dose = 1 
    return dose/(sqrt(2*pi)*straggle)*exp(-(x-range)**2/2/straggle**2)

x = linspace(0,4,gridpoints)
nx = profile(x)
dx = x[1] - x[0] # use np.diff(x) if x is not uniform
dxdx = dx**2

figure(figsize=(12,8))

plot(x,nx)
timestep = 0.5
steps = 21
diffusion_coefficient = 0.002
for i in range(steps):
    coefficients = [-1.785714e-3, 2.539683e-2, -0.2e0, 1.6e0,
                    -2.847222e0,
                    1.6e0, -0.2e0, 2.539683e-2, -1.785714e-3]
    ccf = (np.convolve(nx, coefficients) / dxdx)[4:-4] # second order derivative
    nx = timestep*diffusion_coefficient*ccf + nx
    plot(x,nx)

有噪声的输出

在最初的几个时间步骤中,一切看起来都很好,但随后我开始得到高频噪声,这是从通过二阶导数放大的数值误差中积累起来的。由于似乎很难提高浮点精度,我希望还有其他方法可以抑制这种情况?我已经增加了用于构造二阶导数的点数。

1个回答

使用显式时间步长方法求解偏微分方程依赖于满足一定的CFL 条件以实现稳定性。由于您使用的是前向 Euler时间步长方案,因此您必须确保您的时间步长与网格间距相比足够小。

在热方程的情况下(菲克第二定律是热方程),你的 CFL 数必须满足C

C=kΔt(Δx)2<A

其中是扩散系数,是一些常数,通常在 (0,1] 范围内,取决于所使用的特定方程和方法。当您增加网格点的数量时,这会对您的时间步长施加一些严格的限制 (减少 ) 并且是使用隐式方法的主要原因之一。kAΔx

请注意,此条件对于稳定性是必要的,这意味着如果不满足此条件,数值解最终将崩溃。对准确性的担忧是另一个话题,但如果解决方案失败了,你肯定会不准确。