當沒有公式時,就架一張格網
到此為止,你的工具箱裝滿了精確解:達朗貝爾公式、分離變數法、熱核、格林函數。它們很美,也很稀有。把定義域換成不規則的形狀、讓某個係數隨位置變化、或加上一點點非線性,乾淨的公式就枯竭了。對大多數真實的偏微分方程而言,誠實的處境是:根本不存在解的封閉表達式——可是我們仍然需要數字。數值方法這一級,談的就是如何可靠地生出那些數字,而有限差分是最古老、也最透明的入口。
這想法簡單得令人卸下心防。我們不再到處尋找光滑函數 u(x,t),而是鋪下一張規則的格網:位置 x_j = j h 彼此相距 h,時刻 t_n = n k 彼此相隔一步 k。我們只會在這些交叉點上詢問 u 的值,並把該格點值記為 U_j^n,作為真值 u(x_j, t_n) 的近似。一個定義在整片區域上的連續未知量,就化成了一張有限的數字表——某個電腦真能裝下的東西。技藝藏在填表的法則裡,而那法則來自把偏微分方程中的每個導數,換成一個 有限差分近似。
導數是斜率;差分是弦
就從你在單變數微積分學到的那個定義出發:一點處的導數 u_x 是斜率的極限,即當 h 縮向零時 (u(x + h) - u(x)) / h 的極限。有限差分的把戲,就是拒絕取極限,停在一個很小但真實的 h 上。這給出前向差分 (U_{j+1} - U_j) / h,用 j 處的值與它右邊的鄰居來誠實地估計 u_x。從幾何看,真正的導數是 x_j 處切線的斜率,而前向差分是連接曲線上兩個鄰近點的弦的斜率——很接近,但並不相同。
用同一招,還有後向差分 (U_j - U_{j-1}) / h,倚靠左邊的鄰居;以及中心差分 (U_{j+1} - U_{j-1}) / (2h),把兩側平均。對於二階導數 u_xx——主宰熱方程的那一個——自然的選擇是把一排三個點合起來:(U_{j+1} - 2 U_j + U_{j-1}) / h^2。把它讀成右邊的值加左邊的值再減去中間的兩倍,全部除以 h^2;當中間那點恰好落在比鄰居低的凹谷裡時,它就又大又正,這正是你早已信任的 u_xx「向上凹」的圖像。每一道這樣的配方都是一個小小的樣板(stencil):公式伸手去觸碰的一組固定格點。
forward u_x ~ ( U_{j+1} - U_j ) / h
backward u_x ~ ( U_j - U_{j-1} ) / h
centred u_x ~ ( U_{j+1} - U_{j-1} ) / (2h)
second u_xx ~ ( U_{j+1} - 2 U_j + U_{j-1} ) / h^2
stencil for u_xx: o ---- o ---- o
j-1 j j+1泰勒定理是那位誠實的會計
弦比起切線究竟錯了多少?泰勒定理給出精確的答案,而這正是整個主題的核心。把真解在 x_j 附近展開:u(x_j + h) = u + h u_x + (h^2 / 2) u_xx + (h^3 / 6) u_xxx + ...,其中每個導數都在 x_j 處取值。把這代入前向差分,領頭的 u 與第一個 h u_x 項恰好還原出 u_x;剩下的一切都是誤差。留下來的是 (h / 2) u_xx 加上更小的碎片——這就是 截斷誤差,差分公式與它所模仿的導數之間的落差。
那個領頭剩餘量的大小,就是精度階數。前向差分的誤差約為 (h/2) u_xx,一項正比於 h,故它是一階精確:把 h 減半,誤差大致也減半。現在對中心差分做同樣的記帳,一個小小的奇蹟出現了——u(x_j + h) 與 u(x_j - h) 對稱的展開使 u_xx 項彼此抵消,存活下來的誤差正比於 h^2。中心差分是二階:把 h 減半,誤差掉到四分之一。觸碰的點數相同,卻是好得多的交易,純粹因為對稱性殺掉了領頭的誤差項。
從單一導數到一整個格式
現在把這些零件組裝成一個對付真實偏微分方程的方法。取熱方程 u_t = k u_xx。把時間導數換成 t 方向的前向差分,把空間導數換成 x 方向的中心二階差分,你就得到經典的 FTCS 格式——前向時間、中心空間(Forward Time, Centred Space)。對新時間層上那唯一的未知量求解,得到一個顯式更新:U_j^{n+1} = U_j^n +(k·diff / h^2)(U_{j+1}^n - 2 U_j^n + U_{j-1}^n)。把它唸出來:一點上的新溫度,是舊溫度被推向鄰居平均值的結果,恰恰是「熱量湧入凹谷」的直覺,如今化成電腦一步步往前推進的算術。
- 鋪下格網:選定空間步長 h 與時間步長 k,並由初始資料設定 U_j^0,即 U_j^0 = f(x_j)。
- 為每個導數挑一個樣板:u_t 用時間前向,u_xx 用三點中心二階差分。
- 代入 u_t = k u_xx,並對唯一的新時間值 U_j^{n+1} 做代數求解。
- 掃過所有內部的 j,用第 n 列填出第 n+1 列;在兩端施加邊界值。
- 重複,讓 n 往前推進,直到抵達你所關心的最終時刻。
這個模式——先把空間離散化,把偏微分方程化成一個關於時間、彼此耦合的大型常微分方程組,再把它往前推——好用到有了專屬名字,叫做 線方法。每個格點在時間中描出一條「線」,而空間樣板告訴鄰居們如何彼此對話。值得停下來看看我們做了什麼:偏微分方程——那個開啟整個主題的東西——被化約成一個你早已會積分的常微分方程組,再化成一張數字表上純粹的算術。
小的截斷誤差是必要的,卻不充分
一個截斷誤差隨 h 與 k 縮小而趨於零的格式,稱為相容(consistent)——它確實在逼近正確的那條偏微分方程,而非某個鄰居。相容性正是截斷誤差所認證的性質,你或許會盼望這就是全部。並不是,而這正是本級最重要的一份誠實。一個格式可以在每一點都有漂亮地微小的截斷誤差,卻仍然產出徹底的垃圾,因為隨著推進反覆進行,每一步的微小誤差可能放大、自我滋養。熱方程的 FTCS 就是教科書級的前車之鑑:取一個相對於 h^2 太大的時間步 k,算出的解便爆發成每一步都翻倍的狂亂振盪,儘管每一個別的差分都是忠實的 O(h^2) 近似。
缺的那塊是穩定性——一個保證,確保誤差隨步數累積而維持有界,而不是炸開。相容性加上穩定性合起來給出收斂性,那真正的獎賞:當格網加密時 U_j^n 確實趨向真值 u(x_j, t_n),在極限中還原出古典解。這個三方關係正是本主題著名的等價定理,下一篇導讀將全篇獻給它;眼下的教訓是:截斷誤差恰恰是兩根支柱之一。它告訴你格式瞄準了正確的標靶——卻完全沒說推進過程會不會讓答案爆炸。
還有一個值得點名的微妙之處,因為它纏繞著本級其餘的內容。一個格式實際犯下的誤差,常常看起來像是來自一條略為不同的偏微分方程——所謂的 修正方程。舉例來說,對流問題的一階迎風格式,行為就彷彿在解一條額外栓上了一個小擴散項的對流方程,產生人為的塗抹,稱為 數值擴散。截斷誤差的展開正是揭露此事的工具:那個領頭的剩餘項,就是我們上面算出的同一個 h u_xx,它字面上就是一個真方程從未擁有的擴散。因此截斷誤差不只是一個待界定的數字——讀對了,它告訴你格網所犯錯誤的性格。