Anda di halaman 1dari 65

An Introductory Comparative Study

of Partial Dierential Equation Analysis


in Matlab
1
and R
2
W. E. Schiesser
Lehigh University
Bethlehem, USA
3
Revised
20MAR13
1
Matlab is a product of the Mathworks, Inc. (http://www.mathworks.com)
2
R is an open source scientic programming system (http://www.R-project.org/)
3
Iacocca B312, Lehigh University, 111 Research Drive, Bethlehem, PA 18015 USA;
wes1@lehigh.edu; 610-758-4264
1
Table of Contents
Introduction 3
1.1 Example No. 1 3
1.1.1 ODE routine in Matlab 4
1.1.2 ODE routine in R 7
1.1.3 Main program in Matlab 13
1.1.4 Main program in R 17
1.1.5 Comparison of Matlab and R output 22
1.2 Example No. 2 28
1.2.1 ODE routine in Matlab 30
1.2.2 ODE routine in R 32
1.2.3 Main program in Matlab 37
1.2.4 Main program in R 41
1.2.5 Comparison of Matlab and R output 47
1.3 Conclusions 53
Appendix 1 - Derivation of an analytical solution for example no. 1 54
1.1a Analytical solution by nite Fourier sine transform 54
1.1b Analytical solution by the Greens function 58
References 61
2
Introduction
The intent of this introductory study of partial dierential equation (PDE) analysis is to
provide a comparison of the coding in Matlab and R for a basic or generic PDE. For this
purpose, we have selected as the example PDE variants of the 1D diusion equation.
(1.1) Example No. 1
The 1D diusion equation is
u
t
=

_
D
u
x
_
x
(1.1)
where
Variables Interpretation
parameters
u dependent variable
x boundary value independent variable
t initial value independent variable
D diusivity (a parameter to be specied)
Table 1.1: Variables and parameters in eq. (1.1)
The objective is to compute the solution to eq. (1.1), u(x, t), in numerical form.
Eq. (1.1) is rst order in t and second order in x. It therefore requires one initial
condition (IC) and two boundary conditions (BCs).
u(x, t = 0) = 0 (1.2a)
u(x = 0, t) = 1;
u(x = 1, t)
x
= 0 (1.2b)(1.2c)
BC (1.2b) is termed Dirichlet since the dependent variable u is specied. BC (1.2c) is
termed Neumann since the derivative u/x is specied.
D in eq. (1.1) can be a function of the independent variables x, t and/or the dependent
variable u (D = D(x, t, u)) so that eq. (1.1) can have a variable coecient (D a function
of x, t) or can be nonlinear (D a function of u) or a combination of these cases.
Eqs. (1.1) and (1.2) constitute the complete specication of the example PDE. We
now consider the coding of these equations in a side-by-side format in Matlab and R.
The numerical solutions of eqs. (1.1) and (1.2) are computed using a basic technique,
the method of lines (MOL), in which the spatial derivative terms (e.g., the RHS of eq.
(1.1)) are replaced with algebraic approximations, in this case, nite dierences (FDs)
1
.
3
The spatial variable (x) is thereby represented algebraically on a grid and only one
independent variable (t) remains so that the PDE is replaced with an approximating set
of ordinary dierential equations (ODEs) in the remaining initial value variable (t).
We now consider a routine for the ODE system in Matlab and then in R for compar-
ison
2
.
(1.1.1) ODE routine in Matlab
A MOL/ODE routine for eqs. (1.1) and (1.2) is in Listing 1.1a.
function ut=pde_1(t,u)
%
% Parameters
global xl xu nx ncall ndss ncase
%
% BC at x = 0 (Dirichlet)
u(1)=1;
%
% ux
if (ndss== 2) ux=dss002(xl,xu,nx,u); % second order
elseif(ndss== 4) ux=dss004(xl,xu,nx,u); % fourth order
elseif(ndss== 6) ux=dss006(xl,xu,nx,u); % sixth order
elseif(ndss== 8) ux=dss008(xl,xu,nx,u); % eighth order
elseif(ndss==10) ux=dss010(xl,xu,nx,u); % tenth order
end
%
% BC at x = 1 (Neumann)
ux(nx)=0;
%
% Diffusivity
for i=1:nx
if(ncase==1)D(i)=1 ;end
if(ncase==2)D(i)=u(i) ;end
if(ncase==3)D(i)=exp(u(i));end
ux(i)=D(i)*ux(i);
end
%
% uxx
if (ndss== 2) uxx=dss002(xl,xu,nx,ux); % second order
elseif(ndss== 4) uxx=dss004(xl,xu,nx,ux); % fourth order
1
Other approximations include nite elements, nite volumes, least squares, spectral
elements.
2
An additional comparison of Matlab and R is available from [1]; application of R to
dierential equation numerical integration is discussed in [4].
4
elseif(ndss== 6) uxx=dss006(xl,xu,nx,ux); % sixth order
elseif(ndss== 8) uxx=dss008(xl,xu,nx,ux); % eighth order
elseif(ndss==10) uxx=dss010(xl,xu,nx,ux); % tenth order
end
%
% PDE
ut=uxx;
ut(1)=0;
%
% Increment calls to pde_1
ncall=ncall+1;
Listing 1.1a: ODE Matlab routine for eqs. (1.1) and (1.2)
We can note the following details about Listing 1.1a.
The function and a global area are dened.
function ut=pde_1(t,u)
%
% Parameters
global xl xu nx ncall ndss ncase
The global area is used to access variables and parameters dened numerically in
other routines, and in particular the main program that is discussed subsequently.
BC (1.2b) is implemented at grid point 1 corresponding to x = 0.
%
% BC at x = 0 (Dirichlet)
u(1)=1;
The derivative u/x is computed by a call to one of ve library dierentiation
routines. These routines are available from a download (http://www.pdecomp.net,
v. Compendium book).
%
% ux
if (ndss== 2) ux=dss002(xl,xu,nx,u); % second order
elseif(ndss== 4) ux=dss004(xl,xu,nx,u); % fourth order
elseif(ndss== 6) ux=dss006(xl,xu,nx,u); % sixth order
elseif(ndss== 8) ux=dss008(xl,xu,nx,u); % eighth order
elseif(ndss==10) ux=dss010(xl,xu,nx,u); % tenth order
end
5
For the present case, ndss = 4 is set in the main program (and made available
through the global area) so that fourth order FD approximations in dss004 are
used in calculating the derivative u/x which is placed in the vector ux. The
RHS input parameters of dss004, xl,xu,nx,u, are dened numerically in the main
program. For the rst call to pde 1, u is set by IC (1.2a), and in subsequent calls
to pde 1 by the ODE integrator, ode15s, called in the main program (note that u
is the second input argument of pde 1).
BC (1.2c) is used to reset the derivative u(x = x
u
= 1, t)/x from dss004 (at grid
point nx).
%
% BC at x = 1 (Neumann)
ux(nx)=0;
The diusivity D in eq. (1.1) is dened for three cases, ncase=1,2,3. The value of
ncase is coded in the main program.
%
% Diffusivity
for i=1:nx
if(ncase==1)D(i)=1 ;end
if(ncase==2)D(i)=u(i) ;end
if(ncase==3)D(i)=exp(u(i));end
ux(i)=D(i)*ux(i);
end
These cases correspond to
ncase Diusivity (eq. (1.1))
1 D = constant
2 D = u
3 D = e
u
Table 1.2: Diusivity in eq. (1.1)
The coding demonstrates the ease of handling nonlinearities numerically.
The second derivative in x (the eq. (1.1) RHS) is computed as the derivative of the
rst derivative, so-called stagewise dierentiation.
6
%
% uxx
if (ndss== 2) uxx=dss002(xl,xu,nx,ux); % second order
elseif(ndss== 4) uxx=dss004(xl,xu,nx,ux); % fourth order
elseif(ndss== 6) uxx=dss006(xl,xu,nx,ux); % sixth order
elseif(ndss== 8) uxx=dss008(xl,xu,nx,ux); % eighth order
elseif(ndss==10) uxx=dss010(xl,xu,nx,ux); % tenth order
end
Since this second derivative in the vector uxx is then the RHS of eq. (1.1), it can
be used next to program eq. (1.1).
The following code illustrates the ease of the MOL programming of eq. (1.1).
%
% PDE
ut=uxx;
ut(1)=0;
Here we have used the Matlab vector utility (rather than subscripting). The trans-
pose ensures ut is returned as a column vector as required by the ODE inte-
grator ode15s. Also, since BC (1.2b) species u(x = 0, t) = 1, the derivative
u(x = 0, t)/t = 0 which is programmed to ensure the ODE integrator ode15s
does not move u(x = 0, t) away from its specied value. In other words, the ODE
at x = 0 is dened by BC (1.2b) rather than by PDE (1.1).
Finally, the number of calls to pde 1 is incremented (and returned to the main
program as a global variable).
%
% Increment calls to pde_1
ncall=ncall+1;
This completes the programming of eqs. (1.1), (1.2b) and (1.2c). The only remaining
requirement is the programming of IC (1.2a) which is in the main program discussed
subsequently.
We now consider the equivalent ODE routine programmed in R.
(1.1.2) ODE routine in R
A MOL/ODE routine in R for eqs. (1.1) and (1.2) is in Listing 1.1b.
pde_1=function(t,u,parms){
#
# BC at x = 0 (Dirichlet)
u[1]=1;
7
#
# ux
if (ndss== 2){ux=dss002(xl,xu,nx,u); # second order
}else if(ndss== 4){ux=dss004(xl,xu,nx,u); # fourth order
}else if(ndss== 6){ux=dss006(xl,xu,nx,u); # sixth order
}else if(ndss== 8){ux=dss008(xl,xu,nx,u); # eighth order
}else if(ndss==10){ux=dss010(xl,xu,nx,u); # tenth order
}
#
# BC at x = 1 (Neumann)
ux[nx]=0;
#
# Diffusivity
D=rep(0,nx);
for(i in 1:nx){
if(ncase==1){D[i]=1 ;}
if(ncase==2){D[i]=u[i] ;}
if(ncase==3){D[i]=exp(u[i]);}
ux[i]=D[i]*ux[i];
}
#
# uxx
if (ndss== 2){uxx=dss002(xl,xu,nx,ux); # second order
}else if(ndss== 4){uxx=dss004(xl,xu,nx,ux); # fourth order
}else if(ndss== 6){uxx=dss006(xl,xu,nx,ux); # sixth order
}else if(ndss== 8){uxx=dss008(xl,xu,nx,ux); # eighth order
}else if(ndss==10){uxx=dss010(xl,xu,nx,ux); # tenth order
}
#
# PDE
ut=rep(0,nx);
ut=uxx;
ut[1]=0;
#
# Increment calls to pde_1
ncall <<- ncall+1;
#
# Return derivative vector
return(list(c(ut)));
}
Listing 1.1b: ODE R routine for eqs. (1.1) and (1.2)
We can now make a comparsion of Listings 1.1a and 1.1b.
Each routine starts with a function denition.
8
Matlab
function ut=pde_1(t,u)
%
% Parameters
global xl xu nx ncall ndss ncase
R
pde_1=function(t,u,parms){
In the case of Matlab, a global area is dened. For R, variables and parameters
dened in the superior routine, in this case, the main program, are automatically
available to the subordinate routine.
The programming of BC (1.2b) is similar in both systems
Matlab
%
% BC at x = 0 (Dirichlet)
u(1)=1;
R
#
# BC at x = 0 (Dirichlet)
u[1]=1;
Note the use of % for a comment and ( ) for an array in Matlab; in R, these are #
and [ ].
The calculation of the rst derivative u/x is similar in the two systems.
Matlab
%
% ux
if (ndss== 2) ux=dss002(xl,xu,nx,u); % second order
elseif(ndss== 4) ux=dss004(xl,xu,nx,u); % fourth order
elseif(ndss== 6) ux=dss006(xl,xu,nx,u); % sixth order
elseif(ndss== 8) ux=dss008(xl,xu,nx,u); % eighth order
elseif(ndss==10) ux=dss010(xl,xu,nx,u); % tenth order
end
9
R
#
# ux
if (ndss== 2){ux=dss002(xl,xu,nx,u); # second order
}else if(ndss== 4){ux=dss004(xl,xu,nx,u); # fourth order
}else if(ndss== 6){ux=dss006(xl,xu,nx,u); # sixth order
}else if(ndss== 8){ux=dss008(xl,xu,nx,u); # eighth order
}else if(ndss==10){ux=dss010(xl,xu,nx,u); # tenth order
}
The if - else if - else syntax is slightly dierent, including the use of end in
Matlab and } in R.
The programming of BC (1.2c) is similar.
Matlab
%
% BC at x = 1 (Neumann)
ux(nx)=0;
R
#
# BC at x = 1 (Neumann)
ux[nx]=0;
The programming of the diusivity for the three cases ncase=1,2,3 and the linear
(ncase=1) or nonlinear (ncase=2,3) function in eq. (1.1), Du/x, is within a for.
Note the dierence in the syntax of the for, i.e., for i=1:nx for Matlab and for(i
in 1:nx) for R. Also, the for in Matlab is concluded with end while in R, it is
concluded with }.
Matlab
%
% Diffusivity
for i=1:nx
if(ncase==1)D(i)=1 ;end
if(ncase==2)D(i)=u(i) ;end
if(ncase==3)D(i)=exp(u(i));end
10
ux(i)=D(i)*ux(i);
end
R
#
# Diffusivity
D=rep(0,nx);
for(i in 1:nx){
if(ncase==1){D[i]=1 ;}
if(ncase==2){D[i]=u[i] ;}
if(ncase==3){D[i]=exp(u[i]);}
ux[i]=D[i]*ux[i];
}
Note that Matlab automatically (dynamically) allocates (denes) the array D while R
requires that the array is declared (preallocated) before it is used, that is, D=rep(0,nx).
rep is a R utility that in this case sets the nx elements of D to zero. These values of
D are then set to the required values for the calculation, but D must rst be declared.
ux was declared by the call to a dss routine (in this case, dss004 since ndss=4 from
the main program in Listing 1.2b to follow) so that the use of rep was not required.
The programming of the second derivative (with the linear/nonlinear diusivity
function) is similar to the programming of the rst derivative.
Matlab
%
% uxx
if (ndss== 2) uxx=dss002(xl,xu,nx,ux); % second order
elseif(ndss== 4) uxx=dss004(xl,xu,nx,ux); % fourth order
elseif(ndss== 6) uxx=dss006(xl,xu,nx,ux); % sixth order
elseif(ndss== 8) uxx=dss008(xl,xu,nx,ux); % eighth order
elseif(ndss==10) uxx=dss010(xl,xu,nx,ux); % tenth order
end
R
#
# uxx
if (ndss== 2){uxx=dss002(xl,xu,nx,ux); # second order
}else if(ndss== 4){uxx=dss004(xl,xu,nx,ux); # fourth order
11
}else if(ndss== 6){uxx=dss006(xl,xu,nx,ux); # sixth order
}else if(ndss== 8){uxx=dss008(xl,xu,nx,ux); # eighth order
}else if(ndss==10){uxx=dss010(xl,xu,nx,ux); # tenth order
}
The calculation of the second derivative uxx is by dierentiation of the rst derivative
ux, that is, by stagewise dierentiation.
The programming of eq. (1.1) is similar in the two systems.
Matlab
%
% PDE
ut=uxx;
ut(1)=0;
R
#
# PDE
ut=rep(0,nx);
ut=uxx;
ut[1]=0;
For Matlab, a transpose of u is required for the integrator ode15s. For R, the vector
of derivatives ut must rst be declared (with a rep). In both cases, the vector utility
is used so the programming of ut can be accomplished with a single line of code
(without subscripting). Also, in both cases, the derivative in t at x = 0 is set to
zero for the Neumann BC (1.2b).
The number of calls to the ODE routine is incremented. For Matlab, the new value
of ncall is returned to the main program through the global area. For R this value
is returned with <<-.
Matlab
%
% Increment calls to pde_1
ncall=ncall+1;
R
12
#
# Increment calls to pde_1
ncall <<- ncall+1;
In Matlab, the computed derivative vector, ut, is returned through the LHS argu-
ment of pde 1. In R, the derivative vector is returned as a list. Note also the use
of the R vector utility c. That is, ut is declared a vector, then a list, and nally
is returned. This format for the return is required by the R ODE integrators in
the library deSolve [4] (including lsodes used in the R main program discussed
subsequently).
Matlab
ut returned as the LHS argument
R
#
# Return derivative vector
return(list(c(ut)));
}
The nal } concludes pde 1 in R.
This completes the programming of the ODE routine in R. The main programs that
called the ODE routines are considered next.
(1.1.3) Main program in Matlab
The main program in Matlab that calls the ODE routine pde 1 in Listing 1.1a is in
Listing 1.2a.
%
% Clear previous files
clear all
clc
%
% Parameters shared with the ODE routine
global xl xu nx ncall ndss ncase
%
% Grid in x, initial condition
xl=0;xu=1;nx=26;
for ix=1:nx
xg(ix)=(xu-xl)*(ix-1)/(nx-1);
13
u0(ix)=0;
end
%
% Independent variable for ODEs
t0=0.0;tf=1.5;nout=11;
tout=linspace(t0,tf,nout);
ncall=0;
%
% ODE integration
ncase=1;ndss=4;
[t,u]=ode15s(@pde_1,tout,u0);
%
% Display selected output
for it=1:nout
if(it==1);u(it,1)=0;end
if(it> 1);u(it,1)=1;end
fprintf(\n t x u(x,t)\n);
for ix=1:5:nx
fprintf(%7.2f%8.2f%12.5f\n,t(it),xg(ix),u(it,ix));
end
end
fprintf(\n ncall = %4d\n,ncall);
%
% Plot numerical solution
figure(1);
plot(xg,u);
xlabel(x);ylabel(u(x,t));
title(u(x,t) vs x, t=0,0.15,...,1.5);
Listing 1.2a: Main program that calls pde 1 of Listing 1.1a
We can note the following details about Listing 1.2a.
Previous les are cleared and a global area is dened.
%
% Clear previous files
clear all
clc
%
% Parameters shared with the ODE routine
global xl xu nx ncall ndss ncase
The global area provides for a sharing of variables and parameters between routines,
in this case, between the main program of Listing 1.2a and the ODE routine of
Listing 1.1a.
14
A grid in x of 26 points is dened for 0 x 1. The grid point values are then
placed in array xg and the IC vector of eq. (1.2a) is placed in array u0.
%
% Grid in x, initial condition
xl=0;xu=1;nx=26;
for ix=1:nx
xg(ix)=(xu-xl)*(ix-1)/(nx-1);
u0(ix)=0;
end
Here we have used a for with subscripting, which was selected to facilitate a com-
parison with the R code to follow. Other Matlab utilities could have been used. For
example, xg could be dened numerically with
xg=[xl:(xu-xl)/(nx-1):xu];
in place of the for where a transpose () has been used to convert xg to a column
vector. Similarly, the IC vector could have been coded as
u0=zeros(nx,1);
which species a vector u0 of zeros with nx rows and 1 column.
The vector of output values of t, tout, is dened by the Matlab utility linspace
for 0 t 1.5 with 11 values (including at t = 0).
%
% Independent variable for ODEs
t0=0.0;tf=1.5;nout=11;
tout=linspace(t0,tf,nout);
ncall=0;
In other words, tout has the values t = 0, 0.15, ..., 1. Finally, the counter for the
calls to pde 1 in Listing 1.1a is initialized.
The 26 ODEs are integrated by a call to ode15s, a sti integrator with a variety of
options. In this, only the default options are used.
%
% ODE integration
ncase=1;ndss=4;
[t,u]=ode15s(@pde_1,tout,u0);
15
Also, ncase is specied to select the diusivity in pde 1 of Listing 1.1a. ndss =
4 selects the dss004 dierentiator in Listing 1.1a. ncase and ndss are passed to
pde 1 as global parameters.
In the call to ode15s, note the use of pde 1 in Listing 1.1a, the vector of output
values of t, tout, and the IC vector u0. Generally, the order of these inputs must
be maintained as used here when calling ode15s. The solution is returned as t, a
vector of values of t in tout, and u, a 2D array with dimensions u(11,26) for the
11 values of t and the 26 corresponding ODE solutions.
The numerical ODE solution is displayed with fprintf. First, the value of u(x =
0, t) is set according to IC (1.2a) for t = 0 and according to BC (1.2b) for t > 0. The
reason this is required is because the Matlab integrators in general do not return a
dependent variable that is set algebraically rather than by the integration of an ODE.
Thus, u(x = 0) is dened algebraically in pde 1 of Listing 1.1a for use with the MOL,
but this value is not returned to the main program of Listing 1.2a and therefore must
be dened explicitly in the main program. Also, the distinction between it=1 for
t = 0 and it>1 for t > 0 is required because there is an inconsistency between IC
(1.2a) and BC (1.2b). This amounts to a nite unit step or discontinuity which can
be handled computationally because eq. (1.1) is parabolic and therefore tends to
smooth discontinuities (generally, this would not happen with hyperbolic PDEs).
%
% Display selected output
for it=1:nout
if(it==1);u(it,1)=0;end
if(it> 1);u(it,1)=1;end
fprintf(\n t x u(x,t)\n);
for ix=1:5:nx
fprintf(%7.2f%8.2f%12.5f\n,t(it),xg(ix),u(it,ix));
end
end
fprintf(\n ncall = %4d\n,ncall);
Note that the for in ix displays only every fth value of the solution (for ix=1:5:nx)
to keep the displayed output to a modest size (that is, u(x, t) for x = 0, 0.20, ..., 10).
Finally, the number of calls to pde 1 of Listing 1.1a is displayed as an indication
of the eort required to compute a solution. Note that in general Matlab denes a
character string with a single quote () while this is done with a double quote (")
in R.
A plot of u(x, t) against x is produced with a single call to the Matlab utility plot
which matches the dimension of xg (26) with the second dimension of u (also 26)
as dened by the ODE integrator, ode15s. In this way, t becomes a parameter in
the plotting with a series of nout=11 curves through the rst dimension of u (11).
16
%
% Plot numerical solution
figure(1);
plot(xg,u);
xlabel(x);ylabel(u(x,t));
title(u(x,t) vs x, t=0,0.15,...,1.5);
Labeling of the horizontal and vertical axes, and a title for the plot are also added.
This completes the programming of eqs. (1.1), (1.2b) and (1.2c). The only remaining
requirement is the programming of IC (1.2a) which is in the main program discussed
subsequently.
(1.1.4) Main program in R
The main program in R is considered next with a comparison of equivalent statements
from Listing 1.2a.
#
# Access ODE integrator
library("deSolve");
#
# Access functions
setwd("c:/R/pde_intro");
source("pde_1.R");
source("dss004.R");
#
# Grid in x, initial condition
xl=0;xu=1;nx=26;
xg=rep(0,nx);u0=rep(0,nx);
for(ix in 1:nx){
xg[ix]=(xu-xl)*(ix-1)/(nx-1);
u0[ix]=0;
}
#
# Independent variable for ODEs
t0=0;tf=1.5;nout=11;
tout=seq(from=0,to=tf,by=(tf-t0)/(nout-1));
ncall=0;
#
# ODE integration
ncase=1;ndss=4;
out=lsodes(y=u0,times=tout,func=pde_1,parms=NULL)
#
# Display selected output
17
for(it in 1:nout){
if(it==1){out[it,2]=0;}
if(it> 1){out[it,2]=1;}
cat(sprintf("\n t x u(x,t)\n"));
for(ix in 1:nx){
if((ix-1)*(ix- 6)*(ix-11)*(ix-16)
*(ix-21)*(ix-26)==0){
cat(sprintf("%7.2f%8.2f%12.5f\n",
out[it,1],xg[ix],out[it,ix+1]));
}
}
}
cat(sprintf("\n ncall = %4d\n",ncall));
#
# Plot numerical solution
par(mfrow=c(1,1));
matplot(x=xg,y=t(out[,-1]),type="l",xlab="x",
ylab="u(x,t) vs x, t=0,0.15,...,1.5",xlim=c(xl,xu),
main="u(x,t) vs x, t=0,0.15,...,1.5;",lty=1,lwd=2);
Listing 1.2b: Main program that calls pde 1 of Listing 1.1b
We can note the following details of Listing 1.2b with a comparison of the equivalent
Matlab statements in Listing 1.2a.
Some preliminaries are rst programmed.
Matlab
%
% Clear previous files
clear all
clc
%
% Parameters shared with the ODE routine
global xl xu nx ncall ndss ncase
R
#
# Access ODE integrator
library("deSolve");
#
# Access functions
18
setwd("c:/R/pde_intro");
source("pde_1.R");
source("dss004.R");
The Matlab statements have already been considered (in Section (1.1.3)). The R
statements access the ODE library deSolve followed by the ODE routine pde 1 of
Listing 1.1b and the library dierentiator dss004. The setwd utility (set working
directory) species the location of these two les (note the use of the forward slash,
/, rather than the usual backslash \).
The grid in x has 26 points for 0 x 1.
Matlab
%
% Grid in x, initial condition
xl=0;xu=1;nx=26;
for ix=1:nx
xg(ix)=(xu-xl)*(ix-1)/(nx-1);
u0(ix)=0;
end
R
#
# Grid in x, initial condition
xl=0;xu=1;nx=26;
xg=rep(0,nx);u0=rep(0,nx);
for(ix in 1:nx){
xg[ix]=(xu-xl)*(ix-1)/(nx-1);
u0[ix]=0;
}
For the R code, the grid in x xg and the IC array u0 are rst declared (preal-
located) with a rep. Alternative R coding for the grid can be considered, e.g.,
xg=seq(from=xl,to=xu,by=(xu-xl)*(ix-1)/(nx-1)) based on the R utility seq.
u0 is already an nx-vector of zeros from u0=rep(0,nx) and therefore does not require
the programming in the for.
The output points in t are specied.
Matlab
%
19
% Independent variable for ODEs
t0=0.0;tf=1.5;nout=11;
tout=linspace(t0,tf,nout);
ncall=0;
R
#
# Independent variable for ODEs
t0=0;tf=1.5;nout=11;
tout=seq(from=0,to=tf,by=(tf-t0)/(nout-1));
ncall=0;
Note the use of seq for R in place of linspace for Matlab.
The ODE integration in R is by lsodes ([4]).
Matlab
%
% ODE integration
ncase=1;ndss=4;
[t,u]=ode15s(@pde_1,tout,u0);
R
#
# ODE integration
ncase=1;ndss=4;
out=lsodes(y=u0,times=tout,func=pde_1,parms=NULL)
The @ in the rst RHS argument of ode15s indicates this argument is a function
(pde 1 of Listing 1.1a) rather than a parameter or variable. The solution array
from lsodes, out ([4]), contains both the 11 values of t and the 26 ODE solutions.
Therefore, the dimensions of out are out(11,27). The second dimension in out is
27 rather than 26 to include t as explained next. Note the use of the IC vector,
u0, the vector of output values of t, tout, and the ODE routine, pde 1 in Listing
1.1b. The argument parms (to pass parameters to the ODE routine) is unused.
y,times,func,parms are reserved names for lsodes.
An alternative for the ODE integration is
ode(y=u0,times=tout,func=pde_1,parms=NULL)
20
The R utility ode uses the integrator lsoda as the default. lsoda switches between
a nonsti and sti integrator depending on an eigenvalue analysis (the a stands
for automatic).
lsoda and lsodes have a variety of options as explained in the R documentation.
Here we have used the defaults for lsodes.
The numerical solution is displayed in a similar way for Matlab and R.
Matlab
%
% Display selected output
for it=1:nout
if(it==1);u(it,1)=0;end
if(it> 1);u(it,1)=1;end
fprintf(\n t x u(x,t)\n);
for ix=1:5:nx
fprintf(%6.2f%8.3f%10.5f\n,t(it),xg(ix),u(it,ix));
end
end
fprintf(\n ncall = %4d\n,ncall);
R
#
# Display selected output
for(it in 1:nout){
if(it==1){out[it,2]=0;}
if(it> 1){out[it,2]=1;}
cat(sprintf("\n t x u(x,t)\n"));
for(ix in 1:nx){
if((ix-1)*(ix- 6)*(ix-11)*(ix-16)
*(ix-21)*(ix-26)==0){
cat(sprintf("%7.2f%8.2f%12.5f\n",
out[it,1],xg[ix],out[it,ix+1]));
}
}
}
cat(sprintf("\n ncall = %4d\n",ncall));
Note the use of out[it,2] for u(x = 0, t) in the R coding since out[it,1] references
t. Thus, out[it,27] references u(x = 1, t). Also, the output is for every fth value
of x, that is, x = 0, 0.2, ..., 1 through the use of the if in ix. A comparsion of the
21
Matlab and R numerical output is given subsequently. The nal value of the number
of calls to pde 1 in Listing 1.1b is displayed.
The plotting in R is by the matplot utility. A 1 1 array of plots, that is, a single
plot, is specied with par(mfrow=c(1,1)).
Matlab
%
% Plot numerical solution
figure(1);
plot(xg,u);
xlabel(x);ylabel(u(x,t));
title(u(x,t) vs x, t=0,0.15,...,1.5);
R
#
# Plot numerical solution
par(mfrow=c(1,1));
matplot(x=xg,y=t(out[,-1]),type="l",xlab="x",
ylab="u(x,t) vs x, t=0,0.15,...,1.5",xlim=c(xl,xu),
main="u(x,t) vs x, t=0,0.15,...,1.5;",lty=1,lwd=2);
The labeling of the plots in Matlab and R is similar. matplot has additional param-
eters for specifying the line type and the horizontal axis limits. The vertical axis is
scaled as a default (ylim is also available).
This concludes the R programming for eqs. (1.1) and (1.2). The output from Listings 1.1a
and 1.2a for Matlab, and Listings 1.1b and 1.2b for R, is now discussed and compared.
(1.1.5) Comparison of Matlab and R output
Abbreviated output from Listings 1.1a and 1.2a is given in Table 1.3.
t x u(x,t)
0.00 0.00 0.00000
0.00 0.20 0.00000
0.00 0.40 0.00000
0.00 0.60 0.00000
0.00 0.80 0.00000
0.00 1.00 0.00000
.
.
22
(output for t = 0.15
to 0.30 removed)
.
.
t x u(x,t)
0.45 0.00 1.00000
0.45 0.20 0.87040
0.45 0.40 0.75347
0.45 0.60 0.66065
0.45 0.80 0.60105
0.45 1.00 0.58052
.
.
(output for t = 0.60
to 1.35 removed)
.
.
t x u(x,t)
1.50 0.00 1.00000
1.50 0.20 0.99033
1.50 0.40 0.98160
1.50 0.60 0.97467
1.50 0.80 0.97022
1.50 1.00 0.96869
ncall = 154
Table 1.3: Output from Listings, 1.1a 1.2a for ncase=1 (D = 1)
We can note the following details about this output.
IC (1.2a) (t = 0) is correct. This is perhaps an obvious detail, but checking the IC
is always a good idea since if it is incorrect, the remainder of the numerical output
will also be incorrect.
BC (1.2b) (x = 0, t > 0) is correct. This is also an important detail since it is this
unit value that drives the entire system of 26 away from the zero initial value.
The solution approaches u(x, t ) = 1 which is the correct exact solution (see
eqs. (1.3)). Note in particular that this constant, unit value satises eqs. (1.1) and
(1.2).
The computational eort is quite modest with ncall = 154.
Abbreviated output from Listings 1.1b and 1.2b is given in Table 1.4
23
t x u(x,t)
0.00 0.00 0.00000
0.00 0.20 0.00000
0.00 0.40 0.00000
0.00 0.60 0.00000
0.00 0.80 0.00000
0.00 1.00 0.00000
.
.
(output for t = 0.15
to 0.30 removed)
.
.
t x u(x,t)
0.45 0.00 1.00000
0.45 0.20 0.87036
0.45 0.40 0.75342
0.45 0.60 0.66064
0.45 0.80 0.60107
0.45 1.00 0.58055
.
.
(output for t = 0.60
to 1.35 removed)
.
.
t x u(x,t)
1.50 0.00 1.00000
1.50 0.20 0.99028
1.50 0.40 0.98152
1.50 0.60 0.97456
1.50 0.80 0.97009
1.50 1.00 0.96855
ncall = 230
Table 1.4: Output from Listings 1.1b 1.2b for ncase=1 (D = 1)
Again, the details for Table 1.3 apply to Table 1.4. The computational eort is modest
with ncall = 230.
The two solutions in Tables 1.3, 1.4 are compared in Table 1.5 at t = 0.45.
Matlab (Table 1.3)
t x u(x,t)
24
0.45 0.00 1.00000
0.45 0.20 0.87040
0.45 0.40 0.75347
0.45 0.60 0.66065
0.45 0.80 0.60105
0.45 1.00 0.58052
R (Table 1.4)
t x u(x,t)
0.45 0.00 1.00000
0.45 0.20 0.87036
0.45 0.40 0.75342
0.45 0.60 0.66064
0.45 0.80 0.60107
0.45 1.00 0.58055
Table 1.5: Comparison of the numerical solutions at t = 0.45
The two solutions agree to four gures where they are changing relatively rapidly (at
t = 0.45). The graphical output is in Figs. 1.1 (Matlab) and 1.2 (R) (placed at the end).
The two plots have essentially the same features. The dierences are due to dierent
plotting utilities, plot for Matlab and matplot for R.
The following analytical solution to eqs. (1.1) and (1.2) is derived in Appendix 1,
u(x, t) = 1 2

i=1
1

i
e
(
2
i
/L
2
)t
sin(
i
x/L) (1.3a)
with the eigenvalues

i
= (i 1/2), i = 1, 2, ... (1.3b)
The approach to the steady state (equilibrium) solution u(x, t ) = 1 (from eq.
(1.3a)) is clear in Figs. 1.1 and 1.2. A comparison of the analytical and numerical
solutions follows.
R (Table 1.4)
t x u(x,t)
0.45 0.00 1.00000
0.45 0.20 0.87036
0.45 0.40 0.75342
0.45 0.60 0.66064
0.45 0.80 0.60107
0.45 1.00 0.58055
25
Analytical solution
(eqs. (1.3))
t x u(x,t)
0.45 0.00 1.00000
0.45 0.20 0.87036
0.45 0.40 0.75342
0.45 0.60 0.66064
0.45 0.80 0.60107
0.45 1.00 0.58055
Table 1.6: Comparison of the numerical and analytical solutions
The agreement in Table 1.6 is to ve gures, which is perhaps unexpected with only 26
points in x (26 ODEs). An R routine for the calculation of the analytical solution values
in Table 1.6 is listed in the Appendix.
For ncase=2,3 in Listings 1.1 and 1.2 (for D = u, D = e
u
as programmed in List-
ings 1.1), analytical soltions are not readily available for comparison with the numerical
solutions. These cases illustrate the ease of computing the solution to a nonlinear PDE
when an analytical solution may not be available.
Abbreviated numerical output from Listing 1.2b for ncase=2,3 is given in Tables 1.7,
1.8.
t x u(x,t)
0.00 0.00 0.00000
0.00 0.20 0.00000
0.00 0.40 0.00000
0.00 0.60 0.00000
0.00 0.80 0.00000
0.00 1.00 0.00000
.
.
(output for t = 0.15
to 0.30 removed)
.
.
t x u(x,t)
0.45 0.00 1.00000
0.45 0.20 0.85877
0.45 0.40 0.69904
0.45 0.60 0.51985
0.45 0.80 0.32228
0.45 1.00 0.17349
.
26
.
(output for t = 0.60
to 1.35 removed)
.
.
t x u(x,t)
1.50 0.00 1.00000
1.50 0.20 0.97933
1.50 0.40 0.96021
1.50 0.60 0.94467
1.50 0.80 0.93450
1.50 1.00 0.93096
ncall = 584
Table 1.7: Output from Listings 1.1b, 1.2b for ncase=2 (D = u)
We note in particular that u(x, t) has not approached the equilibrium solution u(x, t
) = 1 at t = 1.50 as closely for ncase=2 as for ncase=1 in Table 1.4. This is as expected
since for ncase=2 and D = u, 0 u 1 which gives 0 D 1, while for ncase=1,
D = 1. Thus, for ncase=2, the diusivity is lower and therefore the rate of diusion is
lower. This results in a slower response to u(x, t) = 1. This slower response is evident
from comparing Figs. 1.2 and 1.3.
Also, the number of calls to pde 1 increased from 230 for ncase=1 to 584 for ncase=2.
This increase can be attributed to the greater computational eort for the integration
of the 26 nonlinear ODEs (ncase=2) than is required for the linear ODEs of case=1. In
particular, the Newton solver in lsodes requires more iterations for convergence in the
nonlinear case.
t x u(x,t)
0.00 0.00 0.00000
0.00 0.20 0.00000
0.00 0.40 0.00000
0.00 0.60 0.00000
0.00 0.80 0.00000
0.00 1.00 0.00000
.
.
(output for t = 0.15
to 0.30 removed)
.
.
t x u(x,t)
0.45 0.00 1.00000
0.45 0.20 0.96808
27
0.45 0.40 0.93819
0.45 0.60 0.91359
0.45 0.80 0.89734
0.45 1.00 0.89165
.
.
(output for t = 0.60
to 1.35 removed)
.
.
t x u(x,t)
1.50 0.00 1.00000
1.50 0.20 0.99997
1.50 0.40 0.99994
1.50 0.60 0.99992
1.50 0.80 0.99990
1.50 1.00 0.99990
ncall = 423
Table 1.8: Output from Listings 1.1b, 1.2b for ncase=3 (D = e
u
)
We note in particular that u(x, t) has approached the equilibrium solution u(x, t ) =
1 at t = 1.50 more closely for ncase=3 than for ncase=1 in Table 1.4. This is as expected
since for ncase=3 and D = e
u
, 0 u 1 which gives 1 D e, while for ncase=1,
D = 1. Thus, for ncase=3, the diusivity is higher and therefore the rate of diusion is
higher. This results in a faster response to u(x, t) = 1. This faster response is evident
from comparing Figs. 1.2 and 1.4.
Also, the number of calls to pde 1 increased from 230 for ncase=1 to 423 for ncase=3.
Again, this increase can be attributed to the greater computational eort for the integra-
tion of the 26 nonlinear ODEs (ncase=3) than is required for the linear ODEs of case=1.
In particular, the Newton solver in lsodes requires more iterations for convergence in
the nonlinear case.
(1.2) Example No. 2
The PDE considered as the second example is the following nonlinear form of the diusion
equation.
u
t
=
u
x

2
u
x
2
(1.5a)
The dependent variable, u(x, t), and the independent variables, x and t, are explained in
Table 1.1.
Eq. (1.5) is rst order in t and second order in x so it requires one IC and two BCs.
28
u(x, t = 0) = f(x) (1.6a)
u(x
l
, t)
x
=
u(x
u
, t)
x
= 0 (1.6b,c)
Eqs (1.6b,c) require some additional discussion.
BCs (1.6b,c) are Neumann since the derivative u/x is specied at the boundaries,
x = x
l
, x
u
. However, this derivative is also a nonlinear coecient in eq. (1.5a) so
that at the boundaries,
u(x = x
l
, t)
t
=
u(x = x
u
, t)
t
= 0 (1.6d,e)
Eqs. (1.6d,e) in eect specify Dirichlet BCs since they can be integrated to give
u(x = x
l
, t) = c
l
; u(x = x
u
, t) = c
u
; (1.6f,g)
where c
l
, c
u
are specied constants. In other words, the dependent variable u(x, t)
is specied at the boundaries corresponding to Dirichlet BCs.
This conclusion raises the question of how the BCs in the MOL analysis should be
implemented (coded). There are two possibilities:
The BCs can be implemented without using the PDE. For example, this is
usually done with Dirichlet BCs (just the dependent variable at the boundaries
is used).
The PDE can be used at the boundaries with the BCs included in the approxi-
mation of the PDE. For example, this is usually done with Neumann and third
type BCs. We now consider this second approach for BCs (1.6f,g) with f(x) in
eq. (1.6a) taken as a unit step.
Since BCs (1.6f,g) are used, BCs (1.6b,c) are not actually observed in the solution.
This apparent contradiction results from the nonlinear coecient of eq. (1.5a). To
demonstrate this, a solution is also computed for the linear diusion equation
u/t =
2
u/x
2
(1.5b)
for which BCs (1.6b,c) are clearly observed.
The Matlab programming of eqs. (1.5) and (1.6) is in Listing 1.3a that follows.
29
(1.2.1) ODE routine in Matlab
The following programming of eqs. (1.5) and (1.6) is analogous to Listing 1.1a.
function ut=pde_1(t,u)
%
% Parameters
global xl xu nx ncall ndss ncase
%
% ux
if (ndss== 2) ux=dss002(xl,xu,nx,u); % second order
elseif(ndss== 4) ux=dss004(xl,xu,nx,u); % fourth order
elseif(ndss== 6) ux=dss006(xl,xu,nx,u); % sixth order
elseif(ndss== 8) ux=dss008(xl,xu,nx,u); % eighth order
elseif(ndss==10) ux=dss010(xl,xu,nx,u); % tenth order
end
%
% BCs (Neumann)
ux(1) =0;
ux(nx)=0;
nl=2;nu=2;
%
% uxx
if (ndss== 2) uxx=dss042(xl,xu,nx,u,ux,nl,nu); % second order
elseif(ndss== 4) uxx=dss044(xl,xu,nx,u,ux,nl,nu); % fourth order
elseif(ndss== 6) uxx=dss046(xl,xu,nx,u,ux,nl,nu); % sixth order
elseif(ndss== 8) uxx=dss048(xl,xu,nx,u,ux,nl,nu); % eighth order
elseif(ndss==10) uxx=dss050(xl,xu,nx,u,ux,nl,nu); % tenth order
end
%
% PDE
for(i=1:nx)
if(ncase==1)ut(i)=ux(i)^2*uxx(i);end
if(ncase==2)ut(i)=uxx(i);end
end
ut=ut;
%
% Increment calls to pde_1
ncall=ncall+1;
Listing 1.3a: ODE Matlab routine for eqs. (1.5) and (1.6)
We can note the following details about Listing 1.3a.
The function and a global area are dened.
30
function ut=pde_1(t,u)
%
% Parameters
global xl xu nx ncall ndss ncase
The rst derivative in eq. (1.5a), u/x, is computed by a call to one of ve rst
derivative routines, dss002 to dss010, as selected by ndss set in the main program
to follow. For the purpose of the subsequent calculations, ndss=4. Also, nx=21 and
xl=0,xu=1 are dened in the main program. Note that these parameters are passed
as global to pde 1.
%
% ux
if (ndss== 2) ux=dss002(xl,xu,nx,u); % second order
elseif(ndss== 4) ux=dss004(xl,xu,nx,u); % fourth order
elseif(ndss== 6) ux=dss006(xl,xu,nx,u); % sixth order
elseif(ndss== 8) ux=dss008(xl,xu,nx,u); % eighth order
elseif(ndss==10) ux=dss010(xl,xu,nx,u); % tenth order
end
BCs (1.6b,c) are implemented.
%
% BCs (Neumann)
ux(1) =0;
ux(nx)=0;
nl=2;nu=2;
nl=nu=2 species Neumann BCs to the second derivative routines (nl=nu=1 specify
Dirichlet BCs).
The second derivative in eqs. (1.5),
2
u/x
2
, is computed by a call to one of ve
second derivative routines, dss042 to dss050 (again ndss=4 is used).
%
% uxx
if (ndss== 2) uxx=dss042(xl,xu,nx,u,ux,nl,nu); % second order
elseif(ndss== 4) uxx=dss044(xl,xu,nx,u,ux,nl,nu); % fourth order
elseif(ndss== 6) uxx=dss046(xl,xu,nx,u,ux,nl,nu); % sixth order
elseif(ndss== 8) uxx=dss048(xl,xu,nx,u,ux,nl,nu); % eighth order
elseif(ndss==10) uxx=dss050(xl,xu,nx,u,ux,nl,nu); % tenth order
end
The PDE is programmed to give a derivative vector, ut, corresponding to the LHS
of eqs. (1.5) according to ncase set in the main program. For ncase=1, eq. (1.5a)
is used. For ncase=2, eq. (1.5b) is used.
31
%
% PDE
for(i=1:nx)
if(ncase==1)ut(i)=ux(i)^2*uxx(i);end
if(ncase==2)ut(i)=uxx(i);end
end
ut=ut
The close resemblance of this coding to eqs. (1.5) is clear. A transpose then produces
a column derivative vector as required by the ODE integrator ode15s.
Finally, the counter for the calls to pde 1 is incremented (and returned to the main
program as part of the output).
%
% Increment calls to pde_1
ncall=ncall+1;
We next consider the corresponding routine in R for the nx=21 ODEs.
(1.2.2) ODE routine in R
The ODE routine in R for eqs. (1.5) is in Listing 1.3b.
pde_1=function(t,u,parms){
#
# ux
if (ndss== 2){ux=dss002(xl,xu,nx,u); # second order
}else if(ndss== 4){ux=dss004(xl,xu,nx,u); # fourth order
}else if(ndss== 6){ux=dss006(xl,xu,nx,u); # sixth order
}else if(ndss== 8){ux=dss008(xl,xu,nx,u); # eighth order
}else if(ndss==10){ux=dss010(xl,xu,nx,u); # tenth order
}
#
# BCs (Neumann)
ux[1] =0;
ux[nx]=0;
nl=2;nu=2;
#
# uxx
if (ndss== 2){uxx=dss042(xl,xu,nx,u,ux,nl,nu); # second order
}else if(ndss== 4){uxx=dss044(xl,xu,nx,u,ux,nl,nu); # fourth order
}else if(ndss== 6){uxx=dss046(xl,xu,nx,u,ux,nl,nu); # sixth order
}else if(ndss== 8){uxx=dss048(xl,xu,nx,u,ux,nl,nu); # eighth order
}else if(ndss==10){uxx=dss050(xl,xu,nx,u,ux,nl,nu); # tenth order
32
}
#
# PDE
ut=rep(0,nx);
for(i in 1:nx){
if(ncase==1){ut[i]=ux[i]^2*uxx[i];}
if(ncase==2){ut[i]=uxx[i];}
}
#
# Increment calls to pde_1
ncall <<- ncall+1;
#
# Return derivative vector
return(list(c(ut)));
}
Listing 1.3b: ODE R routine for eqs. (1.5) and (1.6)
We can now make a comparsion of Listings 1.3a and 1.3b.
Each routine starts with a function denition.
Matlab
function ut=pde_1(t,u)
%
% Parameters
global xl xu nx ncall ndss ncase
R
pde_1=function(t,u,parms){
In the case of Matlab, a global area is dened. For R, variables and parameters
dened in the superior routine, in this case, the main program, are automatically
available to the subordinate routine.
The calculation of the rst derivative u/x is similar in the two systems.
Matlab
%
% ux
if (ndss== 2) ux=dss002(xl,xu,nx,u); % second order
elseif(ndss== 4) ux=dss004(xl,xu,nx,u); % fourth order
33
elseif(ndss== 6) ux=dss006(xl,xu,nx,u); % sixth order
elseif(ndss== 8) ux=dss008(xl,xu,nx,u); % eighth order
elseif(ndss==10) ux=dss010(xl,xu,nx,u); % tenth order
end
R
#
# ux
if (ndss== 2){ux=dss002(xl,xu,nx,u); # second order
}else if(ndss== 4){ux=dss004(xl,xu,nx,u); # fourth order
}else if(ndss== 6){ux=dss006(xl,xu,nx,u); # sixth order
}else if(ndss== 8){ux=dss008(xl,xu,nx,u); # eighth order
}else if(ndss==10){ux=dss010(xl,xu,nx,u); # tenth order
}
The if - else if - else syntax is slightly dierent, including the use of end in
Matlab and } in R.
The programming of BCs (1.6b,c) is similar.
Matlab
%
% BCs (Neumann)
ux(1) =0;
ux(nx)=0;
nl=2;nu=2;
R
#
# BCs (Neumann)
ux[1] =0;
ux[nx]=0;
nl=2;nu=2;
The programming of the second derivative in eqs. (1.5) is similar to the programming
of the rst derivative.
Matlab
%
34
% uxx
if (ndss== 2) uxx=dss042(xl,xu,nx,u,ux,nl,nu); % second order
elseif(ndss== 4) uxx=dss044(xl,xu,nx,u,ux,nl,nu); % fourth order
elseif(ndss== 6) uxx=dss046(xl,xu,nx,u,ux,nl,nu); % sixth order
elseif(ndss== 8) uxx=dss048(xl,xu,nx,u,ux,nl,nu); % eighth order
elseif(ndss==10) uxx=dss050(xl,xu,nx,u,ux,nl,nu); % tenth order
end
R
%
% uxx
if (ndss== 2) uxx=dss042(xl,xu,nx,u,ux,nl,nu); % second order
elseif(ndss== 4) uxx=dss044(xl,xu,nx,u,ux,nl,nu); % fourth order
elseif(ndss== 6) uxx=dss046(xl,xu,nx,u,ux,nl,nu); % sixth order
elseif(ndss== 8) uxx=dss048(xl,xu,nx,u,ux,nl,nu); % eighth order
elseif(ndss==10) uxx=dss050(xl,xu,nx,u,ux,nl,nu); % tenth order
end
The calculation of the second derivative uxx is by one of ve second derivative
routines, dss042 to dss050.
The programming of eqs. (1.5) is similar in the two systems.
Matlab
%
% PDE
for(i=1:nx)
if(ncase==1)ut(i)=ux(i)^2*uxx(i);end
if(ncase==2)ut(i)=uxx(i);end
end
ut=ut;
R
#
# PDE
ut=rep(0,nx);
for(i in 1:nx){
if(ncase==1){ut[i]=ux[i]^2*uxx[i];}
if(ncase==2){ut[i]=uxx[i];}
}
35
The result is the derivative vector ut (the LHS of eqs. (1.5)). For Matlab, this
vector is dynamically allocated as it is formed. For R, this vector is rst declared
(preallocated) with rep.
The number of calls to the ODE routine is incremented. For Matlab, the new value
of ncall is returned to the main program through the global area. For R this value
is returned with <<-.
Matlab
%
% Increment calls to pde_1
ncall=ncall+1;
R
#
# Increment calls to pde_1
ncall <<- ncall+1;
In Matlab, the computed derivative vector, ut, is returned through the LHS argu-
ment of pde 1. In R, the derivative vector is returned as a list. Note also the use
of the R vector utility c. That is, ut is declared a vector, then a list, and nally is
returned. This format for the return is required by the R ODE integrators in the
library deSolve [4] (including lsodes used in the R main program discussed next).
Matlab
ut returned as the LHS argument
R
#
# Return derivative vector
return(list(c(ut)));
}
The nal } concludes pde 1 in R.
This completes the programming of the ODE routine in R. The main programs that
called the ODE routines are considered next.
36
(1.2.3) Main program in Matlab
The main program in Matlab that calls the ODE routine pde 1 in Listing 1.3a is in
Listing 1.4a.
%
% Clear previous files
clear all
clc
%
% Parameters shared with the ODE routine
global xl xu nx ncall ndss ncase
%
% Select case
%
% ncase = 1 - nonlinear
%
% ncase = 2 - linear
%
ncase=1;
%
% Grid in x, initial condition
xl=0;xu=1;nx=21;
for(ix=1:nx)
xg(ix)=(xu-xl)*(ix-1)/(nx-1);
if(ix==11)u0(ix)=0.5;end
if(ix< 11)u0(ix)=0; end
if(ix> 11)u0(ix)=1; end
end
%
% Independent variable for ODEs
t0=0;nout=11;
if(ncase==1)tf=0.1;end
if(ncase==2)tf=0.5;end
tout=linspace(t0,tf,nout);
ncall=0;
%
% ODE integration
ndss=4;
[t,u]=ode15s(@pde_1,tout,u0);
%
% Display selected output
for(it=1:nout)
fprintf(\n t x u(x,t)\n);
for(ix=1:nx)
37
if((ix-1)*(ix- 6)*(ix-11)*(ix-16)...
*(ix-21)==0)
fprintf(%7.2f%8.2f%12.5f\n,...
t(it),xg(ix),u(it,ix));
end
end
end
fprintf(\n ncall = %4d\n,ncall);
%
% Plot numerical solution
if(ncase==1)
plot(xg,u);
xlabel(x);ylabel(u(x,t));
title(u(x,t) vs x, t = 0,0.01,...,0.1);
end
if(ncase==2)
plot(xg,u);
xlabel(x);ylabel(u(x,t));
title(u(x,t) vs x, t = 0,0.05,...,0.5);
end
Listing 1.4a: Main program that calls pde 1 of Listing 1.3a
We can note the following details about Listing 1.4a.
Previous les are cleared and a global area is dened.
%
% Clear previous files
clear all
clc
%
% Parameters shared with the ODE routine
global xl xu nx ncall ndss ncase
The global area provides for a sharing of variables and parameters between routines,
in this case, between the main program of Listing 1.4a and the ODE routine of
Listing 1.3a.
The selection of eq. (1.5a) and (1.5b) is according to ncase.
%
% Select case
%
% ncase = 1 - nonlinear
%
38
% ncase = 2 - linear
%
ncase=1;
A grid in x of 21 points is dened for 0 x 1 with a uniform interval
(xu-xl)/(nx-1)=(1-0)/(21-1)=0.05
The grid point values are then placed in array xg and the IC vector of eq. (1.6a) is
placed in array u0.
%
% Grid in x, initial condition
xl=0;xu=1;nx=21;
for(ix=1:nx)
xg(ix)=(xu-xl)*(ix-1)/(nx-1);
if(ix==11)u0(ix)=0.5;end
if(ix< 11)u0(ix)=0; end
if(ix> 11)u0(ix)=1; end
end
We have used a unit step for f(x) in eq. (1.6a). Since this is a nite discontinuity,
we can only approximate it numerically, in this case as a unit ramp with the values
f(x = 0.45) = 0, f(x = 0.5) = 0.5, f(x = 0.55) = 1 (that will be clear in the
graphical output to follow).
The vector of output values of t, tout, is dened by the Matlab utility linspace.
Since the nonlinear PDE, eq. (1.5a), responds more rapidly in t than the linear
PDE, eq. (1.5b), it has a shorter t scale, 0 t 0.1, while eq. (1.5b) has the t
scale, 0 t 0.5. This dierence in t scales was determined by trial and error (and
observing the plotted solutions).
for 0 t 1 with 11 values (including at t = 0).
%
% Independent variable for ODEs
t0=0;nout=11;
if(ncase==1)tf=0.1;end
if(ncase==2)tf=0.5;end
tout=linspace(t0,tf,nout);
ncall=0;
Finally, the counter for the calls to pde 1 in Listing 1.1a is initialized.
The 21 ODEs are integrated by a call to ode15s, a sti integrator with a variety of
options. In this, only the default options are used.
39
%
% ODE integration
ndss=4;
[t,u]=ode15s(@pde_1,tout,u0);
ndss = 4 selects dss004,dss044 in Listing 1.3a. ndss is passed to pde 1 as a global
parameter.
In the call to ode15s, note the use of pde 1 in Listing 1.3a, the vector of output
values of t, tout, and the IC vector u0. Generally, the order of these inputs must
be maintained as used here when calling ode15s. The solution is returned as t, a
vector of values of t in tout, and u, a 2D array with dimensions u(11,21) for the
11 values of t and the 21 corresponding ODE solutions.
The numerical ODE solution is displayed with fprintf as a function of t (with the
for in it) and x (with the for in ix). To keep the volume of output to a manageable
level, the solution is displayed at x = 0, 0.25, 0.5, 0.75, 1 (ix=1,6,11,16,21). Rather
than using the if, this selected output could also be produced with for ix=1:5:nx
but the if was used for a more direct comparison with the R programming in Listing
1.4b. Also, the if has the advantage that any values of x can be selected for the
output (through the choice of the values of ix).
%
% Display selected output
for(it=1:nout)
fprintf(\n t x u(x,t)\n);
for(ix=1:nx)
if((ix-1)*(ix- 6)*(ix-11)*(ix-16)...
*(ix-21)==0)
fprintf(%7.2f%8.2f%12.5f\n,...
t(it),xg(ix),u(it,ix));
end
end
end
fprintf(\n ncall = %4d\n,ncall);
Finally, the number of calls to pde 1 of Listing 1.3a is displayed as an indication
of the eort required to compute a solution. Note that in general Matlab denes a
character string with a single quote () while this is done with a double quote (")
in R.
A plot of u(x, t) against x is produced with a single call to the Matlab utility plot
which matches the dimension of xg (21) with the second dimension of u (also 21)
as dened by the ODE integrator, ode15s. In this way, t becomes a parameter in
the plotting with a series of nout=11 curves through the rst dimension of u (11).
40
%
% Plot numerical solution
if(ncase==1)
plot(xg,u);
xlabel(x);ylabel(u(x,t));
title(u(x,t) vs x, t = 0,0.01,...,0.1);
end
if(ncase==2)
plot(xg,u);
xlabel(x);ylabel(u(x,t));
title(u(x,t) vs x, t = 0,0.05,...,0.5);
end
Labeling of the horizontal and vertical axes, and a title for the plot are also added.
The dierence in the t interval for ncase=1,2 is included in the title.
This completes the programming of eqs. (1.5) and (1.6). The only remaining re-
quirement is the programming of IC (1.6a) which is in the main program discussed
subsequently.
(1.2.4) Main program in R
The main program in R is considered next with a comparison of equivalent statements
from Listing 1.4a.
#
# Access ODE integrator
library("deSolve");
#
# Access functions
setwd("c:/R/pde_intro");
source("pde_1.R");
source("dss004.R");
source("dss044.R");
#
# Select case
#
# ncase = 1 - nonlinear
#
# ncase = 2 - linear
#
ncase=1;
#
# Grid in x, initial condition
xl=0;xu=1;nx=21;
41
xg=rep(0,nx);u0=rep(0,nx);
for(ix in 1:nx){
xg[ix]=(xu-xl)*(ix-1)/(nx-1);
if(ix==11){u0[ix]=0.5;}
if(ix< 11){u0[ix]=0;}
if(ix> 11){u0[ix]=1;}
}
#
# Independent variable for ODEs
t0=0;nout=11;
if(ncase==1){tf=0.1;}
if(ncase==2){tf=0.5;}
tout=seq(from=0,to=tf,by=(tf-t0)/(nout-1));
ncall=0;
#
# ODE integration
ndss=4;
out=lsodes(y=u0,times=tout,func=pde_1,parms=NULL)
#
# Display selected output
for(it in 1:nout){
cat(sprintf("\n t x u(x,t)\n"));
for(ix in 1:nx){
if((ix-1)*(ix- 6)*(ix-11)*(ix-16)
*(ix-21)==0){
cat(sprintf("%7.2f%8.2f%12.5f\n",
out[it,1],xg[ix],out[it,ix+1]));
}
}
}
cat(sprintf("\n ncall = %4d\n",ncall));
#
# Plot numerical solution
par(mfrow=c(1,1));
if(ncase==1){
matplot(x=xg,y=t(out[,-1]),type="l",xlab="x",
ylab="u(x,t) vs x, t=0,0.01,...,0.1",xlim=c(xl,xu),
main="u(x,t) vs x, t=0,0.01,...,0.1;",lty=1,lwd=2);
}
if(ncase==2){
matplot(x=xg,y=t(out[,-1]),type="l",xlab="x",
ylab="u(x,t) vs x, t=0,0.05,...,0.5",xlim=c(xl,xu),
main="u(x,t) vs x, t=0,0.05,...,0.5;",lty=1,lwd=2);
}
42
Listing 1.4b: Main program that calls pde 1 of Listing 1.3b
We can note the following details of Listing 1.4b with a comparison of the equivalent
Matlab statements in Listing 1.4a.
Some preliminaries are rst programmed.
Matlab
%
% Clear previous files
clear all
clc
%
% Parameters shared with the ODE routine
global xl xu nx ncall ndss ncase
R
#
# Access ODE integrator
library("deSolve");
#
# Access functions
setwd("c:/R/pde_intro");
source("pde_1.R");
source("dss004.R");
source("dss044.R");
The Matlab statements have already been considered (in Section (1.2.3)). The R
statements access the ODE library deSolve followed by the ODE routine pde 1
of Listing 1.1b and the library dierentiators dss004,dss044. The setwd utility
(set working directory) species the location of these two les (note the use of the
forward slash, /, rather than the usual backslash \).
The selection of ncase=1,2 is the same in Matlab and R.
The grid in x has 21 points for 0 x 1. The IC is an approximation to a unit
step as discussed previously in Section 1.2.3.
Matlab
%
% Grid in x, initial condition
xl=0;xu=1;nx=21;
43
for(ix=1:nx)
xg(ix)=(xu-xl)*(ix-1)/(nx-1);
if(ix==11)u0(ix)=0.5;end
if(ix< 11)u0(ix)=0; end
if(ix> 11)u0(ix)=1; end
end
R
#
# Grid in x, initial condition
xl=0;xu=1;nx=21;
xg=rep(0,nx);u0=rep(0,nx);
for(ix in 1:nx){
xg[ix]=(xu-xl)*(ix-1)/(nx-1);
if(ix==11){u0[ix]=0.5;}
if(ix< 11){u0[ix]=0;}
if(ix> 11){u0[ix]=1;}
}
For the R code, the grid in x xg and the IC array u0 are rst declared (preallocated)
with a rep. Alternative R coding for the grid can be considered, e.g.,
xg=seq(from=xl,to=xu,by=(xu-xl)*(ix-1)/(nx-1))
based on the R utility seq.
The output points in t are specied.
Matlab
%
% Independent variable for ODEs
t0=0;nout=11;
if(ncase==1)tf=0.1;end
if(ncase==2)tf=0.5;end
tout=linspace(t0,tf,nout);
ncall=0;
R
#
# Independent variable for ODEs
44
t0=0;nout=11;
if(ncase==1){tf=0.1;}
if(ncase==2){tf=0.5;}
tout=seq(from=0,to=tf,by=(tf-t0)/(nout-1));
ncall=0;
Note the use of seq for R in place of linspace for Matlab.
The ODE integration in R is by lsodes ([4]).
Matlab
%
% ODE integration
ndss=4;
[t,u]=ode15s(@pde_1,tout,u0);
R
#
# ODE integration
ndss=4;
out=lsodes(y=u0,times=tout,func=pde_1,parms=NULL)
The @ in the rst RHS argument of ode15s indicates this argument is a function
(pde 1 of Listing 1.3a) rather than a parameter or variable. The solution array
from lsodes, out ([4]), contains both the 11 values of t and the 21 ODE solutions.
Therefore, the dimensions of out are out(11,22). The second dimension in out is
22 rather than 21 to include t as explained next. Note the use of the IC vector,
u0, the vector of output values of t, tout, and the ODE routine, pde 1 in Listing
1.3b. The argument parms (to pass parameters to the ODE routine) is unused.
y,times,func,parms are reserved names for lsodes.
An alternative for the ODE integration is
ode(y=u0,times=tout,func=pde_1,parms=NULL)
The R utility ode uses the integrator lsoda as the default. lsoda switches between
a nonsti and sti integrator depending on an eigenvalue analysis (the a stands
for automatic).
lsoda and lsodes have a variety of options as explained in the R documentation.
Here we have used the defaults for lsodes.
The numerical solution is displayed in a similar way for Matlab and R.
45
Matlab
%
% Display selected output
for(it=1:nout)
fprintf(\n t x u(x,t)\n);
for(ix=1:nx)
if((ix-1)*(ix- 6)*(ix-11)*(ix-16)...
*(ix-21)==0)
fprintf(%7.2f%8.2f%12.5f\n,...
t(it),xg(ix),u(it,ix));
end
end
end
fprintf(\n ncall = %4d\n,ncall);
R
#
# Display selected output
for(it in 1:nout){
cat(sprintf("\n t x u(x,t)\n"));
for(ix in 1:nx){
if((ix-1)*(ix- 6)*(ix-11)*(ix-16)
*(ix-21)==0){
cat(sprintf("%7.2f%8.2f%12.5f\n",
out[it,1],xg[ix],out[it,ix+1]));
}
}
}
cat(sprintf("\n ncall = %4d\n",ncall));
Note the oset of 1 in the second subscript of out, i.e., ix+1, in the R coding since
out[it,1] references t. Thus, out[it,22] references u(x = 1, t). Also, the output
is for every fourth value of x, that is, x = 0, 0.25, ..., 1 through the use of the if
in ix. A comparsion of the Matlab and R numerical output is given subsequently.
The nal value of the number of calls to pde 1 in Listing 1.3b is displayed.
The plotting in R is by the matplot utility. A 1 1 array of plots, that is, a single
plot, is specied with par(mfrow=c(1,1)).
(start)
Matlab
46
%
% Plot numerical solution
if(ncase==1)
plot(xg,u);
xlabel(x);ylabel(u(x,t));
title(u(x,t) vs x, t = 0,0.01,...,0.1);
end
if(ncase==2)
plot(xg,u);
xlabel(x);ylabel(u(x,t));
title(u(x,t) vs x, t = 0,0.05,...,0.5);
end
R
#
# Plot numerical solution
par(mfrow=c(1,1));
if(ncase==1){
matplot(x=xg,y=t(out[,-1]),type="l",xlab="x",
ylab="u(x,t) vs x, t=0,0.01,...,0.1",xlim=c(xl,xu),
main="u(x,t) vs x, t=0,0.01,...,0.1;",lty=1,lwd=2);
}
if(ncase==2){
matplot(x=xg,y=t(out[,-1]),type="l",xlab="x",
ylab="u(x,t) vs x, t=0,0.05,...,0.5",xlim=c(xl,xu),
main="u(x,t) vs x, t=0,0.05,...,0.5;",lty=1,lwd=2);
}
The labeling of the plots in Matlab and R is similar. matplot has additional param-
eters for specifying the line type and the horizontal axis limits. The vertical axis is
scaled as a default (ylim is also available).
This concludes the R programming for eqs. (1.5) and (1.6). The output from Listings 1.3a
and 1.4a for Matlab, and Listings 1.3b and 1.4b for R, is now discussed and compared.
(1.2.5) Comparison of Matlab and R output
Abbreviated output from Listings 1.3a and 1.4a is given in Table 1.9.
t x u(x,t)
0.00 0.00 0.00000
0.00 0.25 0.00000
0.00 0.50 0.50000
47
0.00 0.75 1.00000
0.00 1.00 1.00000
t x u(x,t)
0.01 0.00 0.00000
0.01 0.25 0.09146
0.01 0.50 0.49995
0.01 0.75 0.90848
0.01 1.00 1.00000
. .
. .
. .
Output from t = 0.02 to 0.08
removed
. .
. .
. .
t x u(x,t)
0.09 0.00 0.00000
0.09 0.25 0.24177
0.09 0.50 0.49998
0.09 0.75 0.75819
0.09 1.00 1.00000
t x u(x,t)
0.10 0.00 0.00000
0.10 0.25 0.24444
0.10 0.50 0.49998
0.10 0.75 0.75553
0.10 1.00 1.00000
ncall = 440
Table 1.9: Output from Listings, 1.3a 1.4a for ncase=1 (nonlinear PDE)
We can note the following details about this output.
IC (1.6a) (t = 0) is correct (as programmed in Listing 1.4a). Checking the IC is
always a good idea since if it is incorrect, the remainder of the numerical output
will also be incorrect.
The solution approaches
u(x, t ) = x (1.7a)
48
as reected in the output for t = 0.1. This steady state solution clearly satises
eq. (1.5a). It does not satisfy Neumann BCs (1.16b,c) directly, but rather, satises
Dirichlet BCs (1.6f,g) (with c
l
= 0, c
u
= 1) as discussed previously. This nal linear
solution is also reected in Figs. 1.5 and 1.7.
The computational eort is modest with ncall = 440.
Abbreviated output from Listings 1.3b and 1.4b is given in Table 1.10
t x u(x,t)
0.00 0.00 0.00000
0.00 0.25 0.00000
0.00 0.50 0.50000
0.00 0.75 1.00000
0.00 1.00 1.00000
t x u(x,t)
0.01 0.00 0.00000
0.01 0.25 0.09148
0.01 0.50 0.50000
0.01 0.75 0.90852
0.01 1.00 1.00000
. .
. .
. .
Output from t = 0.02 to 0.08
removed
. .
. .
. .
t x u(x,t)
0.09 0.00 0.00000
0.09 0.25 0.24180
0.09 0.50 0.50000
0.09 0.75 0.75820
0.09 1.00 1.00000
t x u(x,t)
0.10 0.00 0.00000
0.10 0.25 0.24447
0.10 0.50 0.50000
0.10 0.75 0.75553
0.10 1.00 1.00000
ncall = 350
49
Table 1.10: Output from Listings 1.3b 1.4b for ncase=1 (nonlinear PDE)
Again, the details for Table 1.9 apply to Table 1.10. The computational eort is modest
with ncall = 350.
The two solutions in Tables 1.9, 1.10 are compared in Table 1.11 at t = 0.1.
Matlab (Table 1.9)
t x u(x,t)
0.10 0.00 0.00000
0.10 0.25 0.24444
0.10 0.50 0.49998
0.10 0.75 0.75553
0.10 1.00 1.00000
R (Table 1.10)
t x u(x,t)
0.10 0.00 0.00000
0.10 0.25 0.24447
0.10 0.50 0.50000
0.10 0.75 0.75553
0.10 1.00 1.00000
Table 1.11: Comparison of the numerical solutions for ncase=1 at t = 0.1
The two solutions agree to four gures. The graphical output is in Figs. 1.5 (Matlab)
and 1.7 (R). The approach to the solution of eq. (1.7a) is clear (and also conrmed by
the t = 0.1 output in Tables 1.9 and 1.10).
For ncase=2, the linear PDE, eq. (1.5b), is integrated by Matlab (Listings 1.3a, 1.4a)
and R (Listings 1.3b, 1.4b), to give the following numerical output.
t x u(x,t)
0.00 0.00 0.00000
0.00 0.25 0.00000
0.00 0.50 0.50000
0.00 0.75 1.00000
0.00 1.00 1.00000
t x u(x,t)
0.05 0.00 0.11463
0.05 0.25 0.22397
0.05 0.50 0.50000
0.05 0.75 0.77603
0.05 1.00 0.88537
50
t x u(x,t)
0.10 0.00 0.26324
0.10 0.25 0.33252
0.10 0.50 0.50000
0.10 0.75 0.66748
0.10 1.00 0.73676
. .
. .
. .
Output from t = 0.15 to 0.45
removed
. .
. .
. .
t x u(x,t)
0.50 0.00 0.49535
0.50 0.25 0.49671
0.50 0.50 0.49999
0.50 0.75 0.50327
0.50 1.00 0.50463
ncall = 124
Table 1.12: Output from Listings 1.3a 1.4a for ncase=2 (linear PDE)
The corresponding R output from Listings 13.b and 1.4b follows
t x u(x,t)
0.00 0.00 0.00000
0.00 0.25 0.00000
0.00 0.50 0.50000
0.00 0.75 1.00000
0.00 1.00 1.00000
t x u(x,t)
0.05 0.00 0.11459
0.05 0.25 0.22400
0.05 0.50 0.50000
0.05 0.75 0.77600
0.05 1.00 0.88541
t x u(x,t)
0.10 0.00 0.26324
0.10 0.25 0.33254
0.10 0.50 0.50000
51
0.10 0.75 0.66746
0.10 1.00 0.73676
. .
. .
. .
Output from t = 0.15 to 0.45
removed
. .
. .
. .
t x u(x,t)
0.50 0.00 0.49543
0.50 0.25 0.49677
0.50 0.50 0.50000
0.50 0.75 0.50323
0.50 1.00 0.50457
ncall = 188
Table 1.13: Output from Listings 1.3b 1.4b for ncase=2 (linear PDE)
The computational eort is quite modest with ncall = 124,188. The two solutions are
compared in Table 1.14.
Matlab (Table 1.12)
t x u(x,t)
0.10 0.00 0.26324
0.10 0.25 0.33252
0.10 0.50 0.50000
0.10 0.75 0.66748
0.10 1.00 0.73676
R (Table 1.13)
t x u(x,t)
0.10 0.00 0.26324
0.10 0.25 0.33254
0.10 0.50 0.50000
0.10 0.75 0.66746
0.10 1.00 0.73676
Table 1.14: Comparison of the numerical solutions for ncase=2 at t = 0.1
52
Table 1.14 indicates the solutions agree to four gures at t = 0.1 where they are changing
rapidly. The graphical output for ncase=1 is given in Fig. 1.6 (Matlab) and Fig. 1.8
(R). The approach to the steady state solution
u(x, t ) = 0.5 (1.7b)
is clear (and also conrmed by the t = 0.5 output in Tables 1.12 and 1.13).
(1.3) Conclusions
The preceding discussion of the PDE numerical methods for eqs. (1.1) and (1.2) (example
no. 1) and for eqs. (1.5) and (1.6) (example no.), and the associated Matlab and R coding,
indicated the following points.
The prgramming of examples nos. 1 and 2, for the linear and nonlinear cases, is
straighforward. Also the programming in Matlab and R has a similar format.
The graphical output from Matlab and R is similar in the essential details. Dier-
ences are due to the plotting routines plot and matplot.
The numerical solutions have good accuracy as determined, for example, by com-
paring the Matlab and R solutions, and for example no. 1, by comparison of the
numerical and analytical solutions.
The ODE integrators, ode15s and lsodes, eciently calculated the ODE numerical
solutions.
The procedures used for the numerical integration of the PDEs in R can be readily
extended to nonlinear systems of PDEs in 1D, 2D and 3D for a variety of BCs. For this
reason, the development of PDE applications in R is expected to continue.
53
Appendix 1
Derivation of an analytical solution for example no. 1
We consider the derivation of an analytical solution for eqs. (1.1) and (1.2) by two
methods: (1) nite Fourier sine transform and (2) Greens function.
(1.1a) Analytical solution by nite Fourier sine transform
We consider the analytical solution of eqs. (1.1) and (1.2) by a nite Fourier sine trans-
form (FST), which is equivalent to the method of separation of variables. The FST
transform pair (forward and inverse transforms) is ([3], pp 405-415)
F
x
{f(x)} =
_
L
0
f(x) sin(
i
x)dx = f(
i
) (1.4a)
F
1
x
_
f(
i
)
_
=
2
L

i=1
f(
i
) sin(
i
x) = f(x) (1.4b)
where an overline (overbar) is used to denote a transformed function. The FST is termed
nite because the interval in x, 0 x L, is nite. The consequence of this nite
interval is that the inversion (by eq. (1.4b)) involves an innite series (rather than an
integral). This makes the inversion particularly easy, that is, it just requires substitution
of f(
i
) in an innite series (rather than evaluation of an integral).
A table of FST pairs can be developed by application of the forward transform, eq.
(1.4a), to a series of functions of x. FST pairs of particular relevance in the solution of
eq. (1.1) and (1.2) follow.
no. f(x) f(
i
)
1 0 0
2 1
1

i
3
d
2
f(x)
dx
2
(1)
i+1
df(x = L)
dx
+
i
f(x = 0)
2
i
f(
i
)
4
u(x, t)
t
du(
i
, t)
dt
Table 1.9: Table of FST pairs (
i
= (i 1/2)/L)
For example, pair (1) follows as
F
x
{0} =
_
L
0
(0) sin(
i
x)dx = 0
54
Similarly, for pair (2)
F
x
{1} =
_
L
0
(1) sin(
i
x)dx =
1

i
cos(
i
x)|
L
0
=
1

i
[1 cos(
i
L)] =
1

i
Pair (3) follows from
F
x
_
d
2
f(x)
dx
2
_
=
_
L
0
_
d
2
f(x)
dx
2
_
sin(
i
x)dx
followed by integration by parts twice ([3], p 408).
Pair (4) follows from
F
x
_
u(x, t)
t
_
=
_
L
0
u(x, t)
t
sin(
i
x)dx =

t
__
L
0
u(x, t) sin(
i
x)dx
_
=
df(
i
)
dt
To apply the FST to eqs. (1.1) and (1.2), we multiply eq. (1.1) by sin(
i
) and integrate
from x = 0 to x = L.
_
L
0
u(x, t)
t
sin(
i
x)dx =
_
L
0

2
u(x, t)
x
2
sin(
i
x)dx (1.4c)
Application of the FSTs in Table 1.9 to eq. (1.4c) gives the ODE
du(
i
, t)
dt
=
i

2
i
u(
i
, t) (1.4d)
where we have applied BCs (1.2b) and (1.2c) (this illustrates an advantage of the FST,
that is, it naturally includes BCs). From pair (3), f(x = 0) u(x = 0, t) = 1, df(x =
L)/dx u(x = L, t)/x = 0.
Eq. (1.4d) requires an IC which is the FST of eq. (1.2a).
u(
i
, t = 0) = 0 (1.4e)
Eq. (1.4e) follows from pair (1) in Table 1.9.
Since 0 t in eq. (1.4d), we can apply a Laplace transform, dened as
L
t
{f(t)} =
_

0
f(t)e
st
dt = f(s) (1.4f)
A table of Laplace transform pairs can be developed by application of the forward
transform, eq. (1.4f), to a series of functions of t. Laplace transform pairs of particular
relevance in the solution of eq. (1.4d) follow.
55
no. f(t) f(s)
1 0 0
2 1
1
s
3 e
at
1
s + a
4 f(s)g(s)
_
t
0
f()g(t )d
5
df(t)
dt
sf(s) f(t = 0)
Table 1.10: Table of Laplace transform pairs
Pair (2) follows from eq. (1.4f).
L
t
{1} =
_

0
(1)e
st
dt =
1
s
e
st
|

0
=
1
s
Pair (3) follows from eq. (1.4f)
L
t
_
e
at
_
=
_

0
e
at
e
st
dt =
_

0
e
(s+a)t
dt =
1
s + a
e
(s+a)t
|

0
=
1
s + a
Pair (4) involves the convolution integral
_
t
0
f()g(t )d and is readily available from
tabulated Laplace transform pairs.
Pair(5) follows from eq. (1.4f) and integration by parts
L
t
_
df(t)
dt
_
=
_

0
df(t)
dt
e
st
dt = f(t)e
st
|

0
(s)
_

0
f(t)e
st
dt = f(t = 0) + sf(s)
For f(t) u(
i
, t), eq. (1.4f) gives
L
t
{u(
i
, t)} =
_

0
u(
i
, t)e
st
dt = u(
i
, s) (1.4g)
Then eq. (1.4d) transforms to
su(
i
, s) =

i
s

2
i
u(
i
, s)
which follows from the application of pairs (2), (3) and (5) in Table 1.10. Note that
that eq. (1.1) after two successive integral transforms in x and t (denoted with a double
overline) is reduced to an algebraic equation.
56
Solution for u(
i
, s) gives
u(
i
, s) =

i
s(s +
2
i
)
(1.4h)
Application of transform pair (4) of Table 1.10 to eq. (1.4h) gives
u(
i
, t) = L
1
t
_
u(
i
, s)
_
=
i
_
t
0
e

2
i

d
=

i

2
i
e

2
i

|
t
0
=
1

i
(1 e

2
i
t
) (1.4i)
Eq. (1.4i) can be veried by substitution in eq. (1.4d).
Eq. (1.4d) Eq. (1.4i)
du(
i
, t)
dt

i
e

2
i
t

i

i

2
i
u(
i
, t)
i
(1 e

2
i
t
)
0 0
Table 1.11: Verication of eq. (1.4i) as the solution to eq. (1.4d)
Eq. (1.4i) also satises IC (1.4e).
Then the inverse FST of eq. (1.4b) gives the solution to eq. (1.1)
u(x, t) = F
1
x
_
1

i
(1 e

2
i
t
)
_
=
2
L

i=1
1

i
(1 e

2
i
t
) sin(
i
x)
= 1
2
L

i=1
1

i
e

2
i
t
sin(
i
x) (1.4j)
where we have made use of
2
L

i=1
1

i
sin(
i
x) = 1
that follows from eq. (1.4b) and transform pair (2) of Table 1.9.
57
Eq. (1.4j) can be conrmed as the solution of eqs. (1.1) and (1.2).
Eq. (1.1) Eq. (1.4j)
u
t

i
e

2
i
t

2
u
x
2

i
e

2
i
t
0 0
Table 1.12: Verication of eq. (1.4i) as the solution to eq. (1.4d)
IC (1.2a) is veried as
u(x, t = 0) = 1
2
L

i=1
1

i
e

2
i
(0)
sin(
i
x) = 1 1 = 0
BC (1.2b) is veried as
u(x = 0, t) = 1
2
L

i=1
1

i
e

2
i
t
sin(
i
(0)) = 1 0 = 1
BC (1.2c) is veried as
u(x, t = 0)
x
=
2
L

i=1
e

2
i
t
cos(
i
L) = 0
This completes the solution of eqs. (1.1) and (1.2) by successive integral transforms.
The solution, eq. (1.4j), can also be derived through the use of a Greens function.
(1.1b) Analytical solution by the Greens function
An analytical solution to eqs. (1.1) and (1.2) is available through the use of a Greens
function ([2], pp 48-49).
u(x, t) = D
_
t
0

G(x, , t )|
=0
d (1.5a)
where G(x, , t) is the Greens function
G(x, , t) =
2
L

n=0
sin
_
(2n + 1)x
2L
_
sin
_
(2n + 1)
2L
_
exp
_

2
(2n + 1)
2
t
4L
2
_
(1.5b)
Substitution of eq. (1.5b) in eq. (1.5a) gives
58
u(x, t) =
2
L

n=0
sin
_
(2n + 1)x
2L
_ _
(2n + 1)
2L
_
cos
_
(2n + 1)
2L
_
=0

_
t
0
exp
_

2
(2n + 1)
2
(t )
4L
2
_
d
=
2
L

n=0
_
(2n + 1)
2L
_
sin
_
(2n + 1)x
2L
_ _
t
0
exp
_

2
(2n + 1)
2
(t )
4L
2
_
d
exp
_

2
(2n + 1)
2
t
4L
2
_
can be factored out of the integral and the integration in com-
pleted.
u(x, t) =
2
L

n=0
_
(2n + 1)
2L
_
sin
_
(2n + 1)x
2L
_
exp
_

2
(2n + 1)
2
4L
2
t
_

_
4L
2

2
(2n + 1)
2
_
exp
_

2
(2n + 1)
2
4L
2

_
t
0
=
2
L

n=0
_
2L
(2n + 1)
_
sin
_
(2n + 1)x
2L
_
exp
_

2
(2n + 1)
2
4L
2
t
_ _
exp
_

2
(2n + 1)
2
4L
2
t
_
1
_
= 2

n=0
_
1
(n + 1/2)
_
sin
_
(n + 1/2)x
L
_ _
1 exp
_

2
(n + 1/2)
2
L
2
t
__
With a change in the summation index n,
u(x, t) = 2

n=1
_
1
(n 1/2)
_
sin
_
(n 1/2)x
L
_ _
1 exp
_

2
(n 1/2)
2
L
2
t
__
With the application of pair (2) in Table 1.9,
u(x, t) = 1 2

n=1
_
1
(n 1/2)
_
sin
_
(n 1/2)x
L
_
exp
_

2
(n 1/2)
2
L
2
t
_
With
i
= (n 1/2),
u(x, t) = 1 2

n=1
_
1

i
_
exp
_

2
i
L
2
t
_
sin
_

i
x
L
_
(1.5c)
Eqs. (1.4i) and (1.5c) are the same.
The numerical evaluation of the analytical solution, eqs. (1.4i) and (1.5c) (and eq.
(1.3)), is accomplished by the following R routine.
59
#
# Parameters
L=1;
#
# t
t=0.45;
# t=5;
#
# x
x=seq(from=0,to=1,by=0.2);
#
# Heading
cat(sprintf("\n t x u(x,t)\n"));
#
# Step through x
for(ix in 1:6){
#
# Analytical solution u(x,t)
anal=0;
#
# Step through eigenvalues, terms in solution
for(i in 1:5){
#
# Eigenvalue
lam=(i-1/2)*pi;
#
# Next term in series solution
anal=anal+(2/lam)*exp(-(lam^2/L^2)*t)*sin(lam*x[ix]/L);
}
#
# Display analytical solution at x,t
cat(sprintf("%7.2f%8.2f%12.5f\n",t,x[ix],1-anal));
#
# Next value of x
}
Listing 1.3: R routine for the numerical evaluation of the analytical solution
The details of Listing 1.3 are essentially self-explanatory by a comparison with eqs. (1.3),
(1.4i), (1.5c). Note in particular the statement
anal=anal+(2/lam)*exp(-(lam^2/L^2)*t)*sin(lam*x[ix]/L)
for the series in the RHS of eqs. (1.3), (1.4i) and (1.5c). For t > 0 (e.g., t=0.45),
the series converges rapidly and therefore only 5 terms are required to obtain accurate
numerical values of the analytical solution.
60
The eigenvalue
i
= (i 1/2) is programmed as lam=(i-1/2)*pi where the in-line
value of in R has been used. The output from Listing 1.3 is given in Table 1.6.
This derivation of the analytical solution to eqs. (1.1) and (1.2) illustrates the relative
complexity of the analytical approach to PDE analysis. Also, for the two cases D =
u, D = e
u
, an analytical approach may not be possible. But analytical solutions play an
important role as a stringent test of numerical methods, e.g., Table. 1.6, and therefore
ideally the two approaches should be used in parallel.
References
[1] Hiebeler, D., Matlab/R Reference
http://www.math.umaine.edu/hiebeler/comp/matlabR.html
[2] Polyanin, A. D. (2002), Handbook of Linear Partial Dierential Equations for Engi-
neers and Scientists, Chapman and Hall/CRC, Boca Raton, FL
[3] Schiesser, W.E (1994), Computational Mathematics in Engineering and Applied Sci-
ence: ODEs, DAEs, and PDEs, CRC Press, Boca Raton, FL
[4] Soetaert, K., J. Cash and F. Mazzia (2012), Solving Dierential Equations in R,
Springer-Verlag, Heidelberg, Germany
61
Index
A
analytical solution 54
comparison with numerical solution 25,44
derivation by Fourier transform 54
derivation by Greens function 58
numerical evaluation 60
verication 57-58
B
boundary condition 3,29
Dirichlet 29
inconsistency with initial condition 16
boundary value variable 3
Neumann 29,31,34
programming 29
C
convolution integral 56
D
dependent variable 3
dierentiation routine, see dss004
diusion equation 3
linear 29
nonlinear 28
diusivity 3
linear form 3-4,6,8,11
numerical solution 22-24
nonlinear form 3-4,6,8,11
numerical solution 26
Dirichlet boundary condition 3-4,9,29
dss004 4-7,11,30-31,34,43
dss044 30-31,34,43
discontinuity 16
E
eigenvalue 25
F
nite sin transform 54
see also Fourier transform
Fourier transform 54
62
inverse 54
PDE solution 54-58
table 54
G
Greens function 58
PDE solution 58-59
I
independent variable 3,28
innite series solution 25
initial condition 3,29
insistency with boundary condition 16
initial value variable 3
integral transform 31
repeated 31
L
Laplace transform 56
convolution 56
ODE solution 56-57
table 56
lsoda 13,20
lsodes 13,17
M
main program in Matlab 13,37
main program in R 17,41
Matlab
comparison with R 9-11,13,18-21
output 22-25
for 6,10,13,16
format 14
fprintf 16,21
single quote 40
function 5
global 5,9,13-14,18
if 7,10,16
linspace 14-15,37
main program 13,37,41
ode15s 7,14-15
plot 16-17
transpose 5,7,12,15,32
vector facility 5,7,12
63
vector denition 15
zeros 15
method of lines 4
ODE routine in Matlab 4,30
ODE routine in R 7,32
spatial grid 13-15,17
temporal grid 15,17
MOL, see method of lines
N
Neumann boundary condition 3-4,6,9,29,31,34
nonlinear PDE solution 26-28
numerical PDE solution 25,47
comparison with analytical solution 25,47
O
ODE
analytical integration
Laplace transform 56
verication 57
numerical integration
ode15s 7,15
lsoda 13,20
lsodes 13,17
routine in Matlab 5
routine in R 7
ordinary dierential equation, see ODE
P
parabolic PDE 16,28
partial dierential equation, see PDE
PDE 3
analytical solution 54
verication 57
linear numerical solution 22-24
nonlinear numerical solution 26-28
R
R (programming)
<<- 13
array declaration 11
cat 18,21
comparison with Matlab 9-11,13,18-21
output 23-25
64
deSolve 13,17
for 8,11
function 7
list 8,13,36
return 8,13,36
global variable 13
<<- 13,33
if 8,11
library 17
list 8,13
lsoda 13,20
lsodes 13,17
matplot 18,22
ode 20
lsoda 20
out 17,20-21
par(mrow) 18,22
rep 8,11-12,17
return 8,13
setwd 17-18
seq 17,19,44
source 17-18
sprintf 18,21
quote " 40
vector facility 8,12
S
Stagewise dierentiation 6
U
Unit ramp 39
Unit step 39
65

Anda mungkin juga menyukai