MathPDE A Package To Solve PDEs by Finite Differences
MathPDE A Package To Solve PDEs by Finite Differences
MathPDE A Package To Solve PDEs by Finite Differences
MathPDE: A Package to
Solve PDEs by Finite
Differences
K. Sheshadri
Peter Fritzson
‡ 1. Introduction
Mathematical problems described by partial differential equations (PDEs) are ubiquitous
in science and engineering. Examples range from the simple (but very common) diffusion
equation, through the wave and Laplace equations, to the nonlinear equations of fluid
mechanics, elasticity, and chaos theory. However, few PDEs have closed-form analytical
solutions, making numerical methods necessary. The numerical task is made difficult by
the dimensionality and geometry of the independent variables, the nonlinearities in the
system, sensitivity to boundary conditions, a lack of formal understanding of the kind of
solution method to be employed for a particular problem, and so on.
In Section 4, we discuss application examples that illustrate the strengths and limitations
of MathPDE. The examples chosen are divided into problems in one, two, and three dimen-
sions, and there is a section on two nonlinear problems.
In Section 5, we give a summary of our work and make some concluding remarks.
Needs@"MathPDE`"D;
diffusion1D = 8
8
8¶∂8t,1< u@x, tD ã ¶∂8x,2< u@x, tD<,
8x ã 0, u@x, tD ã 0<,
8x ã 1, u@x, tD ã 0<,
8t ã 0, u@x, tD ã x H1 - xL<
<,
8
88x, 0, 1<<
<
<;
The list has two elements: the first element defines the PDE, the boundary conditions, and
finally the initial condition, each as a list, and the second element defines the spatial do-
main as an iterator.
· 2.2 Setup
Once the problem is defined, the following command sets up the numerical code.
SetupMathPDE@diffusion1D, 8<D
Execute:
SolvePDE@Nx, dt, m, nD
MathPDE is installed.
In this case, the last argument 8< of SetupMathPDE is empty because there are no pa-
rameters in the input problem. If there were parameters, they could be specified in this
list. After completing the symbolic part, the command loads MathCode, which then gener-
ates C++ code and compiles it. In the present problem, the C++ code is a set of 13 func-
tions in addition to the main() function. The executable is also installed by MathCode, so
that we can run it from the notebook interface.
We can extract the solution computed by this command by invoking solutionAt and
we can plot it.
0.00002
0.000015
0.00001
-6
5´ 10
20 40 60 80 100
We can uninstall the C++ program and delete all the files related to MathCode if we do
not need them.
UninstallCode@D;
Quit
‡ 3. Design of MathPDE
In the finite-difference method, the independent variables are regarded as discrete and the
become differences between values at a combination of these grid points; the actual combi-
nation depends on the nature of the difference approximation. After such an approxi-
mation is performed, no derivatives are left and only the functions are evaluated at the
grid points; the resulting system of relations between the values of dependent variables at
a set of neighboring grid points is referred to as the stencil for the PDE system. Applying
the stencil at all the grid points results in a system of coupled algebraic equations. In time-
dependent problems, to which the present work is addressed, the solution at any time tn
(which is discretized as well) is determined, in general, from the solution up to the
previous time instant tn-1 ; the solution values at each grid point at the time instant tn are
the unknowns in the algebraic system.
Depending on the kind of discretization used, we may be able to explicitly solve for each
unknown from one of the algebraic equations. In such a case, the difference scheme is
called explicit. In cases where we cannot do this explicitly, we refer to the difference
scheme as implicit.
Let us illustrate this with the example of the one-dimensional diffusion equation that we
solved in Section 2. Suppose we replace ut Hx, tL by a first-degree forward approximation,
HuHx, t + kL - uHx, tLL ê k, and uxx Hx, tL by a second-degree central approximation,
HuHx + h, tL - 2 uHx, tL + uHx - h, tLL ë h2 , where k and h are the step sizes along t and x. The
result is the difference equation
HuHx, t + kL - uHx, tLL ê k = HuHx + h, tL - 2 uHx, tL + uHx - h, tLL ë h2 (2)
that can be easily solved for uHx, t + kL to get
h2 uHx, tL - 2 k uHx, tL + k uH-h + x, tL + k uHh + x, tL
uHx, k + tL = , (3)
h2
so we have an explicit finite-difference method. A simple but important observation is
that the right-hand side of the above equation involves dependent variable values at time t
that are already known, so we can use the right-hand side to recursively compute the depen-
dent variable at any grid point and at any time, given the initial and boundary conditions.
On the other hand, if we replace uxx Hx, tL by a second-degree central approximation,
HuHx + h, t + kL - 2 uHx, t + kL + uHx - h, t + kLL ë h2 at time t + k, rather than at time t, then
we get a difference equation
HuHx, t + kL - uHx, tLL ê k = HuHx + h, t + kL - 2 uHx, t + kL + uHx - h, t + kLL ë h2 (4)
that cannot be solved for the dependent variable uHx, t + kL in terms of uHx, tL. In this case,
we have an implicit finite-difference method, since the spatial derivative is advanced to
the highest time t + k. In this case, since we have a linear system, we can state the problem
in terms of matrices, and typically we have to solve a matrix problem of the kind
A ÿ X ‡ B. Nonlinear systems have to be handled differently; see Section 3.1.5.
In the symbolic part, MathPDE first extracts the list of all the derivatives of dependent
variables with respect to independent variables from the equations specified by the user.
This is straightforward using symbolic programming. Then an important decision to make
is to choose the finite-difference approximation (FDA) to use for each derivative. This is
based on the following simple algorithm.
Suppose we have to choose an FDA degree for the nth derivative with respect to x of
uHx, tL. We look for all the derivatives of u with respect to x in the given PDE, and find
the highest order, nmax ; we use nmax as the approximation degree for all derivatives of u
with respect to x, no matter what order. The same procedure works for derivatives with re-
spect to other independent variables. The next thing to decide is which discretization to
choose among the 2 nmax + 1 possible choices for the FDA (see Section 3.1.2). We choose
a central-difference approximation scheme for derivatives with respect to spatial variables
and a forward scheme for time derivatives. Implicit schemes can be obtained by advanc-
ing spatial derivatives. It is easy to see that this algorithm leads to the approximation
schemes discussed above for the diffusion equation. MathPDE generates both explicit and
implicit schemes, and the choice between them is made at run time based on considera-
tions of numerical stability (see Section 3.1.3).
For boundary conditions, we choose a forward or a backward scheme, depending on
whether the condition applies at the left or the right boundary.
It is possible for the user to intervene and force a different scheme (see Section 3.1.4).
FD2@2, 2, 2D
81, - 2, 1<
This gives us the coefficients in the resulting stencil (compare with the coefficients on the
right-hand side of equation (2)). A MathPDE function diffApprox@D based on the
above function FD2@D can then be used to obtain the FDA of any derivative. The follow-
ing gives the second-degree (degree = 2) central approximation (kind = 2) to a sec-
ond-order (order = 2) derivative.
This gives the first-degree forward approximation to a first-order time derivative; here h
and k are the step sizes in x and t, respectively. Mixed derivatives can be easily handled
with recursive calls to diffApprox@D, as done by the MathPDE function disÖ
cretize@D that discretizes equations involving derivatives, as illustrated by the dis-
cretization of the following PDE.
- u@x, tD + u@x, 1 + tD
k
discretize@
D@u@x, y, tD, 8x, 2<D + D@u@x, y, tD, 8y, 2<D +
2 D@u@x, y, tD, 8x, 1<, 8y, 1<D ã D@u@x, y, tD, 8t, 2<D,
8u@x@82, 2<, 82, 2<D, y@82, 2<, 82, 2<D, t@82, 1<, 82, 1<DD<,
8h1, h2, k<D
The second argument to the function discretize@D, 8u@x@82, 2<, 82, 2<D,
y@82, 2<, 82, 2<D, t@82, 1<, 82, 1<DD<, specifies the FDA to use for each
derivative that appears in the PDE. It contains the two integers degree and kind to be
passed as arguments to diffApprox@D for each derivative. Thus, the first argument
82, 2< of x means that the FDA must be second degree, central, for the first x derivative
of u; the second argument of x specifies the integers required to approximate the second
derivative of u with respect to x, and so on.
From the inequality on the left, we get k ë h2 § 1 ê H1 - cosHq hLL. Since the smallest value
of cosHq hL is -1, we get
k ë h2 § 1 ê 2 (9)
as the criterion for the difference equation (5) to have a stable solution.
Based on this kind of analysis, MathPDE provides a function stabineq@D that returns
the stability criterion for simple PDEs like diffusion and wave equations. This is used to
help eliminate computational procedures that could be unstable when the step sizes cho-
sen violate the criterion; in such cases, MathPDE selects an appropriate implicit scheme.
There is an important issue that arises in the case of a higher-degree FDA. Let us consider
a fourth-degree central approximation of a spatial derivative.
1 1 4
- u@- 2 + x, tD + u@- 1 + x, tD -
2 12 3
h
5 4 1
u@x, tD + u@1 + x, tD - u@2 + x, tD
2 3 12
Here is the basic algorithm on which SuperLU is based, which is a sparse Gaussian elimi-
nation procedure to solve a matrix equation A ÿ X = B.
Ë Compute an LU decomposition of A, Pr Dr APc Dc = L U. Here, Pr and Pc are row
and column permutation matrices and Dr and Dc are the so-called equilibration ma-
trices, both diagonal. These four matrices are suitably chosen so as to enhance the
sparsity of L and U, numerical stability, and parallelism. In a simple implementa-
tion offered in the subroutine dgssv, the equilibration matrices Dr and Dc are
taken to be identity matrices.
Ë Once we have the LU decomposition, the solution vector X can be efficiently com-
puted using X = Dc Pc U -1 L-1 Pr Dr B, multiplying from right to left.
The sparse matrix A must be provided in the Harwell–Boeing column-compressed format
to save storage. A row-compressed format is also possible, that is, in which A¬ is in col-
umn-compressed format, but involves some preprocessing to transform into the Harwell–
Boeing format; this is followed in the data structure SuperMatrix. In this storage format,
an N µ N sparse matrix A, in which only nnz elements are nonzero, is specified in terms of
three row vectors a@0 : nnz - 1D, asub@0 : nnz - 1D, and xa@0 : ND (that have, respectively,
nnz, nnz, and N + 1 elements).
Ë The successive elements of a@0 : nnz - 1D are obtained by sequentially going over
the columns of A, running down each column, and picking the nonzero elements
of A.
Ë The elements of asub@0 : nnz - 1D are simply the row indices in A of the elements
of a@0 : nnz - 1D .
Ë The kth element of xa@0 : ND, xa@kD, for 1 § k § N, is the total number of nonzero el-
ements of A up to and including the kth column, and xa@0D = 0.
Let us illustrate this storage format for the following sparse matrix (taken from the Su-
perLU user guide [13]).
s 0 u u 0
l u 0 0 0
A= 0 l p 0 0
0 0 0 e u
l l 0 0 r
For this choice of A, N = 5, nnz = 12, and using the indexing conventions of C,
a = Hs l l u l l u p u e u rL, asub = H0 1 4 1 2 4 0 2 0 3 3 4L, and xa = H0 3 6 8 10 12L.
Matrices such as these, along with other information like N, nnz, and the matrix B (that
can be specified as a simple row vector of length N) are required by the SuperLU subrou-
tine dgssv that solves the matrix system A ÿ X = B.
10 10
9 9
8 8
7 7
6 6
5 5
4 4
3 3
2 2
1 1
1 2 3 4 5 6 7 8 9 10 11
The domain is a circle of radius 1, centered at the origin (the point H6, 6L in the grid). The
bounding box is a square with vertices at the points H1, 1L, H11, 1L, H11, 11L, H1, 11L.
1 - y2 <<, 88y, -1, 1<<<. When we treat this domain descriptor as an iterator, it
is clear that all the points inside the unit circle as well as those on its circumference are
covered. Furthermore, only these points, and no other, are covered. In other words, the
actual domain is a subset of the bounding box. For rectangular domains, the actual domain
is the bounding box, whereas for other kinds of geometry, the actual domain is a proper
subset of the bounding box. This is made possible because the limits of one of the inde-
The Mathematica Journal 13 © 2011 Wolfram Media, Inc.
pendent variables, x, are treated as functions of the other independent variable, y.
In MathPDE, this domain is specified in the format 888x, - 1 - y2 ,
MathPDE: A Package to Solve PDEs by Finite Differences 15
2
1 - y <<, 88y, -1, 1<<<. When we treat this domain descriptor as an iterator, it
is clear that all the points inside the unit circle as well as those on its circumference are
actual domain is a subset of the bounding box. For rectangular domains, the actual domain
is the bounding box, whereas for other kinds of geometry, the actual domain is a proper
subset of the bounding box. This is made possible because the limits of one of the inde-
pendent variables, x, are treated as functions of the other independent variable, y.
For our example, here is the lower limit for x.
xLeft1 @yD = - 1 - y2 ;
It is easy to discretize the domain now. Since we know the bounding box, we can obtain
the discretized lower limit of x.
1 HNy - yL H- 1 + yL
1 - RoundB H- 1 + NxL - 1 + 2 AbsB F F
2 H- 1 + NyL2
Here Nx and Ny are the number of grid points in the bounding box in the x and y direc-
tions, respectively. Arguing in the same manner, we have the following formula for the up-
per limit of x.
1 HNy - yL H- 1 + yL
1 + RoundB H- 1 + NxL 1 + 2 AbsB F F
2 H- 1 + NyL2
This is the overall algorithm we use for discretizing spatial domains. When the domain in
question is nonrectangular, there are some issues that we need to be careful about. We
now elaborate on some of these, continuing with the example of a circular domain.
Let us list the points lying on the left and right boundaries of the circle.
886, 1<, 83, 2<, 82, 3<, 81, 4<, 81, 5<,
81, 6<, 81, 7<, 81, 8<, 82, 9<, 83, 10<, 86, 11<<
886, 1<, 89, 2<, 810, 3<, 811, 4<, 811, 5<,
811, 6<, 811, 7<, 811, 8<, 810, 9<, 89, 10<, 86, 11<<
Here, there is a danger if one is not careful. If the point 86, 1< alone is chosen as being
on the circumference on the line y == 1, as is done above, then the lower y neighbor of
85, 2< ( in the interior) is the point 85, 1<, which would be outside the domain. There-
fore, it is necessary to keep all the points 84, 1<, 85, 1<, …, 88, 1< on the circumfer-
ence. Here are improved versions of the definitions for xLeft1 and xRight1.
We remark here that formulas xL1 and xR1 lead to extra computation compared with
xLeft1 and xRight1. However, since these computations are performed only on the
domain boundaries, and not at all the points, the additional burden of this improvised
algorithm is insignificant for large grids.
Let us once again look at the left and right boundaries of the circular domain.
884, 1<, 83, 2<, 82, 3<, 81, 4<, 81, 5<,
81, 6<, 81, 7<, 81, 8<, 82, 9<, 83, 10<, 84, 11<<
888, 1<, 89, 2<, 810, 3<, 811, 4<, 811, 5<,
811, 6<, 811, 7<, 811, 8<, 810, 9<, 89, 10<, 88, 11<<
Although the differences are only on the lines y = 1 and y = Nx, it is important that the
neighbors of all interior points are now treated as being on the boundary, and not outside.
There is a shortcoming of this improvised algorithm: since the points 84, 1<, 85, 1<,
…, 88, 1<are all treated as being on the circumference of the circular domain, the actual
domain used in computations is therefore not exactly circular, but a distorted circle. This
is a price we pay for describing nonrectangular domains using a Cartesian system of coordi-
nates. It can be noted, however, that the extent of this distortion is negligible for large
grids. In cases where such a distortion affects the quality of solution obtained, one needs
to be more careful.
One last point we would like to discuss concerns the notion of subdomains. Above, we
mentioned that the domain is specified as 888x, - 1 - y2 , 1 - y2 <<,
88y, -1, 1<<<, so one could ask why this format is used instead of a simpler iterator
like 88x, - 1 - y2 , 1 - y2 <<, 88y, -1, 1<<.
The reason is that we want to be able to describe more involved domains like this irregu-
lar domain (boundaries shown in solid lines).
Graphics@
8Line@884, 0<, 86, 0<, 86, 4<, 84, 4<, 84, 3<, 80, 3<,
80, 1<, 82, 1<, 82, 2<, 84, 2<, 84, 0<<D, Dashed,
Line@880, 1<, 80, 0<, 84, 0<<D, Line@882, 0<, 82, 1<<D,
Line@880, 4<, 84, 4<<D,
Style@8Text@"x0", 80, 0< - 80, .3<D,
Text@"x1", 82, 0< - 80, .3<D,
Text@"x2", 84, 0< - 80, .3<D,
Text@"x3", 86, 0< - 80, .3<D,
Text@"y0", 80, 0< - 8.3, 0<D,
Text@"y1", 80, 1< - 8.3, 0<D,
Text@"y2", 80, 2< - 8.3, 0<D,
Text@"y3", 80, 3< - 8.3, 0<D,
Text@"y4", 80, 4< - 8.3, 0<D<, FontFamily Ø "Courier",
12D
<, ImageSize Ø 8300, 200<D
y4
y3
y2
y1
y0
x0 x1 x2 x3
This domain can be described using the following list, in which there are two sublists in
the x part of the domain descriptor. We call these sublists subdomains. On the other hand,
the y part has only one subdomain. It is clear that with this approach, we are able to de-
scribe and discretize a wide range of geometries, regular and irregular. The user needs to
be able to describe the functional dependence (between independent variables) that de-
fines the nature of geometry.
One last point related to the notion of subdomains concerns the way to describe boundary
conditions on a segment of the boundary. Suppose we want to apply a Dirichlet boundary
condition u@x, y, tD ã c1 on the line joining the points 8x 1, y 2< and
8x 2, y 2<, which is a segment of the boundary of the domain shown. This is done by in-
cluding a boundary condition like 8888x, x1, x2<<, 88y, y2, y2<<<,
u@x, y, tD == c1< in the problem list. The iterator corresponding to the boundary
above generates the grid points that lie on this boundary segment.
diffusion2dcircle = 9
9
9¶∂8t,1< u@x, y, tD == ¶∂8x,2< u@x, y, tD + ¶∂8y,2< u@x, y, tD=,
8x == - Sqrt@1 - y ^ 2D, u@x, y, tD == 0.<,
8x == Sqrt@1 - y ^ 2D, u@x, y, tD == 0.<,
8t == 0, u@x, y, tD ==
If@x ^ 2 + y ^ 2 < 0.5, 1. - x ^ 2 - y ^ 2, 0D<
=,
8
88x, - Sqrt@1 - y ^ 2D, Sqrt@1 - y ^ 2D<<, 88y, - 1, 1<<
<
=;
The domain 888x, -Sqrt@1 - y^2D, Sqrt@1 - y^2D<<, 88y, -1, 1<<< de-
scribes a circle that we discussed in the previous subsection. When discretized, it becomes
888x, xL1@y, Nx, NyD, xR1@y, Nx, NyD<<, 88y, 1, Ny<<<, where the func-
tions xL1 and xR1 were defined earlier. Having discretized the domain, there now re-
mains the problem of decomposing it into boundary and interior regions, where the
boundary conditions and the difference equations (corresponding to the PDE) must be ap-
plied. We now describe the way in which this is done in MathPDE.
Let us begin by examining the boundary conditions. In the present example, we have two
Dirichlet boundary conditions for u@x, y, tD = 0 at the left and right branches of the
circular domain, x = xL1@y, Nx, NyD and x = xR1@y, Nx, NyD.
Clearly, the interior region begins with the point x = xL1@y, Nx, NyD + 1 and ends
with the point x = xR1@y, Nx, NyD - 1 at each value of y. Furthermore, the points on
the circumference for y = 1, namely, 884, 1<, 85, 1<, 86, 1<, 87, 1<, 88, 1<< (for
Nx = Ny = 11), as well as the points on the circumference for y = Ny,
884, 11<, 85, 11<, 86, 11<, 87, 11<, 88, 11<<, must be part of the boundary. As a result, the
boundaries are described by list1 and list2 and the interior region described by
list3 .
list1 = 888x, xL1@y, Nx, NyD, xL1@y, Nx, NyD<<, 88y, 1, Ny<<<;
list2 = 888x, xR1@y, Nx, NyD, xR1@y, Nx, NyD<<, 88y, 1, Ny<<<;
This is the overall domain decomposition algorithm that MathPDE implements. We now
elaborate on a few issues that arise in connection with matching the difference equations
and the boundary conditions at the boundary.
When the lowest-degree difference approximation is used to generate the difference
equations from the PDE (see Section 3.1.1), the domain for the circle above determines
the set of grid points at which the difference equations apply. However, when we use a
higher-degree difference approximation, matching the difference equations with the
boundary conditions is a tricky issue. As we have already mentioned in Section 3.1.4, we
use the lowest-degree stencil on a few grid layers near the boundary, with the higher-
degree stencil taking over beyond this region into the interior. As a result, the interior
region for the circle must be further decomposed into two subregions: a few layers near
the boundary where the lowest-degree difference equations apply, and the rest of the
interior region where higher-degree equations apply.
For example, here is the difference equation when a fourth-degree spatial scheme is used
for the two-dimensional diffusion equation.
- u@x, y, tD + u@x, y, 1 + tD
ã
dt
1 1 4 5
- u@x, - 2 + y, tD + u@x, - 1 + y, tD - u@x, y, tD +
dy2 12 3 2
4 1
u@x, 1 + y, tD - u@x, 2 + y, tD +
3 12
1 1 4 5
- u@- 2 + x, y, tD + u@- 1 + x, y, tD - u@x, y, tD +
dx2 12 3 2
4 1
u@1 + x, y, tD - u@2 + x, y, tD
3 12
The region where the lowest-degree (i.e., second-degree in this case) stencil applies is this
set of four regions, which is the difference between the regions list3 and stencil4.
888y, 3, - 2 + Ny<, 8x, xL1@y, Nx, NyD + 1, xL1@y, Nx, NyD + 1<<,
88y, 3, - 2 + Ny<, 8x, xR1@y, Nx, NyD - 1, xR1@y, Nx, NyD - 1<<,
88y, 2, 2<, 8x, xL1@y, Nx, NyD + 1, xR1@y, Nx, NyD - 1<<,
88y, - 1 + Ny, - 1 + Ny<,
8x, xL1@y, Nx, NyD + 1, xR1@y, Nx, NyD - 1<<<
Finally, we comment on a correction required in the definitions of xL1 and xR1 that de-
scribe the boundary region. The left and right boundaries that make up the circular domain
meet on the lines y = 1 and y = Ny. As we argued in Section 3.2.1, the boundary inter-
sects each of these lines at a set of points, and not just one point. As a result, all the points
from xL1@1, Nx, NyD to xR1@1, Nx, NyD must be included in the boundary region;
similarly, all the points from xL1@Ny, Nx, NyD to xR1@Ny, Nx, NyD must also be in-
cluded in the boundary region. The original definitions of xL1 and xR1 do not include all
these points, and we must therefore replace them by the set of regions that correctly de-
scribes the boundary region.
8
88x, xL1@y, Nx, NyD, xL1@y, Nx, NyD<, 8y, 2, Ny - 1<<,
88x, xL1@y, Nx, NyD, xR1@y, Nx, NyD - 1<, 8y, 1, 1<<,
88x, xL1@y, Nx, NyD, xR1@y, Nx, NyD - 1<, 8y, Ny, Ny<<,
88x, xR1@y, Nx, NyD, xR1@y, Nx, NyD<, 8y, 1, Ny<<,
<
This list also ensures that points where two boundaries intersect are included in only one
of them, and not counted twice. The domain decomposition algorithm implemented by
MathPDE takes this into account.
We first generate the list deflist after creating a context MathPDE`, whose elements
are of the form 8head, lhs Ø rhs<.
BeginPackage@"MathPDE`"D;
deflist =
:8xL1, xL1@y, Nx, NyD Ø Min@1 + xLeft1@- 1 + y, Nx, NyD,
xLeft1@y, Nx, NyD, 1 + xLeft1@1 + y, Nx, NyDD<,
:xLeft1, xLeft1@y, Nx, NyD Ø
1 HNy - yL H- 1 + yL
1 - RoundB H- 1 + NxL - 1 + 2 F>>;
2 H- 1 + NyL2
DefineFunction@head_, rule_D :=
Module@8pat<,
DownValues@headD = 8<;
pat = Map@ToExpression@StringJoin@ToString@Ò1D, "_"DD &,
ruleP1TD;
DownValues@headD =
8RuleDelayed üü 8HoldPattern üü 8pat<, ruleP2T<<;
D
Off@General::"spell1"D;
Attributes@DefineFunctionD = 8HoldAll<;
DefineFunction@head_, rule_D :=
Module@8pat, min, max, rhs<,
DownValues@headD = 8<;
pat = Map@ToExpression@StringJoin@ToString@Ò1D, "_"DD &,
ruleP1TD;
rhs = ruleP2T ê. Min ß min ê. Max ß max;
DownValues@headD =
8HRuleDelayed üü 8HoldPattern üü 8pat<,
rhs ê. min@a_, b_, c_D ß min@8a, b, c<D ê.
max@a_, b_, c_D ß max@8a, b, c<D<L ê. min ß Min ê.
max ß Max<;
D
Begin@"MathPDE`Private`"D;
MathPDE`xL1
xL1@y_, Nx_, Ny_D := Min@81 + xLeft1@- 1 + y, Nx, NyD, xLeft1@y, Nx, NyD
MathPDE`xLeft1
1 HNy-yL H-1+yL
xLeft1@y_, Nx_, Ny_D := 1 - RoundB H- 1 + NxL - 1 + 2 F
2 H-1+NyL2
End@D;
EndPackage@D;
We note one more thing here. Since the body of xL1 depends explicitly on another
function, xLeft1, it is important that the latter be still undefined when the former is
defined. The sequence of function generations must therefore be arranged with proper
regard for their interdependence. One more thing to note is that the body of each of the
functions automatically generated must involve purely numerical operations and no
symbolic ones. This is important, since we are finally interested in translating the program
into a compiled language (like C++ or Fortran 90) by employing the code generator
MathCode [14].
Some of the functions automatically generated do not have such a simple structure as
xL1. These include, for instance, the function SolvePDE that we encountered in Section
2. Such functions perform more complicated operations, and involve local variables that
must be declared in a Module. Such definitions are generated using special-purpose func-
tions available in MathPDE, and functions like DefineFunction above will not do.
However, the essential idea is still the same, and is based on delayed evaluation and the
use of DownValues.
Needs@"MathCode`"D;
We have to start the context MathPDE`, and mention MathCodeContexts within the
path of the package.
BeginPackage@"MathPDE`", 8MathCodeContexts<D;
However, since the functions xL1 and xLeft1 have already been defined, we simply
end the package.
EndPackage@D;
We next declare the function prototypes. This specifies the data types of all the arguments
and the output. In our simple example, all data types involved are integers.
We then build the C++ code for the functions xL1 and xLeft1 with the following
command.
BuildCode@"MathPDE`"D;
The next command runs the Mathematica code for the function xL1.
InstallCode@D;
MathPDE is installed.
It can be seen that there is a slight enhancement in speed; however, the enhancement fac-
tor depends on the problem. Here is the C++ code generated.
!! MathPDE.cc
#include "MathPDE.h"
#include "MathPDE.icc"
#include <math.h>
void MathPDE_TMathPDEInit ()
{
;
}
int MathPDE_TxL1 ( const int &y, const int &Nx, const int &Ny)
{
return LightMin( make_lightN(3, 1+MathPDE_TxLeft1 (-1+y,
Nx, Ny),
MathPDE_TxLeft1 (y, Nx, Ny), 1+MathPDE_TxLeft1 (1+y,
Nx, Ny) ));
}
int MathPDE_TxLeft1 ( const int &y, const int &Nx, const int
&Ny)
{
return 1+-irint(((-1+Nx)*(-1+2*pow(pow(-1+Ny, -2)*(Ny+-
y)*(-1+y),
0.5)))/2);
}
We compiled just two functions, xL1 and xLeft1. MathPDE automates this sequence of
commands and generates, compiles, and installs code for all the numerical functions auto-
matically generated for the given PDE problem (nine functions, for the example of the
one-dimensional diffusion equation; see Section 2.2). The
TheMathematica
resultingJournal
code13computes the Media,
© 2011 Wolfram so- Inc.
lution to the PDE, as demonstrated in Section 2.3.
26 K. Sheshadri and Peter Fritzson
We compiled just two functions, xL1 and xLeft1. MathPDE automates this sequence of
commands and generates, compiles, and installs code for all the numerical functions auto-
matically generated for the given PDE problem (nine functions, for the example of the
one-dimensional diffusion equation; see Section 2.2). The resulting code computes the so-
lution to the PDE, as demonstrated in Section 2.3.
‡ 4. Examples
This section presents a range of example PDE problems solved using MathPDE: the
examples are chosen to illustrate the many features of MathPDE; for example, higher-
degree approximation schemes, nonlinear problems, different kinds of boundary
condition, non-rectangular geometries, and so on. All the problems are time-dependent
PDE problems, mainly of the parabolic and hyperbolic types.
We now solve a variety of PDE problems using MathPDE. The solution steps involved
are much like in Section 2, and are obvious from the context. If MathPDE is installed on
your system, all the commands should work when executed in the sequence they are given
in below.
Needs@"MathPDE`"D;
diffusion2 = 8
8
8¶∂8t,1< u@x, tD == ¶∂8x,2< u@x, tD<,
8x == 0, ¶∂8x,1< u@x, tD == 0.<,
8x == 1, u@x, tD == 0<,
8t == 0, u@x, tD == If@x < .15, x, 1 - xD<
<,
8
88x, 0, 1<<
<
<;
SetupMathPDE@diffusion2, 8<D
To save space here as well as in the rest of Section 4, we have cut out the detailed com-
ments returned by MathPDE when the function SetupMathPDE is executed.
0.004
0.003
0.002
0.001
20 40 60 80 100
The difference here from the example presented in Section 4 is that the derivative at the
left end of the system is zero, which leads to a different solution profile. In both cases, how-
ever, the solutions decay to a uniform concentration distribution in the long time limit.
We can uninstall the C++ program, and delete all the MathCode-related files if we do not
need them.
UninstallCode@D;
Quit
Needs@"MathPDE`"D;
wave = 8
8
8¶∂8t,2< u@x, tD == H1 ê c ^ 2L ¶∂8x,2< u@x, tD<,
8x == 0, u@x, tD == 0<,
8x == 1, u@x, tD == 0<,
8t == 0, u@x, tD == x H1 - xL, ¶∂8t,1< u@x, tD ã der1<
<,
8
88x, 0, 1<<
<
<;
In this case, we can choose numerical values for c and der1 at run time; the code gener-
ated for SolvePDE is such that these parameters can be passed as real arguments when
we execute the program. We now run SolvePDE by choosing numerical values for these
parameters.
0.25
0.2
0.15
0.1
0.05
20 40 60 80 100
We can choose a different set of values for the parameters of the problem.
20 40 60 80 100
-0.05
-0.1
-0.15
-0.2
We can uninstall the C++ program, and delete all the MathCode-related files if we do not
need them.
UninstallCode@D;
Quit
Needs@"MathPDE`"D;
diffusion2d = 9
9
9¶∂8t,1< u@x, y, tD == ¶∂8x,2< u@x, y, tD + ¶∂8y,2< u@x, y, tD=,
8x == 0, u@x, y, tD == 0<,
8x == 1, u@x, y, tD == 0<,
8y == 0, u@x, y, tD == 0<,
8y == 1, u@x, y, tD == 0<,
8t == 0, u@x, y, tD ==
Exp@- HHx - 0.5L ^ 2 + Hy - 0.5L ^ 2L ê 0.02D<
=,
8
88x, 0, 1<<, 88y, 0, 1<<
<
=;
AbsTime@SetupMathPDE@diffusion2d, 8<DD
ListPlot3D@
list = Table@solutionAt@i, j, 1, tot1, tot2D, 8i, 1, tot1<,
8j, 1, tot2<D,
PlotRange Ø 880, tot1<, 80, tot2<,
80, 0.03781262962361607`<<D
0.03
20
0.02
0.01 15
0
0 10
5
10 5
15
20 0
We can try this example using NDSolve as well. Let us choose the same step sizes as cho-
sen above for MathPDE so as to compare the two solutions.
TimingA
soln =
Quiet ü
NDSolveA
9¶∂8t,1< u@x, y, tD == ¶∂8x,2< u@x, y, tD + ¶∂8y,2< u@x, y, tD,
u@0, y, tD == 0, u@x, 0, tD == 0, u@1, y, tD == 0,
u@x, 1, tD == 0,
u@x, y, 0D == Exp@- HHx - 0.5L ^ 2 + Hy - 0.5L ^ 2L ê 0.02D=,
u, 8x, 0, 1<, 8y, 0, 1<, 8t, 0, 0.5<,
MaxSteps Ø 820, 20, 50<EE
The solution has not homogenized yet, although the solution obtained using MathPDE
was more spread out. However, suppose we let NDSolve automatically choose its step
sizes.
TimingA
soln =
Quiet ü
NDSolveA
9¶∂8t,1< u@x, y, tD == ¶∂8x,2< u@x, y, tD + ¶∂8y,2< u@x, y, tD,
u@0, y, tD == 0, u@x, 0, tD == 0, u@1, y, tD == 0,
u@x, 1, tD == 0,
u@x, y, 0D == Exp@- HHx - 0.5L ^ 2 + Hy - 0.5L ^ 2L ê 0.02D=,
u, 8x, 0, 1<, 8y, 0, 1<, 8t, 0, 5<EE
Now the solution is more spread out, and agrees with the solution produced by MathPDE.
We can uninstall the C++ program, and delete all the MathCode-related files if we do not
need them.
UninstallCode@D;
Quit
Needs@"MathPDE`"D;
diffusion2dcircle = 9
9
9¶∂8t,1< u@x, y, tD == ¶∂8x,2< u@x, y, tD + ¶∂8y,2< u@x, y, tD=,
8x == - Sqrt@1 - y ^ 2D, u@x, y, tD == 0.<,
8x == Sqrt@1 - y ^ 2D, u@x, y, tD == 0.<,
8t == 0, u@x, y, tD ==
Exp@- HHx - 0.5L ^ 2 + Hy - 0.5L ^ 2L ê 0.02D<
=,
8
88x, - Sqrt@1 - y ^ 2D, Sqrt@1 - y ^ 2D<<, 88y, - 1, 1<<
<
=;
The boundary conditions are specified on the left and right semicircles. Since we describe
a nonrectangular domain using Cartesian coordinates, one of the coordinates, x, has been
made to depend on the other, y, in the domain description.
We now set up the problem using MathPDE.
AbsTime@SetupMathPDE@diffusion2dcircle, 8<D;D
In this case MathPDE has generated 21 functions (as opposed to 13 in the previous exam-
ple) that are translated into C++ code and compiled by MathCode. The extra functions in
this case are required to compute the grid for the circular domain.
0.00008
0.00006 50
0.00004
40
0.00002
0 30
10 20
20
30 10
40
50
Although we use Cartesian coordinates to describe a circular domain, the jagged nature of
the circular boundary is not predominant at this level of granularity (50 grid steps in each
of the two directions), and the solution appears fairly smooth.
We can uninstall the C++ program, and delete all the MathCode-related files if we do not
need them.
UninstallCode@D;
Quit
Needs@"MathPDE`"D;
wave2drectangle = 9
9
9H1 ê c ^ 2L ¶∂8t,2< u@x, y, tD ==
A1 I¶∂8x,2< u@x, y, tD + ¶∂8y,2< u@x, y, tDM +
A2 I¶∂8x,1< I¶∂8x,1< u@x, y, tD + ¶∂8y,1< v@x, y, tDMM,
H1 ê c ^ 2L ¶∂8t,2< v@x, y, tD ==
A1 I¶∂8x,2< v@x, y, tD + ¶∂8y,2< v@x, y, tDM +
A2 I¶∂8y,1< I¶∂8x,1< u@x, y, tD + ¶∂8y,1< v@x, y, tDMM=,
8x == 0, u@x, y, tD == 0, v@x, y, tD == 0<,
8x == 1, u@x, y, tD == 0, v@x, y, tD == 0<,
8y == 0, u@x, y, tD == 0, v@x, y, tD == 0<,
8y == 1, u@x, y, tD == 0, v@x, y, tD == 0<,
8t == 0, u@x, y, tD == H1 - xL x H1 - yL y,
¶∂8t,1< u@x, y, tD == 0.1, v@x, y, tD ã H1 - xL x H1 - yL y,
¶∂8t,1< v@x, y, tD == 0.2<
=,
8
88x, 0, 1<<, 88y, 0, 1<<
<
=;
In this problem, there are some parameters, and so we have to input them in a list as an ar-
gument to the setup function.
Let us now compute the solution for a set of values of the parameters.
0
-0.01 20
-0.02
15
-0.03
10
5
10 5
15
20
0.02
20
0
-0.02 15
10
5
10 5
15
20
We can uninstall the C++ program, and delete all the MathCode-related files if we do not
need them.
UninstallCode@D;
Quit
Needs@"MathPDE`"D;
wave2d2circle = 9
9
9H1 ê c ^ 2L ¶∂8t,2< u@x, y, tD ==
A1 I¶∂8x,2< u@x, y, tD + ¶∂8y,2< u@x, y, tDM +
A2 I¶∂8x,1< I¶∂8x,1< u@x, y, tD + ¶∂8y,1< v@x, y, tDMM,
H1 ê c ^ 2L ¶∂8t,2< v@x, y, tD ==
A1 I¶∂8x,2< v@x, y, tD + ¶∂8y,2< v@x, y, tDM +
A2 I¶∂8y,1< I¶∂8x,1< u@x, y, tD + ¶∂8y,1< v@x, y, tDMM=,
8x == - Sqrt@1 - y ^ 2D, u@x, y, tD == 0, v@x, y, tD == 0<,
8x == Sqrt@1 - y ^ 2D, u@x, y, tD == 0, v@x, y, tD == 0<,
8t == 0, u@x, y, tD == Exp@- HHx - 0.4L ^ 2 + Hy - 0.4L ^ 2L ê 0.1D,
¶∂8t,1< u@x, y, tD == 0.1,
v@x, y, tD == Exp@- HHx + 0.4L ^ 2 + Hy + 0.4L ^ 2L ê 0.1D,
¶∂8t,1< v@x, y, tD == 0.2<
=,
8
88x, - Sqrt@1 - y ^ 2D, Sqrt@1 - y ^ 2D<<, 88y, - 1, 1<<
<
=;
0.2
20
0
15
-0.2
10
5
10 5
15
20
0.2 20
0
15
-0.2
10
5
10 5
15
20
We can uninstall the C++ program, and delete all the MathCode-related files if we do not
need them.
UninstallCode@D;
Quit
Needs@"MathPDE`"D;
wave3d =
9
9
9H1 ê c ^ 2L ¶∂8t,2< u@x, y, z, tD ==
A1 I¶∂8x,2< u@x, y, z, tD + ¶∂8y,2< u@x, y, z, tD +
¶∂8z,2< u@x, y, z, tDM +
A2
I¶∂8x,1< I¶∂8x,1< u@x, y, z, tD + ¶∂8y,1< v@x, y, z, tD +
¶∂8z,1< w@x, y, z, tDMM,
H1 ê c ^ 2L ¶∂8t,2< v@x, y, z, tD ==
A1 I¶∂8x,2< v@x, y, z, tD + ¶∂8y,2< v@x, y, z, tD +
¶∂8z,2< v@x, y, z, tDM +
A2
I¶∂8y,1< I¶∂8x,1< u@x, y, z, tD + ¶∂8y,1< v@x, y, z, tD +
¶∂8z,1< w@x, y, z, tDMM,
H1 ê c ^ 2L ¶∂8t,2< w@x, y, z, tD ==
A1 I¶∂8x,2< w@x, y, z, tD + ¶∂8y,2< w@x, y, z, tD +
¶∂8z,2< w@x, y, z, tDM +
A2
I¶∂8z,1< I¶∂8x,1< u@x, y, z, tD + ¶∂8y,1< v@x, y, z, tD +
¶∂8z,1< w@x, y, z, tDMM
=,
8x == - 0.5, u@x, y, z, tD == 0, v@x, y, z, tD == 0,
w@x, y, z, tD == 0<,
8x == 0.5, u@x, y, z, tD == 0, v@x, y, z, tD == 0,
w@x, y, z, tD == 0<,
8y == - 0.5, u@x, y, z, tD == 0, v@x, y, z, tD == 0,
w@x, y, z, tD == 0<,
8y == 0.5, u@x, y, z, tD == 0, v@x, y, z, tD == 0,
w@x, y, z, tD == 0<,
8z == - 2, u@x, y, z, tD == 0, v@x, y, z, tD == 0,
w@x, y, z, tD == 0<,
8z == 2, u@x, y, z, tD == 0, v@x, y, z, tD == 0,
w@x, y, z, tD == 0<,
8t == 0, u@x, y, z, tD ==
Exp@- HHx - 0.04L ^ 2 + Hy - 0.04L ^ 2L ê 0.01D,
¶∂8t,1< u@x, y, z, tD == 0.1,
v@x, y, z, tD == Exp@- HHx + 0.04L ^ 2 + Hy + 0.04L ^ 2L ê 0.01D,
¶∂8t,1< v@x, y, z, tD == 0.2,
w@x, y, z, tD == Exp@- Hz ^ 2L ê 0.01D,
¶∂8t,1< w@x, y, z, tD == 0.3<
=,
8
88x, - 0.5, 0.5<<, 88y, - 0.5, 0.5<<, 88z, - 2, 2<<
<
=;
Here we have taken simple Dirichlet boundary conditions; the practically interesting cases
could have Robin boundary conditions involving normal derivatives of the fields, in
which case we would need to do a little more work to transform the normal derivatives
into suitable combinations of derivatives with respect to Cartesian coordinates.
For this problem, we use a slightly different version of the setup function that does not
make MathCode-related declarations; it returns a list that has the prototype information
about the functions for which C++ code is desired.
We now apply the function MathCodePart to the list mcode to make declarations, gen-
erate C++ code, compile it, and install the executable.
AbsTime@MathCodePart üü mcodeD
8187.3093376 Second, Null<
Let us define a function to extract function values (for u) over a two-dimensional cross
section.
plotlistu@z_D :=
Table@solutionAt@i, j, z, 1, tot1, tot2, tot3D,
8i, 1, tot1<, 8j, 1, tot2<D;
Here is the plot of the dependent variable u over a two-dimensional cross section for
z = H4 - 1L * H1.0 ê 8.0L = 0.375.
ListPlot3D@plotlistu@4DD
0
8
-0.05
6
-0.1
2 4
4
6 2
We can plot the other dependent variables v and w in the same manner. Let us define a
function to extract function values for v over a two-dimensional cross section.
plotlistv@z_D :=
Table@solutionAt@i, j, z, 2, tot1, tot2, tot3D,
8i, 1, tot1<, 8j, 1, tot2<D;
Here is the plot of the dependent variable v over a two-dimensional cross section for
z = H4 - 1L * H1.0 ê 8.0L = 0.375.
ListPlot3D@plotlistv@4DD
0 8
-0.05
6
2 4
4
6 2
Finally, let us define a function to extract function values for w over a two-dimensional
cross section.
plotlistw@z_D :=
Table@solutionAt@i, j, z, 3, tot1, tot2, tot3D,
8i, 1, tot1<, 8j, 1, tot2<D;
Here is the plot of the dependent variable w over a two-dimensional cross section for
z = H4 - 1L * H1.0 ê 8.0L = 0.375.
ListPlot3D@plotlistw@4DD
0.2 8
0.1
6
0
2 4
4
6 2
We can uninstall the C++ program, and delete all the MathCode-related files if we do not
need them.
UninstallCode@D;
Quit
Needs@"MathPDE`"D;
nonlinear =
8
8
8¶∂8t,1< u@x, tD + u@x, tD ¶∂8x,1< u@x, tD == c * ¶∂8x,2< u@x, tD<,
8x == 0, u@x, tD == u1<,
8x == 1, u@x, tD == u1<,
8t == 0, u@x, tD == u1 + x H1 - xL<
<,
8
88x, 0, 1<<
<
<;
In this case, the PDE leads to a nonlinear algebraic system that must be solved iteratively.
Let us choose a small time step of 0.01 and evolve the solution by 100 time steps (i.e., up
to t = 1) for a spatial size of 100 grid points. We first choose c = 1, so we have the advec-
tion-diffusion limit.
0.00002
0.000015
0.00001
-6
5´ 10
20 40 60 80 100
We now solve the problem with c = 0: in this limit, we have the inviscid Burger’s
equation.
0.25
0.2
0.15
0.1
0.05
20 40 60 80 100
The solution varies very strongly in space near the right boundary. This indicates that fi-
nite-difference approximation is not very good for such problems. Indeed, if we evolve
the solution by a further 15 time steps, we can see the quality of the solution deteriorate
further.
0.25
0.2
0.15
0.1
0.05
20 40 60 80 100
Now there are wild fluctuations near the right boundary, and the solution is not reliable.
Let us solve the problem using NDSolve.
0.25
0.2
0.15
0.1
0.05
This agrees well with the solution obtained using MathPDE, and the rapid fall near the
right end of the system must be noticed. Let us now plot the solution at a later time,
t = 1.15.
0.25
0.225
0.2
0.175
0.15
0.125
Now we can see that there are regions where the solution shows strong fluctuations, al-
though there are differences between the solutions obtained by MathPDE and NDSolve.
Examples such as these illustrate the limitations of MathPDE, based as it is on finite-differ-
ence discretization.
We can uninstall the C++ program, and delete all the MathCode-related files if we do not
need them.
UninstallCode@D;
Quit
Needs@"MathPDE`"D;
nonlinear1 =
9
9
9uH0,1L @x, tD == IuH2,0L @x, tDM ^ 2 + c * uH1,0L @x, tD=,
8x == 0, u@x, tD == 0<,
8x == 1, u@x, tD == 0<,
8t == 0, u@x, tD == x H1 - xL<
=,
8
88x, 0, 1<<
<
=;
SetupMathPDE@nonlinear1, 8c<D
0.00075
0.0005
0.00025
20 40 60 80 100
-0.00025
-0.0005
-0.00075
AbsTime@NullD
20 40 60 80 100
-0.002
-0.004
-0.006
-0.008
We can uninstall the C++ program, and delete all the MathCode-related files if we do not
need them.
UninstallCode@D;
Quit
Needs@"MathPDE`"D;
nonlinear2 =
9
9
9uH0,1L @x, tD == IuH2,0L @x, tDM ^ 2 + c * uH1,0L @x, tD=,
9x == 0, uH1,0L @x, tD == 0.=,
8x == 1, u@x, tD == 0<,
8t == 0, u@x, tD == x H1 - xL<
=,
8
88x, 0, 1<<
<
=;
SetupMathPDE@nonlinear2, 8c<D
We solve it for c = 1.
20 40 60 80 100
-0.005
-0.01
-0.015
-0.02
-0.025
Now the solution profile is different, because the derivative at the left boundary must be
zero, according to the boundary condition. Finally, we solve it for c = 0.
Now the solution profile is different, because the derivative at the left boundary must be
zero, according to the boundary condition. Finally, we solve it for c = 0.
AbsTime@SolvePDE@100, 0.01, 0.0, 1, 100, 0.001, 10D;D
82.7439456 Second, Null<
20 40 60 80 100
-0.002
-0.004
-0.006
-0.008
-0.01
We can uninstall the C++ program, and delete all the MathCode-related files if we do not
need them.
UninstallCode@D;
Quit
‡ 5. Conclusion
In this article, we have presented a PDE solving system, MathPDE, that is based on Mathe-
matica. We have demonstrated it for a variety of time-dependent PDE problems, and
made comparisons with NDSolve in a few cases.
We have discussed at length the basic ideas underlying the design of MathPDE. We be-
lieve that there is scope for improvement in many areas, like the adaptive step sizes for
space and time, the way in which higher-degree approximations are implemented, and so
on. The limitations of MathPDE for nonlinear problems are obvious, based as it is on fi-
nite differences.
The main attractions of MathPDE are its ability to handle a wide range of spatial domains
and the generation of a standalone C++ program for performing numerical computation.
‡ References
[1] H. P. Langtangen, “Computational Partial Differential Equations: Numerical Methods and Diff-
pack Programming,” Lecture Notes in Computational Science and Engineering, Vol. 2,
Berlin: Springer-Verlag, 1999.
[2] J. R. Rice and R. F. Boisvert, Solving Elliptic Problems Using ELLPACK, New York:
Springer, 1985. www.cs.purdue.edu/ellpack/ellpack.html.
[3] E. Mossberg, K. Otto, and M. Thuné, “Object-Oriented Software Tools for the Construction
of Preconditioners,” Scientific Programming, 6(3), 1997 pp. 285–295.
www.informatik.uni-trier.de/~ley/db/journals/sp/sp6.html.
[4] K. Åhlander, “An Object-Oriented Framework for PDE Solvers,” Ph.D. thesis, Department of
Scientific Computing, Uppsala University, Sweden, 1999.
uu.diva-portal.org/smash/record.jsf?pid=diva2:162116.
[5] W. D. Henshaw. “Overture Documentation, LLNL Overlapping Grid Project.” (May 23, 2011)
www.llnl.gov/CASC/Overture/henshaw/overtureDocumentation/overtureDocumentation.html.
[6] W. F. Ames, Numerical Methods for Partial Differential Equations, 3rd ed., San Diego: Aca-
demic Press, 1992.
[7] C. F. Gerald and P. O. Wheatley, Applied Numerical Analysis, 5th ed., Reading, MA: Addi-
son-Wesley, 1994.
[8] B. Gustafsson, H.-O. Kreiss, and J. Oliger, Time Dependent Problems and Difference Meth-
ods, New York: Wiley, 1995.
[9] M. Oh, “Modeling and Simulation of Combined Lumped and Distributed Processes,” Ph.D.
thesis, University of London, 1995.
[10] K. Sheshadri and P. Fritzson, “A Mathematica-Based PDE Solver Generator,” Proceedings
of SIMSʼ99, Conference of the Scandinavian Simulation Society, Linköping, Sweden, 1999
pp. 66–78.
[11] K. Sheshadri and P. Fritzson, “A General Symbolic PDE Solver Generator: Explicit
Schemes,” Scientific Programming, 11(1), 2003 pp. 39–55.
dl.acm.org/citation.cfm?id=1240066&CFID=40011545&CFTOKEN=28188005.
[12] K. Sheshadri and P. Fritzson, “A General Symbolic PDE Solver Generator: Beyond Explicit
Schemes,” Scientific Programming, 11(3), 2003 pp. 225–235.
dl.acm.org/citation.cfm?id=1240103.
[13] J. W. Demmel, J. R. Gilbert, and X. S. Li, SuperLU Usersʼ Guide.
crd.lbl.gov/~xiaoye/SuperLU.
[14] P. Fritzson, MathCode C++, Linköping, Sweden: MathCore Engineering AB, 1998.
www.mathcore.com.
[15] B. Fornberg, “Calculation of Weights in Finite Difference Formulas,” SIAM Review, 40(3),
1998 pp. 685–691. amath.colorado.edu/faculty/fornberg/Docs/sirev_cl.pdf.
K. Sheshadri and P. Fritzson, “MathPDE: A Package to Solve PDEs by Finite Differences,” The Mathematica
Journal, 2011. dx.doi.org/doi:10.3888/tmj.13-20.
was a guest researcher with Linköping University, Sweden in 1999, and had a collabora-
tion with the university from 2000 to 2005, when the present work was done. Currently he
is a lead scientist at Connexios Life Sciences, Bangalore, India.
Peter Fritzson is a professor and research director of the Programming Environment
Laboratory at Linköping University. He is also director of the Open Source Modelica
Consortium, director of the MODPROD center for model-based product development,
and vice chairman of the Modelica Association, organizations he helped to establish.
During 1999–2007 he served as chairman of the Scandinavian Simulation Society and
secretary of the European simulation organization, EuroSim. Fritzson’s current research
interests are in software technology, especially programming languages, tools, and
environments; parallel and multicore computing; compilers and compiler generators; and
high-level specification and modeling languages, with special emphasis on tools for
object-oriented modeling and simulation, where he is one of the main contributors and
founders of the Modelica language. Fritzson has authored or coauthored more than 210
technical publications, including 16 books or proceedings.
K. Sheshadri
Peter Fritzson
Programming Environment Laboratory
Department of Computer and Information Science,
Linköping University, S-581 83 Linköping, Sweden
[email protected]
[email protected]