heat_mpi, a C++ code which solves the 1D Time Dependent Heat Equation using MPI.
This program solves
dUdT - k * d2UdX2 = F(X,T)over the interval [A,B] with boundary conditions
U(A,T) = UA(T), U(B,T) = UB(T),over the time interval [T0,T1] with initial conditions
U(X,T0) = U0(X)
To apply the finite difference method, we define a grid of points X(1) through X(N), and a grid of times T(1) through T(M). In the simplest case, both grids are evenly spaced. We denote by U(I,J) the approximate solution at spatial point X(I) and time T(J).
A second order finite difference can be used to approximate the second derivative in space, using the solution at three points equally separated in space.
A forward Euler approximation to the first derivative in time is used, which relates the value of the solution to its value at a short interval in the future.
Thus, at the spatial point X(I) and time T(J), the discretized differential equation defines a relationship between U(I-1,J), U(I,J), U(I+1,J) and the "future" value U(I,J+1). This relationship can be drawn symbolically as a four node stencil:
U(I,J+1) | | U(I-1,J)-----U(I,J)--------U(I+1,J)
Since we are given the value of the solution at the initial time, we can use the stencil, plus the boundary condition information, to advance the solution to the next time step. Repeating this operation gives us an approximation to the solution at every point in the space-time grid.
To solve the 1D heat equation using MPI, we use a form of domain decomposition. Given P processors, we divided the interval [A,B] into P equal subintervals. Each processor can set up the stencil equations that define the solution almost independently. The exception is that every processor needs to receive a copy of the solution values determined for the nodes on its immediately left and right sides.
Thus, each processor uses MPI to send its leftmost solution value to its left neighbor, and its rightmost solution value to its rightmost neighbor. Of course, each processor must then also receive the corresponding information that its neighbors send to it. (However, the first and last processor only have one neighbor, and use boundary condition information to determine the behavior of the solution at the node which is not next to another processor's node.)
The naive way of setting up the information exchange works, but can be inefficient, since each processor sends a message and then waits for confirmation of receipt, which can't happen until some processor has moved to the "receive" stage, which only happens because the first or last processor doesn't have to receive information on a given step.
It is worth investigating how to improve the information exchange (an exercise for the reader!). The odd processors could SEND while the even processors RECEIVE for instance, guaranteeing that messages would not have to wait in a buffer.
The latest versions of MPI no longer support the special C++ MPI bindings, so the examples given here have reverted to using the C MPI bindings.
The information on this web page is distributed under the MIT license.
heat_mpi is available in a C version and a C++ version and a Fortran90 version.
mpi_test, a C++ code which uses the message passing interface (MPI) for parallel computations in a distributed memory environment.