# Solvers

## Saint-Venant

${\partial }_{t}{\int }_{\Omega }\mathbf{\text{q}}d\Omega ={\int }_{\partial \Omega }\mathbf{\text{f}}\left(\mathbf{\text{q}}\right)\cdot \mathbf{\text{n}}d\partial \Omega -{\int }_{\Omega }hg\nabla {z}_{b}$ $\mathbf{\text{q}}=\left(\begin{array}{c}\hfill h\hfill \\ \hfill h{u}_{x}\hfill \\ \hfill h{u}_{y}\hfill \end{array}\right),\phantom{\rule{0.278em}{0ex}}\phantom{\rule{0.278em}{0ex}}\phantom{\rule{0.278em}{0ex}}\phantom{\rule{0.278em}{0ex}}\phantom{\rule{0.278em}{0ex}}\phantom{\rule{0.278em}{0ex}}\mathbf{\text{f}}\left(\mathbf{\text{q}}\right)=\left(\begin{array}{cc}\hfill h{u}_{x}\hfill & \hfill h{u}_{y}\hfill \\ \hfill h{u}_{x}^{2}+\frac{1}{2}g{h}^{2}\hfill & \hfill h{u}_{x}{u}_{y}\hfill \\ \hfill h{u}_{x}{u}_{y}\hfill & \hfill h{u}_{y}^{2}+\frac{1}{2}g{h}^{2}\hfill \end{array}\right)$

${\partial }_{t}\left(h{\mathbf{\text{u}}}_{l}\right)+\nabla \cdot \left(h{\mathbf{\text{u}}}_{l}\otimes {\mathbf{\text{u}}}_{l}+\frac{g{h}^{2}}{2}\mathbf{\text{I}}\right)=-gh\nabla {z}_{b}-{\partial }_{z}\left(h\mathbf{\text{u}}w\right)+\nu h{\partial }_{{z}^{2}}\mathbf{\text{u}}$

• Green-Naghdi ${\partial }_{t}{\int }_{\Omega }\mathbf{\text{q}}d\Omega ={\int }_{\partial \Omega }\mathbf{\text{f}}\left(\mathbf{\text{q}}\right)\cdot \mathbf{\text{n}}d\partial \Omega -{\int }_{\Omega }hg\nabla {z}_{b}+h\left(\frac{g}{\alpha }\nabla \eta -D\right)$ $\alpha h\mathcal{\text{𝒯}}\left(D\right)+hD=b$ $b=\left[\frac{g}{\alpha }\nabla \eta +{\mathcal{\text{𝒬}}}_{1}\left(u\right)\right]$

## Systems of conservation laws

${\partial }_{t}\left(\begin{array}{c}\hfill {s}_{i}\hfill \\ \hfill {\mathbf{\text{v}}}_{j}\hfill \end{array}\right)+\nabla \cdot \left(\begin{array}{c}\hfill {\mathbf{\text{F}}}_{i}\hfill \\ \hfill {\mathbf{\text{T}}}_{j}\hfill \end{array}\right)=0$

${\partial }_{t}\mathbf{\text{q}}+\nabla \cdot \left(\mathbf{\text{q}}\mathbf{\text{u}}\right)=-\nabla p+\nabla \cdot \left(\mu \nabla \mathbf{\text{u}}\right)+\rho \mathbf{\text{a}}$ ${\partial }_{t}p+\mathbf{\text{u}}\cdot \nabla p=-\rho {c}^{2}\nabla \cdot \mathbf{\text{u}}$

## Electrohydrodynamics

• Ohmic conduction ${\partial }_{t}{\rho }_{e}=\nabla \cdot \left(K\nabla \varphi \right)$ $\nabla \cdot \left(\epsilon \nabla \varphi \right)=-{\rho }_{e}$
• Ohmic conduction of charged species ${\partial }_{t}{c}_{i}=\nabla \cdot \left({K}_{i}{c}_{i}\nabla \varphi \right)$
• Electrohydrodynamic stresses ${M}_{ij}=\varepsilon \left({E}_{i}{E}_{j}-\frac{{E}^{2}}{2}{\delta }_{ij}\right)$

## Viscoelasticity

$\rho \left[{\partial }_{t}\mathbf{\text{u}}+\nabla \cdot \left(\mathbf{\text{u}}\otimes \mathbf{\text{u}}\right)\right]=-\nabla p+\nabla \cdot \left(2{\mu }_{s}\mathbf{\text{D}}\right)+\nabla \cdot {\mathbf{\text{\tau}}}_{p}+\rho \mathbf{\text{a}}$ ${\mathbf{\text{\tau}}}_{p}=\frac{{\mu }_{p}\mathbf{\text{f_s}}\left(\mathbf{\text{A}}\right)}{\lambda }$ $\Psi =\mathrm{log}\mathbf{\text{A}}$ ${D}_{t}\Psi =\left(\Omega \cdot \Psi -\Psi \cdot \Omega \right)+2\mathbf{\text{B}}+\frac{{e}^{-\Psi }{\mathbf{\text{f}}}_{r}\left({e}^{\Psi }\right)}{\lambda }$

## Other equations

• Hele-Shaw/Darcy flows $\mathbf{\text{u}}=\beta \nabla p$ $\nabla \cdot \left(\beta \nabla p\right)=\zeta$
• Advection ${\partial }_{t}{f}_{i}+\mathbf{\text{u}}\cdot \nabla {f}_{i}=0$
• Interfacial forces $\varphi \mathbf{\text{n}}{\delta }_{s}$
• Reaction–Diffusion $\theta {\partial }_{t}f=\nabla \cdot \left(D\nabla f\right)+\beta f+r$
• Poisson–Helmholtz $\nabla \cdot \left(\alpha \nabla a\right)+\lambda a=b$
• Runge–Kutta time integrators $\frac{\partial \mathbf{\text{u}}}{\partial t}=L\left(\mathbf{\text{u}},t\right)$
• Signed distance field

# General orthogonal coordinates

When not written in vector form, some of the equations above will change depending on the choice of coordinate system (e.g. polar rather than Cartesian coordinates). In addition, extra terms can appear due to the geometric curvature of space (e.g. equations on the sphere). An important simplification is to consider only orthogonal coordinates. In this case, consistent finite-volume discretisations of standard operators (divergence etc…) can be obtained, for any orthogonal curvilinear coordinate system, using only a few additional geometric parameters.

The face vector fm is the scale factor for the length of a face i.e. the physical length is $fm\Delta$ and the scalar field cm is the scale factor for the area of the cell i.e. the physical area is $cm{\Delta }^{2}$. By default, these fields are constant and unity (i.e. the Cartesian metric).

Several metric spaces/coordinate systems are predefined:

# Tracking floating-point exceptions

On systems which support signaling NaNs (such as GNU/Linux), Basilisk is set up so that trying to use an unitialised value will cause a floating-point exception to be triggered and the program to abort. This is particularly useful when developing adaptive algorithms and/or debugging boundary conditions.

To maximise the “debugging potential” of this approach it is also recommended to use the trash() function to reset any field prior to updates. This will guarantee that older values are not mistakenly reused. Note that this call is quite expensive and needs to be turned on by adding -DTRASH=1 to the compilation flags (otherwise it is just ignored).

Doing

ulimit -c unlimited

before running the code will allow generation of core files which can be used for post-mortem debugging (e.g. with gdb).

## Visualising stencils

It is often useful to visualise the values of fields in the stencil which triggered the exception. This can be done using the -catch option of qcc.

We will take this code as an example:

#include "utils.h"

int main()
{
init_grid (16);
scalar a[];
trash ({a});
foreach()
a[] = x;
vector ga[];
}

Copy and paste this into test.c, then do

ulimit -c unlimited
qcc -DTRASH=1 -g -Wall test.c -o test -lm
./test

you should get

Floating point exception (core dumped)

Then do

gdb test core

you should get

...
Core was generated by ./test'.
Program terminated with signal 8, Arithmetic exception.
#0  0x0000000000419dbe in gradients (f=0x7fff5f412430, g=0x7fff5f412420)
at /home/popinet/basilisk/wiki/src/utils.h:203
203		  v.x[] = (s[1,0] - s[-1,0])/(2.*Delta);

i.e. the exception occured in the gradients() function of utils.h.

To visualise the stencil/fields which lead to the exception do

qcc -catch -g -Wall test.c -o test -lm
./test 

you should now get

Caught signal 8 (Floating Point Exception)
Caught signal 6 (Aborted)
Last point stencils can be displayed using (in gnuplot)
set size ratio -1
set key outside
v=0
plot 'cells' w l lc 0, 'stencil' u 1+3*v:2+3*v:3+3*v w labels tc lt 1 title columnhead(3+3*v), 'coarse' u 1+3*v:2+3*v:3+3*v w labels tc lt 3 t ''
Aborted (core dumped)

gnuplot
gnuplot> set size ratio -1
gnuplot> set key outside
gnuplot> v=0
gnuplot> plot 'cells' w l lc 0, 'stencil' u 1+3*v:2+3*v:3+3*v w labels tc lt 1 title columnhead(3+3*v), 'coarse' u 1+3*v:2+3*v:3+3*v w labels tc lt 3 t ''

With some zooming and panning, you should get this picture

The red numbers represent the stencil the code was working on when the exception occured. It is centered on the top-left corner of the domain. Cells both inside the domain and outside (i.e. ghost cells) are represented. While the field inside the domain has been initialised, ghost cell values have not. This causes the gradients() function to generate the exception when it tries to access ghost cell values.

To initialise the ghost-cell values, we need to apply the boundary conditions i.e. add

  boundary ({a});

after initialisation. Recompiling and re-running confirms that this fixes the problem.

Note that the blue numbers are the field values for the parent cells (in the quadtree hierarchy). We can see that these are also un-initialised but this is not a problem since we don’t use them in this example.

The v value in the gnuplot script is important. It controls which field is displayed. v=0 indicates the first field allocated by the program (i.e. a[] in this example), accordingly ga.x[] and ga.y[]` have indices 1 and 2 respectively.