Hele-Shaw flow solver

    Flows dominated by friction such as Hele-Shaw flows or flows in porous media (Darcy flows) can be modelled as \displaystyle \mathbf{u} = \beta\nabla p with p analogous to a pressure and where \beta can be a function of space and time. If the fluid is also incompressible, p needs to verify the Poisson equation \displaystyle \nabla\cdot(\beta\nabla p) = \zeta

    \beta is often a function of the properties of the fluid such as its composition, temperature and/or density etc… which also requires the solution of advection–diffusion equations.

    In the following we start from the advection solver and add the definition of the velocity through the Poisson equation for the pressure. This is very similar to what is done for the streamfunction–vorticity Navier–Stokes solver.

    #include "advection.h"
    #include "poisson.h"

    We allocate the pressure p and divergence field \zeta. The \beta coefficients need to be defined at face locations to match the locations of the face pressure gradients (and the face velocity components). These two sets of coefficients are stored in a vector field. We also allocate space to store the statistics of the Poisson solver.

    scalar p[], zeta[];
    face vector beta[];
    mgstats mgp;

    We change the default gradient function (used for advection) to minmod-limited (rather than the centered default).

    event defaults (i = 0)
      gradient = minmod2;

    At every timestep, but after all the other events for this timestep have been processed (the ‘last’ keyword), we update the pressure field p by solving the Poisson equation with variable coefficient \beta.

    event pressure (i++, last)
      mgp = poisson (p, zeta, beta);

    We then update the velocity field by computing the face pressure gradients.

      trash ({u});
        u.x[] = beta.x[]*(p[] - p[-1])/Delta;