Crank Nicholson Method
Crank Nicholson Method
Crank Nicholson Method
Lecture O10
Crank-Nicolson method &!
Stiff ODEs
ACCURACY OF CRANK-NICOLSON
Going to show that the Crank-Nicolson time-marching method is
2nd-order accurate.
l
l+1
1 d
d
l+1
l
3
= + t
+
+ t (. . . )
2 dt
dt
That is, that the local truncation error is proportional to t3, or
that the global truncation error is proportional to t2.
ACCURACY OF CRANK-NICOLSON
Taylor-series expand about tl:
l
2 l
d
l+1
l
21 d
= + t
+ t
+
2
dt
2 dt
t (. . . )
(10.1)
l+1
d
t
dt
l+1
21
d
t
2 dt2
l+1
t3 (. . . )
(10.2)
d
l+1+ t
dt
2 l
1
d
d
2
+ t
t
2
2
dt
dt
2 l+1
1
d
2
+ t
2 dt2
3
+ t (...)
l+1
l+1
l+1
l+1
d
d
+
dt
dt
d2
dt2
21
t
2
d2
dt2
l+1
1 d
= + t
+
2 dt
2 l
21 d
+ t
4 dt2
l
d
dt
2
l+1
d
dt2
Crank-Nicolson
l+1
t (. . . ) Error
t3 (. . . )
ACCURACY OF CRANK-NICOLSON
l
l+1
1 d
d
l+1
l
= + t
+
Lets further analyse !
2 dt
dt
this term
2 l
2 l+1
d
21 d
3
+ t
+
t
(.
.
.
)
(10.3)
4 dt2
dt2
Taylor-series expand d2/dt2 about tl:
2
l+1
d
d
d
2
= 2 + t 3 + t (. . . )
2
dt
dt
dt
Substitute back into Eq. (10.3) to get
l
l+1
1 d
d
l+1
l
3
= + t
+
+ t (. . . )
2 dt
dt
l+1
d
1 d
+
t
2 dt
dt
l+1
3
+ t (. . . )
Small
STABILITY OF CRANK-NICOLSON
Consider the model problem
d
=
dt
1+
=
1
=
t/2
t/2
l+1
STABILITY OF CRANK-NICOLSON
1+
l+1
=
1
t/2
t/2
= l
For stability (solution not to blow up) we need ||1.
1+
t/2
Crank-Nicolson:
=
1
t/2
1+
t/2
That is,
1
1
t/2
1 + Re t/2 + i Im t/2
1
1
i Im t/2
Re t/2
(1 + Re t/2)2 + ( Im t/2)2
1
2+(
2
(1
t/2)
t/2)
Re
Im
(1 +
Re
t/2) (1
Re
t0
Re
t/2)
Im
12
t)3
t)5
Im
80
+ ...
STABILITY OF CRANK-NICOLSON
which is of order O( Im t)3 . So compared to the Euler methods the phase error
here
of the same(solution
order, but the
term has
in the
denominator
instead
Foris stability
notleading
to blow
up)12 we
need
||1.
of 3 and will be smaller.
That is,
Im
Stable
Unstable
Re
RK-2
Stability region
of implicit
Euler and
CrankNicolson
scheme
RK-4
Euler
So far, we have learnt to solve single ODE using implicit Crank-Nicolson method. What if you are
required a system of M ODEs?
d 1
= f1 ( 1 , 2 , 3 , . . . . . . ,
dt
d 2
= f2 ( 1 , 2 , 3 , . . . . . . ,
dt
d 3
= f3 ( 1 , 2 , 3 , . . . . . . ,
dt
.. ..
.=.
d M
= fM ( 1 , 2 , 3 , . . . . . . ,
dt
M , t)
M , t)
M , t)
M , t)
d 1
= f1 (
dt
1 , t)
Crank-Nicolson
l+1
1
t
l
= 1+
f1 (
2
l l
1, t )
+ f1 (
l+1 l+1
)
1 ,t
d 1
= f1 (
dt
1 , t)
Crank-Nicolson
l+1
1
l
1
t
+
f1 (
2
l l
1, t )
+ f1 (
l+1 l+1
)
1 ,t
d 1
= f1 (
dt
d 2
= f2 (
dt
1,
2 , t)
1,
2 , t)
Crank-Nicolson
l+1
1
l+1
2
t
=
+
f1 (
2
t
l
= 2+
f2 (
2
l
1
l
1,
l l
2, t )
l
1,
l l
2, t )
+ f1 (
l+1
1 ,
l+1 l+1
)
2 ,t
+ f2 (
l+1
1 ,
l+1 l+1
)
2 ,t
d 1
= f1 (
dt
1 , t)
Crank-Nicolson
l+1
1
l
1
t
+
f1 (
2
d 1
= f1 (
dt
d 2
= f2 (
dt
l l
1, t )
1,
2 , t)
1,
2 , t)
+ f1 (
l+1 l+1
)
1 ,t
Crank-Nicolson
l+1
1
l+1
2
t
f1 (
2
t
l
= 2+
f2 (
2
=
l
1
l
1,
l l
2, t )
l
1,
l l
2, t )
+ f1 (
l+1
1 ,
l+1 l+1
)
2 ,t
+ f2 (
l+1
1 ,
l+1 l+1
)
2 ,t
l+1
1
l+1
2
l+1
3
t
=
+
f1 (
2
t
l
= 2+
f2 (
2
t
l
= 3+
f3 (
2
l
1
d 1
= f1 (
dt
d 2
= f2 (
dt
d 3
= f3 (
dt
1,
2,
3 , t)
1,
2,
3 , t)
1,
2,
3 , t)
Crank-Nicolson
l
1,
l
2,
l l
3, t )
l
1,
l
2,
l l
3, t )
l
1,
l
2,
l l
3, t )
+ f1 (
l+1
1 ,
l+1
2 ,
l+1 l+1
)
3 ,t
+ f2 (
l+1
1 ,
l+1
2 ,
l+1 l+1
)
3 ,t
+ f3 (
l+1
1 ,
l+1
2 ,
l+1 l+1
)
3 ,t
how to solve an implicit vector equation using NewtonRaphson iterations (using Jacobians).
d2
+
2
dt
Set:
=0
= d /dt
=
=
3
1
d 1
= f1 (
dt
d 2
= f2 (
dt
1,
1,
d 1
dt
d 2
dt
2 , t)
2 , t)
=
=
l+1
2
t
=
+
f1 (
2
t
l
= 2+
f2 (
2
l
1
l
1,
l l
2, t )
l
1,
l l
2, t )
3
1
Crank-Nicolson
Crank-Nicolson
l+1
1
+ f1 (
l+1
1 ,
l+1 l+1
)
2 ,t
l+1
1
+ f2 (
l+1
1 ,
l+1 l+1
)
2 ,t
l+1
2
t
+
2
t
l
2+
2
l
1
l
2
l+1
2
l
1
l 3
1)
l+1
1
l+1 3
1 )
l+1
1
t
+
2
t
l
2+
2
l
1
l+1
2
l
2
+
l
1
l+1
2
l+1
1
l 3
1)
l+1 3
1 )
At every time step you need to solve a system of 2 equations for the 2 unknowns, 1l+1 and 2l+1.
Note that the values of 1l and 2l are usually known.
f=
l+1
1
l+1
2
l
1
l
2
t/2
t/2
l
2
l
1
+
+
l+1
2
( l1 )3
l+1
1
+(
l+1 3
1 )
0
0
This equation is nonlinear and we need some iterative method to solve it. In Lecture O07, we saw how
the Newton-Raphson method can be used to solve a system of equations. The generic formula is
2
6
6
6
6
6
6
6
4
g1 /
g2 /
g3 /
g4 /
..
.
p1
p1
p1
p1
gM / p1
g1 /
g2 /
g3 /
g4 /
..
.
p2
p2
p2
p2
...
...
...
...
..
.
g1 /
g2 /
g3 /
g4 /
..
.
pM
pM
pM
pM
gM / p2
...
gM / pM
3 8
>
>
>
7 >
>
7 >
<
7 >
7
7
7 >
>
7 >
>
5 >
>
>
:
p1,new
p2,new
p3,new
p4,new
pM,new
9
>
>
>
>
>
>
>
=
p1,old
p2,old
p3,old
p4,old > =
>
>
..
>
>
.
>
>
;
pM,old
..
2
6
6
6
6
6
6
6
4
g1 /
g2 /
g3 /
g4 /
..
.
p1
p1
p1
p1
gM / p1
g1 /
g2 /
g3 /
g4 /
..
.
p2
p2
p2
p2
...
...
...
...
..
.
g1 /
g2 /
g3 /
g4 /
..
.
pM
pM
pM
pM
gM / p2
...
gM / pM
3 8
>
>
>
7 >
>
7 >
<
7 >
7
7
7 >
>
7 >
>
5 >
>
>
:
p1,new
p2,new
p3,new
p4,new
pM,new
9
>
>
>
>
>
>
>
=
p1,old
p2,old
p3,old
p4,old > =
>
>
..
>
>
.
>
>
;
pM,old
g1 (p1,old , p2,old )
g2 (p1,old , p2,old )
f=
l+1
1
l+1
2
l
1
l
2
t/2
t/2
l
2
l
1
+
+
l+1
2
( l1 )3
l+1
1
+(
l+1 3
1 )
f=
p1
p2
l
1
l
2
t/2
t/2
l
2
l
1
+ p2
+ ( l1 )3 + p1 + p31
0
0
0
0
f=
l
1
l
2
p1
p2
l
2
l
1
t/2
t/2
+ p2
+ ( l1 )3 + p1 + p31
0
0
J=
@f1 /@p1
@f2 /@p1
@f1 /@p2
@f2 /@p2
Jmn
@fm
=
=
@pn
1
2
t/2(1 + 3p1 )
t/2
1
We need to iterate using the equation below at every time step until pnew converges.
1
t/2(1 + 3p21 )
t/2
1
p1,new
p2,new
p1,old
p2,old
p1
p2
l
1
l
2
t/2
t/2
l
2
l
1
+ p2
+ ( l1 )3 + p1 + p31
function MPO10p1()!
clear all;!
close all;!
!
Delta_t=0.1;!
t=0:Delta_t:50; !
%!
%Preallocating Memory!
%!
phi=zeros(length(t),2);!
phi(1,1)=1.0;phi(1,2)=0.0;!
for n=1:length(t)-1!
phi(n+1,:)=FindPhilplus1(Delta_t,phi(n,:));!
end!
%Check with Matlab solution!
[tmat,phimat] = ode23(@ExampleO10p1,[0 50],[1 0]);!
!
hold off!
plot(t,phi(:,1),'ko',tmat,phimat(:,1),'b-');hold on!
legend('Crank-Nicolson','MATLAB ode23()');!
plot(t,phi(:,2),'ko',tmat,phimat(:,2),'b-');!
!
function p=FindPhilplus1(Delta_t,Phil)!
eps=1.0; %Just making sure you go through the loop at least once!
p=Phil; %Guess value for p!
while eps>1.0e-13!
[gfunc,jacobian]=ExampleFunctionWithJacobian(p,Delta_t,Phil);!
eps=max(abs(gfunc));!
temp=jacobian\(-gfunc); !
p=temp'+p;!
end!
!
function [gfunc,jac]=ExampleFunctionWithJacobian(p, Delta_t,Phil)!
gfunc=[p(1)-Phil(1)-(Delta_t/2.)*(Phil(2)+p(2)); p(2)-Phil(2)+(Delta_t/
2.)*(Phil(1)+Phil(1).^3+ p(1)+p(1).^3)];!
jac=[1 -Delta_t/2.0; (Delta_t/2.0)*(1+3*p(1).^2)
1];!
!
function dphidt = ExampleO10p1(t,phi)!
dphidt = zeros(2,1);
% a column vector!
dphidt(1) = phi(2);!
dphidt(2) = -phi(1)-phi(1).^3;
1
t/2(1 + 3p21 )
t/2
1
p1,new
p2,new
p1,old
p2,old
1.5
CrankNicolson
MATLAB ode23()
1
0.5
0.5
1.5
p1
p2
l
1
l
2
10
15
t/2
t/2
20
25
l
2
l
1
30
35
40
+ p2
+ ( l1 )3 + p1 + p31
45
50
Stiff Systems
A stiff system has rapidly changing components as
well as slowly changing ones. An example of a stiff
system is given by!
!
d
=
dt
1000 + 3000
2000e
0.998e
1000t
2.002e
(t) = 3
0.998e
1000t
2.002e
1000t
(t) = 3
3
0.998e
2.002e
1000t
2.002e
2.5
(t)
1.5
0.998e
0.5
0.5
1000t
1.5
2.5
3.5
Example 10.2:
solution to!
!
!
!
!
Use ode23(), ode23s(), explicit Euler and 4th order Runge-Kutta to obtain numerical
d
=
dt
1000 + 3000
2000e
dx
= x
dt
2.83
1+ h+
2 2
h
2
eI = 0
-2.79
-2.0
h+
2 2
h
+
2
3 3
4 4
h
h
+
+1
6
24
eI = 0
-2.83
Output
3
Exact solution
ode23()
ode23s()
MyEuler()
MyRK4
2.5
function MPO10p2()!
!
%Solving ODE using different Matlab functions!
% and compare with exact solution!
clear all!
close all!
Delta_t=0.002;!
!
%Exact solution!
texact=linspace(0,4,500);!
xexact=3-0.998*exp(-1000*texact)-2.002*exp(-texact);!
!
%Solving solution using different ODE!
[t1,x1]=ode23(@dxdt,[0, 4],0.0);!
[t2,x2]=ode23s(@dxdt,[0, 4],0.0);!
[t3,x3]=MyEuler(@dxdt,[0, 4],0.0,Delta_t);!
[t4,x4]=MyRK4(@dxdt,[0, 4],0.0,Delta_t);!
!
%Plotting solution!
plot(texact,xexact,'k-',t1,x1,'r-', t2,x2,'g-', t3,x3,'b-',t4,x4,'mo-')!
axis([0 4 0 3]);!
legend('Exact solution','ode23()','ode23s()','MyEuler()','MyRK4')!
!
xlabel('t','Fontsize',14);!
ylabel('x','Fontsize',14);!
!
function [t,x]=MyEuler(ODEfunc,tspan,x0,Delta_t)!
%This function solves only one ODE.!
t=tspan(1):Delta_t:tspan(2);!
x(1)=x0;!
for n=1:length(t)-1!
x(n+1)=x(n)+ODEfunc(t(n),x(n))*Delta_t;!
end!
!
function [t,x]=MyRK4(ODEfunc,tspan,x0,Delta_t)!
%This function assumes you are only solving!
%one ODE.!
t=tspan(1):Delta_t:tspan(2);!
x(1)=x0;!
for n=1:length(t)-1!
k1=ODEfunc(t(n),x(n));!
k2=ODEfunc(t(n)+(Delta_t/2),x(n)+(Delta_t/2)*k1);!
k3=ODEfunc(t(n)+(Delta_t/2),x(n)+(Delta_t/2)*k2);!
k4=ODEfunc(t(n)+Delta_t,x(n)+Delta_t*k3);!
x(n+1)=x(n)+((1/6)*k1+(1/3)*(k2+k3)+(1/6)*k4)*Delta_t;!
end!
!
function xp=dxdt(tn,xn) !
xp=-1000*xn+3000-2000*exp(-tn);
1.5
t=0.002
0.5
0.5
1.5
2.5
3.5
3
Exact solution
ode23()
ode23s()
MyEuler()
MyRK4
2.5
1.5
0.5
0.5
1.5
2.5
3.5
At first glance, it looks like all MATLAB functions give the same
Implicit methods
Implicit methods are methods where the solution at!
time level (l+1) is defined implicitly. These methods are
useful for solving ODEs that are stiff. In this subject, you
have been introduced to two implicit methods
d
(t) = f ( , t)
dt
Implicit Euler
l+1
Crank-Nicolson
l+1
t f(
l+1
l+1
,t
t
l l
+
f( , t ) + f(
2
l+1
l+1
,t
d
=
dt
1000 + 3000
2000e
1000
1000
l+1
l+1
+ 3000
+ 3000
2000e
(1 + 1000 t)
l+1
l+1
=
=
t 3000
l
+ t 3000
2000e
l+1
l+1
2000e
2000e
(1 + 1000 t)
l+1
l+1
l+1
=
=
l+1
function MPO10p3()!
clear all;!
close all;!
!
!
Delta_t=0.1;!
t=0:Delta_t:4.0;!
!
%Preallocating memory!
phi=zeros(size(t));!
!
phi(1)=0.0;!
for n=1:length(t)-1!
phi(n+1)=(phi(n)+Delta_t*(3000-2000*exp(-t(n+1))))/(1+1000*Delta_t);!
end!
plot(t,phi);!
l
l+1
3
2.5
1.5
0.5
0.5
1.5
2.5
3.5
t 3000
2000e
(1 + 1000 t)
l+1
2.5
1.5
0.5
0.5
1.5
2.5
3.5
t
The solution above was calculated with implicit Eulers method with t=0.1. This is a about 2
orders of magnitude greater than the t value used for RK4 and explicit Eulers methods (see
example O10.2). Also, note, no oscillations in the numerical solution!! In general, for stiff problems,
it is usually better to use implicit methods.
!
!
!
!
!
!
!
!
!
!
!
!
!
!
d 1
dt
d 2
dt
d 3
dt
=
=
=
1 3
1 2
Applying the Crank-Nicolson scheme will require you to solve the following algebraic!
sytem of equations every time step.
2
6
6
6
6
6
4
1/2 t
1/2 t r 1 l+1
l+1
1/2 t
b
3
1
l+1
l+1
1
2
3
l+1
l+1
l+1
2
1
l+1
l+1
l+1
3
2
l+1
l+1
1/2
2
1/2
1/2
t r
t
b
2
2
0
7
7 6
7
7 6
l
l
7=4 0 7
1 3
5
7
5
0
l
function MPO10p4()!
clear all;!
close all;!
!
Delta_t=0.01;!
t=0:Delta_t:20; !
%!
%Preallocating Memory!
%!
phiCN=zeros(length(t),3);!
InitialConditions=[5 5 5];!
phiCN(1,:)=InitialConditions;!
for l=1:length(t)-1!
phiCN(l+1,:)=FindPhilplus1CrankNicolson(Delta_t,phiCN(l,:));!
end!
figure(1);!
plot(t,phiCN(:,1),'b-');!
xlabel('t','Fontsize',18);!
ylabel('\phi_1(t)','Fontsize',18);!
!!
!!
function p=FindPhilplus1CrankNicolson(Delta_t,Phil)!
eps=1.0; %Just making sure you go through the loop at least once!
p=Phil; %Guess value for p!
while eps>1.0e-13!
[gfunc,jacobian]=ExampleFunctionWithJacobianCN(p,Delta_t,Phil);!
eps=max(abs(gfunc));!
temp=jacobian\(-gfunc); %this is more efficient than inv(jacobian)*(-gfunc)!
p=temp'+p;!
end!
2
6
6
6
6
6
4
1/2 t
1/2 t r 1 l+1
l+1
1/2 t
b
3
1
l+1
l+1
1
2
3
l+1
l+1
l+1
2
1
l+1
l+1
l+1
3
2
l+1
l+1
1/2
2
1/2
1/2
t r
t
b
1
1
2
2
2
3
0
7
7 6
7
7 6
l
l
7=4 0 7
1 3
5
7
5
0
l
20
20
10
10
1(t)
15
1(t)
15
10
10
15
15
20
10
12
14
16
18
20
20
15
10
10
10
10
15
15
10
12
10
12
14
16
18
20
10
12
14
16
18
20
MATLAB ode45()
15
20
20
1(t)
1(t)
20
14
16
18
20
20
15
10
1(t)
10
15
20
10
12
14
16
18
20
20
15
10
1(t)
10
15
20
10
12
14
16
18
20
20
15
10
1(t)
10
15
20
10
12
14
16
18
20
MATLAB ode45()
RelTol=1.0e-3
15
15
10
10
1(t)
1(t)
20
10
10
15
15
20
10
12
14
16
18
20
20
RelTol=1.0e-5
14
16
18
20
12
14
16
18
20
20
RelTol=1.0e-8
15
10
10
10
10
15
15
RelTol=1.0e-12
15
1(t)
1(t)
12
20
20
10
10
12
14
16
18
20
20
10
RelTol=1.0e-3
20
15
10
1(t)
10
15
20
10
12
14
16
18
20
RelTol=1.0e-5
RelTol=1.0e-5
20
15
10
1(t)
10
RelTol=1.0e-8
15
20
0
10
12
14
16
18
20
RelTol=1.0e-8
20
15
10
1(t)
10
RelTol=1.0e-12
15
20
10
12
14
16
18
20
20
15
10
10
15
20
10
12
14
16
18
20
t
20
RelTol=1.0e-12
15
10
1(t)
1(t)
10
15
20
10
12
14
16
18
20
15
10
1(t)
10
15
20
10
12
14
16
18
20
RelTol=1.0e-12