使⽤有限差分法求解⼀维波动⽅程∂u/∂t+c∂u/∂x=a∂²u/∂x²,u(x, 0) = sin x,x大于-π,小于π,能呈现某一时刻图像
时间: 2024-03-04 15:50:55 浏览: 96
好的,我们可以使用显式欧拉法来数值求解这个一维波动方程。具体地,我们将空间区间 $[-\pi,\pi]$ 均匀地分成 $N$ 个点,时间区间 $[0,T]$ 均匀地分成 $M$ 个点,设 $\Delta x$ 和 $\Delta t$ 分别表示空间和时间上的步长,则:
$$
\begin{aligned}
&\Delta x=\frac{2\pi}{N-1},\quad x_i=-\pi+i \Delta x, \quad i=0,1,\ldots,N-1\\
&\Delta t=\frac{T}{M-1},\quad t_j=j\Delta t,\quad j=0,1,\ldots,M-1
\end{aligned}
$$
记 $u_{i,j}=u(x_i,t_j)$,则有以下差分格式:
$$
\frac{u_{i,j+1}-u_{i,j}}{\Delta t}+c\frac{u_{i,j}-u_{i-1,j}}{\Delta x}=a\frac{u_{i+1,j}-2u_{i,j}+u_{i-1,j}}{\Delta x^2}
$$
其中 $u_{i,j+1}$ 表示时间上的后一步,$u_{i,j}$ 表示当前的值,$u_{i,j-1}$ 表示时间上的前一步,$u_{i-1,j}$ 和 $u_{i+1,j}$ 表示空间上的左右两个点。
对于 $i=0$ 和 $i=N-1$ 的点,我们需要根据端点条件进行处理。这里我们采用自然边界条件,即:
$$
\begin{aligned}
&u_{0,j+1}=u_{1,j+1}\\
&u_{N-1,j+1}=u_{N-2,j+1}
\end{aligned}
$$
对于初始条件 $u(x,0)=\sin x$,我们可以用 $\sin$ 函数在 $[-\pi,\pi]$ 上的值来初始化 $u_{i,0}$。
最后,我们可以使用 Matplotlib 来绘制某一时刻的波动图像。具体来说,假设我们要绘制时间 $t=T/2$ 时刻的波动图像,我们可以使用以下代码:
```python
import numpy as np
import matplotlib.pyplot as plt
# 设置参数
c = 1
a = 1
N = 100
M = 1000
T = 10
# 计算步长
dx = 2 * np.pi / (N - 1)
dt = T / (M - 1)
# 初始化网格
u = np.zeros((N, M))
x = np.linspace(-np.pi, np.pi, N)
t = np.linspace(0, T, M)
u[:, 0] = np.sin(x)
# 迭代计算
for j in range(M - 1):
for i in range(1, N - 1):
u[i, j + 1] = u[i, j] + dt / dx * c * (u[i, j] - u[i - 1, j]) + \
a * dt / dx ** 2 * (u[i + 1, j] - 2 * u[i, j] + u[i - 1, j])
# 处理端点
u[0, j + 1] = u[1, j + 1]
u[N - 1, j + 1] = u[N - 2, j + 1]
# 绘制波动图像
plt.plot(x, u[:, int(M / 2)])
plt.show()
```
这里我们将空间区间分成了 $100$ 个点,时间区间分成了 $1000$ 个点,总时间为 $10$,然后使用了自然边界条件和 $\sin$ 函数来初始化网格,并使用显式欧拉法进行迭代计算。最后,我们绘制了时间为 $5$ 时刻的波动图像。你可以根据需要进行调整。
阅读全文