ポテンシャル流れは、非粘性かつ非回転の理想流体の流れを扱う理論です。一見制約が強い仮定に見えますが、高レイノルズ数の流れにおいて物体から離れた領域の流れをよく近似し、翼理論や船舶工学の基礎として実用的に重要です。
本記事では、速度ポテンシャルと流れ関数の定義から基本的な流れの解を導出し、重ね合わせの原理を用いて円柱まわりの流れを構成し、Pythonで可視化します。
本記事の内容
- 速度ポテンシャルの定義
- 流れ関数の定義
- ラプラス方程式
- 基本解(一様流・湧き出し・渦・二重湧き出し)
- 重ね合わせの原理
- 円柱まわりの流れ
- Pythonでの可視化
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
速度ポテンシャル
非回転流の条件
流れが 非回転(irrotational) であるとは、渦度がゼロであることを意味します。
$$ \bm{\omega} = \nabla \times \bm{v} = \bm{0} $$
ベクトル解析の定理により、回転がゼロのベクトル場はスカラー関数の勾配として表せます。
定義
非回転流では、速度ポテンシャル(velocity potential) $\phi$ が存在し、
$$ \boxed{\bm{v} = \nabla \phi} $$
成分表示では、
$$ u = \frac{\partial \phi}{\partial x}, \quad v = \frac{\partial \phi}{\partial y}, \quad w = \frac{\partial \phi}{\partial z} $$
速度ポテンシャルは、流体の運動を一つのスカラー関数で記述できるという大きな利点を持ちます。
流れ関数
2次元非圧縮性流れの場合
2次元の非圧縮性流れでは、連続の方程式 $\nabla \cdot \bm{v} = 0$ が自動的に満たされるようなスカラー関数 流れ関数(stream function) $\psi$ を定義できます。
$$ \boxed{u = \frac{\partial \psi}{\partial y}, \quad v = -\frac{\partial \psi}{\partial x}} $$
この定義を連続の方程式に代入すると、
$$ \frac{\partial u}{\partial x} + \frac{\partial v}{\partial y} = \frac{\partial^2 \psi}{\partial x \partial y} – \frac{\partial^2 \psi}{\partial x \partial y} = 0 $$
自動的に満たされます。
流れ関数の性質
- 流線: $\psi = \text{const.}$ の曲線は流線を表す
- 体積流量: 2つの流線 $\psi_1$ と $\psi_2$ の間の単位奥行きあたりの体積流量は $Q = \psi_2 – \psi_1$
$\phi$ と $\psi$ の直交性
非回転かつ非圧縮の2次元流れでは、$\phi$ と $\psi$ の等値線は互いに直交します。
$\phi$ と $\psi$ の関係は、
$$ u = \frac{\partial \phi}{\partial x} = \frac{\partial \psi}{\partial y}, \quad v = \frac{\partial \phi}{\partial y} = -\frac{\partial \psi}{\partial x} $$
これは コーシー-リーマンの関係式 に他なりません。複素関数 $W(z) = \phi + i\psi$($z = x + iy$)を 複素ポテンシャル と呼び、$W(z)$ は複素変数 $z$ の正則関数です。
ラプラス方程式
導出
非圧縮性条件 $\nabla \cdot \bm{v} = 0$ に $\bm{v} = \nabla \phi$ を代入すると、
$$ \nabla \cdot (\nabla \phi) = \nabla^2 \phi = 0 $$
$$ \boxed{\nabla^2 \phi = \frac{\partial^2 \phi}{\partial x^2} + \frac{\partial^2 \phi}{\partial y^2} = 0} $$
同様に、非回転条件 $\nabla \times \bm{v} = \bm{0}$ から流れ関数に対しても、
$$ \boxed{\nabla^2 \psi = 0} $$
すなわち、$\phi$ と $\psi$ はともに ラプラス方程式 を満たす 調和関数 です。
ラプラス方程式は線形であるため、重ね合わせの原理 が成り立ちます。複数の基本解を足し合わせることで、複雑な流れを構成できます。
基本解
以下では、2次元のポテンシャル流れの基本的な解を示します。
1. 一様流
速度 $U$ で $x$ 方向に流れる一様流は、
$$ \phi = Ux, \quad \psi = Uy $$
$$ u = U, \quad v = 0 $$
2. 湧き出し(Source)と吸い込み(Sink)
原点に強さ $m$ の 湧き出し(source) を置きます。$m > 0$ が湧き出し、$m < 0$ が吸い込み(sink)です。
極座標 $(r, \theta)$ を用いると、
$$ \phi = \frac{m}{2\pi} \ln r, \quad \psi = \frac{m}{2\pi} \theta $$
速度は放射方向のみで、
$$ v_r = \frac{m}{2\pi r}, \quad v_\theta = 0 $$
体積流量は原点を囲む任意の閉曲線について $Q = m$ です。
3. 渦(Vortex)
原点に強さ $\Gamma$ の 点渦(point vortex) を置きます。
$$ \phi = \frac{\Gamma}{2\pi} \theta, \quad \psi = -\frac{\Gamma}{2\pi} \ln r $$
速度は接線方向のみで、
$$ v_r = 0, \quad v_\theta = \frac{\Gamma}{2\pi r} $$
循環は原点を囲む任意の閉曲線について $\Gamma$ です。
4. 二重湧き出し(Doublet)
湧き出しと吸い込みを接近させ、$m \to \infty$、間隔 $\delta \to 0$ で $m\delta = \mu$(二重湧き出しの強さ)を一定に保った極限が 二重湧き出し(doublet) です。
$$ \phi = -\frac{\mu}{2\pi} \frac{\cos\theta}{r} = -\frac{\mu}{2\pi} \frac{x}{x^2 + y^2} $$
$$ \psi = -\frac{\mu}{2\pi} \frac{\sin\theta}{r} = -\frac{\mu}{2\pi} \frac{y}{x^2 + y^2} $$
円柱まわりの流れ
一様流 + 二重湧き出し
一様流(速度 $U$)と原点の二重湧き出し(強さ $\mu = 2\pi U a^2$)を重ね合わせると、半径 $a$ の円柱まわりの流れが得られます。
$$ \phi = U\left(r + \frac{a^2}{r}\right)\cos\theta $$
$$ \psi = U\left(r – \frac{a^2}{r}\right)\sin\theta $$
$r = a$ で $\psi = 0$ となり、これは円柱表面(流線)を表します。
速度成分は、
$$ v_r = U\left(1 – \frac{a^2}{r^2}\right)\cos\theta, \quad v_\theta = -U\left(1 + \frac{a^2}{r^2}\right)\sin\theta $$
円柱表面($r = a$)では $v_r = 0$(壁面条件)、$v_\theta = -2U\sin\theta$ です。
ダランベールのパラドックス
ベルヌーイの定理を用いて円柱表面の圧力分布を求め、力を積分すると、抗力も揚力もゼロ になります。
$$ p(\theta) = p_\infty + \frac{1}{2}\rho U^2(1 – 4\sin^2\theta) $$
$$ F_x = \oint p \cos\theta \, dS = 0, \quad F_y = \oint p \sin\theta \, dS = 0 $$
これを ダランベールのパラドックス と呼びます。実際の流れでは粘性の影響(境界層の剥離と後流)により抗力が生じますが、ポテンシャル流れではそれを扱えません。
循環を加えた流れ
円柱に循環 $\Gamma$ を加えると(一様流 + 二重湧き出し + 渦)、
$$ \psi = U\left(r – \frac{a^2}{r}\right)\sin\theta – \frac{\Gamma}{2\pi}\ln\frac{r}{a} $$
このとき揚力が発生し、クッタ-ジュコーフスキーの定理 から、
$$ L = \rho U \Gamma $$
(単位スパンあたりの揚力)
Pythonでの可視化
import numpy as np
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 2, figsize=(14, 12))
# 共通のグリッド
x = np.linspace(-4, 4, 400)
y = np.linspace(-4, 4, 400)
X, Y = np.meshgrid(x, y)
r2 = X**2 + Y**2
r = np.sqrt(r2)
theta = np.arctan2(Y, X)
U = 1.0 # 一様流速
a = 1.0 # 円柱半径
# --- (1) 基本解: 湧き出し + 渦 ---
m_source = 5.0
Gamma_vortex = 5.0
psi_source = m_source / (2 * np.pi) * theta
psi_vortex = -Gamma_vortex / (2 * np.pi) * np.log(r + 1e-10)
# 湧き出し
axes[0, 0].contour(X, Y, psi_source, levels=30, colors='blue', linewidths=0.8)
# 渦の流線を重ねて表示
psi_v_only = -Gamma_vortex / (2 * np.pi) * np.log(r + 1e-10)
axes[0, 0].contour(X, Y, psi_v_only, levels=30, colors='red',
linewidths=0.8, linestyles='--')
axes[0, 0].set_xlabel('$x$', fontsize=12)
axes[0, 0].set_ylabel('$y$', fontsize=12)
axes[0, 0].set_title('Source (blue) + Vortex (red)', fontsize=13)
axes[0, 0].set_aspect('equal')
axes[0, 0].set_xlim(-4, 4)
axes[0, 0].set_ylim(-4, 4)
# --- (2) 一様流 + 湧き出し (半物体 / Rankine half-body) ---
psi_uniform = U * Y
psi_rankine = psi_uniform + m_source / (2 * np.pi) * theta
axes[0, 1].contour(X, Y, psi_rankine, levels=np.linspace(-5, 5, 40),
colors='blue', linewidths=0.8)
# 分岐流線 psi = m/2 を強調
axes[0, 1].contour(X, Y, psi_rankine, levels=[m_source / 2],
colors='red', linewidths=2.0)
axes[0, 1].set_xlabel('$x$', fontsize=12)
axes[0, 1].set_ylabel('$y$', fontsize=12)
axes[0, 1].set_title('Uniform + Source (Rankine half-body)', fontsize=13)
axes[0, 1].set_aspect('equal')
axes[0, 1].set_xlim(-4, 4)
axes[0, 1].set_ylim(-4, 4)
# --- (3) 円柱まわりの流れ(循環なし)---
# 円柱内部をマスク
mask = r < a
psi_cylinder = U * (r - a**2 / (r + 1e-10)) * np.sin(theta)
psi_cylinder[mask] = np.nan
axes[1, 0].contour(X, Y, psi_cylinder, levels=np.linspace(-3, 3, 30),
colors='blue', linewidths=0.8)
circle = plt.Circle((0, 0), a, color='gray', fill=True, alpha=0.5)
axes[1, 0].add_patch(circle)
axes[1, 0].set_xlabel('$x$', fontsize=12)
axes[1, 0].set_ylabel('$y$', fontsize=12)
axes[1, 0].set_title('Flow around cylinder (no circulation)', fontsize=13)
axes[1, 0].set_aspect('equal')
axes[1, 0].set_xlim(-4, 4)
axes[1, 0].set_ylim(-4, 4)
# --- (4) 円柱まわりの流れ(循環あり)---
Gamma_cyl = 4 * np.pi * U * a # 強い循環
psi_cyl_circ = (U * (r - a**2 / (r + 1e-10)) * np.sin(theta)
- Gamma_cyl / (2 * np.pi) * np.log(r / a + 1e-10))
psi_cyl_circ[mask] = np.nan
axes[1, 1].contour(X, Y, psi_cyl_circ, levels=np.linspace(-8, 8, 40),
colors='blue', linewidths=0.8)
circle2 = plt.Circle((0, 0), a, color='gray', fill=True, alpha=0.5)
axes[1, 1].add_patch(circle2)
# 揚力の方向を矢印で表示
axes[1, 1].annotate('Lift', xy=(0, 2.5), fontsize=14, color='red',
ha='center', va='bottom',
arrowprops=dict(arrowstyle='->', color='red', lw=2))
axes[1, 1].set_xlabel('$x$', fontsize=12)
axes[1, 1].set_ylabel('$y$', fontsize=12)
axes[1, 1].set_title(f'Flow around cylinder ($\\Gamma = {Gamma_cyl:.1f}$)', fontsize=13)
axes[1, 1].set_aspect('equal')
axes[1, 1].set_xlim(-4, 4)
axes[1, 1].set_ylim(-4, 4)
plt.tight_layout()
plt.show()
左上のグラフでは、湧き出し(放射状の流線)と渦(同心円の流線)という2つの基本解を重ねて示しています。
右上のグラフでは、一様流と湧き出しの重ね合わせによるランキン半物体(Rankine half-body)を示しています。赤い線は分岐流線で、この内側が「物体」として振る舞います。
左下のグラフでは、循環なしの円柱まわりの流れ(一様流 + 二重湧き出し)を示しています。上下対称であり、揚力はゼロです。
右下のグラフでは、循環を加えた円柱まわりの流れを示しています。上下の非対称性が生じ、上方の流れが加速されて圧力が下がるため、上向きの揚力が発生します。
まとめ
本記事では、ポテンシャル流れの理論を解説しました。
- 速度ポテンシャル: $\bm{v} = \nabla \phi$ — 非回転流で存在
- 流れ関数: $u = \partial\psi/\partial y$, $v = -\partial\psi/\partial x$ — $\psi = \text{const.}$ が流線
- ラプラス方程式: $\nabla^2 \phi = 0$, $\nabla^2 \psi = 0$ — 線形なので重ね合わせ可能
- 基本解: 一様流、湧き出し、渦、二重湧き出し
- 円柱まわりの流れ: 一様流 + 二重湧き出し。循環を加えると揚力 $L = \rho U \Gamma$ が発生
次のステップとして、以下の記事も参考にしてください。