Application Center - Maplesoft

App Preview:

Lesson 18: Finite Difference Method

You can switch back to the summary page by clicking here.

Learn about Maple
Download Application


 

Lesson18.mw

ORDINARY DIFFERENTIAL EQUATIONS POWERTOOL

Lesson 18 -- Finite Difference Method

Prof. Douglas B. Meade

Industrial Mathematics Institute

Department of Mathematics

University of South Carolina

Columbia, SC 29208

URL:   http://www.math.sc.edu/~meade/

E-mail: meade@math.sc.edu

Copyright  2001  by Douglas B. Meade

All rights reserved

-------------------------------------------------------------------

>

Outline of Lesson 18

18.A Overview of the Finite Difference Method

18.B Example 1

18.C Example 2

>

Initialization

> restart;

> with( DEtools ):

> with( plots ):

Warning, the name changecoords has been redefined

> interface( rtablesize=25 );

10

>

18.A Overview of the Finite Difference Method

The finite difference method for the two-point boundary value problem

d^2*y/(dx^2)+p(x) dy/dx+q(x)*y = f(x)

 y(a) = r   

 y(b) = s   

with Dirichlet boundary conditions seeks to obtain approximate values of the solution at a collection of nodes, x[k] , in the interval [a, b] . Typically, the interval is uniformly partitioned into N equal subintervals of length h = (b-a)/N . In this case, x[k] = a+k*h for k = 0, 1, ..., N . Let y[k] = y(x[k]) , k = 0, 1, `...`, N , denote the value of the solution at each node. Note that the boundary conditions imply y[0] = r and y[N] = s so there are actually only (N-1 ) unknowns. To determine a system of (N-1 ) equations satisfied by y[1] , y[2] , ..., y[N-1] , replace the first and second derivatives of the unknown function at the interior partion points with the central difference approximations

`y'`(x[k]) = (y[k+1]-y[k-1])/(2*h)            

`y''`(x[k]) = (y[k+1]-2*y[k]+y[k-1])/(h^2)

For linear problems, the resulting system of equations is linear. For nonlinear problems, an iterative method such as Gauss-Seidel is typically used to obtain an approximate solution.

For the Neumann boundary conditions

`y'`(a) = alpha, `y'`(b) = beta

the discretization at each of the N+1 nodes yields N+1 equations in the N+3 unknowns y[-1], y[0], y[1], `...`, y[N-1], y[N], y[N+1] , where the unknowns y[-1] and y[N+1] are introduced by the discretizations at each of the endpoints.  To obtain two additional equations, apply the central difference approximation for the first derivative to the boundary conditions, resulting in the two additional equations

(y[1]-y[-1])/(2*h) = alpha

and

(y[N+1]-y[N-1])/(2*h) = beta

Clearly, the same strategy works for the Robin boundary conditions

y(a)+kappa[a]*`y'`(a) = lambda[a]

y(b)+kappa[b]*`y'`(b) = lambda[b]

as well as the general linear boundary conditions

a[11]*y(a)+a[12]*`y'`(a)+b[11]*y(b)+b[12]*`y'`(b) = B[1]

a[21]*y(a)+a[22]*`y'`(a)+b[21]*y(b)+b[22]*`y'`(b) = B[2]

or for any combination of one type condition at one end and a different type boundary condition at the other end.

>

18.B Example 1

Consider the BVP

> ode1 := diff( y(x), x$2 ) + 2 * diff( y(x), x ) - 10 * y(x) = 7*exp(-x) + 4;

> bc1 := y(0)=2, y(1)=-5;

ode1 := (diff(y(x), `$`(x, 2)))+2*(diff(y(x), x))-10*y(x) = 7*exp(-x)+4

bc1 := y(0) = 2, y(1) = -5

>

with boundary conditions specified at the points

> a := 0;

> b := 1;

a := 0

b := 1

>

To find the finite difference solution to this BVP with

> N := 10;

N := 10

>

subdivisions, we have the nodal spacing

> h := (b-a)/N;

h := 1/10

>

and the nodes

> X   := k -> a+k*h:
'X'[k] = X(k);

X[k] = 1/10*k

>

To simplify the task of writing the nodal equations, define the finite-difference operators

> Yp  := k -> (y[k+1]-y[k-1])/2/h;

> Ypp := k -> (y[k+1]-2*y[k]+y[k-1])/h^2;

>

Yp := proc (k) options operator, arrow; 1/2*(y[k+1]-y[k-1])/h end proc

Ypp := proc (k) options operator, arrow; (y[k+1]-2*y[k]+y[k-1])/h^2 end proc

>

so that the nodal equations at the interior nodes x[1], `...`, x[9] are

> for k from 1 to N-1 do

>  eq[k] := eval( ode1,

>                 {x=X(k), y(x)=y[k],

>                  diff(y(x),x)=Yp(k),

>                  diff(y(x),x$2)=Ypp(k)} );

> end do;

eq[1] := 110*y[2]-210*y[1]+90*y[0] = 7*exp((-1)/10)+4

eq[2] := 110*y[3]-210*y[2]+90*y[1] = 7*exp((-1)/5)+4

eq[3] := 110*y[4]-210*y[3]+90*y[2] = 7*exp((-3)/10)+4

eq[4] := 110*y[5]-210*y[4]+90*y[3] = 7*exp((-2)/5)+4

eq[5] := 110*y[6]-210*y[5]+90*y[4] = 7*exp((-1)/2)+4

eq[6] := 110*y[7]-210*y[6]+90*y[5] = 7*exp((-3)/5)+4

eq[7] := 110*y[8]-210*y[7]+90*y[6] = 7*exp((-7)/10)+4

eq[8] := 110*y[9]-210*y[8]+90*y[7] = 7*exp((-4)/5)+4

eq[9] := 110*y[10]-210*y[9]+90*y[8] = 7*exp((-9)/10)+4

>

The boundary conditions provide the two equations

> eq[0] := y[0] = rhs(bc1[1]);

> eq[N] := y[N] = rhs(bc1[2]);

eq[0] := y[0] = 2

eq[10] := y[10] = -5

>

Even though this system of equations is linear, the exact solution is so cumbersome it's best to obtain an approximate (numeric) solution via fsolve .  Thus, the nodal values are computed to be

> fd_sol1 := fsolve( {seq( eq[k], k=0..N )}, {seq( y[k], k=0..N )} );

fd_sol1 := {y[0] = 2., y[10] = -5., y[5] = -1.776139097, y[6] = -2.241575344, y[4] = -1.313002310, y[7] = -2.754878381, y[3] = -.7962549349, y[8] = -3.357332563, y[2] = -.1510839407, y[9] = -4.0905043...

>

These results are reformatted as points (for plotting) via

> fd_table1 := eval( seq([X(k),y[k]],k=0..N), fd_sol1 );

fd_table1 := [0, 2.], [1/10, .7287947840], [1/5, -.1510839407], [3/10, -.7962549349], [2/5, -1.313002310], [1/2, -1.776139097], [3/5, -2.241575344], [7/10, -2.754878381], [4/5, -3.357332563], [9/10, -...fd_table1 := [0, 2.], [1/10, .7287947840], [1/5, -.1510839407], [3/10, -.7962549349], [2/5, -1.313002310], [1/2, -1.776139097], [3/5, -2.241575344], [7/10, -2.754878381], [4/5, -3.357332563], [9/10, -...

>

and as a table, via

> Matrix([fd_table1]);

Matrix([[0, 2.], [1/10, .7287947840], [1/5, -.1510839407], [3/10, -.7962549349], [2/5, -1.313002310], [1/2, -1.776139097], [3/5, -2.241575344], [7/10, -2.754878381], [4/5, -3.357332563], [9/10, -4.090...

>

Because of the simple nature of this example, Maple is able to determine that the exact solution of this BVP is

> infolevel[dsolve] := 3:

> exact_sol1 := combine(dsolve( { ode1, bc1 }, y(x) ));

> infolevel[dsolve] := 0:

`Methods for second order ODEs:`
`--- Trying classification methods ---`

`trying a quadrature`

`trying high order exact linear fully integrable`

`trying differential order: 2; linear nonhomogeneous with symmetry [0,1]\

`

`trying a double symmetry of the form [xi=0, eta=F(x)]`

`Try solving first the homogeneous part of the ODE`

`   -> Tackling the linear ODE "as given":`

`      checking if the LODE has constant coefficients`

`      <- constant coefficients successful`

`   <- successful solving of the linear ODE "as given"`

`   -> Determining now a particular solution to the non-homogeneous ODE`\

`      building a particular solution using variation of parameters`

`   <- solving first the homogeneous part of the ODE successful`

exact_sol1 := y(x) = (-23/5-167/55*exp(-1-11^(1/2))+7/11*exp(-1))*exp((-1+11^(1/2))*x)/(-exp(-1-11^(1/2))+exp(-1+11^(1/2)))+(167/55*exp(-1+11^(1/2))+23/5-7/11*exp(-1))*exp(-(1+11^(1/2))*x)/(-exp(-1-11...

>

Figure 18.1 is used to compare the exact and finite-difference solutions.

> plot( [rhs(exact_sol1),[fd_table1]], x=a..b,

>      color=[BLACK,GREEN], style=[line,point], symbolsize=16,

>      legend=[`exact`,`finite difference`], title="Figure 18.1" );

[Plot]

>

This also shows good agreement between the finite-difference and exact solutions.

>

18.C Example 2

Consider the BVP

> ode2 := x^2 * diff( y(x), x$2 ) + x * diff( y(x), x ) + 4 * y(x) = -2*x + 7;

> bc2 := y(1)=7, y(4)=-1;

ode2 := x^2*(diff(y(x), `$`(x, 2)))+x*(diff(y(x), x))+4*y(x) = -2*x+7

bc2 := y(1) = 7, y(4) = -1

>

The boundary conditions are given at

> a := 1;

> b := 4;

a := 1

b := 4

>

The finite difference method with

> N := 10;

N := 10

>

subdivisions means the nodal spacing is

> h := (b-a)/N;

h := 3/10

>

and the nodes are

> unassign('k');
X   := k -> a+k*h:

'X'[k] = X(k);

X[k] = 1+3/10*k

>

Again defining the finite-difference operators

> Yp  := k -> (y[k+1]-y[k-1])/2/h;

> Ypp := k -> (y[k+1]-2*y[k]+y[k-1])/h^2;

Yp := proc (k) options operator, arrow; 1/2*(y[k+1]-y[k-1])/h end proc

Ypp := proc (k) options operator, arrow; (y[k+1]-2*y[k]+y[k-1])/h^2 end proc

>

the nodal equations at the interior nodes  x[1], `...`, x[9] are

> for k from 1 to N-1 do

>  eq[k] := eval( ode2,

>                 {x=X(k), y(x)=y[k],

>                  diff(y(x),x)=Yp(k),

>                  diff(y(x),x$2)=Ypp(k)} );

> end do;

eq[1] := 377/18*y[2]-302/9*y[1]+299/18*y[0] = 22/5

eq[2] := 280/9*y[3]-476/9*y[2]+232/9*y[1] = 19/5

eq[3] := 779/18*y[4]-686/9*y[3]+665/18*y[2] = 16/5

eq[4] := 517/9*y[5]-932/9*y[4]+451/9*y[3] = 13/5

eq[5] := 1325/18*y[6]-1214/9*y[5]+1175/18*y[4] = 2

eq[6] := 826/9*y[7]-1532/9*y[6]+742/9*y[5] = 7/5

eq[7] := 2015/18*y[8]-1886/9*y[7]+1829/18*y[6] = 4/5

eq[8] := 1207/9*y[9]-2276/9*y[8]+1105/9*y[7] = 1/5

eq[9] := 2849/18*y[10]-2702/9*y[9]+2627/18*y[8] = (-2)/5

>

The boundary conditions provide the two equations

> eq[0] := y[0] = rhs(bc2[1]);

> eq[N] := y[N] = rhs(bc2[2]);

eq[0] := y[0] = 7

eq[10] := y[10] = -1

>

Even though this system of equations is linear, the exact solution is so cumbersome it's best to obtain an approximate (numeric) solution via fsolve .  Thus, the nodal values are computed to be

> fd_sol2 := fsolve( {seq( eq[k], k=0..N )}, {seq( y[k], k=0..N )} );

fd_sol2 := {y[0] = 7., y[3] = 13.47176924, y[5] = 10.23684928, y[4] = 12.17255258, y[2] = 13.62172773, y[6] = 7.991185491, y[1] = 11.83640952, y[8] = 3.313083031, y[7] = 5.640864412, y[10] = -1., y[9]...

>

These results are reformatted as points (for plotting) via

> fd_table2 := eval( seq([X(k),y[k]],k=0..N), fd_sol2 );

fd_table2 := [1, 7.], [13/10, 11.83640952], [8/5, 13.62172773], [19/10, 13.47176924], [11/5, 12.17255258], [5/2, 10.23684928], [14/5, 7.991185491], [31/10, 5.640864412], [17/5, 3.313083031], [37/10, 1...fd_table2 := [1, 7.], [13/10, 11.83640952], [8/5, 13.62172773], [19/10, 13.47176924], [11/5, 12.17255258], [5/2, 10.23684928], [14/5, 7.991185491], [31/10, 5.640864412], [17/5, 3.313083031], [37/10, 1...

>

and as a table, via

> Matrix( [fd_table2] );

Matrix([[1, 7.], [13/10, 11.83640952], [8/5, 13.62172773], [19/10, 13.47176924], [11/5, 12.17255258], [5/2, 10.23684928], [14/5, 7.991185491], [31/10, 5.640864412], [17/5, 3.313083031], [37/10, 1.0846...

>

Because of the simple nature of this example, Maple is able to determine that the exact solution of this BVP is

> infolevel[dsolve] := 3:

> exact_sol2 := combine(dsolve( { ode2, bc2 }, y(x) ));

> infolevel[dsolve] := 0:

`Methods for second order ODEs:`
`--- Trying classification methods ---`

`trying a quadrature`

`trying high order exact linear fully integrable`

`trying differential order: 2; linear nonhomogeneous with symmetry [0,1]\

`

`trying a double symmetry of the form [xi=0, eta=F(x)]`

`Try solving first the homogeneous part of the ODE`

`   -> Tackling the linear ODE "as given":`

`      checking if the LODE has constant coefficients`

`      checking if the LODE is of Euler type`

`      <- LODE of Euler type successful`

`   <- successful solving of the linear ODE "as given"`

`   -> Determining now a particular solution to the non-homogeneous ODE`\

`      trying a rational particular solution`

`      <- rational particular solution successful`

`   <- solving first the homogeneous part of the ODE successful`

exact_sol2 := y(x) = 1/20*(-23*sin(2*ln(x))-113*sin(2*ln(x)-4*ln(2))+35*sin(4*ln(2))-8*x*sin(4*ln(2)))/sin(4*ln(2))

>

Figure 18.2 is used to compare the exact and finite-difference solutions.

> plot( [rhs(exact_sol2),[fd_table2]], x=a..b,

>      color=[BLACK,GREEN], style=[line,point], symbolsize=16,

>      legend=[`exact`,`finite difference`], title="Figure 18.2" );

[Plot]

>

This also shows good agreement between the finite-difference and exact solutions.

>

[Back to ODE Powertool Table of Contents]

>