BES is a multi-threaded, three-dimensional unstructured finite volume code written from scratch in C++. It solves the Euler equations implicitly or explicitly, with local time stepping and Courant number adaptation for convergence acceleration. It is written to be a lightweight solver, and has been tested in both Windows 64 bit and Linux Ubuntu 64 bit. Currently it supports meshes in the Gmsh format.

Click the download page to see the binary download options, or check out the code on GitHub. More compilation instructions are given there.


The subsonic 2D case of a NACA0012 airfoil in freestream Mach number of 0.5 at zero angle of attack was calculated and compared with results from AGARD.

The case converged smoothly, almost monotonically within only 500 iterations. The pressure distribution matches the reference results well. Next, a transonic case was simulated to test the shock capturing capabilities of the code. The results were compared against that from Pulliam for a freestream Mach number of 0.8 at 1.25 degrees angle of attack.


Again, we see good agreement of the results from BES. The shock at the top was at the same location, while the bottom shock was a little smeared out. This is because unstructured triangular meshes were used in BES whereas body fitted structured mesh was used in the reference result. The convergence for the transonic case took a little longer. This was because of the moving shock on the top and bottom surfaces taking a while to reach steady state in the simulation. We see that the limiter was working nicely and we were able to reach machine zero eventually.

Using BES

To use BES, you would need 3 items in the case folder:

  1. Configuration file – Specifies solver settings, flow conditions, mesh file and output folder location etc.
  2. Mesh file – Currently Gmsh format supported, boundary conditions specified as physical surfaces/lines in mesh file.
  3. Output folder – Results written in vtk or csv format. Wall properties will also be written if user specifies it.

In the configuration file, the settings and flow conditions are specified. It is a plain text file with comments denoted by double slashes “//“. A sample configuration file is given below. Other than the 6 required options, default values are assigned in the sample configuration file. Valid options for settings are given in the square brackets, and the format is given when more than one numerical value is required for the input.

// Input file for NACA0012 airfoil test case

MESH_FORMAT                     = GMSH            // Required. [GMSH]
MESH_FILE                       = nacaAirfoil.msh // Required. Relative to current directory.

OUTPUT_FORMAT                   = VTK    // [VTK, CSV]
OUTPUT_SLIP_WALL                = NO     // [NO, YES]
OUTPUT_FOLDER                   = output // Required. Relative to current directory.

SOLVER_TYPE                     = EXPLICIT              // [EXPLICIT, IMPLICIT]

EXPLICIT_SCHEME                 = MULTI_STEP                      // [MULTI_STEP], ignored in implicit solver.
MULTI_TIME_STEP_OPTIONS         = 4, 0.0833, 0.2069, 0.4265, 1.0  // Format: NUM_COEFF, COEFF_1, COEFF_2,...

COURANT_NUM                     = 1        // Minimum Courant, constant Courant number when no adaptation.
ADAPTIVE_COURANT_NUM_MAX        = 30       // Maximum Courant number during adaptation
LOCAL_TIME_STEP                 = NO       // [NO, YES]

NUMBER_OF_TIME_STEP             = 500 // Required
SAVE_INTERVAL                   = 100 // Required

FREESTREAM_RAMP                 = 0   // Number of iterations for ramp up. Set <=0 for no ramp.
FREESTREAM_RAMP_START_FRAC      = 0.5 // Fraction of freestream value to set BC with at start of simulation.

VENKATAKRISHNAN_FACTOR          = 5.0             // Parameter in limiter.

FLUX_SCHEME                     = ROE  // [ROE]
HARTEN_CORRECTION_LIMIT         = 0.05 // Local Mach number when correction will take place.

GAS_CONSTANT                    = 287.0 // Perfect gas constant.
SPECIFIC_HEAT_RATIO             = 1.4   // Perfect gas ratio of specific heat.

FREESTREAM_MACH                 = 0.5,0 // Required. Format: U_VEL, V_VEL, W_VEL. Omit W_VEL for 2D cases.

LINEAR_SOLVER_MAX_ITER          = 1000          // Maximum iteration for linear solver.
LINEAR_SOLVER_ABS_TOL           = 1E-7          // Absolute tolerance for linear solver.

Currently, BES supports Gmsh format, with the boundary conditions specified as physical surfaces or lines in the file. The mesh file name also needs to be correctly specified in the configuration file. For example, in the nacaAirfoil.geo file,

Physical Line ("FREESTREAM") = {1, 2, 3, 4};
Physical Line ("SLIP_WALL") = {5};

The physical name FREESTREAM and SLIP_WALL are used to denote freestream and slip wall boundary respectively.

The output folder has to be created before running the case, otherwise BES will not write the results.

With all that in place, you can run BES with the configuration file name as the first argument. For example, in the NACA example case, we run BES on the command line with:

BES nacaAirfoil.besi

Once the calculation is complete, the results can be found in the output folder. The .vtk files can be opened with Paraview.

Like what you see?

If you have any suggestions or spot any bugs in the code, I would greatly appreciate it if you let me know. Further discussion on the theory and programming used in BES can be found in my posts. If you think that you might want a customized code, with additional capabilities, or integration into another software for example, do not hesitate to contact me.

BES is copyright (C) 2018 by Joel Ho Mun Onn and released under version 3.0 of the GNU General Public License. Users are free to use, modify and integrate it with open-source software, but not with closed-source software they wish to distribute (that would require another license).