有限差分法走投無路之處
前一級教你以這種方式解偏微分方程:把一個樣板蓋到一張規則格點上——把每一個導數換成鄰近值之差,要求方程在每一個內部節點上成立,你就得到一個又大又稀疏的線性系統去解。五點拉普拉斯算子是它的招牌——乾淨、快速,在一個矩形上用起來令人愉快。麻煩出在「規則格點」與「矩形」這兩個詞。只要你的區域是一片渦輪葉片、一條人類主動脈、一具帶圓角的車身,或是一個裂縫尖端,一張工整的、與座標軸對齊的格點就再也貼不上那個形狀了。你可以試著把邊界做成階梯狀,但你捏造出來的那些角落並不在真正的問題裡,而那裡的準確度就會受害。有限差分法是一個在滿是曲線的世界裡,鍾愛直尺的方法。
有限元素法一開始就乾脆拒絕了格點。它不讓點排成一行一行地行進,而是把區域剁成一張由小三角形或四面體組成的網格——一塊塊扁平的小片,你可以把它們嚴絲合縫地貼上任何彎曲的邊界,在風起雲湧處細密、在平靜處粗疏。但立刻就冒出一個謎題。導數是定義在一點上的;那麼在兩個扁平三角形相接的接縫上、解可能有個折角之處,你要怎麼去問一個二階導數?誠實的答案是:在這裡,堅持偏微分方程那個古典的、逐點的形式,根本就堅持錯了東西。我們需要一種方式,把同一段物理陳述出來,使它能在折角、不規則網格與彎曲牆面之中存活。那個重述就是弱形式,而抵達它,正是本篇的全部任務。
乘上一個測試函數再積分
取最簡單而有趣的偏微分方程,一根受熱棒或一條受載弦的一維模型:在 0 到 1 的區間上 -u''(x) = f(x),並且 u(0) = 0、u(1) = 0。那個古典的、或稱強形式,要求這個方程在每一個點 x 上都成立,這悄悄地要求 u 處處都得有一個貨真價實的二階導數。弱形式的第一步,是把那個要求鬆綁成某個更溫和的東西。挑任何一個在兩端點處皆為零的光滑測試函數 v(x),把整個方程乘上它,再沿著整根棒積分:-u''(x)*v(x) dx 的積分,等於 f(x)*v(x) dx 的積分。我們不再堅持方程逐點成立,而開始堅持它在平均意義下、以 v 加權後成立。把 v 想成一支探針:你不是在某一點量溫度,而是把探針壓上整根棒,讀出一個加權的總量。
決定性的訣竅在這裡,而它無非就是分部積分。左邊我們有 -u''*v dx 的積分。做一次分部積分,把一個導數從 u 身上挪到 v 身上:-u''*v dx 的積分變成 u'*v' dx 的積分,再減去一個在端點處取值的邊界項 [u'*v]。但我們選的 v 在兩端點都為零,所以那個邊界項死掉了。剩下的東西平衡得令人屏息:u'(x)*v'(x) dx 的積分,等於 f(x)*v(x) dx 的積分,且要求對每一個容許的測試函數 v 都成立。注意導數發生了什麼事。我們起初需要 u 的兩個導數,如今卻只需要 u 與 v 各一個導數——這個負擔被均勻地分攤掉了。這正是為什麼這個形式被稱為「弱」:它對 u 的要求,比原方程少。
STRONG form (pointwise): -u''(x) = f(x) for every x in (0,1), u(0)=u(1)=0
multiply by test fn v, v(0)=v(1)=0, integrate:
integral of -u''(x) v(x) dx = integral of f(x) v(x) dx
integrate by parts (boundary term vanishes since v(0)=v(1)=0):
WEAK form: integral of u'(x) v'(x) dx = integral of f(x) v(x) dx for ALL such v
\_______ a(u,v) ________/ \______ L(v) ______/
two 2nd-derivatives -> one 1st-derivative on each side為何「更弱」其實更強
對解要求得更少卻反而有幫助,這感覺是顛倒的。它的回報是:弱形式接納了強形式會拒絕的那些解,而那些恰恰是我們算得出來的。一個由直線段拼成的函數——一個分段線性的帽子形狀,就像你先前見過的分段線性內插——在它的折角處沒有二階導數,所以它永遠無法逐點滿足 -u'' = f。但它的一階導數幾乎處處存在(那不過是一階階梯狀的常數斜率),所以 u'*v' dx 的積分完全說得通。弱形式樂於讓簡單的、帶折角的、對網格友善的函數參賽。我們把門加寬,正是為了讓那些我們真能用網格造出來的候選者,得以走進來。
在那個消失的邊界項裡還藏著第二份禮物,它關乎邊界條件。u(0) = u(1) = 0 這個條件,必須由我們親手築進候選函數的空間裡——我們只允許那些在兩端本來就為零的函數。這種「釘住數值」型的條件被稱為本質邊界條件,因為它們對於連空間本身的定義都是本質的。但假設那根棒的端點改為被絕熱,規定的是斜率 u'(0) 而非數值。這類條件結果就住在我們丟掉的那個邊界項裡頭;藉由選擇 v 在那裡是否為零,這類條件會自動被吸收進弱形式,根本不必加諸於空間之上。這些是自然邊界條件。本質與自然邊界條件之間的區別——一個烤進空間裡、一個從積分裡掉出來——是分部積分一個直接而長久的後果。
伽遼金:從無窮多測試函數到一個矩陣
弱形式仍然活在一個無窮維的世界裡:它必須對整個函數空間裡的每一個測試函數 v 都成立,而未知的 u 也在那個空間裡遊走。電腦無法同時擺弄無窮多個函數,所以我們做數值分析一向做的事——把那個無窮空間,換成它的一個有限的、可操控的片段。挑一組有限的簡單積木函數,即定義在網格上的形狀函數 phi_1, ..., phi_N(在一維裡,就是那些小帽子函數,每一個都是一頂在單一網格節點上達到尖峰、在所有其他節點上為零的帳篷)。尋找一個近似解,它只是這些函數的組合:u_h(x) = c_1*phi_1(x) + ... + c_N*phi_N(x)。那 N 個未知數 c_1, ..., c_N 就是電腦全部要找的東西。我們把一個未知函數,換成了一張有限的未知係數清單。
現在輪到那個替整個方法命名的選擇了。我們仍然需要把那 N 個係數釘死,而我們手上仍有一個想被測試函數 v 去測試的弱形式。伽遼金的想法是:就用我們拿來組裝解的那同一批積木去測試——要求弱方程在 v = phi_1 時成立,再在 v = phi_2 時成立,如此一路到 v = phi_N。每一個測試函數的選擇給出一條純量方程,所以 N 個測試函數恰好給出關於 N 個未知數 c_i 的 N 條方程——一個方形系統,既不欠定也不超定。把 u_h 代入 a(u_h, phi_j) = L(phi_j),再用線性性,就把每一條方程變成一列:c_i 與 a(phi_i, phi_j) 之積對 i 求和,等於 L(phi_j)。那是一個喬裝過的線性系統 A c = b,其中 A_{ji} = a(phi_i, phi_j)、b_j = L(phi_j)。
如果你心裡隱隱響起一個鈴聲,那就相信它:這正是前面某一級裡最小平方法背後那個相同的投影想法。在那裡你無法精確命中一個目標向量,於是你藉由要求殘差與某個子空間正交,找到了該子空間中最近的那一點。伽遼金法對函數做的正是這件事:u_h 無法精確滿足偏微分方程,於是我們要求它的殘差「正交」於形狀函數所張成的空間,其中的內積就是積分 a(.,.)。伽遼金法,就是把「以正交投影求最佳近似」從向量提升到函數空間——而這也是你稍後會遇到的那套誤差理論,Cea 引理的種子,它說算出來的 u_h 與網格所能提供的最佳近似,只差一個常數倍。
你建好了什麼,以及它接下來通往何處
退一步看整條流水線的形狀,因為這一級剩下的部分不過是把它填滿。你從一個解不出來的偏微分方程、與一個對格點而言太彆扭的區域出發。你把偏微分方程重述成它的弱形式,方法是乘上一個測試函數再做分部積分,這同時把所需的光滑度減半,並把你的邊界條件分類成本質的與自然的。你把無窮的函數空間,換成由網格上的形狀函數所張成的有限空間,再施以伽遼金法,把「對所有測試函數成立」變成 N 條具體的方程。其結果是一個線性系統 A c = b,其矩陣 A——由形狀函數導數之積的積分築成——就是下一篇那個著名的剛度矩陣。一個有著無窮多未知數的連續問題,化成了一個有限的矩陣方程,而我們手上早已備有解這類方程的一整箱工具。
在我們繼續之前,有兩個誠實的提醒。其一,a(phi_i, phi_j) 與 L(phi_j) 裡的每一個積分,本身都是在電腦上用數值數值積分近似算出的——通常是在每個元素上做高斯數值積分——所以連 A 與 b 的元素都帶著一點近似誤差,更別說這一切都是在浮點數裡完成的,那裡 0.1 沒有精確的二進位形式。其二,弱形式並不把困難的問題變容易;它把它們變得可陳述。它所產生的剛度矩陣可能很大,而且對於錯誤的元素選擇或一張形狀差勁的網格,還可能是病態的,使得解 A c = b 會像任何病態系統那樣損失精度——這正是為什麼接下來幾篇裡網格與元素的選擇如此要緊。