帮助实现热方程的有限差分方案

计算科学 pde 有限差分 Python 抛物线pde
2021-12-23 05:06:00

我试图通过有限差分近似来解决以下问题:

ut=kuxx , on and ;0<x<Lt>0

u(0,t)=u(L,t)=0 ;

u(x,0)=f(x)

我把当作我的问题。u(x,0)=f(x)=x2

编程根本不是我的强项,所以我在实现方面遇到了一些问题。这是我的代码:

 ## This program is to implement a Finite Difference method approximation
## to solve the Heat Equation, u_t = k * u_xx,
## in 1D w/out sources & on a finite interval 0 < x < L. The PDE
## is subject to B.C: u(0,t) = u(L,t) = 0,
## and the I.C: u(x,0) = f(x).
import numpy as np
import matplotlib.pyplot as plt

# definition of solution to u_t = k * u_xx
def u(x,t):
    return u

# definition of initial condition function  
def f(x):
    return x^2

# parameters    
L = 1
T = 10
N = 10
M = 10
s = 0.25

# uniform mesh
x_init = 0
x_end = L
dx = float(x_end - x_init) / N

# time discretization
t_init = 0
t_end = T
dt = float(t_end - t_init) / M

t = np.zeros(M+1)
t = np.arange(t_init, t_end, dt)

# Boundary Conditions
for m in xrange(0, M):
    t[m] = m * dt
    u(0, t[m]) = 0
    u(N, t[m]) = 0

# Initial Conditions
for j in xrange(0, N):
    x[j] = j * dx
    u(x[j], 0) = f(x[j])

# finite difference scheme
for j in xrange(1, N-1):
    u(x[j],t[m+1]) = u(x[j],t[m]) + s * ( u(x[j+1],t[m]) - 
    2 * u(x[j],t[m]) + u(x[j-1],t[m]) )

所以特别是,我想知道(1)我的函数定义是否可以?(2) 我的均匀网格和时间离散化好吗?(3) 我是否为参数选择了合理的值?(我知道对于较小的,近似值更准确,但缺点是计算时间增加......)ΔxΔt

(4) 我的循环如何(对于初始/边界条件)?我觉得我需要一个用于有限差分方案的嵌套循环。一个用于 j 值的 for 循环和另一个用于及时遍历每个值 m 的 for 循环。它是否正确?...另外,我不断收到错误消息: u(0, t[m]) = 0 "can't assign to function call." 那里有什么问题?

在此先感谢您的帮助!正如我所提到的,我的编程能力不是很强,所以我觉得做这件事就像一条离水的鱼。

2个回答

不要担心编程技能,每个人在某些时候都是初学者。实际上这是一个好的开始。假设这是一个练习,我将给出一些提示。实际上,乔沃德的回答是完整的,这只是对他的建议的改写,我希望是一种对初学者更友好的语言。因此,如果您确实接受了答案,那应该是他的;)

  1. 您对解决方案的定义在 Python 中没有意义。我建议将它存储在一个NxMnumpy 数组中。这样,您就可以使用切片符号轻松定义初始条件和边界条件(即1-dim 数组U[:,0] = x**2在哪里,请参阅 参考资料)。xnumpy.linspace

  2. 您似乎正在对空间中的二阶导数使用中心差分方案。定义通常是

    uxx(xi)=ui+12ui+ui1h2
    在哪里h是空间步长(你的dx)。

  3. 您正在使用一种称为显式欧拉前向欧拉的显式时间步进方案,它是有条件的稳定的。这意味着您的离散化必须满足某个条件才能使您的解决方案保持有界,或者换句话说,您的时间步长必须足够小。另一个解决方法是使用隐式方法,例如无条件稳定的后向 Euler请注意,虽然这对于本质上稳定的热方程很好,但它可能不是中性或不稳定问题的最佳选择,因为您的数值解可能会受到过度稳定(也称为数值阻尼)的影响。

  4. 您只实现了内部循环。您还需要一个外部循环来及时推进。

所以你的第一个大问题是你在第(4)点提出的问题,你说你得到错误' u(0, t[m]) = 0 "can't assign to function call" '。您正在尝试通过将数据分配给函数来存储数据。那是行不通的。您实现此代码的方式,实际上应该u(x,t)由一个可以通过 访问的二维数组表示u[m][j],其中m时间值相关联,并空间价值。mthjjth

您还注意到,您应该有一个嵌套的 for 循环。做一个外循环时间,然后一个内循环循环空间离散化。

现在假设您的值s对您的问题有意义,我看到的另一个潜在问题是您的步长,dt. 我很确定这个时间步长不会基于 的值而稳定,dx因为您似乎只是在使用显式欧拉时间步进方案。尝试选择一些dt与 成比例的dx*dx,比如dt=0.1*dx*dx,看看它对你来说是怎样的。