跳轉到內容

並行譜數值方法/時間步長

來自華夏公益教科書,開放的書籍,開放的世界

我們現在簡要討論如何求解初值問題。有關更多資訊,請參見 Bradie (Chap. 7)[1]。Boyce 和 DiPrima 中也提供了一個更長但仍然簡短的介紹。[2]

向前尤拉

[編輯 | 編輯原始碼]

為了有效地計算計算機上的微分方程解,方便地在有限數量的指定點進行計算,然後在這些點之間插值。對於許多計算來說,使用網格很方便,網格上的點彼此相隔等距。

在本節的其餘部分 將是我們的步長,假設它是一個常數。在求解 ODE 或 PDE 時,選擇 不是隨機選擇的,而是需要一些直覺和/或理論分析。我們將從最基本的數值方法向前尤拉方法開始。首先用 表示第 時間步的時間,用 表示第 時間步的計算解,其中 。步長 方面的定義為 。首先從具有初始條件的基本 ODE 開始,其中 是某個任意函式, 是我們的解,

 

 

 

 

( 1)

微分方程可以用有限差分來逼近,

現在我們要做的就是用代數方法求解

 

 

 

 

( 2)

如果我們想要計算 在時間 時的值,那麼我們可以利用公式 2 生成時間 時的近似值。首先找到 並用它來計算 。然後我們重複這個過程,直到達到最終時間。

一個示例計算

[edit | edit source]

讓我們以公式 1 中的 ODE 為例,其初始條件為 ,其中 。使用向前尤拉法,讓我們繪製兩個示例,其中

公式 1 中的 ODE 的數值解,其中 f(t,y) = y,展示了向前尤拉法在不同時間步長選擇下的準確性。

毫無疑問,與 相比,更小的步長,如 ,將更加準確。觀察 的曲線,可以發現 僅在 4 個點處計算,然後在每個點之間進行直線插值。這顯然不太準確,但可以粗略地瞭解函式的樣子。對於 的解可能需要執行 10 倍的步驟,但它顯然更加準確。向前尤拉法是 一階方法的示例,並使用泰勒展開式中的前兩項[腳註 1] 來逼近精確解。

其中,比 O 階更高的項在逼近解中被省略。將其代入等式 2 ,我們得到:

在消去項併除以 後,我們得到:

由此可以清楚地看出,該方法的精度隨步長線性變化,因此它是 一階精度的。

向後尤拉法

[編輯 | 編輯原始碼]

可以透過使用向後差分商來逼近導數,從而獲得向前尤拉法的變體。使用等式 1 並應用:

將索引從 步進到 ,我們得到:

注意 不是像向前尤拉方法那樣明確地寫出來的。相反,這個方程隱式地定義了 ,必須求解才能確定 的值。求解的難易程度完全取決於函式 的複雜程度。例如,如果 僅僅是 ,那麼可以使用二次方程,但是許多非線性偏微分方程需要其他方法。這些方法中的一部分將在後面介紹。

Crank-Nicolson 方法

[edit | edit source]

透過對向前尤拉方法和向後尤拉方法進行平均,我們可以找到 Crank-Nicolson 方法

重新排列,我們得到:

再次注意 不是像向前尤拉方法那樣明確地寫出來的。這個方程隱式地定義了 ,因此必須代數求解才能得到

向前尤拉、向後尤拉和 Crank-Nicolson 方法的穩定性

[edit | edit source]

讓我們看一下以下常微分方程

其中 是一個常數,而 ,其中 。我們用前向尤拉法、後向尤拉法和 Crank-Nicolson 時間步進方案對這個 ODE 進行數值求解。結果如下

而精確解由下式給出

方程 2 中 ODE 的數值解,其中 λ = 20,時間步長為 h = 0.1,演示了前向尤拉法的非穩定性以及後向尤拉法和 Crank-Nicolson 法的穩定性。

上圖顯示了兩種方法如何收斂到解,但前向尤拉解對於所選時間步長是非穩定的。下面的清單是一個 Matlab 程式,你可以用它來改變 的值,看看對於固定時間步長,這將如何改變方法的穩定性。

 

 

 

 

( A)
Matlab 程式 程式碼下載
% A program to demonstrate instability of timestepping methods
% when the timestep is inappropriately choosen.

%Differential equation: y'(t)=-y(t) y(t_0)=y_0
%Initial Condition, y(t_0)=1 where t_0=0
clear all; clc; clf;

%Grid
h=.1;
tmax=4;
Npoints = tmax/h;
lambda=.1;

%Initial Data
y0=1;
t_0=0;
t(1)=t_0;
y_be(1)=y0;
y_fe(1)=y0;
y_imr(1)=y0;

for n=1:Npoints
%Forward Euler
    y_fe(n+1)=y_fe(n)-lambda*h*y_fe(n);
     %Backwards Euler
    y_be(n+1)=y_be(n)/(1+lambda*h);
     %Crank Nicolson
    y_imr(n+1)=y_imr(n)*(2-lambda*h)/(2+lambda*h)
    t(n+1)=t(n)+h;
end

%Exact Solution
tt=[0:.001:tmax];
exact=exp(-lambda*tt);

%Plot
figure(1); clf; plot(tt,exact,'r-',t,y_fe,'b:',t,y_be,'g--',t,y_imr,'k-.');
xlabel time; ylabel y;
legend('Exact','Forward Euler','Backward Euler',...
'Crank Nicolson');

 

 

 

 

( Ap)
一個 Python 程式,用來演示不同時間步進方法的非穩定性。 程式碼下載
#!/usr/bin/env python
"""
A program to demonstrate instability of timestepping methods#
when the timestep is inappropriately choosen.################
"""

from math import exp
import matplotlib.pyplot as plt
import numpy

#Differential equation: y'(t)=-l*y(t) y(t_0)=y_0
#Initial Condition, y(t_0)=1 where t_0=0

# Definition of the Grid
h = 0.1	# Time step size
t0 = 0	# Initial value
tmax = 4	# Value to be computed y(tmax)
Npoints = int((tmax-t0)/h)	# Number of points in the Grid

t = [t0]

# Initial data
l = 0.1
y0 = 1	# Initial condition y(t0)=y0
y_be = [y0]	# Variables holding the value given by the Backward Euler Iteration
y_fe = [y0]	# Variables holding the value given by the Forward Euler Iteration
y_imr = [y0]	# Variables holding the value given by the Midpoint Rule Iteration

for i in xrange(Npoints):
    y_fe.append(y_fe[-1]*(1-l*h))
    y_be.append(y_be[-1]/(1+l*h))
    y_imr.append(y_imr[-1]*(2-l*h)/(2+l*h))
    t.append(t[-1]+h)


print "Exact Value: y(%d)=%f" % (tmax, exp(-4))
print "Backward Euler Value: y(%d)=%f" % (tmax, y_be[-1])
print "Forward Euler Value: y(%d)=%f" % (tmax, y_fe[-1])
print "Midpoint Rule Value: y(%d)=%f" % (tmax, y_imr[-1])

# Exact Solution
tt=numpy.arange(0,tmax,0.001)
exact = numpy.exp(-l*tt)

# Plot
plt.figure()
plt.plot(tt,exact,'r-',t,y_fe,'b:',t,y_be,'g--',t,y_imr,'k-.');
plt.xlabel('time')
plt.ylabel('y')
plt.legend(('Exact','Forward Euler','Backward Euler',
'Implicit Midpoint Rule'))
plt.show()

前向尤拉法、後向尤拉法和 Crank-Nicolson 時間步進方案對於 的穩定性和精度

[edit | edit source]

我們現在嘗試理解這些觀察結果,以便我們有一些指導方針來設計穩定的數值方法。如果數值解可以被不依賴步長的函式所限制,那麼具有有界解的初值問題的數值解是穩定的。通常使用兩種方法來理解穩定性。第一種方法是線性化穩定性,它涉及計算線性系統的特徵值,以檢視小的擾動是增長還是衰減。第二種方法是計算與微分方程相關的能量類數量,並檢查它是否保持有界。

我們假設 ,以便 ODE 的精確解不會無限制地增長。前向尤拉法得到

我們可以對後向尤拉方法進行類似的計算,得到

因此,後向尤拉方法是無條件穩定的,而前向尤拉方法不是。我們留下了Crank-Nicolson方法的分析作為練習。

第二種方法,常用於顯示偏微分方程的穩定性,是尋找能量式的量並證明該量可以限制解,並防止解變得過大或過小。通常,該量被選為非負的,那麼只需要推匯出一個上限。我們概述瞭如何對常微分方程進行此操作,以便我們可以在觀察偏微分方程時使用相同的思想。回想一下,前向尤拉演算法由下式給出

乘以該式,我們發現

現在要獲得關於 的界限,該界限以 表示,我們使用以下事實

因此,如果

因此,如果 ,那麼 ,因此我們得到了穩定性,再次看到該演算法在時間步長足夠小的情況下是穩定的。在很多情況下,很大,因此時間步長 需要非常小。在這種情況下,前向尤拉方法在計算機上可能非常慢。

穩定性不是數值方法逼近初值問題解的唯一要求。我們還希望證明,隨著時間步長的減小,數值逼近會變得更好。對於前向尤拉方法,我們有

現在如果

那麼[腳註 2]

所以

我們可以做類似的計算來證明Crank-Nicolson方法是二階的。在這種情況下,我們使用圍繞的泰勒展開式。

所以

因此

因此,這是一個二階方法。

  1. 確定隱式中點規則對於常微分方程 穩定的實數 和時間步長。在 對應時間步長 的圖表中繪製穩定區域。
  2. 證明後向尤拉方法是一階方法。

備註

[edit | edit source]
  1. 泰勒展開式的推導可以在大多數微積分書籍中找到。
  2. 我們將使用大O符號來表示,如果,那麼當 時,我們有,其中 是某個常數。
  1. Bradie (2006)
  2. Boyce and DiPrima (2010)

參考文獻

[edit | edit source]

Boyce, W.E.; DiPrima, R.C. (2010). Elementary Differential Equations and Boundary Value Problems. Wiley. {{cite book}}: Cite has empty unknown parameter: |lnguage= (help)

Bradie, B. (2006). A Friendly Introduction to Numerical Analysis. Pearson.

華夏公益教科書