Installation#
Hermes-3 can be installed using CMake or spack. Using CMake is a more manual process which requires you to provide all of the dependencies yourself, but it has been used extensively and the documentation provides a module list for several HPC systems.
Spack capability has recently been added and allows an easy way to install the dependencies, making it much easier to install Hermes-3 without a module environment, e.g. on a workstation or laptop.
Using CMake#
Compilation process#
Compilation is achieved in two stages - the first is configuration where all the compile-time
options are read in. The second is the build which results in a ready-to-use Hermes-3 installation
in a directory named build by default. The build directory name can be changed to have
multiple builds available at the same time.
If you make changes to the code, you can skip straight to the build stage to save time. Only modified files will be recompiled.
Hermes-3 is built using CMake. During configuration BOUT++ will be automatically downloaded as a submodule, together with some dependencies. The correct version of netCDF is downloaded and compiled automatically for convenience. FFTW is assumed to be installed already.
Hermes-3 uses two solvers: SUNDIALS cvode for
time-dependent simulations and the faster PETSc beuler for steady-state transport problems. While SUNDIALS
can be downloaded and installed automatically, PETSc requires manual installation.
Installing with SUNDIALS (cvode) only#
If you only want to use the cvode solver, then the
recommended way to build Hermes-3 links to the SUNDIALS library:
Configure with cmake, downloading and linking to SUNDIALS and NetCDF4:
cmake . -B build -DBOUT_DOWNLOAD_SUNDIALS=ON -DBOUT_DOWNLOAD_NETCDF_CXX4=ON
Build, compiling Hermes-3 and all dependencies using 4 parallel cores (adjust as necessary):
cmake --build build -j 4
Run the unit and integrated tests to check that everything is working:
cd build ctest
Note that the integrated tests require MPI, and so may not run on the head nodes of many computing clusters.
Installing with SUNDIALS and PETSc (beuler)#
The steady-state solver beuler requires PETSc and is often preconditioned using the hypre
package, which is automatically downloaded and configured during PETSc installation.
Here is an example PETSc configure setup:
./configure --with-mpi=yes --download-hypre --download-make --with-fortran-bindings=0 --with-debugging=0
Here is an example working script to automatically download and compile PETSc on Viking2:
mkdir petsc-build
wget https://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-3.17.4.tar.gz
tar xzf petsc-3.17.4.tar.gz
cd petsc-3.17.4
./configure COPTFLAGS="-O3" CXXOPTFLAGS="-O3" FOPTFLAGS="-O3" --download-hypre --with-debugging=0 --prefix=../petsc-build
make -j 4 PETSC_DIR=$PWD PETSC_ARCH=arch-linux-c-opt all
make -j 4 PETSC_DIR=$PWD PETSC_ARCH=arch-linux-c-opt install
make -j 4 PETSC_DIR=$PWD/../petsc-build PETSC_ARCH="" check
and on ARCHER2:
mkdir petsc-build
wget https://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-3.17.4.tar.gz
tar xzf petsc-3.17.4.tar.gz
cd petsc-3.17.4
./configure --CC=cc --CXX=CC --FC=ftn COPTFLAGS="-Ofast" CXXOPTFLAGS="-Ofast" FOPTFLAGS="-Ofast" --with-batch --known-64-bit-blas-indices=0 --known-sdor-returns-double=0 --known-snrm2-returns-double=0 --with-fortran-bindings=0 --download-hypre --with-debugging=0 --prefix=../petsc-build
make -j 4 PETSC_DIR=$PWD PETSC_ARCH=arch-linux-c-opt all
make -j 4 PETSC_DIR=$PWD PETSC_ARCH=arch-linux-c-opt install
make -j 4 PETSC_DIR=$PWD/../petsc-build PETSC_ARCH="" check
And here is a working configure example for Perlmutter:
./configure \
--with-mpi=yes --with-precision=double --with-scalar-type=real --with-shared-libraries=1 \
--with-debugging=0 {C,CXX,F}OPTFLAGS="-O3 -march=native" \
--download-hypre --download-fblaslapack=1 \
--prefix=$HOME/local/petsc-3.22.3
Once PETSc is installed, link it to Hermes-3 using the -DBOUT_USE_PETSC=ON CMake flag:
cmake . -B build -DBOUT_DOWNLOAD_SUNDIALS=ON -DBOUT_DOWNLOAD_NETCDF_CXX4=ON -DBOUT_USE_PETSC=ON
If the PETSC_DIR and PETSC_ARCH environment variables have been set,
then CMake should pick them up. If it doesn’t, try doing a clean build by removing
any previously generated build directories.
Dependencies#
Since Hermes-3 heavily relies on BOUT++, the BOUT++ documentation on installation and dependencies contains a lot of useful information. Below is a selection of working module lists for several HPC systems. It is recommended you start with a clean module environment by executing module purge first.
YPI Workstations:
module load mpi/OpenMPI/4.1.1-GCC-10.3.0
module load devel/CMake/3.20.1-GCCcore-10.3.0
module load numlib/OpenBLAS/0.3.15-GCC-10.3.0
module load lib/FlexiBLAS/3.0.4-GCC-10.3.0
ARCHER2:
module swap PrgEnv-cray/8.3.3
module swap cce/15.0.0
module swap cray-mpich/8.1.23
module load cray-python/3.9.13.1
module load netcdf4
module load cmake
module load cray-hdf5
module load cray-netcdf/4.9.0.1
module load cray-parallel-netcdf/1.12.3.1
module load cray-fftw/3.3.10.3
module load valgrind4hpc
Marconi:
module load tools/git/2.32.0-GCCcore-10.3.0-nodocs
module load mpi/OpenMPI/4.1.1-GCC-10.3.0
module load devel/CMake/3.20.1-GCCcore-10.3.0
module load numlib/OpenBLAS/0.3.15-GCC-10.3.0
module load data/netCDF/4.8.0-gompi-2021a
module load lang/SciPy-bundle/2021.05-foss-2021a
Viking2:
module load OpenMPI/4.1.1-GCC-10.3.0
module load git/2.32.0-GCCcore-10.3.0-nodocs
module load CMake/3.20.1-GCCcore-10.3.0
module load OpenBLAS/0.3.15-GCC-10.3.0
module load netCDF/4.8.0-gompi-2021a
module load SciPy-bundle/2021.05-foss-2021a
Ancalagon:
module load OpenMPI/4.1.1-GCC-10.3.0
module load CMake/3.20.1-GCCcore-10.3.0
module load OpenBLAS/0.3.15-GCC-10.3.0
module load SciPy-bundle/2021.05-foss-2021a
module load netCDF/4.8.0-gompi-2021a
Perlmutter:
source /opt/cray/pe/cpe/23.03/restore_lmod_system_defaults.sh
module load craype-x86-rome
module load libfabric
module load craype-network-ofi
module load xpmem
module load cray-libsci
module load PrgEnv-gnu
module load cray-mpich
module load python
module load cray-fftw
module load cray-hdf5
module load cray-netcdf
Slope (flux) limiter settings#
Advection operators in Hermes-3 use slope limiters, also called flux limiters to suppress spurious numerical oscillations near sharp features, while converging at 2nd-order in smooth regions. In general there is a trade-off between suppression of numerical oscillations and dissipation: Too little dissipation results in oscillations that can cause problems (e.g. negative densities), while too much dissipation smooths out real features and requires higher resolution to converge to the same accuracy. The optimal choice of method is problem-dependent.
The CMake flag -DHERMES_SLOPE_LIMITER sets the choice of slope
limiter. The default method is MC, which has been found to
provide a good balance for problems of interest. If more dissipation
is required then this can be changed to MinMod;
if less dissipation is required then this can be changed
to Superbee.
The appropriate limiter is problem-dependent. MinMod can work well
for 1D tokamak simulations with steep gradients, e.g. simulations of detachment
transients in high power machines which are already under-dissipative
due to the lack of cross-field transport. The use of MinMod in 2D or 3D can
lead to over-dissipation, but greater robustness.
Compiling in debug mode#
Please see the relevant page in the BOUT++ documentation.
Custom versions of BOUT++#
If you have already installed BOUT++ and want to use that rather than
configure and build BOUT++ again, set -DHERMES_BUILD_BOUT=OFF and pass
CMake the path to the BOUT++ build directory e.g.
cmake . -B build -DHERMES_BUILD_BOUT=OFF -DCMAKE_PREFIX_PATH=$HOME/BOUT-dev/build
The version of BOUT++ required by Hermes-3 is periodically updated, and is usually derived
from a commit on the next branch of BOUT++. The up to date commit can be found in the
“external” directory of the Hermes-3 repo.
Custom configuration of CMake#
The CMake configuration can be customised: See the BOUT++
documentation
for examples of using cmake arguments, or edit the compile options
interactively before building:
ccmake . -B build
Troubleshooting issues#
The first step to troubleshooting compilation issues should always to delete build folder for a fresh compilation. This can resolve several types of issues.
There have also been several reported issues due to Conda (e.g. making
BOUT++ pick up the Conda MPI installation instead of the module one). A
workaround is to compile with the CMake flag -DBOUT_IGNORE_CONDA_ENV=ON.
Using Spack#
In this section we describe how to build Hermes-3 using spack to manage the installation of standard packages to your local environment. By default, dependencies like NetCDF4, PETSc and SUNDIALS will be installed automatically, as required, but note that it’s also possible to use your own versions of packages (either system-installed or locally-built). While spack can be used to build Hermes-3 at a particular version, the instructions below also allow you to compile BOUT++ and Hermes-3 as part of a development workflow, i.e. using any changes you have made to the code in the working tree of your local repository.
These instructions were last tested using Ubuntu 22.04.1 and spack version 1.1.0. Spack versions prior to 1.0.0 are not compatible with our package files and are no longer supported. The default environment configuration assumes you have gcc installed.
Install Spack#
Instructions for installing spack on a variety of operating systems can be found in the spack docs. The commands below should work for most Debian-based Linux distributions. First, install some prerequisites, e.g for Ubuntu:
sudo apt update
sudo apt install -y build-essential ca-certificates coreutils curl environment-modules gfortran git gpg lsb-release python3 python3-distutils python3-venv unzip zip
Now, clone spack. You must use version v1.0.0 or newer. At the time of writing this section, version v1.1.0 has been tested:
git clone -c feature.manyFiles=true --depth=2 https://github.com/spack/spack.git -b v1.1.0
Important
If you have an existing spack installation of a version before v1.0.0, you will need to uninstall it first. Do this by uninstalling all packages and deleting the spack directory:
spack uninstall --all
rm -rf ~/.spack
Initialise spack. Add this command to your .bashrc or similar to make spack available in all new shells:
. spack/share/spack/setup-env.sh
The spack command should now be available; e.g.
spack --version
> 1.1.0 (0c2be44e4ece21eb091ad5de4c97716b7c6d4c87)
Libraries and executables associated with spack packages are installed to $SPACK_ROOT/opt/spack
by default ($SPACK_ROOT is wherever you cloned spack to). Build files, however, are placed in
$tmpdir, which usually resolves to /tmp/$USER on Linux systems. Since /tmp is typically
cleaned when you reboot your machine, this can be a problem if you need access to a build at some
later time. To change this behaviour, create a config.yml file:
touch $HOME/.spack/config.yaml
and edit it to include
config:
# Put builds in $SPACK_ROOT rather than $tmpdir
build_stage:
- $spack/var/spack/stage
- $user_cache_path/stage
To add gcc to your user-level package list, and register it as a compiler that spack can use, run
spack compiler find
If you don’t do this, the below instructions should still work, but spack will modify the (version-controlled) environment file, spack.yaml, to include the gcc installation details.
Important
Version 1.1.0 of spack sets the built-in package repository to version releases/v2025.11.
The PETSc package in that version has a bug, related to the Hypre dependency, which causes the installation of BOUT++ to fail.
To work around this you can use the develop version of the spack-packages repo instead.
Edit $SPACK_ROOT/etc/spack/defaults/base/repos.yaml as follows:
repos:
builtin:
git: https://github.com/spack/spack-packages.git
branch: develop # branch: releases/v2025.11
and then run spack repo update.
This workaround should not be required when using spack versions newer than 1.1.0.
Install Hermes-3 and dependencies#
The following instructions assume you have already git-cloned Hermes-3 and are in the root directory of the repository.
First, update the git submodules to ensure that you have the correct version of the BOUT-spack
repository checked out:
git submodule update --init --recursive
Then activate the spack environment described in spack.yaml by using the wrapper script:
. activate_h3env
This file provides some useful bash functions and aliases, but it’s also possible to use standard
spack commands to activate the environment. You should see your prompt change to [hermes-3],
indicating that the spack environment is active.
Note
The wrapper script runs spacktivate . -p -v gcc to load a ‘view’ when activating the
environment. If you choose not to use the wrapper, you’ll need to run a similar command in order
for the instructions below to work. For more info on views, see the spack documentation.
Note
If you’ve run spack install in this environment before, it’s advisable to run spack
concretize -f at this point to ensure the concretized ‘spec’ is up to date. See the spack docs for more details.
To install Hermes-3 and all of its dependencies:
spack install -j 8
where the -j argument controls the number of parallel processes used to build packages.
This initial install takes some time to complete, because spack builds a large number of low-level packages. It’s possible to speed things up by adding system-installed packages to your packages.yaml file, but unless storage space is a big concern, letting spack build its own versions is usually the most trouble-free approach. This step rarely need to be repeated in its entirety unless moving to another version of the same compiler, or switching to a different version of spack itself.
The location in which spack builds packages is set via your user configuration options (see
Install Spack), but for convenience, the environment wrapper script automatically generates links to
the BOUT++ and hermes-3 builds in ./builds/spack/boutpp/[hash] and ./builds/spack/hermes-3/[hash] respectively,
(where [hash] is a label that spack assigns). CMake and compiler output can be found in the spack log files, and the
the build itself in a subdirectory spack-build-[hash]. Build directory links are updated every time a spack install
or spack uninstall command is run.
Changing Hermes-3 and BOUT++ versions#
Sometimes, you may want to change the version of either Hermes-3 or BOUT++. They are included in
the spack environment as develop modules, which means they are compiled from their local directories.
To change the version, simply check out a different commit in either your Hermes-3 repo or the
BOUT++ submodule in external/BOUT-dev and run spack install again.
Tip
It is possible to set a build directory with, e.g. spack develop -p . --build-directory ./builds/mybuild hermes-3, but this modifies spack.yaml and is a bit awkward if you need to switch between builds frequently. A more straightforward approach is to use CMake directly, as described below.
Developing Hermes-3 and BOUT++ in the Spack environment#
A convenient way to build Hermes-3 and BOUT++ in development is to use the dependencies installed via the instructions above, or only install the dependencies in the first place:
spack install --only dependencies -j 8
Having the environment activated provides all of the dependencies for compilation using CMake as
described in Using CMake. The wrapper script provides a bash function in_h3env that
runs commands in the hermes-3 build environment, setting all of the necessary paths to find
headers, link libraries etc. To build with CMake, run (e.g.):
export h3_build="./builds/my_build"
in_h3env cmake -DBOUT_USE_SUNDIALS=ON -DBOUT_USE_PETSC=ON -B "$h3_build"
in_h3env cmake --build "$h3_build" -j8
In the above example, PETSc and SUNDIALS support in BOUT++ are turned on at the configuration stage,
which achieves the same result as spack-installing the hermes-3 package directly, assuming that
the previous step was run without changing the default spec in spack.yaml.
The tests can then be run in the usual way with:
cd ./builds/my_build
ctest -j 3
If Hermes-3 was installed with the +xhermes variant (as it is by default), the tests should pass without having to modify any paths.
Tip
If you don’t need to modify the BOUT++ source code, or only need to make infrequent changes,
Hermes-3 builds can be sped up by integrating any changes into the BOUT++ spack package (rerun
spack install --only dependencies -j 8), then configuring Hermes-3 with
-DHERMES_BUILD_BOUT=OFF. This should automatically pick up the spack-installed BOUT++ library.
Without that configuration setting, the Hermes-3 build will compile its own version of BOUT++ and
will always prefer that to any installed in the spack environment.
Configuration options#
To see which variants of Hermes-3 and BOUT++ are available, run
spack info --no-dependencies --no-versions hermes-3
spack info --no-dependencies --no-versions boutpp
Tip
If you know that CMake functionality exists in BOUT++ or hermes-3 which is not configurable via their respective spack packages, you can create an issue in the package repository to request that the option(s) be added.
By default, the top-level ‘spec’ in the environment is hermes-3%gcc ^boutpp+petsc+sundials ^petsc+hypre+mumps,
which tells spack to configure BOUT++ with SUNDIALS and PETSc support (including HYPRE and MUMPS) and to build
Hermes-3 with gcc. To change this, first modify spack.yaml. to (e.g.) include superlu-dist in
the PETSc build instead of MUMPS:
spack:
specs:
- hermes-3%gcc ^boutpp+petsc+sundials ^petsc+hypre+superlu-dist
...
then (re-)install dependencies as necessary:
spack install --only dependencies -j 8
Important
If you’re installing Hermes-3 and/or BOUT++ with CMake (i.e. after running spack install --only
dependencies), the above command will update the installed dependencies according to the spec in
spack.yaml, but you’ll still need to supply the appropriate configuration options to CMake. If
you’re installing Hermes-3 with spack directly, the correct configuration options will be set
automatically.
Using Spack in HPC environments#
You should be able to use spack on any HPC system by cloning the spack repository and following the
instructions as normal. However, many HPC systems have module environments compiled in a way which
is optimised for that system. In order to take advantage of this, you can configure spack to use
the system modules as ‘external’ packages. You can also use spack external find to automatically
detect any enabled modules and make them available in the spack environment.
See the spack HPC tutorial
for more information on using spack in HPC environments.
Useful spack commands/tips#
Updating your environment#
Most of the time, spack will detect when the ‘spec’ in spack.yaml has changed and run spack
concretize automatically to regenerate all of the package details in spack.lock. If you’ve
made changes that aren’t captured by the ‘spec’ string (for example, if the packages in the
BOUT-spack submodule have been updated) , you’ll need to force the update with
spack concretize -f
If in any doubt, run the above to ensure your environment is updated correctly.
Examining the current environment spec#
To see a list of the packages that are installed / will be installed, run
spack spec
Checking package paths#
To see lib, bin, and include paths for installed packages, run
spack find --paths [package_name]
Changing the build type#
To change the build type of Hermes-3 and/or BOUT++ when spack-installing the packages directly, set their ‘build_type’ variants in spack.yaml, e.g.:
spack:
specs:
- hermes-3%gcc build_type=Debug ^boutpp+petsc+sundials ^petsc+hypre+mumps
Next Steps#
You are now ready to try running the examples in the build/examples/ folder. See https://hermes3.readthedocs.io/en/latest/examples.html.