\frac{\partial^2 u}{\partial t^2} = c^2 \frac{\partial^2 u}{\partial x^2} \\
0<x<l,0<t
I want to solve this
u(0)=0,\frac{\partial u}{\partial x}\Big|_{x=l} = 0
The left end is the Dirichlet boundary condition that specifies the value of $ u $ at the boundary, and the right end is the Neumann boundary condition that specifies the derivative value of the boundary value.
The boundary condition is that the left is the fixed end and the right is the free end.
u(x,0) = f(x)\\
\frac{\partial u}{\partial t}=0
If it is the vibration of a string or the vibration of a vertical bar, the initial velocity is 0.
x_i = i\Delta x\\
t^n = n\Delta t\\
u_{i}^n = u(x_i,t^n)\\
(i = 1\cdots m, \Delta x = \frac{l}{m})
And put. However, $ m $ is the number of spatial divisions.
First, set the initial solution.
u_{i}^0 = f(x_i)\\
u_{i}^1 = u_{i}^0
Since the first derivative of time is 0, $ u_ {i} ^ 1 = u_ {i} ^ 0 $.
Next, set the boundary conditions. However, the trouble is that the Neumann boundary condition at the right end is expressed by the spatial derivative, so two elements must be used to express it. Therefore, add another false element to the rightmost boundary. In other words
u_{m+1}^n = u_{m}^n
If so, the Neumann boundary condition at the right end, that the first-order spatial derivative is 0, is satisfied. The leftmost Dirichlet boundary condition can be expressed as follows.
u_1^n = 0
Finally, the equation itself is discretized.
\frac{\partial^2 u}{\partial x^2}\Big|_{x=x_i}=\frac{u_{i+1}-2u_{i}+u_{i-1}}{\Delta x^2}
This can be derived by Taylor-expanding $ u_ {i + 1} $ and $ u_ {i-1} $ with $ x = x_i $.
Thinking in the same way as spatial differentiation,
\frac{\partial^2 u}{\partial t^2} =\frac{u^{n+1}-2u^{n}+u^{n-1}}{\Delta t^2}
Because it is
\begin{align}
u^{n+1}_i &= 2u^{n}_i-u^{n-1}_i + \Delta t^2 \frac{\partial^2 u}{\partial t^2}\Big|_{x=x_i}\\
&= 2u^{n}_i-u^{n-1}_i + c^2 \Delta t^2 \frac{u_{i+1}-2u_{i}+u_{i-1}}{\Delta x^2}
\end{align}
Sample fucking code
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from copy import deepcopy
fig, ax = plt.subplots()
c = 1.
x_left = 0.
x_right = 1.
t = 0.
#Meaning to discretize at 101 points
num_points = 101
dx = (x_right-x_left)/(num_points-1)
#Reserve one extra for Neumann boundary
x = np.linspace(x_left, x_right+dx, num_points+1)
# u = x/Initialize at 1000
u = 1e-3*x
#Neumann boundary conditions
u[-1] = u[-2]
u_before = deepcopy(u)
u_next = deepcopy(u)
#Accumulate the value of u at regular intervals here
u_at_t = [deepcopy(u)]
dt = 0.1 * dx/c
count = 0
while t < 0.5:
print(np.diff(u,2))
u_next[1:num_points] = 2.*u[1:num_points] - u_before[1:num_points] + c*c*dt*dt/(dx*dx) * np.diff(u, 2)
#Neumann boundary conditions
u_next[-1] = u_next[-2]
u_next[0] = 0.
u_before = deepcopy(u)
u = deepcopy(u_next)
u_next = np.zeros(u.shape)
t += dt
count += 1
#Once every 16 steps
if count == 16:
u_at_t.append(deepcopy(u))
count = 0
def update(u, x):
plt.clf()
plt.xlim(x_left, x_right)
plt.ylim(-1e-3, 1e-3)
plt.plot(x, u)
#Function for displaying animation
anim = FuncAnimation(fig, update, fargs=(
x,), frames=u_at_t, interval=10)
plt.show()
# anim.save("foo.mp4", writer="ffmpeg",fps=10)
Note that saving a video can be a heavy task
Continue
Techniques for making videos https://qiita.com/msrks/items/e264872efa062c7d6955 Difference formula https://qiita.com/Ushio/items/0249fd7a5363ccd914dd
Recommended Posts