Jacobi method for heat diffusion problem

The codes covered in class are available, and you can download the tar file with the files. When uncompressed/expanded, both will create a directory named "diffusion", with two subdirectories "c" and "f", for C and Fortran. Choose either, or if you want to, write your own code. In addition, there are files The C/Fortran codes solve a heat diffusion problem on a 2D metal plate, discretized into a (N+2) x (N+2) domain where N is a given mesh parameter. The plate is represented by a 2D array T, although in C it is stored in a 1D array. The update to T on each iteration is in an array dT, standing for "delta T". The outer nodes on the plate, indexed by T(0,:), T(:,0), T(N+1,:), and T(:,N+1), are boundary conditions set by the function BC.c or subroutine BC.f90. The interior nodes, indexed by T(1:N,1:N), are initialized to all zeros.

Your tasks

First, pick C/C++ or Fortran to work with. Make sure you can compile and run the code as is; this may require some changes to the make.inc file to match the platform you are using. If you want, run the code to generate the file "plate" that has a solution in it that you can use to check versions and modification that you make. To do this, set N = 360, tolerance = 1.0e-14, maxits = 500000, and showplate = 1 (for C) or showplate = .true. (for Fortran). That will take some time (I found it took 416909 iterations) and the plate file will be 5 Mbytes. Then save the file as something like "true_solution" or whatever else you want to name it. Then you can use it to check your variants of the code. But don't hand in that file; I can generate the correct solution myself.

The main task is to create three modifications of the function/subroutine jacobi.c or jacobi.f90:

  1. gauss_seidel.c or gauss_seidel.f90, implementing the Gauss-Seidel variant. That is the version which merges the three double-nested loops in the Jacobi version into a single double-nested loop. That will mean the nodes are updated as soon as their update values are known, instead of computing all of the update values in dT and then adding them to T.
  2. omp_jacobi.c or omp_jacobi.f90, where you insert OpenMP directives to make the Jacobi method as fast as possible.
  3. omp_gauss_seidel.c or omp_gauss_seidel.f90, which uses OpenMP to make the Gauss-Seidel method as fast as possible.
Here "as fast as possible" means taking least amount of wall-clock time. According to math theory, the Gauss-Seidel method takes fewer iterations than the Jacobi method does. That does not imply that it will take less time, however.

The main questions will be how much impact does changing to Gauss-Seidel have, how much impact OpenMP has, which of Jacobi or Gauss-Seidel benefits most from using OpenMP, and what kind of OpenMP scheduling (static, dynamic, guided) is best. For the latter, you can get into an infinite number of tests choosing the chunk size for the scheduling. To avoid that, just use default scheduling clauses without specifying the chunksize.

Parameter settings

While testing and debugging your versions it will probably suffice to use the input file "parameters" with the line

128  1234567  1.0e-6  100  1  1
or for Fortran,
128  1234567  1.0e-6  100  .true. 1
Those specify N = 128, maxits = 1234567, tolerance = 1.0e-6, printfrequency = 100, showplate = true, and using method 1 (Jacobi iteration). That will create the convergence and final solution files which you can check against the original version. Once you're confident things are running correctly, use
1000  1234567  1.0e-6  -100  0  1
or for Fortran,
1000  1234567  1.0e-6  -100  .false. 1
Those settings will be suitable for timings and drawing conclusions. You can try larger values of N for fun, but make sure that the run does not terminate from reaching the maximum allowed number of iterations. If that happens, then you cannot draw any conclusions about the relative speed, especially if comparing to a version that did not reach maxits.

Notes and warnings

Most but not all of these points were covered in class:

How and what to hand in

Submit your results through Canvas. In the directory c or f (depending on what language you choose to use) add in a plain text file named "analysis" with your results summarized - this should not take more than one page. Do not use MS Word, LibreOffice Writer, Latex, or some PDF file. Nothing here requires that kind of formating or effort.

Make sure the directory also has your gauss_seidel.*, omp_jacobi.*, and omp_gauss_seidel.* files, where * = c or f90. Also make sure to delete all executable or object files. My makefiles create an executable named "go", and the object files have a .o suffix. The makefiles provided will remove those files do that if you do "make clean" in the directory. Put your name in every file you hand in, as a comment line in the code and as text in your analysis page. Pack the folder using

 tar cf c.tar c 
or
 tar cf f.tar f 
and then submit it via Canvas.


  1. Last Modified: Tue 06 Feb 2018, 06:33 PM