10. Wave motion#
Whereas we previously modeled oscillatory motion using the oscillator equation (purely a function of time), we will now model traveling waves (also works for standing waves) using a class of second-order PDEs known aptly as the wave equation. This PDE will have derivatives with respect to position and time.
Summary of commands#
In this exercise, we will demonstrate the following:
The Animation classes, specifically
FuncAnimation
, from Matplotlib. This is a powerful and fun toolkit for stitching multiple frames of plots together to make an animated figure!
Movie of wave displacement#
A string of length \(4\) is fixed at the two end points such that \(u(0,t) = u(4,t) = 0\).
At \(t = 0\), the string is displaced and released from its equilibrium position such that \(u(x,0) = 4 - (x - 2)^2\), and \(\dfrac{\partial u}{\partial t} \bigg|_{x,t=0} = 2\).
Given that the differential equation is \(c^2 \dfrac{\partial^2 u}{\partial x^2} = \dfrac{\partial^2 u}{\partial t^2}\), with \(c = 1\), the solution is
Make a movie of the displacement of the string in the first \(10\) seconds. Note this will take 10โ15 seconds to finish running!
Note
The following code was generated with some assistance from ChatGPT. Make sure youโre disclosing your sources appropriately! ๐
# import libraries
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
plt.rcParams.update({'animation.html':'jshtml'}) # required for Colab environment
# initialization
dt = 0.1
tmax = 10
nframes = int(tmax / dt)
fps = nframes / tmax
nmax = 10
c = 1
# initialize first picture at t = 0
x = np.linspace(0, 4, 100)
u = 4 - (x - 2) ** 2
fig, ax = plt.subplots()
line, = ax.plot(x, u)
ax.set(xlim=[0,4], ylim=[-5,5], xlabel='length along string', ylabel='displacement',
title='Movie of oscillating string')
plt.close() # avoid duplicate
# update plot for animation
def update(frame):
t = frame * dt
u = np.zeros(x.shape)
for n in range(1, nmax, 2):
u += (128 / (n ** 3 * np.pi ** 3) * np.cos(c * n * np.pi * t / 4) +
32 / (c * n ** 2 * np.pi ** 2) * np.sin(c * n * np.pi * t / 4)) * np.sin(n * np.pi * x / 4)
line.set_ydata(u)
return line,
ani = animation.FuncAnimation(fig, update, frames=nframes, interval=dt*1000, blit=True)
# ani.save('oscillating_string.mp4', writer='ffmpeg', fps=30) # save to disk (๐ tab)
ani # show the animation