0%

BDF2 方法

本文用 BDF2 方法(属于线性多步法)求解ODE,需要用到方程的牛顿迭代,然后用 MATLAB 编程,最后输出结果的误差阶为 2。

BDF 方法

考虑常微分方程初值问题

向后微分公式 (Backward differentiation formula, BDF) 是数值求解常微分方程的隐式线性多步方法. 由于该方法是 A 稳定的, 通常用来求刚性微分方程.

BDF1 方法就是隐式 Euler 方法 (或后退 Euler 方法):

BDF2 方法:

BDF3 方法:

下面使用 BDF2 方法求解常微分方程初值问题.

线性 ODE 例子

方程的真解:.

BDF2 方法求解方程的步骤:

  1. 使用梯形公式计算 ,

    可知:

  2. 使用 BDF2 方法计算 , ,

    计算可得

计算数值解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
% BDF2.m
% BDF method for the ODE model
% u'(t)=t^2+t-u, t in [0,1]
% Initial condition: u(0)=0 ;
% Exact solution: u(t)=-exp(-t)+t^2-t+1.
clear all; close all;
h=0.1;
t=0:h:1; % interval partition
N=length(t)-1;
un=zeros(1,N+1);
un(1)=0; % initial value
% Trapezoidal rule to compute un(2)
un(2)=2/(2+h)*un(1)+h/(2+h)*(t(1)^2+t(1)+un(1))+h/(2+h)*(t(2)^2+t(2));
% BDF2 method
for n=1:N-1
un(n+2)=4/(3+2*h)*un(n+1)-1/(3+2*h)*un(n)+2*h/(3+2*h)*(t(n+2)^2+t(n+2));
end
ue=-exp(-t)+t.^2-t+1; % exact solution
plot(t,ue,'b-',t,un,'r+','LineWidth',1)
legend('Exact','Numerical','location','northwest')
% title('BDF2 method','fontsize',12)
set(gca,'fontsize',12)
xlabel('t','fontsize',16), ylabel('u','fontsize',16)

% computing error
error=max(abs(un-ue))

% print -dpng -r600 BDF2.png
% print -depsc2 BDF2.eps

BDF2.png

计算误差阶

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
% BDF2_error.m
% BDF method for the ODE model
% u'(t)=t^2+t-u, t in [0,1]
% Initial condition: u(0)=0 ;
% Exact solution: u(t)=-exp(-t)+t^2-t+1.
clear all; close all;
Nvec=[10 50 100 500 1000]; % Number of partitions
Error=[];
for k=1:length(Nvec)
N=Nvec(k);
h=1/N;
t=0:h:1; % interval partition
un(1)=0; % initial value
% Trapezoidal rule to compute un(2)
un(2)=2/(2+h)*un(1)+h/(2+h)*(t(1)^2+t(1)+un(1))+h/(2+h)*(t(2)^2+t(2));
% BDF2 method
for n=1:N-1
un(n+2)=4/(3+2*h)*un(n+1)-1/(3+2*h)*un(n)+2*h/(3+2*h)*(t(n+2)^2+t(n+2));
end
ue=-exp(-t)+t.^2-t+1; % exact solution
error=max(abs(un-ue));
Error=[Error,error];
end
plot(log10(Nvec),log10(Error),'ro-','MarkerFaceColor','w','LineWidth',1)
hold on
plot(log10(Nvec),log10(Nvec.^(-2)),'--')
grid on
%title('Convergence of BDF2 method','fontsize',12)
set(gca,'fontsize',12)
xlabel('log_{10}N','fontsize',14), ylabel('log_{10}Error','fontsize',14)

% add annotation of slope
ax = [0.57 0.53];
ay = [0.68 0.63];
annotation('textarrow',ax,ay,'String','slope = -2','fontsize',14)

% computing convergence order
for n=1:length(Nvec)-1
order(n)=-log(Error(n)/Error(n+1))/(log(Nvec(n)/Nvec(n+1)));
end
Error
order

% print -dpng -r600 BDF2_error.png
% print -depsc2 BDF2_error.eps

输出结果

1
2
3
4
5
6
Error =
1.0e-06 *
0.3778 0.0006 0.0000 0.0000 0.0000 0.0000

order =
4.0004 4.0001 3.9990 3.9310 4.3726

BDF2_error.png

非线性例子

方程的真解:.

BDF2 方法求解方程的步骤:

  1. 使用梯形公式计算 ,

    这里需要用牛顿迭代求解一个非线性方程.

  2. 使用 BDF2 方法计算 , ,

    这里每一步都需要用牛顿迭代求解一个非线性方程.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
% BDF2Non.m
% BDF method for the nonlinear ODE model
% u'(t)=u-2t/u, t in [0,1]
% Initial condition: u(0)=1;
% Exact solution: u(t)=sqrt(2*t+1)
clear all; close all;
h=0.1;
t=0:h:1; % interval partition
N=length(t)-1;
un=zeros(1,N+1);
un(1)=1; % initial value
NI(1,N)=0; % Record the number of iterations
% Trapezoidal rule to compute un(2)
X=un(1);
Xprev=0;
while abs(X-Xprev) > abs(X)*1e-14
Xprev=X;
X=X-(X-h/2*X+h*t(2)/X-un(1)-h/2*(un(1)...
-2*t(1)/un(1)))./(1-h/2-h*t(2)/(X^2));
un(2)=X;
NI(1)=NI(1)+1;
end
% BDF2 method
for n=1:N-1
X=un(n+1);
Xprev=0;
while abs(X-Xprev) > abs(X)*1e-14
Xprev=X;
X=X-(X-2/3*h*X+4/3*h*t(n+2)/X-4/3*un(n+1)...
+1/3*un(n))./(1-2/3*h-4/3*h*t(n+2)/(X^2));
NI(n+1)=NI(n+1)+1;
end
un(n+2)=X;
end
ue=sqrt(2*t+1); % exact solution
plot(t,ue,'b-',t,un,'r+','LineWidth',1)
legend('Exact','Numerical','location','northwest')
% title('BDF2 method','fontsize',12)
set(gca,'fontsize',12)
xlabel('t','fontsize',16), ylabel('u','fontsize',16)

% computing error
error=max(abs(un-ue))

% print -dpng -r600 BDF2Non.png
% print -depsc2 BDF2Non.eps

BDF2Non.png

计算误差阶

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
% BDF2Non_error.m
% BDF method for the nonlinear ODE model
% u'(t)=u-2t/u, t in [0,1]
% Initial condition: u(0)=1;
% Exact solution: u(t)=sqrt(2*t+1)
clear all; close all;
Nvec=[100 500 1000 5000 10000]; % Number of partitions
Error=[];
for k=1:length(Nvec)
N=Nvec(k);
h=1/N;
t=0:h:1; % interval partition
un(1)=1; % initial value
NI(1,N)=0; % Record the number of iterations
% Trapezoidal rule to compute un(2)
X=un(1);
Xprev=0;
while abs(X-Xprev) > abs(X)*1e-12
Xprev=X;
X=X-(X-h/2*X+h*t(2)/X-un(1)-h/2*(un(1)...
-2*t(1)/un(1)))./(1-h/2-h*t(2)/(X^2));
un(2)=X;
NI(1)=NI(1)+1;
end
% BDF2 method
for n=1:N-1
X=un(n+1);
Xprev=0;
while abs(X-Xprev) > abs(X)*1e-12
Xprev=X;
X=X-(X-2/3*h*X+4/3*h*t(n+2)/X-4/3*un(n+1)...
+1/3*un(n))./(1-2/3*h-4/3*h*t(n+2)/(X^2));
NI(n+1)=NI(n+1)+1;
end
un(n+2)=X;
end
ue=sqrt(2*t+1); % exact solution
error=max(abs(un-ue));
Error=[Error,error];
end
plot(log10(Nvec),log10(Error),'ro-','MarkerFaceColor','w','LineWidth',1)
hold on
plot(log10(Nvec),log10(Nvec.^(-2)),'--')
grid on
% title('Convergence of BDF2 method','fontsize',12)
set(gca,'fontsize',12)
xlabel('log_{10}N','fontsize',14), ylabel('log_{10}Error','fontsize',14)

% add annotation of slope
ax = [0.57 0.53];
ay = [0.68 0.63];
annotation('textarrow',ax,ay,'String','slope = -2','fontsize',14)

% computing convergence order
for n=1:length(Nvec)-1
order(n)=-log(Error(n)/Error(n+1))/(log(Nvec(n)/Nvec(n+1)));
end
Error
order

% print -dpng -r600 BDF2Non_error.png
% print -depsc2 BDF2Non_error.eps
````

**输出结果**

Error =
1.0e-04 *
0.8167 0.0334 0.0084 0.0003 0.0001

order =
1.9858 1.9958 1.9986 2.0000
```

BDF2Non_error.png