FiniteVolumeSolver
Using AMReX to solve the euler equations with embedded boundaries
Install / Use
/learn @maikel/FiniteVolumeSolverREADME
Finite Volume Solver
This C++17 project provides a framework to solve hyperbolic equations with finite volume methods. The framework assumes an external structured grid library like AMReX or SAMRAI to adaptively refine regions of interest.
One of the main design philosophies is to make the numerical methods re-usable and consistent across different grid implementations. We provide some standard flux methods which can be used out-of-the-box with a large set of hyperbolic equations. Furthermore, a lot of helper classes exist to generate distributed grids for data management which simplifies and modernizes the usage of libraries like AMReX or SAMRAI.
At last, this library is also capable of handling embedded boundaries in a dimensionally split setting as defined in [Klein2009].
We provide a Doxygen documentation.
This framework includes applications that are used in research of combustion processes within a gas turbine. For example, the application AMReX.EB.ConvergentNozzle computes the shock field of a detonation wave that goes through a convergent nozzle within the plenum of a gas turbine
<img src="docs/img/Figure0318.png" />We also investigated the dynamics of multiple tubes that fire in a three-dimensional plenum as shown in the next figure
<img src="docs/img/View-of-the-plenum-with-a-98-blocked-exit-mimicking-the-flow-resistance-of-a-turbine.png" />Installation {#installation}
You can take a look at the GitHub Actions and docker/Containerfile to see the required steps to build this library. Here, we will briefly explain what needs to be done, to compile and link the library against its dependencies.
Conan Configuration {#conan-config}
We use the C++ package manager conan to install dependencies for this library. conan is a python3 package and installable via the python package manager pip3. To install conan open a terminal and use the command
> pip3 install --user conan
to make user-wide installation. You might need to add ${HOME}/.local/bin to your PATH environment variable in case of a user-wide installation.
If you have root access on your machine you can also consider doing a system-wide installation via the command
> sudo pip3 install conan
As a first step, you have to create a conan profile, which describes which toolchain you want to use. To create an auto-detected tool-chain use the command
> conan profile new default --detect
In the case of GCC make sure to use the C++11 ABI. Unfortunately, conan does not choose this by default and we have to adjust the configuration by
> conan profile update settings.compiler.libcxx=libstdc++11 default
> conan profile show default
Configuration for profile default:
[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
compiler=gcc
compiler.version=9
compiler.libcxx=libstdc++11
build_type=Release
[options]
[build_requires]
[env]
Note: The library needs a minimum GCC version of 7 or a minimum LLVM clang version of 5.
We added some custom installation recipes which conan can use to install dependencies like [[AMReX]] or [[HDF5]]. These are stored in the conan subdirectory within this repository.
To create conan packages for our third-party dependencies use commands such as
> conan create /FiniteVolumeSolver/conan/conan-hdf5 HDF5/1.10@local/stable
> conan create /FiniteVolumeSolver/conan/conan-amrex AMReX/development@local/stable
> conan create /FiniteVolumeSolver/conan/conan-vc Vc/1.4.3@local/stable
> conan create /FiniteVolumeSolver/conan/conan-fmt fmt/9.0.0@local/stable
MPI Installation {#mpi-install}
Make sure to have some MPI implementation on your system such that your current conan profile can link against it. This can be achieved by adapting the compiler option of your profile.
CMake Installation {#cmake-install}
CMake is a build generation tool and generates build configuration as Makefiles for example.
Before we start installing all dependencies with conan we need to install a rather new version of CMake. AMReX requires a minimal CMake version of 3.14. Fortunately CMake is quite simple to download and binary packages can be found here.
Building the Library {#build-library}
First use git and clone the library to a local directory
> git clone https://github.com/maikel/FiniteVolumeSolver.git
If you want to build the unit tests you need to pull Catch2 as a git submodule. Enter the source direction and call
> cd FiniteVolumeSolver/
./FiniteVolumeSolver> git submodule update --init
This will checkout the develop branch by default and create a folder named with relative path ./FiniteVolumeSolver. Next, we create an out-of-source build directory where we want to build the library archives and example binaries.
./FiniteVolumeSolver> mkdir build
./FiniteVolumeSolver> cd build
./FiniteVolumeSolver/build> cd build
Inside the build directory we use conan to install the dependencies with the options which we want to use. AMReX for examples has the following configurable build options:
AMReX:eb = True|False [True] # enable embedded boundaries / cut-cells
AMReX:omp = True|False [True] # enable OpenMP parallelization
AMReX:dim = 1|2|3 [3] # spatial dimension used by AMReX
To install [[AMReX]] with embedded boundaries and without OpenMP support (there is no OpenMP support on Apple for example) use within the build directory
./FiniteVolumeSolver/build> conan install <Path-to-FiniteVolumeSolver-Source-Dir> -o AMReX:dim=2 -o AMReX:omp=False
In our case
./FiniteVolumeSolver/build> conan install ../ -o AMReX:dim=2 -o AMReX:omp=False
This will look into the file FiniteVolumeSolver/conanfile.txt and tries to locally install all dependencies which are listed there. After installing these it creates a conanfile.cmake in the build directory which will be read by our CMakeLists.txt file. This, in turn, injects all necessary include and library paths which we need to build our application. Now we use cmake to configure our specific build, i.e.
./FiniteVolumeSolver/build> cmake ../
to configure a Debug build, or
./FiniteVolumeSolver/build> cmake ../ -DCMAKE_BUILD_TYPE=Release
for a Release build. On Linux and macOS this will create Makefiles by default which you can invoke by typing
./FiniteVolumeSolver/build> make
which should build all targets. For other systems, a more general call would be
./FiniteVolumeSolver/build> cmake --build .
Useful build flags
- If you want to link to another python version then the default one you can pass
or directly specify the python executable by-DPYBIND11_PYTHON_VERSION=3.8-DPYTHON_EXECUTABLE=/path/to/python
If some targets fail to build feel free to raise an issue in GitLab.
Code Overview {#code-overview}
We use a layered library design to achieve separation of concerns.
One of the main goals is to have reusable implementations for algorithms which are independent of the concrete storage backend.
We use namespaces to indicate the dependency on various structured grid libraries such as AMReX or SAMRAI.
All components inside of the namespace fub are independent of the concrete AMR backend. Classes and functions of the namespaces fub::amrex or fub::samrai depend on their respective libraries.
This library provides tools to write driver files which form complete applications. Each driver makes its own choices on how to handle program options, input files or its output.
You can find many example applications in the examples/ subfolder within the Git project.
Every example composes layer for layer until a solver is built and run.
An application needs to build up its layers in the following order
- PatchHierarchy (data storage)
- GriddingAlgorithm (algorithmic choice)
- IntegratorContext (data storage / algorithmic choice)
- one or more composed LevelIntegrators (algorithmic choice)
- SubcycleSolver (algorithmic choice)
Note: Each layer in this list is implemented in terms of its predecessor.
Policy Pattern {#policy-pattern}
To provide customization points for the many algorithmic choices in an AMR-enabled simulation we make heavy use of the so-called policy pattern.
Wikipedia: In computer programming, the strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use.
For each algorithmic customization point, we define a concept, which is simply a set of syntactic requirements. Any type which satisfies a particular policy concept can be used as a drop-in replacement for existing algorithms to adjust the method for your special needs. The customization points are chosen to be orthogonal and thus enable them to freely concentrate on a single aspect of the method.
<div class="example"> Any class which has a member function called `UpdateConservatively` with a sufficient function signature satisfies the policy concept for `TimeIntegrator<IntegratorContext>`. This leads to a