[Python] 位相速度と群速度の可視化

## はじめに

大学（高校）で物理を学んでいると、波の位相速度や群速度といった言葉が頻繁に出てきます。これが非常にわかりづらく、僕も理解に苦しんだ過去があります。今回は、Python の簡単なプログラムで波の時間発展をシミュレーション可視化して、位相速度・群速度・波束といった概念をざっくり理解することを目指します。

## 復習
#### 分散関係
波の振動数（周波数）$\omega$ と波数 $k$ の関係を「分散関係（dispersion relation）」と呼びます。
以下簡単のため、１次元波動で考えます。分散関係は $\omega=\omega(k)$ と表されます。

#### 位相速度 (phase speed)
波の位相が伝わる速さのことを位相速度（phase speed）と言います。要は、波の山や谷が動くスピードのことです。位相速度 $c_{p}$ は
```math
c_{p} = \frac{\omega}{k}
```
で与えられます。
#### 群速度 (group velocity)
波の全体的な塊（これを波束という）が移動する速度を群速度 (group velocity) と言います。よく教科書などでは、波のエネルギーが伝わる速度と説明されています。群速度 $v_{g}$ は
```math
%\vec{v}_{g} = \frac{\partial \omega}{\partial \vec{k}}
v_{g} = \frac{\partial \omega}{\partial k}
```
で与えられます。

もし周波数 $\omega$ が波数 $k$ によらず一定であれば、その波は「分散がない（non-dispersive）」と言います。 
分散のない波では、分散関係式は $\omega=ck$ ($c$ は定数)で与えられ、位相速度と群速度は一致することがわかります。この時、波束を構成する角波長成分は全て等しい位相速度で伝播するため、波束が形を崩さず位相速度（$=$ 群速度）で移動します。


## 分散性波動 : 位相速度と群速度が逆向きのケース
分散がある波の例として、位相速度と群速度がそれぞれ逆向きに進むという極端な例を考えてみます。
例えば、下図のように $\omega \propto k^{-1}$ となる分散関係を持つ波がこれに相当します。この時、位相速度は $c_{p}=\omega/k>0$ となることから $x$ 正方向に伝播するのに対して、群速度は $v_{g}=\partial\omega/\partial k <0$ となり $x$ 負方向へと伝播します。
<img width="550" alt="dispersion.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738192/e5a7b17d-a89e-25c5-5197-5ca11e4e7219.png">
[](また、この時波数が小さいほど（つまりより大スケールの波ほど）波の伝搬速度が速いこともわかります。)

## 波束の時間発展シミュレーション

では、実際に上のような分散関係式を満たす波の時間発展をシミュレーションして、結果をプロットしてみましょう。実際にデータに触れてみてこそ深まる理解というのもあると思います。以下の python スクリプトを用います。
```time_evolution_wave_packet.py
import numpy as np
import matplotlib.pyplot as plt

#x-axis (periodic from -pi to pi)
Nx = 400
x = np.linspace(-np.pi,np.pi,Nx)
#time
Nt = 400
time = np.linspace(0,1500,Nt)
#wavenumber range
Nk = 30

#construct the time-series data
data = np.zeros([Nx,Nt])
for t in range(Nt):
    #wave component at each wavenumber k
    data_k = np.zeros([Nx,Nk])
    for k in range(Nk):
        #initial wave packet
        amp_ic = np.exp(-((k-15.0)/3.0)**2) 
        #dispersion relation
        om = 1.0/(k+0.25) 
        data_k[:,k] = amp_ic*np.exp(1j*(k*x[:]-om*time[t])).real
    #superposition of all wavenumbers
    data[:,t] = np.sum(data_k,axis=1)

    #plot each temporal frame
    fig = plt.figure(figsize=(6,8))
    
    ax = plt.subplot2grid((3,1),(0,0),rowspan=2,colspan=1)
    ax.pcolormesh(x,time,np.transpose(data),cmap='RdBu_r',vmin=-4,vmax=4)
    ax.plot([-np.pi,np.pi],[time[t],time[t]],'--k',linewidth=2)
    ax.set_ylabel(r"Time")
    ax.set_xlim(-np.pi,np.pi)
    ax.set_ylim(0,1500)
    ax.set_title('Time = '+str('{:<4.0f}'.format(time[t])),size=14)

    ax = plt.subplot2grid((3,1),(2,0),rowspan=1,colspan=1)
    ax.plot(x,data[:,t],'-k',linewidth=2)
    ax.set_xlabel(r"$x$")
    ax.set_ylabel(r"Amplitude")
    ax.set_xlim(-np.pi,np.pi)
    ax.set_ylim(-5.5,5.5)

    plt.subplots_adjust(top=0.95,bottom=0.08,left=0.15,right=0.95)
    #save each frame in png
    plt.savefig('fig/'+('{:03}'.format(t//4))+'.png',dpi=200)
    fig.clear()
    plt.close(fig)
```
ここで、まず初期条件（$t=0$ における波形）として、波数 $k\approx 15$ のモードにのみ振幅 $A(k)$ をガウス分布で与えることで、局在化した波束を作りました。分散関係は、発散を避けるために $\omega=1/(k+0.25)$ としています。時間 $t$ における波の振幅は
```math
\sum_{k} A(k)\sin{[ kx-\omega(k)t ]}
```
で単純に与えています。従って、シミュレーションとは言っても波の時間発展を記述する方程式を数値的に解いた訳ではなく、あくまで解析解を構築しているプログラムに過ぎないことに注意。

なにはともあれ、上のスクリプトの出力ファイルを動画にしたものが下になります。意外と面白いことが色々と見て取れると思います。
<img width="450" alt="time_v3.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738192/efe76d18-7e5a-1ae1-9979-8e7d6b470e75.gif">


### 位相速度と群速度
まず、位相速度は上のアニメーションに示した $x-t$図において、それぞれ赤・青で表される波の山と谷が右側に伝播する速度（$x-t$図中の等高線の傾き）に対応しています（下図細矢印）。
一方、群速度は $x-t$図において波の振幅が全体的に大きいエリアが全体として左側に進行する速度に対応します（下図太矢印）。
<img width="450" alt="phasegroup.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738192/c046615d-555e-7c15-4247-ab68288a86a5.png">
既に議論した通り、位相速度と群速度が違いに逆方向に伝播していることが確かめられます。

### 波の分散 / 波束の広がり
さらに上のアニメーションをよりよく観察すると、当初（$t=0$で）コンパクトに局在化して存在していた波束が、時間の経過と共におおきく広がり波が全体的に散り散りになっていく様子が確認されます。言い換えれば、波がまさに「分散」していっています。実際に、初期状態（$t=0$）と時間経過後（$t=1500$）における波形をプロットしたものが下図になります。
<img width="700" alt="wave_packet.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738192/9a0d368f-1e2f-80f3-8122-de06c676b917.png">
そもそも、波束というのは異なる波長の波が重ね合わさって出来ているものです。分散性の波であれば、異なる波長の波は異なる位相速度で伝播していくため、波束は元の形を維持できず時間の経過とともに崩れていってしまうのです。
ただし、これは波の構成要素である角波長成分自体が変化したわけではないので、波形のフーリエスペクトルは時間に依らず一定であることに注意。

## まとめ

波の分散関係・位相速度・群速度といった言葉はどの物理の教科書にも出てきますが、初学者にはなかなか実感を伴った理解が難しいのでないかと思います。そんな時は、Python などで簡単なプログラムを書いて実際に様々なパラメータに対して可視化して遊んでみると、徐々に理解が深まるのではないかと思います。この記事が少しでも理解の助けとなれば嬉しいです。