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.

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

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