# A Wave Reflecting On A Boundary

An incident wave

$$u_I(x, t) = F_I(t - x/c)$$

arrives perpendicularly at a boundary separating two media gives rise to a reflected wave

$$u_R(x, t) = F_R(t + x/c)$$

Writing that the disturbance is zero at the boundary (which we set on the origin) we obtain the following

$$u_I(0, t) + u_R(0, t) = 0 \; \forall t \Rightarrow F_R(t) = - F_I(t)$$

In the following lines, we plot that relation with a given waveform.

In [1]:
%matplotlib inline

In [2]:
from pylab import *

In [3]:
t = linspace(-10, 10, num=1000)

In [4]:
def waveform(t):
return sin(5*t) * exp(-abs(t**3))

In [5]:
plot(t, waveform(t))

Out[5]:
[]

By plotting the waveform at different $t - x/c$ (with $c$, the speed of the wave implicitly equal to 1) values, we can see it move forward.

In [6]:
x = linspace(-10, 10, num=1000)

In [7]:
plot(t, waveform(x), label='t=0')
plot(t, waveform(3 - x), label='t=3')
plot(t, waveform(7 - x), label='t=7')
legend(loc='lower left')

Out[7]:

Writing a function that sums up the adding of the waves gives the following result.

In [8]:
def plot_timestep(x, t):
# incident wave
inc = waveform(t - x)
plot(x, inc, label='incident')
# reflected wave
ref = - waveform(t + x)
plot(x, ref, label='reflected')
# sum
plot(x, inc + ref, label='sum', lw=2)

In [9]:
figure(figsize=(10, 7))
for ind, val in enumerate([-3, -0.5, 1, 4]):
subplot(2, 2, ind + 1)
plot_timestep(t, val)
grid(True)
legend(loc='lower right')
title('time = %i' % val)
tight_layout()


This can now be compiled into an animation, courtesy of this nice article by Jake Vanderplas and a helpful comment.

In [10]:
from tempfile import NamedTemporaryFile

VIDEO_TAG = """
{0}" type="video/mp4">
Your browser does not support the video tag.
"""

def anim_to_html(anim):
if not hasattr(anim, '_encoded_video'):
f = NamedTemporaryFile(suffix='.mp4', delete=False)
anim.save(f.name, fps=20, extra_args=['-vcodec', 'libx264', '-pix_fmt', 'yuv420p'])
f.close()
anim._encoded_video = video.encode("base64")

return VIDEO_TAG.format(anim._encoded_video)

In [11]:
from IPython.display import HTML

def display_animation(anim):
plt.close(anim._fig)
return HTML(anim_to_html(anim))

In [12]:
from matplotlib import animation

# First set up the figure, the axis, and the plot element we want to animate
fig = plt.figure()
ax = plt.axes(xlim=(-10, 10), ylim=(-1, 4))
line_inc, = ax.plot([], [], lw=1, label='incident')
line_ref, = ax.plot([], [], lw=1, label='reflected')
line_sum, = ax.plot([], [], lw=2, label='sum')
vlines(0, -1, 4, linestyles='dashed', lw=4)
annotate("totally reflecting wall",
xy=(0, 2), xycoords='data',
xytext=(5, 3.25), textcoords='data',
size=10, va="top", ha="center",
arrowprops=dict(arrowstyle="simple",
)
legend(loc='center right')

# initialization function: plot the background of each frame
def init():
line_inc.set_data([], [])
line_ref.set_data([], [])
line_sum.set_data([], [])
return line_inc, line_ref

# animation function.  This is called sequentially
def animate(i):
x = linspace(-10, 10, 1000)
t = linspace(-7, 7, num=100)[i]
# incident wave
inc = waveform(t - x)
# reflected wave
ref = - waveform(t + x)
# sum
total_wave = inc + ref
line_inc.set_data(x, inc)
line_ref.set_data(x, ref)
line_sum.set_data(x, total_wave + 2)
return line_inc, line_ref

# call the animator.  blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=100, interval=20, blit=True)

# call our new function to display the animation
display_animation(anim)

Out[12]: