渦度と循環

渦度(vorticity)と循環(circulation)は、流体の回転運動を記述する基本量です。渦度は速度場の回転(curl)として局所的な回転を表し、循環はその積分量として流れの大域的な回転特性を表します。

これらの概念は、翼の揚力理論(クッタ-ジュコーフスキーの定理)、乱流の理解、気象学における渦の挙動など、多くの分野で不可欠です。本記事では、渦度と循環の定義から主要な定理までを数式で丁寧に導出し、Pythonで可視化します。

本記事の内容

  • 渦度の定義と物理的意味
  • 循環の定義
  • ストークスの定理との関係
  • ケルビンの循環定理
  • 渦糸と渦管
  • Pythonでの可視化

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

渦度の定義

数学的定義

渦度(vorticity) $\bm{\omega}$ は、速度場 $\bm{v}$ の回転(curl)として定義されます。

$$ \boxed{\bm{\omega} = \nabla \times \bm{v}} $$

直交座標系 $(x, y, z)$ で速度を $\bm{v} = (u, v, w)$ とすると、各成分は次のようになります。

$$ \bm{\omega} = \begin{pmatrix} \omega_x \\ \omega_y \\ \omega_z \end{pmatrix} = \begin{pmatrix} \frac{\partial w}{\partial y} – \frac{\partial v}{\partial z} \\ \frac{\partial u}{\partial z} – \frac{\partial w}{\partial x} \\ \frac{\partial v}{\partial x} – \frac{\partial u}{\partial y} \end{pmatrix} $$

2次元流れ $\bm{v} = (u, v, 0)$ では、渦度は $z$ 成分のみを持ちます。

$$ \omega_z = \frac{\partial v}{\partial x} – \frac{\partial u}{\partial y} $$

物理的意味

渦度は流体要素の 局所的な回転角速度の2倍 に等しいです。

イメージとしては、微小な流体要素の中に十字形の微小な棒を置いたとき、その棒の平均的な回転角速度 $\Omega$ が渦度と $\bm{\omega} = 2\bm{\Omega}$ の関係にあります。

導出

2次元の速度場で、$x$ 軸方向と $y$ 軸方向に置いた微小な線分の回転を考えます。

$x$ 方向に長さ $\delta x$ の線分の $y$ 方向の速度差は $\frac{\partial v}{\partial x} \delta x$ であるため、反時計回りの回転角速度は $\frac{\partial v}{\partial x}$ です。

$y$ 方向に長さ $\delta y$ の線分の $x$ 方向の速度差は $\frac{\partial u}{\partial y} \delta y$ であるため、時計回りの回転角速度は $\frac{\partial u}{\partial y}$ です。

平均回転角速度は、

$$ \Omega = \frac{1}{2}\left(\frac{\partial v}{\partial x} – \frac{\partial u}{\partial y}\right) $$

したがって、

$$ \omega_z = 2\Omega = \frac{\partial v}{\partial x} – \frac{\partial u}{\partial y} $$

非回転流(ポテンシャル流)

渦度がゼロである流れ $\bm{\omega} = \nabla \times \bm{v} = \bm{0}$ を 非回転流(irrotational flow) と呼びます。非回転流では速度ポテンシャルが存在し、ポテンシャル流れとして扱えます。


循環の定義

数学的定義

循環(circulation) $\Gamma$ は、閉曲線 $C$ に沿った速度の線積分として定義されます。

$$ \boxed{\Gamma = \oint_C \bm{v} \cdot d\bm{l}} $$

ここで $d\bm{l}$ は閉曲線 $C$ に沿った微小線素ベクトルです。循環の正の向きは反時計回りと約束します。

物理的意味

循環は、閉曲線で囲まれた領域内の流れの「正味の回転の強さ」を表します。$\Gamma > 0$ なら反時計回りの回転が卓越し、$\Gamma = 0$ なら正味の回転がないことを意味します。


ストークスの定理との関係

ストークスの定理

ベクトル解析のストークスの定理を循環に適用します。

$$ \Gamma = \oint_C \bm{v} \cdot d\bm{l} = \int_S (\nabla \times \bm{v}) \cdot \bm{n} \, dS = \int_S \bm{\omega} \cdot \bm{n} \, dS $$

ここで $S$ は閉曲線 $C$ を縁とする任意の曲面、$\bm{n}$ はその外向き法線です。

この関係式は、循環は閉曲線で囲まれた面を通過する渦度の総和(渦度フラックス)に等しい ことを示しています。

$$ \boxed{\Gamma = \int_S \bm{\omega} \cdot \bm{n} \, dS} $$

非回転流($\bm{\omega} = \bm{0}$)では、任意の閉曲線に対して $\Gamma = 0$ です(ただし、閉曲線の内部に特異点がない場合)。


ケルビンの循環定理

定理の内容

ケルビンの循環定理(Kelvin’s circulation theorem)は、以下の条件下で成り立ちます。

  • 非粘性流体
  • 外力が保存力のみ(重力など)
  • 圧力が密度のみの関数($p = p(\rho)$、バロトロピック流体)

このとき、流体粒子と一緒に動く閉曲線 $C(t)$ に沿った循環は時間によらず一定です。

$$ \boxed{\frac{D\Gamma}{Dt} = 0} $$

導出の概要

オイラーの方程式(非粘性流体の運動方程式)から出発します。

$$ \frac{D\bm{v}}{Dt} = -\frac{1}{\rho}\nabla p + \bm{g} $$

循環の物質微分を計算します。

$$ \frac{D\Gamma}{Dt} = \frac{D}{Dt}\oint_{C(t)} \bm{v} \cdot d\bm{l} $$

ライプニッツ則を使って展開すると、

$$ \frac{D\Gamma}{Dt} = \oint_{C(t)} \frac{D\bm{v}}{Dt} \cdot d\bm{l} + \oint_{C(t)} \bm{v} \cdot \frac{D(d\bm{l})}{Dt} $$

第2項について、$\frac{D(d\bm{l})}{Dt} = d\bm{v}$ であるため、

$$ \oint_{C(t)} \bm{v} \cdot d\bm{v} = \oint_{C(t)} d\left(\frac{v^2}{2}\right) = 0 $$

(閉曲線の一周積分はゼロ)

第1項にオイラー方程式を代入すると、

$$ \oint_{C(t)} \left(-\frac{1}{\rho}\nabla p + \bm{g}\right) \cdot d\bm{l} $$

重力は保存力なので $\oint \bm{g} \cdot d\bm{l} = 0$。バロトロピック条件 $p = p(\rho)$ のとき $\frac{1}{\rho}\nabla p = \nabla\int \frac{dp}{\rho}$ と書けるため、この項もゼロになります。

$$ \therefore \frac{D\Gamma}{Dt} = 0 $$

物理的意味

ケルビンの循環定理は、「非粘性バロトロピック流体中では、渦は新たに生成されない」ことを意味します。これは渦度の保存に関する基本的な定理です。


渦糸と渦管

渦線

渦度ベクトル $\bm{\omega}$ に接する曲線を 渦線(vortex line) と呼びます。流線が速度ベクトルに接するのと同じ関係です。

$$ \frac{dx}{\omega_x} = \frac{dy}{\omega_y} = \frac{dz}{\omega_z} $$

渦管

閉曲線上の各点を通る渦線の集合で構成される管状の面を 渦管(vortex tube) と呼びます。

渦管の重要な性質として、渦管の強さ(渦管を横切る断面の循環)は断面によらず一定です。これは $\nabla \cdot \bm{\omega} = \nabla \cdot (\nabla \times \bm{v}) = 0$ から導かれます。

渦糸

渦管の断面積が無限に小さい極限を 渦糸(vortex filament) と呼びます。渦糸は流体力学の理論で重要な概念であり、揚力理論における束縛渦や自由渦のモデルとして使われます。


Pythonでの可視化

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 3, figsize=(18, 5))

# --- (1) 渦度の可視化(剛体回転 + せん断流) ---
x = np.linspace(-3, 3, 50)
y = np.linspace(-3, 3, 50)
X, Y = np.meshgrid(x, y)

# 剛体回転: u = -Ω*y, v = Ω*x
Omega = 1.0
u_rigid = -Omega * Y
v_rigid = Omega * X

# 渦度 = 2Ω
omega_rigid = np.full_like(X, 2 * Omega)

speed = np.sqrt(u_rigid**2 + v_rigid**2)
im1 = axes[0].pcolormesh(X, Y, omega_rigid, cmap='RdBu_r', shading='auto',
                          vmin=-3, vmax=3)
axes[0].quiver(X[::3, ::3], Y[::3, ::3],
               u_rigid[::3, ::3], v_rigid[::3, ::3],
               color='k', alpha=0.6, scale=30)
plt.colorbar(im1, ax=axes[0], label='$\\omega_z$')
axes[0].set_xlabel('$x$', fontsize=12)
axes[0].set_ylabel('$y$', fontsize=12)
axes[0].set_title('Rigid body rotation ($\\omega_z = 2\\Omega$)', fontsize=13)
axes[0].set_aspect('equal')

# --- (2) 渦なしの渦(自由渦) ---
r2 = X**2 + Y**2 + 0.01
r = np.sqrt(r2)
Gamma_val = 2 * np.pi  # 循環

u_free = -Gamma_val * Y / (2 * np.pi * r2)
v_free = Gamma_val * X / (2 * np.pi * r2)

# 渦度(原点以外ではゼロ)
dx_grid = x[1] - x[0]
dy_grid = y[1] - y[0]
dv_dx = np.gradient(v_free, dx_grid, axis=1)
du_dy = np.gradient(u_free, dy_grid, axis=0)
omega_free = dv_dx - du_dy

im2 = axes[1].pcolormesh(X, Y, omega_free, cmap='RdBu_r', shading='auto',
                          vmin=-5, vmax=5)
axes[1].streamplot(X, Y, u_free, v_free, density=1.5, color='k',
                   linewidth=0.5, arrowsize=0.8)
plt.colorbar(im2, ax=axes[1], label='$\\omega_z$ (numerical)')
axes[1].set_xlabel('$x$', fontsize=12)
axes[1].set_ylabel('$y$', fontsize=12)
axes[1].set_title('Free vortex ($\\omega_z = 0$ except origin)', fontsize=13)
axes[1].set_aspect('equal')

# --- (3) ランキン渦(剛体回転 + 自由渦の組合せ) ---
r_range = np.linspace(0.01, 5, 500)
R_core = 1.0  # 渦核の半径
Gamma_r = 2 * np.pi

# ランキン渦の接線速度
v_theta = np.where(r_range <= R_core,
                   Gamma_r * r_range / (2 * np.pi * R_core**2),
                   Gamma_r / (2 * np.pi * r_range))

# 渦度
omega_rankine = np.where(r_range <= R_core,
                         Gamma_r / (np.pi * R_core**2),
                         0.0)

ax3a = axes[2]
ax3b = ax3a.twinx()

ax3a.plot(r_range, v_theta, 'b-', lw=2, label='$v_\\theta(r)$')
ax3b.plot(r_range, omega_rankine, 'r--', lw=2, label='$\\omega_z(r)$')

ax3a.axvline(x=R_core, color='gray', ls=':', alpha=0.5)
ax3a.text(R_core + 0.1, max(v_theta) * 0.9, '$r = R$', fontsize=10, color='gray')

ax3a.set_xlabel('Radius $r$', fontsize=12)
ax3a.set_ylabel('Tangential velocity $v_\\theta$', fontsize=12, color='b')
ax3b.set_ylabel('Vorticity $\\omega_z$', fontsize=12, color='r')
ax3a.set_title('Rankine Vortex', fontsize=13)

lines1, labels1 = ax3a.get_legend_handles_labels()
lines2, labels2 = ax3b.get_legend_handles_labels()
ax3a.legend(lines1 + lines2, labels1 + labels2, fontsize=10)
ax3a.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

左のグラフでは、剛体回転の速度場と渦度を示しています。剛体回転では渦度は空間的に一様で $\omega_z = 2\Omega$ です。

中央のグラフでは、自由渦(ポテンシャル渦)の流線と渦度を示しています。原点以外では渦度はゼロです。流線は同心円ですが、流体要素自体は回転していません(自転しない)。

右のグラフでは、ランキン渦(Rankine vortex)の接線速度と渦度の半径方向分布を示しています。渦核内($r \leq R$)は剛体回転、渦核外($r > R$)は自由渦になり、渦度は渦核内にのみ存在します。


まとめ

本記事では、渦度と循環について解説しました。

  • 渦度: $\bm{\omega} = \nabla \times \bm{v}$ — 流体の局所的な回転を表す。回転角速度の2倍
  • 循環: $\Gamma = \oint_C \bm{v} \cdot d\bm{l}$ — 閉曲線に沿った速度の線積分
  • ストークスの定理: $\Gamma = \int_S \bm{\omega} \cdot \bm{n} \, dS$ — 循環は渦度フラックスに等しい
  • ケルビンの循環定理: 非粘性バロトロピック流体で $D\Gamma/Dt = 0$
  • 渦管の性質: 渦管の強さは断面によらず一定

次のステップとして、以下の記事も参考にしてください。