科學計算實務:軟體、驗證與可重現性

製造解法(method of manufactured solutions)

/ MMS /

要檢查你的程式是否正確地解了一條方程式,你會很想把它的答案與真實答案比較。但對大多數有趣的微分方程而言,真實答案是未知的——這正是你之所以用數值方法解它的原因。製造解法巧妙地繞過這一點,做法是把邏輯倒過來跑:你不去找某條給定方程式的解,而是「挑」一個你喜歡的解,然後反推出以它為解的那條方程式。如此一來,按建構方式,你手上就握有一個可供比較的精確答案。

以下是平實步驟的食譜。假設你的程式聲稱能解形如 L(u) = f 的 PDE,其中 L 是某個微分算子(例如一維帕松問題的 L(u) = -u''),f 是右端項。第一步,「挑」一個你中意、當作「解」的光滑函數——挑一個沒有特殊結構的,例如 u_manufactured(x) = sin(3x) + x^2。第二步,把它代入左端,並做符號「微分」算出 f 必須是什麼:f(x) = L(u_manufactured) = 9 sin(3x) - 2。第三步,也在邊界上計算 u_manufactured,得到精確的邊界條件。現在把那個 f 與那些邊界條件餵給你的程式。因為你是刻意把問題湊成讓 u_manufactured 恰好是其解,程式的輸出就應該與 u_manufactured 相符——而你可以在每個網格上、每個點精確地量出誤差。

MMS 是程式碼「驗證」的黃金標準,因為它在一個有已知精確答案的問題上測試完整的程式路徑,卻不對答案的形狀施加任何限制——你可以自由選擇能演練到方程式中每一項的解。配合網格細化,它驅動了一個收斂階研究:若你的格式理應是二階的,則每當你把網格減半,量到的誤差就應該減為四分之一,若沒有,你就有臭蟲。誠實的提醒:MMS 驗證的是「程式碼」,不是「模型」——你製造的解不必有物理意義,事實上也不應該有,所以 MMS 對你的方程式是否符合現實隻字未提。此外,計算 f 時你必須「精確地」(用符號或手算)施加那個算子;若你用你正在測試的同一個數值近似去算 f,臭蟲就把自己藏起來了。

要驗證 (0,1) 上 -u'' = f 的帕松求解器,挑 u(x) = sin(pi x)。那麼 f(x) = -u''(x) = pi^2 sin(pi x),且 u(0) = u(1) = 0。把那個 f 與那些邊界值餵給程式。數值答案應該趨近 sin(pi x);對二階方法,網格減半應使最大誤差約降為四分之一。若沒有,這個格式有臭蟲。

先選定答案,藉由對它微分推導出強迫項,再檢查程式能否重現它。

要「精確地」計算強迫項 f——用符號或手算。若你用你正想測試的那個離散化去產生 f,該離散化裡的任何臭蟲也會被烤進 f 裡,從而變得看不見。

又稱
MMSmanufactured solution製造解人造解法