Skip to content

8 - Using External Libraries

While we can make many efforts to write our own optimised data storage and solver routines, a number of libraries exist which will do this far more optimally. In many cases, people will have spent huge amounts of time to write libraries that can perform an action as efficiently as possible, so it is sensible for us to expect their routines to provide a performance increase when compared to ours.

For some smaller routines, you will often be able to find optimal examples shared online, but for larger problems you will often need to incorporate a whole library. In our code, we have facilitated the use of the 'Portable, Extensible Toolkit for Scientific Computation' (PETSc). Installing and using this library is explained in the respective Installation and Compilation sections.

When using an external library, we will generally have to write a 'wrapper' in our code, which provides an interface between our own routines and the routines of the library. An example of this is shown in the code snippets below for the PETSc_Init module, which initialises the PETSc library. We first create our module and use the #include statements to tell the code to use our main path specified in our makefile and then look for this specific file petscsys.h. We then tell it to use petscsys, allowing us to perform actions which require this file, such as initialising PETSc.

module PETSc_Init_Mod
!!Initialize the PETSc Database
#include <petsc/finclude/petscsys.h>
use petscsys

We then write our subroutine which does the actual initialisation, PETSc_Init. We check if the routine has been called already and if not we call PETScInitialize, a routine of the PETSc library. This sets up PETSc such that we can now define our relevant vectors or matrices and then solve the system of equations.

Subroutine PETSc_Init
  PetscErrorCode ierr
  logical :: Called = .false.
  if (.not. Called) then
    Call PetscInitialize(PETSC_NULL_CHARACTER,ierr)
    Called = .true.
    if (ierr /= 0) error stop "Failed to Initialize PETSc"
  end if
end subroutine PETSc_Init

Installing PETSc

The Portable, Extensible Toolkit for Scientific Computation (PETSc) is an optional external library which can be utilised in this problem to solve the system of equations generated by the code. This section will give an explanation of how to download and compile PETSc. Note that the configuring and testing of PETSc may take some time. Installation instructions can also be found at https://petsc.org/release/install/

  • Download a copy of PETSc from: https://petsc.org/release/download/

  • Place the downloaded PETSc folder into the directory of your choice and navigate inside it through a terminal. Configure the code by running:

./configure --download-mpich --download-fblaslapack=1 --prefix=recode
  • Check that the installation was successful by running:
make check

NOTE: save the PETSC_DIR and PETSC_ARCH variables for later, you will be needing them!

Compiling with PETSc

With PETSc installed on your system, the last stage is to set up the environment variables that point to the installation of PETSc. In a terminal copy and paste the following commands but using your own PETSC_DIR and PETSC_ARCH values from before!

export PETSC_DIR="/home/jack/petsc-3.16.0"
export PETSC_ARCH="recode"

Once you have installed PETSc (see installation instructions) and set up the required environment variables, the code can also be compiled to use it instead of the custom storage and solvers.

CMake

Using cmake this can be done by navigating to the build directory and running the following command:

cmake .. -DUSE_PETSC=ON
make all
make install

This should create in the project root the install/bin/diffusion executable, which can be run via

./install/bin/diffusion

FPM - Fortran Package Manager

FPM again is noticeably simpler than cmake. To compile using PETSc in a terminal just type:

fpm run --flag "-DPETSC -I${PETSC_DIR}/include -I${PETSC_DIR}/${PETSC_ARCH}/include" --link-flag "-L${PETSC_DIR}/${PETSC_ARCH}/lib"
Project is up to date
 >Input Read
 >Matrices Created
 >Problem Assembled
 >Output Generated
 >Problem Solved in:  0.658860E-01 seconds

The additional arguments are flags that are passed to the compiler and the linker to ensure that the PETSc libraries are included and linked correctly.