跳轉到

05.4 廣義斯托克斯定理#

本節目標#

  • 認識微分幾何的「總定理」: \(\int_M d\omega = \int_{\partial M} \omega\)
  • 看懂它如何把 Green、Gauss、古典 Stokes 三個定理收進同一句話
  • 理解兩個呼應:邊界的邊界為空( \(\partial \partial M = \varnothing\) )與外微分的平方為零( \(d^2 = 0\) )
  • 掌握證明的核心策略:把流形局部化成 \(\mathbb{R}^n\) 中的小塊,一塊一塊算
  • 動手實驗:同一個向量場,用「形式語言」與「經典語言」兩套算法對照,得到相同答案

定理:一句話統一三個定理#

我們在第 4 章辛苦學了三個積分定理:Green(平面)、Gauss(通量)、Stokes(曲面環流)。當時它們長得不一樣,公式各有一套記法。但用微分形式的語言,它們全部是 同一個定理:

\[ \boxed{\ \int_M d\omega = \int_{\partial M} \omega\ } \]

其中 \(M\) 是 \(n\) 維定向流形(或帶邊界的區域), \(\omega\) 是 \((n-1)\) -form, \(\partial M\) 是 \(M\) 的邊界(帶誘導定向)。

怎麼對應?看 \(n = 2\) 與 \(n = 3\) 就夠了:

定理 流形 \(M\) 形式 \(\omega\) 具體內容
Green 平面區域 \(D\) \(P\,dx + Q\,dy\) \(\iint_D (Q_x - P_y)\,dx\,dy = \oint_{\partial D} P\,dx + Q\,dy\)
Gauss 空間區域 \(V\) 通量 2-form \(\iiint_V \operatorname{div} F\,dV = \iint_{\partial V} F \cdot n\,dS\)
Stokes 曲面 \(S\) 環流 1-form \(\iint_S (\operatorname{curl} F) \cdot n\,dS = \oint_{\partial S} F \cdot dl\)

第 5.1 節的楔積、第 5.2 節的外微分、第 5.3 節的 Hodge 星號,全都只為了在這一節說出這一句話。它們是「文法」,廣義 Stokes 是「主句」。

直覺:內部所有微小漩渦的總和 = 邊界上的環流#

以環流為例( \(n = 2\) ,Green 定理的圖像):

  1. 把區域 \(D\) 切成很多小方格。
  2. 每個小方格上,向量場繞一圈的環流 \(\approx\) 該點的旋度 \(\times\) 面積(這正是 \(d\omega\) 的定義)。
  3. 關鍵觀察:相鄰方格的共用邊,兩邊走的方向相反,環流互相抵消。
  4. 剩下沒被抵消的,只有 最外圈邊界 的貢獻。

所以:

\[ \underbrace{\sum_{\text{小方格}} \text{內部環流}}_{\int_M d\omega} = \underbrace{\text{最外圈環流}}_{\int_{\partial M} \omega} \]

類比:一間公司的內部帳目,每一筆內部轉帳都「有借必有貸」而互相抵消;最後對外的總流量,只看公司與外界的邊界往來。這正是所有「守恆量用邊界流表示」的物理定理(連續方程、能量守恆)的數學骨架。

深刻的呼應: \(\partial \partial M = \varnothing\) 與 \(d^2 = 0\)#

這是本節最漂亮的一件事。兩個「平方為零」互相輝映:

\[ d(d\omega) = 0 \qquad \text{(外微分平方為零,第 5.2 節)} \]
\[ \partial(\partial M) = \varnothing \qquad \text{(邊界的邊界是空集合)} \]

邊界的邊界為什麼是空:線段的邊界是兩個端點,端點(點)的邊界是空。方形的邊界是四條邊,每條邊的端點都被 兩個 相鄰邊共用——帶誘導定向後一正一負,互相抵消。任何維度都一樣:邊界上的每個點恰好是偶數個邊界片的公共點,定向配對後全部成對消去。

兩者為什麼互相呼應?設 \(\omega\) 是某個 \(\alpha\) 的外微分: \(\omega = d\alpha\) ,則

\[ \int_{\partial M} \omega = \int_{\partial M} d\alpha = \int_M d(d\alpha) = \int_M 0 = 0 \]

換句話說:正合形式的邊界積分恆為零。而這件事成立,幾何上的原因正是「 \(\partial M\) 沒有自己的邊界,閉合曲面沒有洞可以漏」。拓樸( \(\partial^2 = 0\) )與分析( \(d^2 = 0\) )在此合而為一,這正是 de Rham 同調論的起點(超出本書範圍,但門已經打開了)。

證明概念:局部化成 \(\mathbb{R}^n\) 的小塊#

完整證明超出本書,但策略值得一讀,因為它是微分幾何證明的標準套路:

  1. 單位分解:用座標卡蓋住 \(M\) ,配上一組「和恆為 \(1\) 」的光滑函數(partition of unity),把 \(\omega\) 拆成一小塊一小塊 \(\omega_i\) ,每一塊只在一個座標卡內不為零。
  2. **化歸到 \(\mathbb{R}^n\) **:每個 \(\omega_i\) 透過座標卡拉回 \(\mathbb{R}^n\) (或半空間 \(x^n \geq 0\) ,處理邊界附近的塊)。問題變成純計算題。
  3. Fubini + 微積分基本定理:在 \(\mathbb{R}^n\) 中, \(d\omega_i\) 的積分展開後,對某個變數逐次積分,由微積分基本定理,內部積分全部抵消,只留下邊界項。
  4. 拼回來:內部座標卡的公共面因定向相反而消去(和方格論證一樣),只剩 \(\partial M\) 上的貢獻。

一句話總結證明:廣義 Stokes = 多重積分版的微積分基本定理。 \(\int_a^b f'(x)\,dx = f(b) - f(a)\) 說的是「區間的導數積分 = 端點(邊界)的值」,廣義 Stokes 把它推廣到任意維度、任意形式。

物理意義:邊界環流 = 內部旋度總量#

以古典 Stokes( \(n = 3\) , \(\omega\) 為向量場 \(F\) 的功形式)為例:

\[ \iint_S (\operatorname{curl} F) \cdot n\,dS = \oint_{\partial S} F \cdot dl \]
  • 左邊:曲面上每一點的 漩渦強度(旋度在法向的分量)全部加總。
  • 右邊:沿曲面邊界走一圈,向量場做的 總環流。

直覺:內部的小漩渦兩兩相鄰處互相抵消(你順時針、我逆時針),只有貼著邊界的那一圈「沒有鄰居來抵消」的流動存活下來。所以「內部漩渦總量」就等於「邊界環流」。

同樣地,Gauss 定理說:內部所有「源頭強度」(散度)的總和 = 邊界總通量;Green 定理說:內部所有 \((Q_x - P_y)\) 的總和 = 邊界環流。全部都是同一個故事。

SymPy 驗證:diffgeom 中的廣義 Stokes#

sympy.diffgeom 沒有內建積分,但 外微分與形式求值 它都會。我們的策略:構造形式、計算 \(d\omega\) 、兩邊分別在「體積上積分」與「邊界上積分」(用 SymPy 的 integrate 對參數積分),確認相等。

先驗證 Green 定理的形式版( \(n = 2\) ):

相容性提醒:本節程式在 SymPy ≥ 1.7 測試通過。預定義流形請用座標卡物件 R2_r(而不是舊式 R2.coord_functions();後者在舊版可用,新版已改由座標卡提供)。若你手上的版本是較舊的 SymPy,把 R2_r. 換成 R2. 即可。

from sympy import symbols, sin, cos, simplify, pi, integrate
from sympy.diffgeom.rn import R2_r
from sympy.diffgeom import Differential

x, y = R2_r.coord_functions()
dx, dy = R2_r.base_oneforms()
ex, ey = R2_r.base_vectors()

# 取 omega = P dx + Q dy,其中 P = -y^3, Q = x^3(經典教科書例子)
P, Q = -y**3, x**3
omega = P*dx + Q*dy

# ① 形式語言:d(omega) 讀係數 => (Q_x - P_y) dx∧dy
d_omega = Differential(omega)
curl_scalar = simplify(d_omega(ex, ey))
print('dω 的係數(= Q_x - P_y):', curl_scalar)   # 3*x**2 + 3*y**2

# ② 左邊:在單位圓盤上積分(用極座標 x = r cos t, y = r sin t)
r, t = symbols('r t', nonnegative=True)
integrand = curl_scalar.subs({x: r*cos(t), y: r*sin(t)}) * r   # 乘 Jacobian r
lhs = integrate(integrate(integrand, (r, 0, 1)), (t, 0, 2*pi))
print('左邊 ∫∫_M dω =', lhs)                     # 3*pi/2

# ③ 右邊:沿邊界單位圓 pull back ω,t: 0 → 2π(逆時針)
#    邊界速度 c'(t) = -sin t · e_x + cos t · e_y,故 ω(c') 的值為
#    a·(-sin t) + b·(cos t),其中 (a, b) 是 ω 的係數(在邊界點取值)
a, b = simplify(omega.rcall(ex)), simplify(omega.rcall(ey))
rhs = integrate(a.subs({x: cos(t), y: sin(t)})*(-sin(t))
              + b.subs({x: cos(t), y: sin(t)})*( cos(t)), (t, 0, 2*pi))
print('右邊 ∫_∂M ω =', rhs)                      # 3*pi/2

print('廣義 Stokes 成立:', simplify(lhs - rhs) == 0)   # True

再驗證古典 Stokes( \(n = 3\) ,曲面取上半球面):

from sympy import symbols, sin, cos, simplify, pi, integrate, Matrix
from sympy.diffgeom.rn import R3_r
from sympy.diffgeom import Differential

x, y, z = R3_r.coord_functions()
dx, dy, dz = R3_r.base_oneforms()
ex, ey, ez = R3_r.base_vectors()

# 向量場 F = (-y, x, 1),對應 1-form omega = -y dx + x dy + dz
omega = -y*dx + x*dy + dz

# ① 形式語言:dω 的 2-form 係數 = curl F 的分量
d_omega = Differential(omega)
curl_1form = [
    simplify(d_omega(ey, ez)),     # (curl F)·e_x 分量
    simplify(d_omega(ez, ex)),     # (curl F)·e_y 分量
    simplify(d_omega(ex, ey)),     # (curl F)·e_z 分量
]
print('curl F =', curl_1form)                          # [0, 0, 2]

# ② 左邊:上半球面(半徑 1)上 (curl F)·n dS
#    參數化 X(θ,φ) = (sinθ cosφ, sinθ sinφ, cosθ)
th, ph = symbols('theta phi', real=True)
X = Matrix([sin(th)*cos(ph), sin(th)*sin(ph), cos(th)])
Xu, Xv = X.diff(th), X.diff(ph)
normal = Xu.cross(Xv)                                  # 外法向
subs_pt = {x: X[0], y: X[1], z: X[2]}
curl_at = Matrix(curl_1form).subs(subs_pt)
lhs = integrate(integrate(curl_at.dot(normal), (th, 0, pi/2)), (ph, 0, 2*pi))
print('左邊 ∫∫_S (curl F)·n dS =', lhs)               # 2*pi

# ③ 右邊:邊界是赤道圓,逆時針(從上看):c(t) = (cos t, sin t, 0)
#    pull back:ω(c'(t)) = a·(-sin t) + b·cos t + c·0,係數在邊界取值
t = symbols('t', real=True)
a, b, c3 = (simplify(omega.rcall(v)) for v in (ex, ey, ez))
subs_b = {x: cos(t), y: sin(t), z: 0}
rhs = integrate(a.subs(subs_b)*(-sin(t)) + b.subs(subs_b)*(cos(t)), (t, 0, 2*pi))
print('右邊 ∮_∂S F·dl =', rhs)                        # 2*pi

print('廣義 Stokes 成立:', simplify(lhs - rhs) == 0)

注意:跑這段程式時,若 lhs 與 rhs 不等,先檢查 定向:曲面法向(Xu.cross(Xv) 在上半球朝外、朝上)與邊界走向(逆時針)必須遵守「右手定則」。定向配錯是初學者最容易踩的坑,答案會剛好差一個負號。

動手實驗:兩種語言對照(形式版 vs 經典版)#

同一個向量場 \(F = (-y^3,\ x^3,\ 0)\) ,平面區域取單位圓盤,我們用 兩套完全不同的算法 算 Green 定理兩側,確認答案一致:

from sympy import symbols, sin, cos, pi, integrate, diff, simplify, Matrix

x, y = symbols('x y', real=True)
r, t = symbols('r t', nonnegative=True)

# 向量場
F = Matrix([-y**3, x**3, 0])

# ===== 經典語言 =====
# 左邊:∂Q/∂x - ∂P/∂y 在圓盤上
P, Q = F[0], F[1]
curl2d = diff(Q, x) - diff(P, y)                       # 3x² + 3y²
lhs_c = integrate(integrate(
    curl2d.subs({x: r*cos(t), y: r*sin(t)}) * r,       # 極座標 + Jacobian
    (r, 0, 1)), (t, 0, 2*pi))
# 右邊:邊界圓上 F·dl,dl = (-sin t, cos t) dt
dl = Matrix([-sin(t), cos(t), 0])
F_b = F.subs({x: cos(t), y: sin(t)})
rhs_c = integrate(F_b.dot(dl), (t, 0, 2*pi))
print('經典語言:', lhs_c, rhs_c)                      # 3*pi/2  3*pi/2

# ===== 形式語言 =====
# 手動實作外微分:ω = P dx + Q dy,dω = (Q_x - P_y) dx∧dy
# (同樣的規則,但把「讀係數 → 外微分 → 積分」當成一條流水線)
def exterior_derivative_1form(p, q):
    # 回傳 dω 在 dx∧dy 上的係數
    return diff(q, x) - diff(p, y)

domega_coeff = exterior_derivative_1form(P, Q)
lhs_f = integrate(integrate(
    domega_coeff.subs({x: r*cos(t), y: r*sin(t)}) * r,
    (r, 0, 1)), (t, 0, 2*pi))
# 邊界 pull back:x→cos t, y→sin t, dx→-sin t dt, dy→cos t dt
rhs_f = integrate(
    (P.subs({x: cos(t), y: sin(t)})*(-sin(t))
     + Q.subs({x: cos(t), y: sin(t)})*cos(t)),
    (t, 0, 2*pi))
print('形式語言:', lhs_f, rhs_f)                      # 3*pi/2  3*pi/2

print('兩種語言一致:', simplify(lhs_c - lhs_f) == 0 and simplify(rhs_c - rhs_f) == 0)

觀察重點: 1. 兩套語言的「左邊」與「右邊」各自一致 —— 因為它們根本是同一個定理的兩種記法。 2. 形式語言的優勢在 結構:經典版要記三個公式(Green/Gauss/Stokes 各一套),形式版只需記一句 \(\int_M d\omega = \int_{\partial M}\omega\) ,連「旋度該取哪些偏導」都由 \(d\) 的定義自動生成。 3. 換個區域(例如環形區域,邊界有內外兩圈)再跑一次:形式版公式完全不變,只要記得 \(\partial M\) 有兩個成分、各帶定向。

小結與練習#

小結

  • 廣義 Stokes 定理: \(\int_M d\omega = \int_{\partial M}\omega\) ,一句話統一 Green、Gauss、Stokes。
  • 直覺:內部小漩渦兩兩抵消,只剩邊界存活 —— 邊界環流 = 內部旋度總量。
  • 深刻呼應: \(d^2 = 0\) (分析)與 \(\partial\partial M = \varnothing\) (拓樸)是一體兩面;正合形式的邊界積分恆為零。
  • 證明策略:單位分解 → 局部化到 \(\mathbb{R}^n\) → Fubini + 微積分基本定理 → 定向抵消拼回。
  • 形式語言的價值:把三個經典公式收成一句,且座標無關、可推廣到任意流形。

練習

  1. 用本節程式碼把向量場換成 \(F = (x^2, -xy, 0)\) ,區域換成單位圓盤,分別用經典語言與形式語言算 Green 定理兩側,確認相等。
  2. 驗證「正合形式的邊界積分為零」:取 \(\alpha = x y\,dx\) ,計算 \(\omega = d\alpha\) ,沿單位圓積分 \(\oint_{\partial D} \omega\) ,確認結果為 \(0\) (並解釋為什麼直接看 \(\oint d(xy)\) 就知道答案)。
  3. (思考)莫比烏斯帶 不可定向,所以無法定義整體的「邊界誘導定向」。說明為什麼廣義 Stokes 定理需要 \(M\) 可定向 —— 提示:方格抵消論證中「一正一負」需要什麼前提?
  4. 環形區域 \(1 \leq r \leq 2\) 的邊界有內外兩圈。寫程式驗證:外圈取逆時針、內圈取順時針時 \(\oint_{\partial M}\omega = \iint_M d\omega\) 成立;若兩圈同向則不成立。
  5. (進階)查閱 de Rham 同調的定義(閉形式 / 正合形式),說明 \(d^2 = 0\) 如何保證「正合 ⊂ 閉」。