Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
mac.h
Go to the documentation of this file.
1/** @file mac.h
2 */
3/**
4# Incompressible Navier--Stokes solver (MAC formulation)
5
6We wish to approximate numerically the incompressible Navier--Stokes
7equations
8\f[
9\partial_t\mathbf{u}+\nabla\cdot(\mathbf{u}\otimes\mathbf{u}) =
10-\nabla p + \nabla\cdot(\nu\nabla\mathbf{u})
11\f]
12\f[
13\nabla\cdot\mathbf{u} = 0
14\f]
15
16We will use the generic time loop, a CFL-limited timestep and we will
17need to solve a Poisson problem. */
18
19#include "run.h"
20#include "timestep.h"
21#include "poisson.h"
22
23/**
24The Markers-And-Cells (MAC) formulation was first described in the
25pioneering paper of [Harlow and Welch,
261965](/src/references.bib#harlow1965). It relies on a *face*
27discretisation of the velocity components `u.x` and `u.y`, relative to
28the (centered) pressure `p`. This guarantees the consistency of the
29discrete gradient, divergence and Laplacian operators and leads to a
30stable (mode-free) integration. */
31
34
35/**
36The only parameter is the viscosity coefficient \f$\nu\f$.
37
38The statistics for the (multigrid) solution of the Poisson problem are
39stored in `mgp`. */
40
41double nu = 0.;
43
44/**
45We need to explicitly set the zero normal velocity condition. */
46
47u.n[left] = 0;
48u.n[right] = 0;
49u.n[top] = 0;
50u.n[bottom] = 0;
51
52/**
53## Time integration
54
55### Advection--Diffusion
56
57In a first step, we compute \f$\mathbf{u}_*\f$
58\f[
59\frac{\mathbf{u}_* - \mathbf{u}_n}{dt} = \nabla\cdot\mathbf{S}
60\f]
61with \f$\mathbf{S}\f$ the symmetric tensor
62\f[
63\mathbf{S} = - \mathbf{u}\otimes\mathbf{u} + \nu\nabla\mathbf{u} =
64\left(\begin{array}{cc}
65- u_x^2 + 2\nu\partial_xu_x & - u_xu_y + \nu(\partial_yu_x + \partial_xu_y)\\
66\ldots & - u_y^2 + 2\nu\partial_yu_y
67\end{array}\right)
68\f]
69
70The timestep for this iteration is controlled by the CFL condition
71(and the timing of upcoming events). */
72
73double dtmax;
74
75event set_dtmax (i++,last) dtmax = DT;
76
77/** @brief Event: stability (i++,last) */
78void event_stability (void) {
79 dt = dtnext (timestep (u, dtmax));
80}
81
82/** @brief Event: advance (i++,last) */
83void event_advance (void)
84{
85
86 /**
87 We allocate a local symmetric tensor field. To be able to compute the
88 divergence of the tensor at the face locations, we need to
89 compute the diagonal components at the center of cells and the
90 off-diagonal component at the vertices.
91
92 ![Staggering of \f$\mathbf{u}\f$ and \f$\mathbf{S}\f$](/src/figures/Sxx.svg) */
93
94 symmetric tensor S[]; // fixme: this does not work on trees
95
96 /**
97 We average the velocity components at the center to compute the
98 diagonal components. */
99
100 for (int _i = 0; _i < _N; _i++) /* foreach */
101 for (int _d = 0; _d < dimension; _d++)
102 S.x.x[] = - sq(u.x[] + u.x[1,0])/4. + 2.*nu*(u.x[1,0] - u.x[])/Delta;
103
104 /**
105 We average horizontally and vertically to compute the off-diagonal
106 component at the vertices. */
107
108 for (int _i = 0; _i < _N; _i++) /* foreach_vertex */
109 S.x.y[] =
110 - (u.x[] + u.x[0,-1])*(u.y[] + u.y[-1,0])/4. +
111 nu*(u.x[] - u.x[0,-1] + u.y[] - u.y[-1,0])/Delta;
112
113 /**
114 Finally we compute
115 \f[
116 \mathbf{u}_* = \mathbf{u}_n + dt\nabla\cdot\mathbf{S}
117 \f] */
118
119 for (int _i = 0; _i < _N; _i++) /* foreach_face */
120 u.x[] += dt*(S.x.x[] - S.x.x[-1,0] + S.x.y[0,1] - S.x.y[])/Delta;
121}
122
123/**
124### Projection
125
126In a second step we compute
127\f[
128\mathbf{u}_{n+1} = \mathbf{u}_* - \Delta t\nabla p
129\f]
130with the condition
131\f[
132\nabla\cdot\mathbf{u}_{n+1} = 0
133\f]
134This gives the Poisson equation for the pressure
135\f[
136\nabla\cdot(\nabla p) = \frac{\nabla\cdot\mathbf{u}_*}{\Delta t}
137\f] */
138
139/** @brief Event: projection (i++,last) */
141{
142 const vector unity[] = {1.[0],1.[0]};
143 mgp = project (u, p, unity, dt, mgp.nrelax);
144}
trace double timestep(void)
Definition atmosphere.h:37
#define dimension
Definition bitree.h:3
int x
Definition common.h:76
const scalar unity[]
Definition common.h:391
static number sq(number x)
Definition common.h:11
@ top
Definition common.h:123
@ bottom
Definition common.h:123
@ left
Definition common.h:123
@ right
Definition common.h:123
double dt
scalar int i
Definition embed.h:74
double dtnext(double dt)
Definition events.h:276
scalar S
Definition gotm.h:16
void event_stability(void)
Event: stability (i++,last)
Definition mac.h:78
double dtmax
Definition mac.h:73
vector u[]
Definition mac.h:33
void event_projection(void)
Event: projection (i++,last)
Definition mac.h:140
void event_advance(void)
Event: advance (i++,last)
Definition mac.h:83
double nu
The only parameter is the viscosity coefficient .
Definition mac.h:41
scalar p[]
The Markers-And-Cells (MAC) formulation was first described in the pioneering paper of Harlow and Wel...
Definition mac.h:32
mgstats mgp
Definition mac.h:42
event set_dtmax(i++, last) dtmax
trace mgstats project(vector uf, scalar p, const vector alpha=unityf, double dt=1., int nrelax=4)
Definition poisson.h:483
def _i
Definition stencils.h:405
Information about the convergence of the solver is returned in a structure.
Definition poisson.h:112
int nrelax
Definition poisson.h:116
scalar x
Definition common.h:47
scalar y
Definition common.h:49
double DT
Definition utils.h:10