
This demo illustrates how to solve Poisson equation using a mixed
(two-field) formulation. In particular, it illustrates how to

* Use mixed and non-continuous finite element spaces
* Set essential boundary conditions for subspaces and H(div) spaces
* Define a (vector-valued) expression using additional geometry information

Equation and problem definition
-------------------------------

An alternative formulation of Poisson equation can be formulated by
introducing an additional (vector) variable, namely the (negative)
flux: :math:`\sigma = \nabla u`. The partial differential equations
then read

.. math::
   \sigma - \nabla u &= 0 \quad {\rm in} \ \Omega, \\
   \nabla \cdot \sigma &= - f \quad {\rm in} \ \Omega,

with boundary conditions

.. math::
   u = u_0 \quad {\rm on} \ \Gamma_{D},  \\
   \sigma \cdot n = g \quad {\rm on} \ \Gamma_{N}.

The same equations arise in connection with flow in porous media, and
are also referred to as Darcy flow.

After multiplying by test functions :math:`\tau` and :math:`v`,
integrating over the domain, and integrating the gradient term by
parts, one obtains the following variational formulation: find
:math:`\sigma \in \Sigma` and :math:`v \in V` satisfying

.. math::
   \int_{\Omega} (\sigma \cdot \tau + \nabla \cdot \tau \ u) \ {\rm d} x
   &= \int_{\Gamma} \tau \cdot n \ u \ {\rm d} s
   \quad \forall \ \tau \in \Sigma, \\

   \int_{\Omega} \nabla \cdot \sigma v \ {\rm d} x
   &= - \int_{\Omega} f \ v \ {\rm d} x
   \quad \forall \ v \in V.

Here :math:`n` denotes the outward pointing normal vector on the
boundary. Looking at the variational form, we see that the boundary
condition for the flux (:math:`\sigma \cdot n = g`) is now an
essential boundary condition (which should be enforced in the function
space), while the other boundary condition (:math:`u = u_0`) is a
natural boundary condition (which should be applied to the variational
form). Inserting the boundary conditions, this variational problem can
be phrased in the general form: find :math:`(\sigma, u) \in \Sigma_g
\times V` such that

.. math::

   a((\sigma, u), (\tau, v)) = L((\tau, v))
   \quad \forall \ (\tau, v) \in \Sigma_0 \times V

where the variational forms :math:`a` and :math:`L` are defined as

.. math::

   a((\sigma, u), (\tau, v)) &=
     \int_{\Omega} \sigma \cdot \tau + \nabla \cdot \tau \ u
   + \nabla \cdot \sigma \ v \ {\rm d} x \\
   L((\tau, v)) &= - \int_{\Omega} f v \ {\rm d} x
   + \int_{\Gamma_D} u_0 \tau \cdot n  \ {\rm d} s

and :math:`\Sigma_g = \{ \tau \in H({\rm div}) \text{ such that } \tau \cdot n|_{\Gamma_N} = g \}`
and :math:`V = L^2(\Omega)`.

To discretize the above formulation, two discrete function spaces
:math:`\Sigma_h \subset \Sigma` and :math:`V_h \subset V` are needed
to form a mixed function space :math:`\Sigma_h \times V_h`. A stable
choice of finite element spaces is to let :math:`\Sigma_h` be the
Brezzi-Douglas-Marini elements of polynomial order :math:`k` and let
:math:`V_h` be discontinuous elements of polynomial order :math:`k-1`.

We will use the same definitions of functions and boundaries as in the
demo for Poisson's equation. These are:

* :math:`\Omega = [0,1] \times [0,1]` (a unit square)
* :math:`\Gamma_{D} = \{(0, y) \cup (1, y) \in \partial \Omega\}`
* :math:`\Gamma_{N} = \{(x, 0) \cup (x, 1) \in \partial \Omega\}`
* :math:`u_0 = 0`
* :math:`g = \sin(5x)`   (flux)
* :math:`f = 10\exp(-((x - 0.5)^2 + (y - 0.5)^2) / 0.02)`   (source term)

With the above input the solution for :math:`u` and :math:`\sigma` will look as
follows:

.. image:: ../mixed-poisson_u.png
    :scale: 75
    :align: center

.. image:: ../mixed-poisson_sigma.png
    :scale: 75
    :align: center

