相速度与群速度的可视化

相速度与群速度 — Phase Velocity vs Group Velocity

在波动物理中,相速度(phase velocity)和群速度(group velocity)是两个截然不同但常被混淆的概念。本文通过一个 Python 动画来直观展示它们的区别。


定义

相速度 $v_p$

相速度是单一频率平面波的等相位面传播速度:

$$v_p = \frac{\omega}{k}$$

其中 $\omega$ 是角频率,$k$ 是波数。

群速度 $v_g$

群速度是波包(波群)包络的传播速度,也是能量和信息传递的速度:

$$v_g = \frac{d\omega}{dk}$$


色散关系:深水波

以深水重力波为例,其色散关系为:

$$\omega^2 = g k$$

由此可以推导出:

$$v_p = \frac{\omega}{k} = \sqrt{\frac{g}{k}}$$

$$v_g = \frac{d\omega}{dk} = \frac{1}{2}\sqrt{\frac{g}{k}} = \frac{v_p}{2}$$

这意味着在深水中,相速度是群速度的两倍——波峰在波包内部向前移动,穿过包络后消失,而新的波峰在包络后方不断生成。


动画演示

下面的动画展示了两个频率接近的正弦波叠加后形成的波包:

  • 🟢 绿色圆点:追踪单个波峰,以相速度 $v_p$ 运动
  • 🟠 橙色方块:追踪包络峰值,以群速度 $v_g$ 运动
  • 🔴 红色虚线:波包的包络线

相速度与群速度动画

可以清楚地看到:绿色标记(相速度)移动得比橙色标记(群速度)更快——波峰在包络内”穿行”。


物理直觉

想象你站在海边观察一组涌浪:

  • 波群(整组波浪的”团”)以群速度缓慢移动
  • 单个波峰在波群内部以更快的相速度移动,从后方涌现、穿过波群、在前方消散

这就是为什么你会看到波峰似乎在波群中”穿行”——因为 $v_p = 2 v_g$。


运行代码

动画由以下 Python 脚本生成(需要 numpy, matplotlib, pillow):

1
2
pip install numpy matplotlib pillow
python group_phase_velocity.py

脚本会在同目录下生成 group_phase_velocity.gif

点击展开完整 Python 代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation, PillowWriter
from pathlib import Path

# 物理参数(深水色散:ω² = g·k)
g = 9.81
k0 = 4.0
dk = 0.3
k1, k2 = k0 - dk, k0 + dk
omega1 = np.sqrt(g * k1)
omega2 = np.sqrt(g * k2)

v_phase = (omega1 + omega2) / (k1 + k2)
v_group = (omega2 - omega1) / (k2 - k1)

x = np.linspace(0, 12, 2000)
fps = 30
n_frames = int(6.0 * fps)

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6), sharex=True,
gridspec_kw={"height_ratios": [2, 1]})
fig.suptitle("Phase Velocity vs Group Velocity", fontsize=16, fontweight="bold")

line_wave, = ax1.plot([], [], lw=1.2, label="Superposed wave")
line_env_pos, = ax1.plot([], [], lw=1.5, ls="--", color="red", label="Envelope")
line_env_neg, = ax1.plot([], [], lw=1.5, ls="--", color="red")
marker_phase, = ax1.plot([], [], "o", color="green", ms=10,
label=f"Phase vel = {v_phase:.2f} m/s")
marker_group, = ax1.plot([], [], "s", color="orange", ms=10,
label=f"Group vel = {v_group:.2f} m/s")
ax1.set_ylim(-2.3, 2.3); ax1.legend(fontsize=8)

line_w1, = ax2.plot([], [], lw=0.9, alpha=0.8, label=f"Wave 1 (k={k1:.2f})")
line_w2, = ax2.plot([], [], lw=0.9, alpha=0.8, label=f"Wave 2 (k={k2:.2f})")
ax2.set_ylim(-1.4, 1.4); ax2.legend(fontsize=8)
ax2.set_xlabel("x (m)")

phase_x0 = 1.0

def animate(frame):
t = frame / fps
y1 = np.cos(k1*x - omega1*t)
y2 = np.cos(k2*x - omega2*t)
y = y1 + y2
env = 2*np.cos(dk*x - 0.5*(omega2-omega1)*t)
line_wave.set_data(x, y)
line_env_pos.set_data(x, env)
line_env_neg.set_data(x, -env)
line_w1.set_data(x, y1); line_w2.set_data(x, y2)
xp = (phase_x0 + v_phase*t) % x[-1]
marker_phase.set_data([xp], [np.interp(xp, x, y)])
xg = (phase_x0 + v_group*t) % x[-1]
marker_group.set_data([xg], [np.interp(xg, x, env)])

anim = FuncAnimation(fig, animate, frames=n_frames, interval=1000/fps, blit=False)
anim.save("group_phase_velocity.gif", writer=PillowWriter(fps=fps))

拓展阅读

  • 无色散介质(如真空中的光波)中,$v_p = v_g$——相速度和群速度相等
  • 反常色散区域,可能出现 $v_g > v_p$ 甚至 $v_g > c$ 的情况,但这并不违反相对论,因为信号速度(front velocity)不超过 $c$
  • 量子力学中,自由粒子的德布罗意波也有 $v_p = 2 v_g$ 的关系