Fluid Dynamics Building Blocks

FDBB (Fluid Dynamics Building Blocks) is a C++ expression template library for fluid dynamics.

Contents

  1. Introduction
  2. Getting started
  3. Core components
  4. The plain program

Introduction

FDBB is a fluid dynamics expression template library written in C++14 (C++11 by compiler flag) that provides the algorithmic building blocks for developing computational fluid dynamics (CFD) tools. It is designed as a header-only C++ library that can be easily integrated into existing CFD codes by including the main header file fdbb.h.

Philosophy

FDBB is implemented as expression template library that builds on existing vector expression template libraries (ETL). The main features of the FDBB library are:

FDBB currently supports the following ETLs and compilers (tested under Linux/macOS)

ETL Remark Clang GCC 4.9 GCC 5.x GCC 6.x PGI 16.10 OracleStudio 12.5
Armadillo not fully supported yet
Arrayfire version 3.3.x and better yes yes yes yes
Blaze version 3.3 and better yes yes yes yes
CMTL4 not fully supported yet
Eigen version 3.2.x and better with patching yes yes yes yes
IT++ version 4.3.1 with patching yes yes yes yes
MTL4 not fully supported yet
uBLAS not fully supported yet
VexCL developer version yes yes yes yes
ViennaCL developer version (1.8.x) yes yes yes yes

Prerequisites

The FDBB library makes extensively use of C++11 features (auto keyword, variadic templates, etc.) so that a C++ compiler with full C++11 support is a prerequisite. Some ETLs, like Blaze, even require C++14 support. Beside that, additional prerequisites depend on the specific ETL used.

Coding style

The coding style of the FDBB library is based on Google's C++ style guide. The ClangFormat tool is used regularly to ensure a consistent code format.

License

The library is licensed under the Mozilla Public License Version 2.0.

The MPL is a simple copyleft license. The MPL's "file-level" copyleft is designed to encourage contributors to share their modifications with the library, while still allowing them to combine the library with code under other licenses (open or proprietary) with minimal restrictions.


Getting started

Obtaining the latest code

Compiling and running the UnitTests

The FDBB library comes with unit tests for all supported ETLs. The compilation requires configuration using CMake at a new, empty folder (in-source builds are disabled).

1 $ mkdir build
2 $ cd build
3 $ cmake ../path/to/FDBB -DFDBB_BUILD_UNITTESTS=ON -DFDBB_BUILD_UNITTESTS_<ETL>=ON -DFDBB_<FEATURE>=ON
4  -- Build files have been written to: /path/to/build
5 $ make
6  ...
7  [100%] Built

compiles the unit tests for the enabled ETLs and features. To see a complete list of supported ETLs and features run

1 $ mkdir build
2 $ cd build
3 $ ccmake ../path/to/FDBB

and set/unset the configuration in the CMake GUI.

After successful compilation executable unit tests are created at the ./unittests/<ETL>/ subdirectory of the build folder.

All compiled unit tests can be run by executing

1 $ make test

If Doxygen is available on your system, you can compile and open the Doxygen HTML pages by executing

1 $ cd build
2 $ make doc
3  ...
4  Built target doc
5 $ firefox doc/html/index.html

Example: Compiling UnitTests for VexCL

To compile the unit tests for the VexCL library under Linux/MacOSX you need to call CMake as follows:

1 $ mkdir build
2 $ cd build
3 $ cmake ../path/to/FDBB -DFDBB_BUILD_UNITTESTS=ON -DFDBB_BUILD_UNITTESTS_VEXCL=ON -DFDBB_WITH_OCL=ON
4  ...
5  Options:
6  FDBB_BUILD_TESTS...................: OFF
7  FDBB_BUILD_UNITTESTS...............: ON
8 
9  Features:
10  FDBB_CXX_STANDARD..................: 14
11  FDBB_WITH_CUDA.....................: OFF
12  FDBB_WITH_MIC......................: OFF
13  FDBB_WITH_OCL......................: ON
14  FDBB_WITH_OMP......................: OFF
15 
16  UnitTests:
17  FDBB_BUILD_UNITTESTS_DEVICES.......: CPU
18  FDBB_BUILD_UNITTESTS_PERFMODE......: OFF
19  FDBB_BUILD_UNITTESTS_PRECISIONS....: ALL
20  FDBB_BUILD_UNITTESTS_SIZES.........: 1000
21  FDBB_BUILD_UNITTESTS_RUNS..........: 1
22  FDBB_BUILD_UNITTESTS_TESTS.........: ALL
23 
24  FDBB_BUILD_UNITTESTS_ARMADILLO.....: OFF
25  FDBB_BUILD_UNITTESTS_ARRAYFIRE.....: OFF
26  FDBB_BUILD_UNITTESTS_BLAZE.........: OFF
27  FDBB_BUILD_UNITTESTS_CMTL4.........: OFF
28  FDBB_BUILD_UNITTESTS_EIGEN.........: OFF
29  FDBB_BUILD_UNITTESTS_ITPP..........: OFF
30  FDBB_BUILD_UNITTESTS_MTL4..........: OFF
31  FDBB_BUILD_UNITTESTS_UBLAS.........: OFF
32  FDBB_BUILD_UNITTESTS_VEXCL.........: ON
33  FDBB_BUILD_UNITTESTS_VIENNACL......: OFF
34  ...
35  -- Build files have been written to: /path/to/build
36 $ make vexcl-unittest
37  ...
38  [100%] Built
39 $ make test
40  Running tests...
41  Test project /path/to/build
42  Start 1: vexcl-unittest
43  1/1 Test #1: vexcl-unittest ............... Passed 0.02 sec
44 
45  100% tests passed, 0 tests failed out of 1
46 
47  Total Test time (real) = 0.03 sec

Example: Compiling selection of UnitTests

It is also possible to specify a selection of unit tests that should be run by specifying a list/file patterns of tests to be included and a list/file pattern of tests to be excluded.

To perform all unit tests for element-wise operations except for the power function you need to call CMake as follows:

1 $ mkdir build
2 $ cd build
3 $ cmake ../path/to/FDBB -DFDBB_BUILD_UNITTESTS=ON -DFDBB_BUILD_UNITTESTS_VEXCL=ON -DFDBB_WITH_OCL=ON \
4  -DFDBB_UNITTESTS_TESTS=ALL \
5  -DFDBB_UNITTESTS_TESTS_INCLUDE="test_op_elem_*" \
6  -DFDBB_UNITTESTS_TESTS_EXCLUDE="test_op_elem_pow"

Including FDBB into own codes

The FDBB library is included in your program by including the header file

#include "fdbb.h"

By default, FDBB assumes C++14 support enabled and all accelerators and parallelization techniques disabled. This behavior can be changed by enabled one or more of the following flags when compiling your program:


Core components

The FDBB library provides the following core components:

Core components are realized as struct's with static member functions that realize the evaluation of variables, fluxes, and flux-Jacobians.

Equations of state

The FDBB library support the following equations of state (EOS) implemented in the file fdbbEOS.hpp:

Further EOS are planned in an upcoming release making use of the CoolProp project.

Example: EOS for an ideal gas

The strucutre fdbb::EOSidealGas implements the EOS for an ideal gas with specific heat at constant volume \(c_v=\frac{7}{2}R\) and specific heat at constant pressure \(c_p=\frac{5}{2}R\) with \(R=8.3144598(48)\, \frac{J}{mol\cdot K}\) being the ideal gas constant. The absolute pressure can then be computed by passing density \(\rho\) and internal energy per unit mass \(e\)

// Equation of state for ideal gas (rho,e)-variant
typedef fdbb::EOSidealGas<double,
std::ratio<7,2>,
std::ratio<5,2> > eos;
// Compute absolute pressure from density and internal energy per unit mass
auto p = eos::p(rho, e);

Example: user-defined EOS

To create a user-defined EOS, you have to implement a new struct derived from the base class fdbb::EOS_pVT, which represents an EOS of the form \(f(p,V,T)=0\) with absolute pressure \(p\), volume \(V\), and absolute temperature \(T\)

The base class is used internally to detect the interface of the eos::p function that is used during the computation of fluxes and flux-Jacobians.

// Equation of state with user-defined calculate_pressure functions
struct fdbbEOS_new : public fdbbEOS_pVT_rhoe
{
// Return pressure computed from density and energy
template<class Td, class Te>
static inline auto p(const Trho& rho, const Te& e)
-> decltype(calculate_p(rho,e))
{
return calculate_p(rho,e);
}
// Print information about EOS
static std::ostream& print(std::ostream& os)
{
os << "User-defined EOS of the form p=p(d,e)\n";
return os;
}
}

Variables

The FDBB library supports the following variables in one, two and three spatial dimensions:

The struct fdbb::Variables provides static member functions to evaluate both primary and secondary variables. The table below gives an overview of available member functions

Variable name Symbol Function name SI base unit SI derived units
(volumetric mass) density \(\rho\) rho \(\rm kg \cdot m^{-3}\)
velocity \(\mathbf{v}\) v<idim> \(\rm m \cdot s^{-1}\)
velocity magnitude \(\|\mathbf{v}\|\) v_mag \(\rm m \cdot s^{-1}\)
velocity magnitude squared \(\|\mathbf{v}\|^2\) v_mag2 \(\rm m \cdot s^{-1}\)
momentum \(\rho \mathbf{v}\) rhov<idim> \(\rm kg \cdot m \cdot s^{-1}\)
momentum magnitude \(\|\rho \mathbf{v}\|\) rhov_mag \(\rm kg \cdot m \cdot s^{-1}\)
momentum magnitude squared \(\|\rho \mathbf{v}\|^2\) rhov_mag2 \(\rm kg \cdot m \cdot s^{-1}\)
total energy per unit volume \(\rho E\) rhoE \(\rm m^{2} \cdot kg \cdot s^{-2}\) \(\rm J\)
total energy per unit mass \(E\) E \(\rm m^{2} \cdot s^{-2}\) \(\rm J \cdot kg^{-1}\)
internal energy per unit volume \(\rho e\) rhoe \(\rm m^{2} \cdot kg \cdot s^{-2}\) \(\rm J\)
internal energy per unit mass \(e\) e \(\rm m^{2} \cdot s^{-2}\) \(\rm J \cdot kg^{-1}\)
kinetic energy per unit volume \(\rho E_{\rm kin}\) rhoE_kin \(\rm m^{2} \cdot kg \cdot s^{-2}\) \(\rm J\)
kinetic energy per unit mass \(E_{\rm kin}\) E_kin \(\rm m^{2} \cdot s^{-2}\) \(\rm J \cdot kg^{-1}\)
total enthalpy per unit volume \(\rho H\) rhoH \(\rm m^{2} \cdot kg \cdot s^{-2}\) \(\rm J\)
total enthalpy per unit mass \(H\) H \(\rm m^{2} \cdot s^{-2}\) \(\rm J \cdot kg^{-1}\)
internal enthalpy per unit volume \(\rho h\) rhoh \(\rm m^{2} \cdot kg \cdot s^{-2}\) \(\rm J\)
internal enthalpy per unit mass \(h\) h \(\rm m^{2} \cdot s^{-2}\) \(\rm J \cdot kg^{-1}\)

Example: conservative variables

// VexCL context
vex::Context ctx( vex::Filter::CPU && vex::Filter::DoublePrecision );
// Vector length
std::size_t N = 10;
// Conservative variables in 1D
vex::vector<double> u0(ctx, N); // density
vex::vector<double> u1(ctx, N); // momentum
vex::vector<double> u2(ctx, N); // total energy
// Initialization
u0 = 2.0;
u1 = 1.0;
u2 = 5.0;
// Conservative variables in 1D
typedef fdbb::Variables<eos, 1, fdbb::EnumForm::conservative> variables;
// Primary variables
auto d = variables::rho (u0, u1, u2);
auto m = variables::rhov<0>(u0, u1, u2);
auto E = variables::rhoE (u0, u1, u2);
// Secondary variables
auto v = variables::v<0> (u0, u1, u2);

Fluxes

tba

Flux-Jacobians

tba


The plain program

#include <vector>
#include <vexcl/vexcl.hpp>
#include "fdbb.h"
// VexCL context
vex::Context ctx( vex::Filter::CPU && vex::Filter::DoublePrecision );
// Vector length
std::size_t N = 10;
// Conservative variables in 1D
vex::vector<double> u0(ctx, N); // density
vex::vector<double> u1(ctx, N); // momentum
vex::vector<double> u2(ctx, N); // total energy
// Initialization
u0 = 2.0;
u1 = 1.0;
u2 = 5.0;
// Equation of state for ideal gas (rho,e)-variant
typedef fdbb::EOSidealGas<double,
std::ratio<7,2>,
std::ratio<5,2> > eos;
// Conservative variables in 1D
typedef fdbb::Variables<eos, 1, fdbb::EnumForm::conservative> variables;
// Primary variables
auto d = variables::rho (u0, u1, u2);
auto m = variables::rhov<0>(u0, u1, u2);
auto E = variables::rhoE (u0, u1, u2);
// Secondary variables
auto v = variables::v<0>(u0, u1, u2);
auto e = vairable::e (u0, u1, u2);
// Compute absolute pressure from density and internal energy
auto p = eos::p (d, e);

This project has received funding from the European's Horizon 2020 research and innovation programme under grant agreement No 678727, project MOTOR (Multi-ObjecTive design Optimization of fluid eneRgy machines).


Author: Matthias Möller