Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
diffusion.h
Go to the documentation of this file.
1/** @file diffusion.h
2 */
3/**
4# Time-implicit discretisation of reaction--diffusion equations
5
6We want to discretise implicitly the reaction--diffusion equation
7\f[
8\theta\partial_tf = \nabla\cdot(D\nabla f) + \beta f + r
9\f]
10where \f$\beta f + r\f$ is a reactive term, \f$D\f$ is the diffusion
11coefficient and \f$\theta\f$ can be a density term.
12
13Using a time-implicit backward Euler discretisation, this can be
14written
15\f[
16\theta\frac{f^{n+1} - f^{n}}{dt} = \nabla\cdot(D\nabla f^{n+1}) + \beta
17f^{n+1} + r
18\f]
19Rearranging the terms we get
20\f[
21\nabla\cdot(D\nabla f^{n+1}) + (\beta - \frac{\theta}{dt}) f^{n+1} =
22- \frac{\theta}{dt}f^{n} - r
23\f]
24This is a Poisson--Helmholtz problem which can be solved with a
25multigrid solver. */
26
27#include "poisson.h"
28
29/**
30The parameters of the `diffusion()` function are a scalar field `f`,
31scalar fields `r` and \f$\beta\f$ defining the reactive term, the timestep
32`dt` and a vector field containing the diffusion coefficient
33`D`. If `D` or \f$\theta\f$ are omitted they are set to one. If \f$\beta\f$ is
34omitted it is set to zero. Both `D` and \f$\beta\f$ may be constant
35fields.
36
37Note that the `r`, \f$\beta\f$ and \f$\theta\f$ fields will be modified by the solver.
38
39The function returns the statistics of the Poisson solver. */
40
43 vector D = {{-1}}, // default 1
44 scalar r = {-1}, // default 0
45 scalar beta = {-1}, // default 0
46 scalar theta = {-1}) // default 1
47{
48
49 /**
50 If *dt* is zero we don't do anything. */
51
52 if (dt == 0.) {
53 mgstats s = {0};
54 return s;
55 }
56
57 /**
58 We define \f$f\f$ and \f$r\f$ for convenience. */
59
60 scalar ar = automatic (r);
61
62 /**
63 We define a (possibly constant) field equal to \f$\theta/dt\f$. */
64
65 const scalar idt[] = - 1./dt;
66 const scalar theta_idt = theta.i >= 0 ? theta : idt;
67
68 if (theta.i >= 0)
69 for (int _i = 0; _i < _N; _i++) /* foreach */
70 theta[] *= idt[];
71
72 /**
73 We use `r` to store the r.h.s. of the Poisson--Helmholtz solver. */
74
75 if (r.i >= 0)
76 for (int _i = 0; _i < _N; _i++) /* foreach */
77 ar[] = theta_idt[]*f[] - ar[];
78 else // r was not passed by the user
79 for (int _i = 0; _i < _N; _i++) /* foreach */
80 ar[] = theta_idt[]*f[];
81
82 /**
83 If \f$\beta\f$ is provided, we use it to store the diagonal term \f$\lambda\f$. */
84
86 if (beta.i >= 0) {
87 for (int _i = 0; _i < _N; _i++) /* foreach */
88 beta[] += theta_idt[];
89 lambda = beta;
90 }
91
92 /**
93 Finally we solve the system. */
94
95 return poisson (f, ar, D, lambda);
96}
int x
Definition common.h:76
scalar f[]
The primary fields are:
Definition two-phase.h:56
trace mgstats diffusion(scalar f, double dt, vector D={{-1}}, scalar r={-1}, scalar beta={-1}, scalar theta={-1})
The parameters of the diffusion() function are a scalar field f, scalar fields r and defining the re...
Definition diffusion.h:42
double dt
scalar s
Definition embed-tree.h:56
vector D[]
The linear system can be inverted with the multigrid Poisson solver.
vector beta[]
Definition hele-shaw.h:40
def _i
Definition stencils.h:405
Information about the convergence of the solver is returned in a structure.
Definition poisson.h:112
int i
Definition common.h:44
#define poisson(...)
Finally, we overload the poisson() function called by [two-phase.h]() with our new function.
Definition thermal.h:243
double theta
This is the generalised minmod limiter.
Definition utils.h:223
#define lambda