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

\[ u(x,t) = \sum_{n=\text{odd}}^{\infty} \left( \dfrac{128}{n^3\pi^3} \cos \left( \dfrac{cn\pi t}{4} \right) + \dfrac{32}{cn^2\pi^2} \sin \left( \dfrac{cn\pi t}{4} \right) \right) \sin \left( \dfrac{n \pi x}{4} \right) \]

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