<br>

<i>
This program was contributed by Martin Kronbichler and Scott Miller.
</i>

<a name="Intro"></a>
<h1>Introduction</h1>

This tutorial program presents the implementation of a hybridizable
discontinuous Galkerin method for the convection-diffusion equation.

<h3> Hybridizable discontinuous Galerkin methods </h3>

One common argument against the use of discontinuous Galerkin elements
is the large number of globally coupled degrees of freedom that one
must solve in an implicit system.  This is because, unlike continuous finite
elements, in typical discontinuous elements there is one degree of freedom at
each vertex <i>for each of the adjacent elements</i>, rather than just one,
and similarly for edges and faces.  As an example of how fast the number of
unknowns grows, consider the FE_DGPMonomial basis: each
scalar solution component is represented by polynomials of degree $p$
with $(1/\text{dim}!) \prod_{i=1}^{\text{dim}}(p+i)$ degrees of freedom per
element. Typically, all degrees of freedom in an element are coupled
to all of the degrees of freedom in the adjacent elements.  The resulting
discrete equations yield very large linear systems very quickly, especially
for systems of equations in 2 or 3 dimensions.

<h4> Reducing the size of the linear system </h4>
To alleviate the computational cost of solving such large linear systems,
the hybridizable discontinuous Galerkin (HDG) methodology was introduced
by Cockburn and co-workers (see the references in the recent HDG overview
article by Nguyen and Peraire @cite Ngu2012).

The HDG method achieves this goal by formulating the mathematical problem using
Dirichlet-to-Neumann mappings.  The partial differential equations are first
written as a first order system, and each field is then discretized via a DG
method.  At this point, the single-valued "trace" values on the skeleton of the
mesh, i.e., element faces, are taken to be independent unknown quantities.
This yields unknowns in the discrete formulation that fall into two categories:
- Face unknowns that only couple with the cell unknowns from both sides of the face;
- Cell unknowns that only couple with the cell and face unknowns
  defined within the same cell. Crucially, no cell interior degree of freedom
  on one cell ever couples to any interior cell degree of freedom of a
  different cell.

The Dirichlet-to-Neumann map concept then permits the following solution procedure:
<ol>
  <li>  Use local element interior data to enforce a Neumann condition on the
skeleton of the triangulation.  The global problem is then to solve for the
trace values, which are the only globally coupled unknowns.
  <li>  Use the known skeleton values as Dirichlet data for solving local
element-level solutions.  This is known as the 'local solver', and is an
<i>embarrassingly parallel</i> element-by-element solution process.
</ol>

<h4> Relation with Static Condensation </h4>
The above procedure also has a linear algebra interpretation---referred to
as <i>static condensation</i>---that was exploited to reduce the size of the
global linear system by Guyan in the context of continuous Finite Elements
@cite G65, and by Fraeijs de Veubeke for mixed methods @cite F65. In the
latter case (mixed formulation), the system reduction was achieved through the
use of discontinuous fluxes combined with the introduction of an additional
auxiliary <i>hybrid</i> variable that approximates the trace of the unknown
at the boundary of every element. This procedure became known as hybridization
and---by analogy---is the reason why the local discontinuous Galerkin method
introduced by Cockburn, Gopalakrishnan, and Lazarov in 2009 @cite CGL2009, and
subsequently developed by their collaborators, eventually came to be known as
the <i>hybridizable discontinuous Galerkin</i> (HDG) method.

Let us write the complete linear system associated to the HDG problem as a
block system with the discrete DG (cell interior) variables $U$ as first block
and the skeleton (face) variables $\Lambda$ as the second block:
@f{eqnarray*}
\begin{pmatrix} A & B \\ C & D \end{pmatrix}
\begin{pmatrix} U \\ \Lambda \end{pmatrix}
=
\begin{pmatrix} F \\ G \end{pmatrix}.
@f}
Our aim is now to eliminate the $U$ block with a Schur complement
approach similar to step-20, which results in the following two steps:
@f{eqnarray*}
(D - C A^{-1} B) \Lambda &=& G - C A^{-1} F, \\
A U &=& F - B \Lambda.
@f}
The point is that the presence of $A^{-1}$ is not a problem because $A$ is a
block diagonal matrix where each block corresponds to one cell and is
therefore easy enough to invert.
The coupling to other cells is introduced by the matrices
$B$ and $C$ over the skeleton variable. The block-diagonality of
$A$ and the structure in $B$ and $C$ allow us to invert the
matrix $A$ element by element (the local solution of the Dirichlet
problem) and subtract $CA^{-1}B$ from $D$. The steps in the Dirichlet-to-Neumann
map concept hence correspond to
<ol>
  <li> constructing the Schur complement matrix $D-C A^{-1} B$ and right hand
    side $G - C A^{-1} F$  <i>locally on each cell</i>
    and inserting the contribution into the global trace matrix in the usual way,
  <li> solving the Schur complement system for $\Lambda$, and
  <li> solving for $U$ using the second equation, given $\Lambda$.
</ol>


<h4> Solution quality and rates of convergence</h4>
Another criticism of traditional DG methods is that the approximate fluxes
converge suboptimally.  The local HDG solutions can be shown to converge
as $\mathcal{O}(h^{p+1})$, i.e., at optimal order.  Additionally, a
super-convergence property can be used to post-process a new approximate
solution that converges at the rate $\mathcal{O}(h^{p+2})$.


<h4> Alternative approaches </h4>

The hybridizable discontinuous Galerkin method is only one way in
which the problems of the discontinuous Galerkin method can be
addressed. Another idea is what is called the "weak Galerkin"
method. It is explored in step-61.


<h3> HDG applied to the convection-diffusion problem </h3>

The HDG formulation used for this example is taken from
<br>
<b>
  N.C. Nguyen, J. Peraire, B. Cockburn:
  <i>An implicit high-order hybridizable discontinuous Galerkin method
  for linear convection–diffusion equations</i>,
  Journal of Computational Physics, 2009, 228:9, 3232-3254.
  <a href="http://dx.doi.org/10.1016/j.jcp.2009.01.030">[DOI]</a>
</b>

We consider the convection-diffusion equation over the domain $\Omega$
with Dirichlet boundary $\partial \Omega_D$ and Neumann boundary
$\partial \Omega_N$:
@f{eqnarray*}
	\nabla \cdot (\mathbf{c} u) - \nabla \cdot (\kappa \nabla u) &=& f,
	\quad \text{ in } \Omega, \\
	u &=& g_D, \quad \text{ on } \partial \Omega_D, \\
	(\mathbf{c} u - \kappa \nabla u)\cdot \mathbf{n} &=& g_N,
	\quad \text{ on }  \partial \Omega_N.
@f}

Introduce the auxiliary variable $\mathbf{q}=-\kappa \nabla u$ and rewrite
the above equation as the first order system:
@f{eqnarray*}
  \mathbf{q} + \kappa \nabla u &=& 0, \quad \text{ in } \Omega, \\
  \nabla \cdot (\mathbf{c} u + \mathbf{q}) &=& f, \quad \text{ in } \Omega, \\
  u &=& g_D, \quad \text{ on } \partial \Omega_D, \\
  (\mathbf{q} + \mathbf{c}u)\cdot\mathbf{n}  &=& g_N,
	\quad \text{ on }  \partial \Omega_N.
@f}

We multiply these equations by the weight functions $\mathbf{v}, w$
and integrate by parts over every element $K$ to obtain:
@f{eqnarray*}
  (\mathbf{v}, \kappa^{-1} \mathbf{q})_K - (\nabla\cdot\mathbf{v}, u)_K
    + \left<\mathbf{v}\cdot\mathbf{n}, {\hat{u}}\right>_{\partial K} &=& 0, \\
  - (\nabla w, \mathbf{c} u + \mathbf{q})_K
    + \left<w, (\widehat{\mathbf{c} u}+{\hat{\mathbf{q}}})\cdot\mathbf{n}\right>_{\partial K}
    &=& (w,f)_K.
@f}

The terms decorated with a hat denote the numerical traces (also commonly referred
to as numerical fluxes).  They are approximations
to the interior values on the boundary of the element.  To ensure conservation,
these terms must be single-valued on any given element edge $\partial K$ even
though, with discontinuous shape functions, there may of course be multiple
values coming from the cells adjacent to an interface.
We eliminate the numerical trace $\hat{\mathbf{q}}$ by using traces of the form:
@f{eqnarray*}
  \widehat{\mathbf{c} u}+\hat{\mathbf{q}} = \mathbf{c}\hat{u} + \mathbf{q}
  + \tau(u - \hat{u})\mathbf{n} \quad \text{ on } \partial K.
@f}

The variable $\hat {u}$ is introduced as an additional independent variable
and is the one for which we finally set up a globally coupled linear
system. As mentioned above, it is defined on the element faces and
discontinuous from one face to another wherever faces meet (at
vertices in 2d, and at edges and vertices in 3d).
Values for $u$ and $\mathbf{q}$ appearing in the numerical trace function
are taken to be the cell's interior solution restricted
to the boundary $\partial K$.

The local stabilization parameter $\tau$ has effects on stability and accuracy
of HDG solutions; see the literature for a further discussion. A stabilization
parameter of unity is reported to be the choice which gives best results. A
stabilization parameter $\tau$ that tends to infinity prohibits jumps in the
solution over the element boundaries, making the HDG solution approach the
approximation with continuous finite elements. In the program below, we choose
the stabilization parameter as
@f{eqnarray*}
  \tau = \frac{\kappa}{\ell} + |\mathbf{c} \cdot \mathbf{n}|
@f}
where we set the diffusion $\kappa=1$ and the diffusion length scale to
$\ell = \frac{1}{5}$.

The trace/skeleton variables in HDG methods are single-valued on element
faces.  As such, they must strongly represent the Dirichlet data on
$\partial\Omega_D$.  This means that
@f{equation*}
  \hat{u}|_{\partial \Omega_D} = g_D,
@f}
where the equal sign actually means an $L_2$ projection of the boundary
function $g$ onto the space of the face variables (e.g. linear functions on
the faces). This constraint is then applied to the skeleton variable $\hat{u}$
using inhomogeneous constraints by the method
VectorTools::project_boundary_values.

Summing the elemental
contributions across all elements in the triangulation, enforcing the normal
component of the numerical flux, and integrating by parts
on the equation weighted by $w$, we arrive at the final form of the problem:
Find $(\mathbf{q}_h, u_h, \hat{u}_h) \in
\mathcal{V}_h^p \times \mathcal{W}_h^p \times \mathcal{M}_h^p$ such that
@f{align*}
  (\mathbf{v}, \kappa^{-1} \mathbf{q}_h)_{\mathcal{T}}
    - ( \nabla\cdot\mathbf{v}, u_h)_{\mathcal{T}}
    + \left<\mathbf{v}\cdot\mathbf{n}, \hat{u}_h\right>_{\partial\mathcal{T}}
    &= 0,
    \quad &&\forall \mathbf{v} \in \mathcal{V}_h^p,
\\
   - (\nabla w, \mathbf{c} u_h)_{\mathcal{T}}
   + (w, \nabla \cdot \mathbf{q}_h)_{\mathcal{T}}
   + (w, (\mathbf{c}\cdot\mathbf{n}) \hat{u}_h)_{\partial \mathcal{T}}
    + \left<w, \tau (u_h - \hat{u}_h)\right>_{\partial \mathcal{T}}
    &=
    (w, f)_{\mathcal{T}},
    \quad &&\forall w \in \mathcal{W}_h^p,
\\
  \left< \mu, \hat{u}_h\mathbf{c} \cdot \mathbf{n}
  		+ \mathbf{q}_h\cdot \mathbf{n}
  	    + \tau (u_h - \hat{u}_h)\right>_{\partial \mathcal{T}}
    &=
    \left<\mu, g_N\right>_{\partial\Omega_N},
    \quad &&\forall \mu \in \mathcal{M}_h^p.
@f}

The unknowns $(\mathbf{q}_h, u_h)$ are referred to as local variables; they are
represented as standard DG variables.  The unknown $\hat{u}_h$ is the skeleton
variable which has support on the codimension-1 surfaces (faces) of the mesh.

We use the notation $(\cdot, \cdot)_{\mathcal{T}} = \sum_K (\cdot, \cdot)_K$
to denote the sum of integrals over all cells and $\left<\cdot,
\cdot\right>_{\partial \mathcal{T}} = \sum_K \left<\cdot,
\cdot\right>_{\partial K}$ to denote integration over all faces of all cells,
i.e., interior faces are visited twice, once from each side and with
the corresponding normal vectors. When combining the contribution from
both elements sharing a face, the above equation yields terms familiar
from the DG method, with jumps of the solution over the cell boundaries.

In the equation above, the space $\mathcal {W}_h^{p}$ for the scalar variable
$u_h$ is defined as the space of functions that are tensor
product polynomials of degree $p$ on each cell and discontinuous over the
element boundaries $\mathcal Q_{-p}$, i.e., the space described by
<code>FE_DGQ<dim>(p)</code>. The space for the gradient or flux variable
$\mathbf{q}_i$ is a vector element space where each component is
a locally polynomial and discontinuous $\mathcal Q_{-p}$. In the code below,
we collect these two local parts together in one FESystem where the first @p
dim components denote the gradient part and the last scalar component
corresponds to the scalar variable. For the skeleton component $\hat{u}_h$, we
define a space that consists of discontinuous tensor product polynomials that
live on the element faces, which in deal.II is implemented by the class
FE_FaceQ. This space is otherwise similar to FE_DGQ, i.e., the solution
function is not continuous between two neighboring faces, see also the results
section below for an illustration.

In the weak form given above, we can note the following coupling patterns:
<ol>
  <li> The matrix $A$ consists of local-local coupling terms.  These arise when the
  local weighting functions $(\mathbf{v}, w)$ multiply the local solution terms
  $(\mathbf{q}_h, u_h)$. Because the elements are discontinuous, $A$
  is block diagonal.
  <li> The matrix $B$ represents the local-face coupling.  These are the terms
  with weighting functions $(\mathbf{v}, w)$ multiplying the skeleton variable
  $\hat{u}_h$.
  <li> The matrix $C$ represents the face-local coupling, which involves the
  weighting function $\mu$ multiplying the local solutions $(\mathbf{q}_h, u_h)$.
  <li>  The matrix $D$ is the face-face coupling;
  terms involve both $\mu$ and $\hat{u}_h$.
</ol>

<h4> Post-processing and super-convergence </h4>

One special feature of the HDG methods is that they typically allow for
constructing an enriched solution that gains accuracy. This post-processing
takes the HDG solution in an element-by-element fashion and combines it such
that one can get $\mathcal O(h^{p+2})$ order of accuracy when using
polynomials of degree $p$. For this to happen, there are two necessary
ingredients:
<ol>
  <li> The computed solution gradient $\mathbf{q}_h$ converges at optimal rate,
   i.e., $\mathcal{O}(h^{p+1})$.
  <li> The cell-wise average of the scalar part of the solution,
   $\frac{(1,u_h)_K}{\text{vol}(K)}$, super-converges at rate
   $\mathcal{O}(h^{p+2})$.
</ol>

We now introduce a new variable $u_h^* \in \mathcal{V}_h^{p+1}$, which we find
by minimizing the expression $|\kappa \nabla u_h^* + \mathbf{q}_h|^2$ over the cell
$K$ under the constraint $\left(1, u_h^*\right)_K = \left(1,
u_h\right)_K$. The constraint is necessary because the minimization
functional does not determine the constant part of $u_h^*$. This
translates to the following system of equations:
@f{eqnarray*}
\left(1, u_h^*\right)_K &=& \left(1, u_h\right)_K\\
\left(\nabla w_h^*, \kappa \nabla u_h^*\right)_K &=&
-\left(\nabla w_h^*, \mathbf{q}_h\right)_K
\quad \text{for all } w_h^* \in \mathcal Q^{p+1}.
@f}

Since we test by the whole set of basis functions in the space of tensor
product polynomials of degree $p+1$ in the second set of equations, this
is an overdetermined system with one more equation than unknowns. We fix this
in the code below by omitting one of these equations (since the rows in the
Laplacian are linearly dependent when representing a constant function). As we
will see below, this form of the post-processing gives the desired
super-convergence result with rate $\mathcal {O}(h^{p+2})$.  It should be
noted that there is some freedom in constructing $u_h^*$ and this minimization
approach to extract the information from the gradient is not the only one. In
particular, the post-processed solution defined here does not satisfy the
convection-diffusion equation in any sense. As an alternative, the paper by
Nguyen, Peraire and Cockburn cited above suggests another somewhat more
involved formula for convection-diffusion that can also post-process the flux
variable into an $H(\Omega,\mathrm{div})$-conforming variant and better
represents the local convection-diffusion operator when the diffusion is
small. We leave the implementation of a more sophisticated post-processing as
a possible extension to the interested reader.

Note that for vector-valued problems, the post-processing works similarly. One
simply sets the constraint for the mean value of each vector component
separately and uses the gradient as the main source of information.

<h3> Problem specific data </h3>

For this tutorial program, we consider almost the same test case as in
step-7. The computational domain is $\Omega \dealcoloneq [-1,1]^d$ and the exact
solution corresponds to the one in step-7, except for a scaling. We use the
following source centers $x_i$ for the exponentials
<ul>
  <li> 1D:  $\{x_i\}^1 = \{ -\frac{1}{3}, 0, \frac{1}{3} \}$,
  <li> 2D: $\{\mathbf{x}_i\}^2 = \{ (-\frac{1}{2},\frac{1}{2}),
                        		 (-\frac{1}{2},-\frac{1}{2}),
  					 (\frac{1}{2},-\frac{1}{2})
  				   \}$,
  <li> 3D: $\{\mathbf{x}_i\}^3 = \{ (-\frac{1}{2},\frac{1}{2}, \frac{1}{4}),
  				      (-\frac{3}{5},-\frac{1}{2}, -\frac{1}{8}),
  				      (\frac{1}{2},-\frac{1}{2}, \frac{1}{2})
  				   \}$.
</ul>

With the exact solution given, we then choose the forcing on the right hand
side and the Neumann boundary condition such that we obtain this solution
(manufactured solution technique). In this example, we choose the diffusion
equal to one and the convection as
\f[
\mathbf{c} = \begin{cases}
1, & \textrm{dim}=1 \\
(y, -x), & \textrm{dim}=2 \\
(y, -x, 1), & \textrm{dim}=3
\end{cases}
\f]
Note that the convection is divergence-free, $\nabla \cdot c = 0$.

<h3> Implementation </h3>

Besides implementing the above equations, the implementation below provides
the following features:
<ul>
  <li> WorkStream to parallelize local solvers. Workstream has been presented
  in detail in step-9.
  <li> Reconstruct the local DG solution from the trace.
  <li> Post-processing the solution for superconvergence.
  <li> DataOutFaces for direct output of the global skeleton solution.
</ul>
