Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Wave equation

Classical Wave equation

2u(x,t)x2=1v22u(x,t)t2\frac{\partial^2 u(x,t)}{\partial x^2 }= \frac{1}{v^2}\frac{\partial^2 u(x,t)}{\partial t^2}
applied photoelectric

Figure 1:The classical wave equation describes any complicated wave in space and time, given the initial conditions.

applied photoelectric

Figure 2:A plucked guitar string is a classic system governed by the 1D wave equation.

Solving Wave Equation: The big picture

u(0,t)=0andu(L,t)=0u(0, t) = 0 \quad \text{and} \quad u(L, t) = 0
u(x,t)=X(x)T(t)u(x, t) = X(x) \cdot T(t)
u=c1u1+c2u2u = c_1 u_1+c_2u_2

Step 1: Plug the Product of Univariate Functions into the Wave Equation

1v22u(x,t)t2=2u(x,t)x2\frac{1}{v^2}\frac{\partial^2 u(x,t)}{\partial t^2} = \frac{\partial^2 u(x,t)}{\partial x^2}
1v22X(x)T(t)t2=2X(x)T(t)x2\frac{1}{v^2}\frac{\partial^2 X(x)T(t)}{\partial t^2} = \frac{\partial^2 X(x)T(t)}{\partial x^2}
X(x)v22T(t)t2=T(t)2X(x)x2\frac{X(x)}{v^2}\frac{\partial^2 T(t)}{\partial t^2} = T(t)\frac{\partial^2 X(x)}{\partial x^2}
1T(t)v22T(t)t2=1X(x)2X(x)x2=K\frac{1}{T(t)v^2}\frac{\partial^2 T(t)}{\partial t^2} = \frac{1}{X(x)}\frac{\partial^2 X(x)}{\partial x^2} = K

Step 2: Solving Each Ordinary Differential Equation

After decomposing the PDE into ODEs, we solve each ODE separately:

2T(t)t2KT(t)v2=0\frac{\partial^2 T(t)}{\partial t^2} - K T(t) v^2 = 0
2X(x)x2KX(x)=0\frac{\partial^2 X(x)}{\partial x^2} - K X(x) = 0

Solution for spatial part

X(x)=Bsin(nπLx)X(x) = B \sin \left(\frac{n \pi}{L} x \right)
applied photoelectric

Figure 3:The first seven solutions (normal modes) of the spatial part of the wave equation on a string of length LL, shown at positive and negative amplitude.

Source
import numpy as np
import matplotlib.pyplot as plt

# Parameters
L = 1.0
B = 1.0
ns = [1, 2, 3, 4]
x = np.linspace(0, L, 800)

# 2x2 subplot
fig, axes = plt.subplots(2, 2, figsize=(8, 6))

for ax, n in zip(axes.ravel(), ns):
    Xn = B * np.sin(n * np.pi * x / L)
    ax.plot(x, Xn, color="C0")
    ax.axhline(0, color="black", linewidth=0.8)
    ax.set_title(f"n = {n}")
    ax.set_xlabel("x")
    ax.set_ylabel("X(x)")
    ax.set_xlim(0, L)

fig.suptitle("Normal modes of a fixed–fixed string")
fig.tight_layout(rect=[0, 0, 1, 0.96])
<Figure size 800x600 with 4 Axes>

Solution for temporal part

T(t)=Dncos(ωnt)+Ensin(ωnt)=Ancos(ωnt+ϕn)T(t) = D_n \cos(\omega_n t) + E_n \sin(\omega_n t) = A_n \cos (\omega_n t + \phi_n)

Step 3 Full solution: A linear combination of normal modes

About nodes

Places where the guitar string stays at the resting position of 0 are called nodes. We notice that the number of nodal points increases with nn.

Source
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML

# Parameters (reduced frames for faster export)
L = 1.0
v = 1.0
B = 1.0
A = {1: 1.0, 2: 1.0, 3: 1.0}
phi = {1: 0.0, 2: 0.0, 3: 0.0}

x = np.linspace(0, L, 600)

def X(n, x):
    return np.sin(n * np.pi * x / L)

def T(n, t):
    omega_n = n * np.pi * v / L
    return np.cos(omega_n * t + phi[n])

def u_mode(n, x, t):
    return B * X(n, x) * T(n, t)

def u_sum(modes, x, t):
    s = np.zeros_like(x)
    for n in modes:
        s += A[n] * X(n, x) * T(n, t)
    return s

omega1 = np.pi * v / L
T1 = 2 * np.pi / omega1
tmax = 2 * T1
frames = 120  # fewer frames
ts = np.linspace(0, tmax, frames)

fig, axes = plt.subplots(2, 2, figsize=(8, 6))
axes = axes.ravel()
titles = ["n = 1", "n = 3", "n = 1 + 2", "n = 1 + 2 + 3"]
lines = []
for ax, title in zip(axes, titles):
    ax.set_xlim(0, L)
    ax.set_ylim(-1.6, 1.6)
    ax.set_xlabel("x")
    ax.set_ylabel("u(x,t)")
    ax.set_title(title)
    ax.axhline(0, linewidth=0.8)
    line, = ax.plot([], [])
    lines.append(line)

fig.suptitle("Standing waves on a fixed–fixed string")

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

def update(idx):
    t = ts[idx]
    lines[0].set_data(x, u_mode(1, x, t))
    lines[1].set_data(x, u_mode(3, x, t))
    lines[2].set_data(x, u_sum([1, 2], x, t))
    lines[3].set_data(x, u_sum([1, 2, 3], x, t))
    return lines

ani = FuncAnimation(fig, update, frames=frames, init_func=init, blit=True, interval=1000*(tmax/frames))

plt.close(fig)  # Prevents static display of the last frame
HTML(ani.to_jshtml())
Loading...

2D Membrane Vibrations

u(x,y,t)=X(x)Y(y)T(t)u(x, y, t) = X(x) Y(y) T(t)
u(x,y,t)=nmAnmcos(ωnmt+ϕnm)sin(nπxa)sin(mπyb)u(x, y, t) = \sum_n \sum_m A_{nm} \cos(\omega_{nm}t + \phi_{nm}) \sin\left(\frac{n\pi x}{a}\right) \sin\left(\frac{m\pi y}{b}\right)
ωnm=vπ(n2a2+m2b2)1/2\omega_{nm} = v\pi \left(\frac{n^2}{a^2} + \frac{m^2}{b^2}\right)^{1/2}

Where:

membrane vibrations

Figure 4:Vibrations of a 2D membrane.

Source
import numpy as np  
import matplotlib.pyplot as plt
import ipywidgets
from ipywidgets import interact, interactive, Dropdown
from matplotlib.animation import FuncAnimation
from IPython.display import HTML

import plotly.graph_objects as go
from plotly.subplots import make_subplots

def membrane2d_mode(n=1, m=1, t=0):
    """
    Calculates the 2D grid of points (X, Y) and the normal mode displacement (Z) of a vibrating 
    rectangular membrane at a specific time t.

    Parameters:
    n (int): Mode number along the x-direction. Default is 1.
    m (int): Mode number along the y-direction. Default is 1.
    t (float): Time at which to evaluate the normal mode. Default is 0.

    Returns:
    X, Y, Z (numpy arrays): Grid of points in the X-Y plane and the corresponding 
                            membrane displacement Z(X, Y, t).
    """
    
    # Constants
    Lx, Ly = 1.0, 1.0  # Dimensions of the rectangular region
    v = 0.1            # Wave speed 
    omega = v * np.pi / Lx * (n**2 + m**2)  # Angular frequency for the normal mode
    
    # Create a spatial grid
    Nx, Ny = 100, 100  # Number of grid points in each dimension
    x, y = np.linspace(0, Lx, Nx), np.linspace(0, Ly, Ny)
    X, Y = np.meshgrid(x, y)

    # Compute the spatial part of the normal mode
    Z = np.sin(m * np.pi * X / Lx) * np.sin(n * np.pi * Y / Ly) * np.cos(omega * t)
    
    return X, Y, Z

def viz_membrane2d_plotly(n=1, m=1, t=0): 
    """
    Visualizes the 2D normal modes of a vibrating membrane on a square geometry using Plotly.
    
    This function displays both a 2D contour plot and a 3D surface plot of the membrane displacement.

    Parameters:
    n (int): Mode number along the x-direction. Default is 1.
    m (int): Mode number along the y-direction. Default is 1.
    t (float): Time at which to evaluate the normal mode. Default is 0.
    """
    
    # Get the membrane displacement at time t
    X, Y, Z = membrane2d_mode(n, m, t)
    
    # Create a Plotly subplot with 2 views: 2D contour and 3D surface
    fig = make_subplots(
        rows=1, 
        cols=2, 
        subplot_titles=('2D Contour Plot', '3D Surface Plot'),
        specs=[[{"type": "contour"}, {"type": "surface"}]]
    )
    
    # Add 2D contour plot to the left side
    fig.add_trace(
        go.Contour(x=X.flatten(), y=Y.flatten(), z=Z.flatten(), colorscale='RdBu'),
        row=1, col=1
    )

    # Add 3D surface plot to the right side
    fig.add_trace(
        go.Surface(x=X, y=Y, z=Z, colorscale='RdBu'),
        row=1, col=2
    )

    # Update the layout for better visualization
    fig.update_layout(
        title_text="2D Contour and 3D Surface Plots of Membrane Vibrational Normal Modes",
        width=1000,
        height=500
    )
    
    # Show the figure
    fig.show()

interact(viz_membrane2d_plotly, n=(1,1), m=(2,3), t=(0,100))
Loading...
Loading...
<function __main__.viz_membrane2d_plotly(n=1, m=1, t=0)>

The sound of music.

The size of a musical instrument reflects the range of frequencies it is designed to produce: smaller instruments produce higher frequencies, larger instruments lower frequencies.

Figure 5:The size of a musical instrument reflects the range of frequencies it is designed to produce: smaller instruments produce higher frequencies, larger instruments lower frequencies.

Example Problems

Problem 1: Simple Harmonic Oscillator

Solve the ODE:

d2ydt2+ω2y=0\frac{d^2 y}{dt^2} + \omega^2 y = 0

where ω\omega is a constant.

Problem 2: Damped Oscillator

Solve the ODE:

d2ydt2+2βdydt+ω2y=0\frac{d^2 y}{dt^2} + 2 \beta \frac{dy}{dt} + \omega^2 y = 0

where β\beta and ω\omega are constants. Consider cases of β2<ω2\beta^2 < \omega^2, β2>ω2\beta^2 > \omega^2 and β2=ω2\beta^2 = \omega^2

Problem 3: ODE with Constant Coefficients

Solve the ODE:

d2ydt24y=0\frac{d^2 y}{dt^2} - 4 y = 0

Problem 4: Simple 2nd order ODE

Solve the ODE:

d2ydt2+9y=0\frac{d^2 y}{dt^2} + 9 y = 0

Problem 5: When ODE gives repeated roots

Solve the ODE:

d2ydt26dydt+9y=0\frac{d^2 y}{dt^2} - 6 \frac{dy}{dt} + 9 y = 0