Frequenting Alphabetic Questions

Helping you and myself



Basilisk comes with many solves and functions, these have often been tested for their spatio-temporal convergence properties in limiting cases. Apart from the errors that are directly relatable to the discretized approach, the iterative multigrid Poisson solver allows a limited TOLERANCE on the solution’s residuals.


Basilisk uses quadtrees to allow efficient adaptive grid refinement. The first thing we need to do is to remove the line setting the grid to Cartesian i.e.

#include "grid/cartesian.h"   (to remove!!)

and to adapt the resolution according to the (wavelet-estimated) discretisation error of field h at each timestep (i++) we add

event adapt (i++) {
  adapt_wavelet ({h}, (double []){4e-3}, maxlevel = 8);

We have just told Basilisk to adapt the resolution according to the (wavelet-estimated) discretisation error of field h. This adaptation is done at each timestep (i++). Whenever the discretisation error is larger than 4. 103 the mesh is refined, down to a maximum of 8 quad tree levels in this case.


For problems with a symmetry of revolution around the z-axis of a cylindrical coordinate system.

  • The longitudinal coordinate (z-axis) is x and the radial coordinate (r-axis) is y.
  • Note that y (and so Y0) cannot be negative.


#include "axi.h"



To report bugs go to the basilsik bugs page.


Simple outflow conditions (i.e. constant pressure) can lead to undesirable backflows. This can be avoided by imposing a coarse mesh close to the outflow boundary, for example:

event adapt (i++) {
  adapt_wavelet ({u}, (double[]){3e-2,3e-2}, 9, 4);
  unrefine (x > 6);



Useful flags

  • -fopenmp (use openmp)
  • -g (use debugger)
  • -lm (link with math library)
  • -Wall (Warning all)


Density (and viscosity) variable

The density and viscosity are defined here using the arithmetic average.

#define ρ(f) ((f)*rho1 + (1. - (f))*rho2)
#define μ(f) ((f)*mu1 + (1. - (f))*mu2)

event properties (i++) {
  foreach_face() {
    double fm = (f[] + f[-1,0])/2.;
    alphav.x[] = 1./ρ(fm);
    muv.x[] = μ(fm);
    alphacv[] = 1./ρ(f[]);


By default Basilisk runs on a quadtree grid. This also automatically sets a two-dimensional spatial domain.

For the example; 3 Dimensions (octree grid) are defined by an option during the generation of the source file:

qcc -source -grid=octree -D_MPI=1 atomisation.c

So compile with this option, or add:

#include "grid/octree.h"

at the top of your simulation file.



Adding gravity force in the y direction

event acceleration (i++) {
  face vector av = a;
    av.x[] -= 0.98;



Face vector

In some cases, it can be necessary to apply different operations to each component of a face vector field. For example let’s assume we need to initialise a face vector field with the components (y,x). This could be done using

face vector u[];
  u.x[] = y;
  u.y[] = x;

Note that the coordinates x and y correspond to the center of the face.

Volume fraction

To initialize the volume fraction

vertex scalar φ[];
  phi[] = sq(DIAMETER/2) - sq(x) - sq(y);
fractions (phi, c);



kdtquery is in the Basilisk release. There is just a missing symbolic link so that it’s automatically accessible through PATH. We will fix this.

In the meantime just do

% ln -s kdt/kdtquery
% which kdtquery



mask() only works on trees dont use

#include"grid/multigrid.h"       (to remove!!)    


Some macros functions are defined in Basilisk (see src/common.h for details)

@define max(a,b) ((a) > (b) ? (a) : (b))
@define min(a,b) ((a) < (b) ? (a) : (b))
@define sq(x) ((x)*(x))
@define cube(x) ((x)*(x)*(x))
@define sign(x) ((x) > 0 ? 1 : -1)
@define noise() (1. - 2.*rand()/(double)RAND_MAX)
@define clamp(x,a,b) ((x) < (a) ? (a) : (x) > (b) ? (b) : (x))
@define swap(type,a,b) { type tmp = a; a = b; b = tmp; }

If you have problems with some macros please read K&R … to understand up more on how to use C preprocessor directives (i.e. all the keywords starting with #) correctly.

A few tips:

  • always enclose expressions within brackets (see #define clamp)
  • be careful to add dots to floating point constants

Minimal example

When you have a problem dont say “I have a problem” or “Dont work”, first take a look to the mailing list and then post a Minimal example please. This includes considering if the issue can be readily reproduced without a time loop run(), without grid adaptivity, on a lower-dimensional grid, and using a higher-in-heirarchy grid type (i.e. employ a Cartesian grid rather than a multigrid, rather than a tree grid).

Minimal example



By default Basilisk place the origin (0,0) at the bottom of the left corner in 2D. To move it at the cent of the box we can set

X0 = -L0/2;
Y0 = -L0/2;

or the origin()function

origin (-L0/2, -L0/2.);

L0 being the box size.

Output in parallel (MPI)

Apart from the output functions provided by Basilisk, a serially implemented output fuction may not work naively when using MPI. A few tips are:

  • Let only a single thread (pid()) write to the disk:
if (pid() == 0) 
  fprintf(fp, "Hallo, this is pid() %d", pid());
char fname[99];
sprintf(fname, "output_pid%d", pid());
FILE * fp = fopen(fname, "w");
fprintf(fp, "Hallo, this is pid() %d", pid());


Random numbers

The noise() function returns random numbers between -1 and 1, example for setting 0 and 1 in a circle of center (0,0) and of radius 0.2

  a[] = (x*x + y*y < sq(0.2))*(noise() > 0.);
boundary ({a});

To limit the most prominent effects of the deterministic pseudo-random-number generator, you can seed with the UNIX time stamp



Surface tension

The surface tension σ and interface curvature κ are associated to each VOF tracer.

The interface is represented by the volume fraction field c by

#include "vof.h"
#include "tension.h"
scalar c[], * interfaces = {c};

and setting by the way σ=1. doing

c.σ = 1.;



Basilisk is used to teach general computational fluid mechanics, see

  • 1st year Master “Environmental Fluid Mechanics” (P-Y Lagrée) M1EFM
  • ARE course on Saint Venant Equations (G Kirstetter) StVenant