You are on page 1of 22

PHY254H1-SUM (Classical Mechanics), University of Toronto

Lecture 10: Travelling waves and wave dispersion


Nicolas Grisouard, nicolas.grisouard@utoronto.ca
5 August 2021

from IPython.display import Image, display, YouTubeVideo, HTML


[1]: import numpy as np
import matplotlib.pyplot as plt
from matplotlib import interactive, rcParams, animation
from ipywidgets import interact, FloatSlider, fixed, IntSlider
interactive(True)
rcParams['figure.dpi'] = 100 # for crisper figures later

Readings:
• French, Chap. 7 until page 234
• For the part about dispersion, this is mostly an original creation though.

1 Expectations
1.1 Remember
• The wave equation ∂2t y = v2 ∂2x y,
• y( x, t) = f ( x − vt) + g( x + vt) is the general solution to the equation above.
• v = ω/k in priority; v = νλ can be easily recovered from the previous equation, but it can
be useful to remember is as such.
• When boundaries are a relevant concept, travelling waves can be decomposed as a sum of
standing wave modes of the cavity.
• A standing wave mode can be interpreted as the superposition of two travelling waves of
equal amplitude, equal frequencies and equal-and-opposite travelling speeds.
• The meaning and definition of the phase speed when multiple wave superpose.
• The meaning and definition of the group speed.
• That phase and group speeds are the same in a non-dispersive medium.
• The interpretation that when it can be defined, the group speed is the speed of propagation
of the energy.

1.2 Understand
• What it means for y( x, t) = f ( x − vt) + g( x + vt) to be the general solution to the wave
equation. In particular, that it can be any shape when v is constant.
• When v depends on frequency or wave number, wave forms may evolve in time due to
dispersion.

1
• f ( x − vt) is the part of the solution that travels towards x > 0, g( x + vt) the one that travels
towards x < 0.

1.3 Apply
• As usual, complete this list with worked examples, tutorials and problem sets.

2 Introduction
This lecture will delve deeper into what waves really do: they travel. The previous lecture on
standing waves provided a useful mathematical description that is widely used, but not always
useful. That’s because these waves don’t go anywhere, and waves are one of the main tools,
Physics uses to move information around. Most detection devices such as eyes or ears use waves
that have travelled from wherever we look or hear towards, and so on. As we will see, both points
of views (standing vs. travelling) are two ways of looking at the same thing.
The demo for this lecture is tiny: it’s just me, trying to whip the rub-
ber hose to create a disturbance (with moderate success, I have to ad-
mit). See below (Jupyter), also at https://youtu.be/4uZecocmN3w or
https://play.library.utoronto.ca/aef20263acb3529805746d6f63d6ed71.
YouTubeVideo('4uZecocmN3w')
[2]:
[2]:

2
While there is no excuse for my poor handling of the rubber hose, there are a couple of good rea-
sons why there are fewer and fewer videos: first, the concepts are increasingly common: we have
all seen ripples in a puddle, or longer waves on larger bodies of water. They are also increasingly
abstract: the propagation of sound waves or light are everyday waves, and yet, their wavy features
cannot easily be observed. We will also study how waves propagate across discontinuities (say,
two different pieces of strings), which is hard to easily observe because we need a type of wave
that propagates slowly enough to be captured by the naked eye, and the physics department did
not have that sort of device in store.

3 Travelling waves as superpositions of modes


Recall the Bell wave machine below, which I start here at the moment when
I talk about travelling waves (also at https://youtu.be/Ki70ShYFtmA?t=193 and
https://play.library.utoronto.ca/c4febe4cb2b4b0e8ee5641ffa524b24f?t=193): a chain of dis-
crete oscillators can look like a standing wave, but also appears to be able to support travelling
waves.
YouTubeVideo('Ki70ShYFtmA', start=193)
[3]:
[3]:

From earlier lectures, we know that the motion, whatever it is, can be decomposed as a sum of
modes. Yes, this decomposition seems awkward here, when I send disturbance pulses down the
chain of oscillators. Indeed, it feels like we could write the travelling motion as a more simple

3
function that translates itself in space, with time. In this section, I show that indeed, you could do
both.
I will illustrate numerically here how the same code I used in the previous lecture to animate
the plucked string can support travelling disturbances. Recall that the code basically consisted of
projecting an initial position onto modes, animating these modes in time, and summing them to
obtain an approximate solution to the time evolution of the string.
I now do the same with and initial, gaussian-shaped perturbation:

( x − L/2)2
 
y(0, x ) = d exp − ,
2σx2

with σx = L/20 (see fig. 1).


I also set ẏ(0, x ) = 0 (no initial velocity). As a result, the initial bump does not have a propaga-
tion direction. It splits into two bumps, with equal amplitudes of 1/2 each and opposite travel
directions.
L = .33 # length of string: 33 cm
[4]: F = 68 # tension in the string: 68 N
mu = 0.125/L # mass per unit lenght of the string
ftsz = 13

x = np.linspace(0., L, 128) # the x array


v = np.sqrt(F/mu) # phase speed
k1 = np.pi/L # the fundamental k; k_n = n*k0 and omega_n = n*v*k0

def plot_gaussian_string():
[5]: xp = 0.1*L # the point where the string is plugged
sigma_x = 0.05*L
x_bump = 0.5*L
y_init = np.exp(-(x - x_bump)**2/(2*sigma_x**2))
# y_ini t = x/xp # the first part of the string; I will deivide all y's by d
# y_init[x > xp] = (L - x[x > xp]) / (L - xp) # the 2nd part

fig = plt.figure()
plt.plot(x/L, y_init, 'r')
plt.xlabel('$x/L$', fontsize=ftsz)
plt.ylabel('$y(0, x)/d$', fontsize=ftsz)
plt.title('The string at $t=0$', fontsize=ftsz)
plt.ylim([0., 1.1])
plt.grid()
plt.tight_layout()

return x, y_init

x, y_init = plot_gaussian_string()
[6]:

4
def plot_gaussian_spectrum(N):
[7]:
k = [n*k1 for n in range(1, N+1)] # the list of k's
omega = [n*k1*v for n in range(1, N+1)] # the list of omega's

mode = {} # all modes stored in a dictionary


alpha = [0.] # alpha coefficients stored in list
y_approx = 0*x # this will be the sum of thre first N modes

# plotting the spectrum


for n in range(1, N+1):
# projection happens on line below!!!
alpha.append(2. * np.trapz(y_init*np.sin(n*np.pi*x/L), x) / L)
mode[n] = alpha[n] * np.sin(n*np.pi*x/L)
y_approx += mode[n]

plt.figure()
for n in range(1, N+1):
plt.plot([n]*2, [0., alpha[n]], 'o-', linewidth=5)
plt.axis([0, N+0.5, 1.1*min(alpha), 1.1*max(alpha)])
plt.axhline(0., color='k')
plt.xlabel('Harmonic number $n$ ($\omega_n = n\pi v/L$)', fontsize=ftsz)
plt.ylabel(r'Modal amplitude $\alpha_n/d$', fontsize=ftsz)
plt.grid()
plt.tight_layout()

return omega, k, mode

N = 32
[8]: omega, k, mode = plot_gaussian_spectrum(N)

5
We see on the spectrum of this initial condition (fig. 2) that the modal amplitudes αn decay, but not
as fast as before: we need more modes before reaching a satisfying approximation of the solution.
We will animate the solution, truncating it to its first 32 modes.
# Various quantities
[9]: imagelist = [] # list of frames to eventually animate

t_end = 2.*np.pi/omega[0]
n_frames = 100 # number of frames for animation
time = np.linspace(0., t_end, n_frames) # time array

# Animation
fig = plt.figure(dpi=100)
ax = plt.gca()
ax.set_xlim([0., 1.])
ax.set_ylim([-1.1, 1.1])
ax.set_xlabel('$x/L$', fontsize=ftsz)
# ax.set_yticks(range(0, N+1))
# ax.set_yticklabels(['$tot$', '1', '2', '3', '4'])
ax.set_ylabel('$y(t, x)/d$', fontsize=ftsz)
ax.grid()

for t in time: # We loop over time to animate the modes


y = 0*x # nx positions for N modes
for n in range(N):
y += mode[n+1]*np.cos(omega[n]*t)

im = plt.scatter(x/L, y, c='b')#c=y, cmap='copper')


imagelist.append([im])

plt.tight_layout()

# Creation of the animation

6
ani = animation.ArtistAnimation(fig, imagelist, interval=60, blit=True, repeat_delay=80)
plt.close()

# Show the animation


[10]: HTML(ani.to_html5_video())

<IPython.core.display.HTML object>
[10]:
# Save the animation
[11]: ani.save('InitialBump.mp4')

(Animation saved under InitialBump.mp4) These are just a bunch of independent modes, doing
their own things!

4 Travelling solutions to the wave equation


Recall that the wave equation is
∂2 y 2
2∂ y
= v . (1)
∂t2 ∂x2

4.1 Decomposition into leftward and rightward-propagating waves


In this lecture, we will mostly ignore the existence of walls. In this context, the variable separation
technique, while still valid, does not provide much useful information. Instead, I will show that
the most general solution to the wave equation, is

y( x, t) = f ( x − vt) + g( x + vt). (2)

The beauty of this solution is that any function that can be written as f ( x − vt) or g( x + vt), i.e., as
a univarate function of x − vt or x + vt, or a combination of both, is a solution of equation (1). But
first, let me describe what it entails to be either f ( x − vt) or g( x + vt).
Imagine your favourite function f ( x ). Now, picture f ( x − 1): it is the same shape of the curve, but
translated by one to the right. Same for f ( x + 1): it is the same, just translated to the left by one.
In either case, if I redefine the origin of x to be one to the right or to the left, the curve will be back
to its original position.
Now, picture f ( x − vt): you should be picturing the same curve, but translating progressively
to the right with time, at a speed v. For the g( x + vt) case, you should be picturing a curve
g( x ), translating to the left with speed v. The decomposition of any solution into f ( x − vt )
and g ( x + vt ) corresponds to a decomposition into right- and leftward propagating waves,
respectively.
The main travelling function we will encounter will be the travelling sinusoidal wave, as animated
below (saved under LeftAndRight.mp4), and for which
 

y( x, t) = A sin ( x ± vt)
λ
= A sin [k( x ± vt)]
h x i
= A sin ω ±t
v
= A sin (kx ± ωt) .

7
We saw this before but let’s but one more coin in the slot.
• λ is called the wavelength of the wave, which corresponds to the spatial period of the wave
(the distance between two consecutive maxima or minima),
• k is its wavenumber,
• ω its angular frequency and
• 2π/ω its period (the duration between two consecutive maxima or minima, at the same
location).
The following relations will be useful:
ω
v= = λν and λ = vT .
k
Careful about the difference between v (“vee”, the velocity) and ν (“nu”, the frequency). Also, the
last T refers to the period of the wave.
# Animation
[12]: fig = plt.figure()
ax = plt.gca()
ax.set_xlim([0., 1.])
ax.set_ylim([-1.1, 4.1])
ax.set_xlabel('$x/L$', fontsize=ftsz)
ax.set_yticks([0., 3.])
ax.set_yticklabels([r'$\sin(kx - \omega t)$', r'$\sin(kx + \omega t)$'],
fontsize=ftsz, rotation='vertical')
ax.grid()

imagelist = []

k = 4*np.pi/L

for t in time: # We loop over time to animate the modes


y = 0*x # nx positions for N modes
f = np.sin(k*(x - v*t))
g = np.sin(k*(x + v*t)) + 3

y = np.vstack((f, g))
x_scat = np.vstack((x, x))
im = plt.scatter(x_scat/L, y, c=y, cmap='copper')
imagelist.append([im])

# Create the animation


ani = animation.ArtistAnimation(fig, imagelist, interval=100, blit=True, repeat_delay=80)
plt.close()

# Show the animation


[13]: HTML(ani.to_html5_video())

<IPython.core.display.HTML object>
[13]:
# Save the animation
[14]: ani.save('LeftAndRight.mp4')

4.2 Solutions to the wave equation


I now prove my early claim that equation (2) is the general solution to the wave equation (1). In a
first time, I will focus on f ( x − vt).
Let us change variables to u = x − vt, therefore, the only dependence of f is on u: f (u). Then,
∂f ∂u d f df
= = .
∂x ∂x du du

8
Likewise,
∂2 f ∂u d2 f d2 f
= = .
∂x2 ∂x du2 du2

For time, we have


2
∂f ∂u d f df ∂2 f 2d f
= = −v and = v ,
∂t ∂t du du ∂t2 du2
and therefore,
∂2 f ∂2 f
2
= v2 2 .
∂t ∂x

A very similar succession of steps, with u = x + vt this time, yields

∂2 g 2
2∂ g
= v .
∂t2 ∂x2

Finally, for y( x, t) = f ( x − vt) + g( x + vt), linearity of the equations derived above implies that

∂2 y 2
2∂ y
= v .
∂t2 ∂x2

This is true for any function, which can take the same form as equation (2). We have not made any
assumption about which functions were in f and g: they can be sinusoidal travelling waves, they
can be bumps, or anything else. In fact, y( x, t) = f ( x − vt) + g( x + vt) is the most general solution
to the wave equation.

4.3 One standing wave as a superposition of two counter-propagating waves


Take one single standing wave on a string, attached to both ends:

yn (t, x ) = Cn cos(ωn t) sin(k n x ),

and recall that


1
sin( a) cos(b) = [sin( a + b) + sin( a − b)] .
2

Therefore,
Cn
yn ( x, t) = [sin(k n x + ωn t) + sin(k n x − ωn t)]
2
Cn
= {sin[k n ( x + vt)] + sin[k n ( x − vt)]} .
2
A standing wave mode can be interpreted as the superposition of a leftward and a rightward
wave! The standing and travelling wave representations are equivalent (see animation saved
under LeftPlusRightEqualStanding.mp4).
# Animation
[15]: fig = plt.figure()
ax = plt.gca()
ax.set_xlim([0., 1.])
ax.set_ylim([-2.1, 13.1])
ax.set_xlabel('$x/L$', fontsize=ftsz)

9
ax.set_yticks([0., 4., 8., 12.])
ax.set_yticklabels([r'$f + g$',
r'$f$ and $g$',
r'$g(x + v t)$',
r'$f(x - v t)$'],
fontsize=ftsz)
ax.grid()

imagelist = []

k = 4*np.pi/L

for t in time: # We loop over time to animate the modes


y = 0*x # nx positions for N modes
# f and g were defined in the previous animation
f = np.sin(k*(x - v*t))
g = np.sin(k*(x + v*t))
y = f + g

y_scat = np.vstack((f+12, g+8, f+4, g+4, y))


x_scat = np.vstack((x, x, x, x, x))
im = plt.scatter(x_scat/L, y_scat, c=y_scat, cmap='copper') #'b')
plt.tight_layout()
imagelist.append([im])

# Create the animation


ani = animation.ArtistAnimation(fig, imagelist, interval=100, blit=True, repeat_delay=80)
plt.close()

# Show the animation


[16]: HTML(ani.to_html5_video())

<IPython.core.display.HTML object>
[16]:
# Save the animation
[17]: ani.save('LeftPlusRightEqualStanding.mp4')

5 Wave dispersion
5.1 Introduction
Previously, we only considered cases, for which the phase speed v does not depend on angular
frequency ω or wavenumber k, because the ratio ω/k was always constant. In general however,
the phase speed depends on the frequency. This has several implications, in particular when
several wave modes are superposed.
Take the propagating bumps we used earlier in this lecture. They were bouncing around on the
string, and if the string had been infinitely long, they would have propagated for ever without
changing shape. Somehow, the interference pattern between all the wave modes that resulted in
the bumps remained stable, all modes being able to “keep up” with the propagation of the bumps.
Now, if the string had been infinitely long, but modes had a different phase speeds, then after a
while, the bumps would change shape. They would break down, the fastest propagating modes
leading the charge, and the slowest propagating modes trailing behind, increasingly so as time
would go on. Sort of like the picture below, about surface gravity waves, where longer waves
travel faster than shorter waves (see tutorial).

10
This phenomenon is called dispersion. The proper way to refer to it is to refer to waves propagating
in a dispersive medium, although I may refer to dispersive waves to keep things short. Some waves
are virtually immune to it. Examples are acoustic waves propagating in air (but propagation in
other media can induce significant dispersion), surface water waves whose wavelengths are much
longer than the fluid is deep, such as swell or tsunami, the waves on a taut string, and EM waves
propagating in perfect vacuum. These are merely results of approximations however, and the
examples below are results for which the approximations hold very well. In general, waves are
subject to dispersion.
In particular, one of the most fundamental properties of waves in dispersive media is that energy
and phase do not propagate at the same speed anymore. In some cases, this leads to the definition
of a so-called group speed, distinct from the phase speed, and which corresponds to the speed of
propagation of the energy.

5.2 Beating in non-dispersive media


Third time is the charm: we mentioned beating for two modes, oscillating in time only. True
beating happens when the amplitudes of the modes are equal to one another. In this case, the
position of mass A is

q1 ( t ) + q2 ( t ) C [cos(ω1 t) + cos(ω2 t)]


xA = = = C cos(ω0 t) cos[(∆ω )t],
2 2
with ∆ω = (ω2 − ω1 )/2 and ω0 = (ω1 + ω2 )/2. Beating is most spectacular when ∆ω  ω1 , in
which case
x A ≈ C cos(ω1 t) cos[(∆ω )t].
See figures below (with the notations of lecture 7).

11
If now waves oscillate in time and space, beating happens again, but as a time-dependent process.
Let our two propagating waves of equal amplitudes be

ψ1 = A cos(k1 x − ω1 t) and ψ2 = A cos(k2 x − ω2 t).

For now, we restrict our analysis to a non-dispersive medium, i.e., ω1 /k1 = ω2 /k2 = v (the phase
speed does not depend on frequency).
The superposition of the two waves yields

ψ = ψ1 + ψ2 = A [cos(k1 x − ω1 t) + cos(k2 x − ω2 t)]


= 2A {cos[(∆k) x − (∆ω )t] cos [k0 x − ω0 t]} ,

with ∆k = (k2 − k1 )/2 and ∆ω = (ω2 − ω1 )/2 the half-separations between wavenumbers and
frequencies, respectively, and

ω1 + ω2 k1 + k2
ω0 = ω1 + ∆ω = and k0 = k1 + ∆k = ,
2 2
the average values of ω and k.
Again, beating is most spectacular when ω1 ≈ ω2 , or ∆ω  ω1 , in which case the time intervals
during which the two waves beat in phase to produce a strong signal are long. See display below
for the wave along x, animated over time (saved under BeatingNonDisp.mp4).
# basic quantities
[18]: omega1 = 2*np.pi*265 # 265 Hz is the frequency of our turning fork
omega2 = 2*np.pi*285 # 265 Hz is the frequency of our turning fork
v = 340. # 340 m/s is the approximate speed of sound in air
ftsz = 13 # font size on plots

12
A = 1. # Why not?
nBeats = 4. # duration, long enough to hear nBeat beats
nBeats_x = 1.5 # distance, long enough to see nBeats_x beats

# derived quantities
k1 = omega1/v
k2 = omega2/v

Domega = 0.5*(omega2 - omega1)


Dk = 0.5*(k2 - k1)

t_end = nBeats*np.pi/Domega
x_end = nBeats_x*np.pi/Dk

time = np.linspace(0., t_end, 2**10)


# x = np.linspace(0., x_end, 512)

x = np.linspace(0., x_end, 512)


[19]: plotcols = ["blue", "green", "blue", "green", "red", "red", "red"]

fig = plt.figure(figsize=(7, 6), dpi=100)


ax = plt.axes(xlim=(0., x_end), ylim=(-2.2, 9.7))
ax.set_xlabel('$x$ [m]')
ax.set_yticks([0., 3.5, 6., 8.5])
ax.set_yticklabels([r'$\psi_1 + \psi_2$',
r'$\psi_1$, $\psi_2$',
r'$\psi_2(x, t)$', r'$\psi_1(x,t)$'],
fontsize=ftsz)
ax.grid()

list_of_lines = []
for index, _ in enumerate(plotcols):
if index < 5:
lobj = ax.plot([], [], lw=1, color=plotcols[index])[0]
else:
lobj = ax.plot([], [], lw=1, color=plotcols[index], linestyle=':')[0]
list_of_lines.append(lobj)

def init():
for line in list_of_lines:
line.set_data([], [])
return list_of_lines

def animate(i):
psi1 = A*np.cos(k1*x - omega1*time[i])
psi2 = A*np.cos(k2*x - omega2*time[i])
psi = psi1 + psi2
envelope = 2*A*np.cos(Dk*x - Domega*time[i])
list_of_lines[0].set_data(x, psi1+8.5)
list_of_lines[1].set_data(x, psi2+6.)
list_of_lines[2].set_data(x, psi1+3.5)
list_of_lines[3].set_data(x, psi2+3.5)
list_of_lines[4].set_data(x, psi)
list_of_lines[5].set_data(x, envelope)
list_of_lines[6].set_data(x, -envelope)
return list_of_lines

ani = animation.FuncAnimation(fig, animate, init_func=init,


frames=len(time), interval=80, blit=True)
plt.tight_layout()
plt.close()

# Show the animation


[20]: HTML(ani.to_html5_video())

<IPython.core.display.HTML object>
[20]:

13
# Save the animation
[21]: ani.save('BeatingNonDisp.mp4')

5.3 Phase speed, group speed


What if now the phase speed v depended on the frequency or wavenumber of the wave? A
medium in which such a phenomenon happens is called dispersive, and it is in fact the most
general case. In this case,
ω
= v(ω ) or v(k),
k
and the general relation between ω and k,

ω = v(k )k,

is called a dispersion relation, and it is a property of the physical characteristics of the medium.
In this section, I do not have to assume that ∆ω  ω1 . Let me reboot the previous derivation
about beating, this time with

ψ1 = A cos(k1 x − ω1 t) and ψ2 = A cos(k2 x − ω2 t).

I will drop the assumption that v is constant later on. We had found that

ψ = ψ1 + ψ2 = 2A cos[(∆k ) x − (∆ω )t] cos [k0 x − ω0 t] .

Therefore,

ψ = E( x, t) cos [k0 x − ω0 t] , with E( x, t) = 2A cos[(∆k ) x − (∆ω )t].

Written as above, the expression is that of a wave of phase speed

ω0
v= ,
k0

modulated in time and space by the envelope E( x, t). Notice that I framed the expression, as if it
were a new one. It does look like one we saw before, but this is evaluated at the mean angular
frequency and mean wavenumber, which didn’t make sense when there was just one angular
frequency.
Of course, just like beating, this representation works best if the modulation happens slowly in
time, i.e., ∆ω  ω0 . That’s just because if the modulation is slow, it feels more comfortable to
think of it as a wave that propagates and evolves slowly. But it can be written as the equation
above in any case.
# basic quantities
[22]: omega1 = 2*np.pi*265 # 265 Hz is the frequency of our turning fork
omega2 = 2*np.pi*285 # 265 Hz is the frequency of our turning fork
v = 340. # 340 m/s is the approximate speed of sound in air
v1 = 360. # speed of sound in air for omega1
v2 = 320. # speed of sound in air for omega2
# note: sound waves in air are virtually non-dispersive!
# These values are unrealistic for sound waves, but good for an example.
ftsz = 13 # font size on plots
A = 1. # Why not?

14
nBeats = 2. # duration, long enough to hear nBeat beats
nBeats_x = 2.5 # distance, long enough to see nBeat_x beats

# derived quantities
k1 = omega1/v1
k2 = omega2/v2

k0 = 0.5*(k1 + k2)
omega0 = 0.5*(omega1 + omega2)

Domega = 0.5*(omega2 - omega1)


Dk = 0.5*(k2 - k1)

t_end = nBeats*np.pi/Domega
x_end = nBeats_x*np.pi/Dk

time = np.linspace(0., t_end, 2**10)


# x = np.linspace(0., x_end, 512)

x = np.linspace(0., x_end, 256)


[23]: plotcols = ["blue", "green", "blue", "green", "red", "red", "red"]

fig = plt.figure(figsize=(7, 6), dpi=100)


ax = plt.axes(xlim=(0., x_end), ylim=(-2.2, 9.7))
ax.set_yticks([0., 3.5, 6., 8.5])
ax.set_yticklabels([r'$\psi_1 + \psi_2 $',
r'$\psi_1$, $\psi_2$',
r'$\psi_2(x, t)$', r'$\psi_1(x, t)$'],
fontsize=ftsz)
ax.set_xlabel('$x$ [m]', fontsize=ftsz)
ax.grid()

plt.tight_layout()

list_of_lines = []
for index, _ in enumerate(plotcols):
if index < 5:
lobj = ax.plot([], [], lw=1, color=plotcols[index])[0]
else:
lobj = ax.plot([], [], lw=1, color=plotcols[index], linestyle=':')[0]
list_of_lines.append(lobj)

def init():
for line in list_of_lines:
line.set_data([], [])
return list_of_lines

def animate(i):
psi1 = A*np.cos(k1*x - omega1*time[i])
psi2 = A*np.cos(k2*x - omega2*time[i])
psi = psi1 + psi2
envelope = 2*A*np.cos(Dk*x - Domega*time[i])
list_of_lines[0].set_data(x, psi1+8.5)
list_of_lines[1].set_data(x, psi2+6.)
list_of_lines[2].set_data(x, psi1+3.5)
list_of_lines[3].set_data(x, psi2+3.5)
list_of_lines[4].set_data(x, psi)
list_of_lines[5].set_data(x, envelope)
list_of_lines[6].set_data(x, -envelope)
return list_of_lines

ani = animation.FuncAnimation(fig, animate, init_func=init,


frames=len(time), interval=80, blit=True)
plt.close()

# Show the animation


[24]: HTML(ani.to_html5_video())

15
<IPython.core.display.HTML object>
[24]:
# Save the animation
[25]: ani.save('BeatingDisp.mp4')

As you can see in the animation above (saved under BeatingDisp.mp4), when the two waves
travel at different velocities, the pattern at each instant is still that of beating. But the difference is
that is the waves travel at different speeds, they “slide by one another”, and the pattern of beating
moves, i.e., the envelope, propagates at a different speed than the wave inside it.
Note: This is a delicate point, which falls under the category of “Understanding came quickly, but only after
a lengthy explanation”. I encourage you stare at the two beating animations I provided to convince yourself,
but it may not be suitable for everyone. Therefore, I also encourage you to seek alternative references: other
textbooks, movies on the web, or else.
How fast does the envelope travel? The envelope is

∆ω
  
E( x, t) = 2A cos[(∆k ) x − (∆ω )t] = 2A cos ∆k x − t .
∆k

This would be the expression of a wave, propagating with a phase speed ∆ω/∆k. The envelope is
not a wave, but this expression still tells us that it travels with velocity ∆ω/∆k.
The velocity of the envelope is called the group velocity. In this case, it is defined as

∆ω ω2 − ω1
vg = = .
∆k k2 − k1

In this particular case, there are only two frequencies. But in practice, the notion of group speed is
only used when there are a bunch of different waves of different frequencies and different wave-
lengths that are all close together. In this example with only two frequencies, let us compute the
approximate value of v g when assuming that it is the case, i.e., that ∆ω  ω0 or ∆k  k0 . The
Taylor series expansion of ω0 (k0 ± ∆k ) is


ω (k0 ± ∆k ) = ω (k0 ) ± ∆k + O(∆k2 ).
dk k=k0

Therefore,
dω dω
ω2 − ω1 ≈ 2∆k = (k2 − k1 ) ,
dk k=k0 dk k=k0
or,
ω2 − ω1 dω
∆k → 0 ⇒ = v g (k0 ) = .
k2 − k1 dk k=k0

The group velocity is the k-derivative of ω(k) evaluated at the mean wavenumber.
One important remark about the result above. While v g = dω/dk is the actual definition of
the group speed, the calculation above was not a derivation. It was merely an illustration of a
continuous process with discrete waves, and in the context of that particular case, is only truly true
when ∆k → 0. Natural superpositions of waves are usually made of a continuous superposition
of waves of slightly different k’s. Because the k’s exist on a continuum, ∆k → 0 actually becomes

16
a valid limit. I will not cover this case, because the mathematical tools necessary to properly treat
it are related to Fourier transforms, which is beyond the scope of this class.
So, remember this: the calculation above is an illustration, not a derivation. Nonetheless, the
true definition of the group speed is vg = dω/dk.
We now have two wave speeds: the phase speed and the group speed. In our 1D case, to go from
one to the other is relatively easy, because

dω d(kv) dv
vg = = = v+k ,
dk dk dk
where everything is evaluated at k = k0 . In a non-dispersive medium where v is constant no
matter ω or k, therefore, dv/dk = 0 and

v g = v in a non-dispersive medium .

It might be easier at this early stage to think in terms of wavelength λ, rather than wavenumber k.
The change of variable k = 2π/λ yields

dv dλ dv 2π dv λ2 dv dv
= =− 2 =− , and vg = v − λ ,
dk dk dλ k dλ 2π dλ dλ

where again everything is evaluated at λ = λ0 .

5.4 Dispersion Relation


5.4.1 Definition
As it turns out, and for reasons that we will touch upon with EM waves in an ionized gas, in most
natural situations and non-dispersive media, dv/dλ > 0 and therefore, v g < v (just like in the
last animation, BeatingDisp.mp4). This is called normal dispersion. The dv/dλ < 0, v g > v is not
impossible, but it is less frequently encountered. We talk about anomalous dispersion. It may sound
harsh and stigmatizing for the poor v g > v case, but again, we will see later why there sometimes
are physical reasons to think so.
The relation linking ω with k is called the dispersion relation of a type of waves in a given
medium. Alternatively, and equivalently, expressions for e.g. ω 2 (k), v(k ), v2 (k ) can also be called
dispersion relations, because ω = kv and there is no loss of information in going from one to the
other.
See sketch below: the three curves (a), (b) and (c) represent three types of dispersion. Curve (a)
represents non-dispersive behaviour because at every point, ω/k = dω/dk. Curve (c) is called
normal: the line from the origin to P has slope ω/k, and it is larger than the slope dω/dk at P.
Curve (b) represents anomalous dispersion.

17
5.4.2 Example: EM waves in an ionized gas
The ionosphere is the layer of the atmosphere of a planet where the gas is very rarefied, and UV
rays of the sun partially ionize the molecules. On Earth, it is found from 60-100 km high, up to 800
km (Note: the ISS orbits at about 400 km altitude). This ionized gas again interacts with EM waves,
and in particular with radio waves. The dispersion relation for radio waves in the ionosphere
becomes
ω 2 (k) = ω 2p + c2 k2 for ω > ω p ,
where c is the phase speed of EM waves in vacuum (the “speed of light”) and ω p is called the
plasma oscillation frequency. The latter is the natural frequency of oscillation of a cloud of negative
charges oscillating around a cloud of positive charges, which is what an ionized gas consists of.
The frequency value is typically ω p /(2π ) = νp ≈ 40 MHz. Waves whose frequency is lower than
ω 2p simply cannot propagate into the ionosphere: it is called a “cut-off frequency”.
This is why long-distance radio transmission works: by bouncing off the ionosphere, radio waves
stick to the ground and can duct along it over long distances. This includes high-frequency (1.6
MHz< ν < 30 MHz) radio waves used by radio amateurs, and AM waves (575 − 1705 kHz).
On the other hand, FM waves have a minimum frequency that is 87.5 MHz, which is higher than
the plasma frequency. Therefore, they don’t travel farther than the visible horizon, and escape to
the ionosphere and then to space after that. This is why FM signals don’t travel much farther than
about 60 km, and why transmitters have to be placed high up on towers or hills.
The phase speed of radio waves, propagating into the ionosphere, is
s s
2 c2 k2 + ω 2p
ω ω p 2
c c
v= = +c = c =r =q .
k k2 c2 k 2 2 2 2 2
c k +ω p −ω p 1 − ω 2p /ω 2
ω 2p +c2 k2

18
Looking at v, you may notice that if this expression is only relevant for ω > ω p , then v > c!!!
However, the famous statement that nothing can travel faster than the speed of light only applies
to what I am going to call “stuff”, i.e., matter, energy, information. . . A phase is not “stuff” in
itself, just a pattern that moves. When light hits Earth from the far reaches of space, it has traveled
in the form of pulses, i.e., light waves that have traveled, bundled within envelopes. Evelopes
travel at the group velocity, not the phase velocity, and according to the equation I am about to
derive, v g = c2 /v < c.
Indeed, we could compute the group speed easily by taking the k-derivative of the dispersion
relation ω 2 = ω 2p + c2 k2 . A shrewder way to do the same thing is to take the differential form of
that equation, i.e.,

2 dω c2 k q
2ωdω = 2c kdk ⇒ v g = = = c 1 − ω 2p /ω 2 .
dk ω

Which brings me to my next point: the fundamentally important interpretation of the group speed
is that the group speed is the speed of propagation of the energy. Think of those light pulses:
they are the ones that carry the energy that will impact light detectors, and if the group speed is
their velocity, then so is the velocity of propagation of energy.

5.5 Collapse of a Gaussian wave packet


I mentioned earlier that with dispersion, disturbances lose their shape over time. Let me illustrate
this behaviour on an example: the Gaussian wave packet.
To illustrate it, I chose the example of deep-water capillary-gravity waves. “Gravity waves” mean
that the restoring force is gravity, a big lump (typically more than a few cm in wavelength) of
water tending to fall due the gravity. “Capillary waves” mean that the restoring force is now due
to surface tension: nature hates interfaces, and surface tension is the mechanism by which tiny
ripples (less than 1 cm in wavelength for the air/water interface) flatten out.
The dispersion relation is
σk3
ω 2 = gk + ,
ρ
where g is the acceleration due to gravity, σ is the surface tension of the air/water interface, and ρ
is the mass density of water, respectively.
In the code below, I chose a wavelength of 1 mm, meaning that the second term on the RHS
dominates over the first term, and the dispersion is anomalous (you can check). I initialize a “wave
packet”. Wave packets are a superposition of waves with a dominant wave with wavenumber k0 ,
superposed with waves, whose amplitude decays as |k − k0 | increases.
I plot in the figure below an example with
2 !
k n − k0

an = exp − ,
∆k

with ∆k controlling the width of the function a(k ). Wave packets are well-localized in space and
time. The energy is concentrated in them, another illustration that the group speed is the speed
of propagation of the energy.
Let’s just animate all of these waves and see what happens to our wave packet. . .

19
# Basic quantities; let's use capillary waves
[26]: lambda0 = 1e-3 # 1 mm for a wavelength
k0 = 2*np.pi/lambda0

dk = k0/20 # wavenumber separation of successive wavenumbers


N = 19 # number of waves
nBeats_x = 1.2 # distance, long enough to see nBeat_x beats

# derived quantities
k_array = np.arange(k0-0.5*dk*(N-1), k0+0.5*dk*N, dk)
A_array = A*np.exp(-(k_array-k0)**2/(3*dk)**2) # all waves have same amplitude
x_end = nBeats_x*np.pi/dk
x = np.linspace(-x_end, x_end, 1024)

psi_n = {} # each individual wave is an item in a dictionnary


psi = 0*x + 0*1j
for ii, kk in enumerate(k_array):
psi_n[ii] = A_array[ii]*np.exp(1j*kk*x) # I will take the real part
psi += psi_n[ii]

yMin, yMax = -N-1., N+1.

# code for the spectrum


[27]: def plot_gaussian_wavepacket():
plt.figure()
for ii in range(N):
plt.plot([k_array[ii]]*2, [0., A_array[ii]], 'o-', linewidth=5)
plt.grid()
plt.ylabel('Plane wave amplitude [m]', fontsize=ftsz)
plt.xlabel('$k$', fontsize=ftsz)

plt.tight_layout()

plot_gaussian_wavepacket()
[28]:

20
# code for the animation
[29]: def omega(k_): # dispersion relation
return np.sqrt(g*k_ + sigma*k_**3/rho) # dispersion relation for deep-water waves

sigma = 7.2e-2 # surface tension of air/water interface [N/m^2]


g = 9.81 # gravitational acceleration [m/s^2]
rho = 1000. # mass density of water [kg/m^3]

nBeats = 8.
t_end = nBeats*np.pi/(omega(k0+dk) - omega(k0))
time = np.linspace(0., t_end, 1024)

fig = plt.figure(dpi=100)
ax = plt.axes(xlim=(-x_end, x_end), ylim=(-10., 10.))
ax.set_xlabel('$x$ [m]', fontsize=ftsz)

ax.grid()

list_of_lines = [ax.plot([], [], lw=1)[0]]

def init():
for line in list_of_lines:
line.set_data([], [])
return list_of_lines

def animate(i):
psi = 0*x + 0*1j
for ii in range(0, N): # each individual psi_n
phase_t = omega(k_array[ii])*time[i]
psi += psi_n[ii]*np.exp(-1j*phase_t)
ax.set_title('$t = {0: 3.0f}$ ms'.format(1000*time[i]))
list_of_lines[0].set_data(x, np.real(psi))

return list_of_lines

ani = animation.FuncAnimation(fig, animate, init_func=init,


frames=len(time), interval=40, blit=True)

plt.close()

# Show the animation


[30]: HTML(ani.to_html5_video())

<IPython.core.display.HTML object>
[30]:
# Save the animation
[31]: ani.save('WavePacket.mp4')

6 Summary
In this lecture, we saw:
• The equivalence of standing and travelling wave representations.
– Like all solutions of the wave equation a BCs, travelling waves are a superposition of
standing wave modes.
– One standing wave mode is the superposition of two equal-and-counter-propagating
sine waves.
• To be a solution to the non-dispersive wave equation, you only have to travel at the right
speed. It doesn’t matter what function describes you, as long as it translates in space at the
right speed.
• Wave dispersion happens when the propagation velocity is not constant anymore, but de-

21
pends on k, ω or equivalent.
• Phase speed is the speed of propagation of the pattern “phase”. Group speed is the speed of
propagation of the envelopes, where energy is concentrated. Therefore, it is often assimilated
with the speed of propagation of energy.
• The three types of dispersion: non-dispersive (v = v g ), normal (v > v g ) and anomalous
(v < v g ).
And a bonus, in the video, one of the landmark experiments of physical oceanography: the Waves
Across the Pacific (WAP) experiment. Walter Munk left us in 2019 at the age of 101, and up until
the end, he would show up to the office in his walker and share all sorts of ideas for research, and
give presentations about how he and his PhD supervisor single-handedly (well, double-handedly)
invented wave forecasting during WWII for beach landing preparations. As he would say, “it was
all linear dynamics, there had to be a way to know in advance the height and frequencies of those
waves on a given day”. And to do that, they used math and physics, not much more advanced
than what you saw in this lecture.
YouTubeVideo("MX5cKoOm6Pk")
[32]:
[32]:

22

You might also like