# sandbox/jmf/faq

Frequenting Alphabetic Questions

Helping you and myself

# A

## Accuracy

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.

## Adaptivity

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. \ 10^{-3} the mesh is refined, down to a maximum of 8 quad tree levels in this case.

## Axisymmetric

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.

Use

#include "axi.h"

# B

## Backflow

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);
}

## Boundary

How print the boundary values

 foreach_boundary(left)
for (int i = -2; i < 0; i++)
fprintf (stderr, "%g %g %g\n", x + i*Δ, y, s[i]);

## Bugs

To report bugs go to the basilsik bugs page.

# C

## Compilation

Useful flags

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

# D

## 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);
}
foreach()
alphacv[] = 1./ρ(f[]);
}

## Dimensions

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.

On a one-dimensional (1D) grid, there is the x direction which goes from the left to the right boundary, located at x = X0 and x = X0 + L0, respectively. On a 2D grid, there also is a y direction, which goes from the bottom to the top boundary, located at y = Y0 and y = Y0 + L0, respectively. Finally, on a 3D grid there exists an aditional z direction: Going from the back to the front boundary, lozated at z = Z0 and z = Z0 + L0, respectively (i.e. a right-handed coordinate system).

# G

## Gravity

Adding gravity force in the y direction

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

# I

## Initialization

### 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[];
...
foreach_face(x)
u.x[] = y;
foreach_face(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[];
foreach_vertex()
phi[] = sq(DIAMETER/2) - sq(x) - sq(y);
fractions (phi, c);

# K

## kdtquery

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

% cd \$BASILISK
% ln -s kdt/kdtquery
% which kdtquery

# M

## Mask

mask() only works on trees dont use

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

## Macros

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

# O

## Origin

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());

# R

## 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

foreach()
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

srand(time(NULL));

# S

## Surface tension

The surface tension \sigma and interface curvature \kappa 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 \sigma = 1. doing

c.sigma = 1.;

# T

## Teaching

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