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


In this example, our aims are the following:
<ol>
  <li>solve the advection equation $\beta \cdot \nabla u = f$;
  <li>show how we can use multiple threads to get results quicker if we have a
    multi-processor machine;
  <li>develop a simple refinement criterion.
</ol>
While the second aim is difficult to describe in general terms without
reference to the code, we will discuss the other two aims in the
following. The use of multiple threads will then be detailed at the
relevant places within the program. We will, however, follow the
general discussion of the WorkStream approach detailed in the
@ref threads "Parallel computing with multiple processors accessing shared memory"
documentation module.


<h3>Discretizing the advection equation</h3>

In the present example program, we want to numerically approximate the
solution of the advection equation
@f[
  \beta \cdot \nabla u = f,
@f]
where $\beta$ is a vector field that describes the advection direction and
speed (which may be dependent on the space variables if
$\beta=\beta(\mathbf x)$), $f$ is a source
function, and $u$ is the solution. The physical process that this
equation describes is that of a given flow field $\beta$, with which
another substance is transported, the density or concentration of
which is given by $u$. The equation does not contain diffusion of this
second species within its carrier substance, but there are source
terms.

It is obvious that at the inflow, the above equation needs to be
augmented by boundary conditions:
@f[
  u = g \qquad\qquad \mathrm{on}\ \partial\Omega_-,
@f]
where $\partial\Omega_-$ describes the inflow portion of the boundary and is
formally defined by
@f[
  \partial\Omega_-
  =
  \{{\mathbf x}\in \partial\Omega: \beta\cdot{\mathbf n}({\mathbf x}) < 0\},
@f]
and ${\mathbf n}({\mathbf x})$ being the outward normal to the domain at point
${\mathbf x}\in\partial\Omega$. This definition is quite intuitive, since
as ${\mathbf n}$ points outward, the scalar product with $\beta$ can only
be negative if the transport direction $\beta$ points inward, i.e. at
the inflow boundary. The mathematical theory states that we must not
pose any boundary condition on the outflow part of the boundary.

Unfortunately, the equation stated above cannot be solved in a stable way using
the standard finite element method. The problem is that
solutions to this equation possess insufficient regularity
perpendicular to the transport direction: while they are smooth along
the streamlines defined by the "wind field"
$\beta$, they may be discontinuous perpendicular to this
direction. This is easy to understand: what the equation $\beta \cdot
\nabla u = f$ means is in essence that the <i>rate of change of $u$ in
direction $\beta$ equals $f$</i>. But the equation has no implications
for the derivatives in the perpendicular direction, and consequently
if $u$ is discontinuous at a point on the inflow boundary, then this
discontinuity will simply be transported along the streamline of the
wind field that starts at this boundary point.
These discontinuities lead to numerical instabilities that
make a stable solution by a standard continuous finite element discretization
impossible.

A standard approach to address this difficulty is the <em>"streamline-upwind
Petrov-Galerkin"</em> (SUPG) method, sometimes also called the
streamline diffusion method. A good explanation of the method can be
found in @cite elman2005 . Formally, this method replaces the step
in which we derive the weak form of the differential equation from
the strong form: Instead of multiplying the equation by a test
function $v$ and integrating over the domain, we instead multiply
by $v + \delta \beta\cdot\nabla v$, where $\delta$ is a
parameter that is chosen in the range of the (local) mesh width $h$;
good results are usually obtained by setting $\delta=0.1h$.
(Why this is called "streamline diffusion" will be explained below;
for the moment, let us simply take for granted that this is how we
derive a stable discrete formulation.)
The value for $\delta$ here is small enough
that we do not introduce excessive diffusion, but large enough that the
resulting problem is well-posed.

Using the test functions as defined above, an initial weak form of the
problem would ask for finding a function $u_h$ so that for all test
functions $v_h$ we have
@f[
  (\beta \cdot \nabla u_h, v_h + \delta \beta\cdot\nabla v_h)_\Omega
  =
  (f, v_h + \delta \beta\cdot\nabla v_h)_\Omega.
@f]
However, we would like to include inflow boundary conditions $u=g$
weakly into this problem, and this can be done by requiring that in
addition to the equation above we also have
@f[
  (u_h, w_h)_{\partial\Omega_-}
  =
  (g, w_h)_{\partial\Omega_-}
@f]
for all test functions $w_h$ that live on the boundary and that are
from a suitable test space. It turns out that a suitable space of test
functions happens to be $\beta\cdot {\mathbf n}$ times the traces of
the functions $v_h$ in the test space we already use for the
differential equation in the domain. Thus, we require that for all
test functions $v_h$ we have
@f[
  (u_h, \beta\cdot {\mathbf n} v_h)_{\partial\Omega_-}
  =
  (g, \beta\cdot {\mathbf n} v_h)_{\partial\Omega_-}.
@f]
Without attempting a justification (see again the literature on the finite
element method in general, and the streamline diffusion method in
particular), we can combine the equations for the differential
equation and the boundary values in the following
weak formulation of
our stabilized problem: find a discrete function $u_h$ such that
for all discrete test functions $v_h$ there holds
@f[
  (\beta \cdot \nabla u_h, v_h + \delta \beta\cdot\nabla v_h)_\Omega
  -
  (u_h, \beta\cdot {\mathbf n} v_h)_{\partial\Omega_-}
  =
  (f, v_h + \delta \beta\cdot\nabla v_h)_\Omega
  -
  (g, \beta\cdot {\mathbf n} v_h)_{\partial\Omega_-}.
@f]


One would think that this leads to a system matrix
to be inverted of the form
@f[
  a_{ij} =
  (\beta \cdot \nabla \varphi_i,
   \varphi_j + \delta \beta\cdot\nabla \varphi_j)_\Omega
  -
  (\varphi_i, \beta\cdot {\mathbf n} \varphi_j)_{\partial\Omega_-},
@f]
with basis functions $\varphi_i,\varphi_j$.  However, this is a
pitfall that happens to every numerical analyst at least once
(including the author): we have here expanded the solution
$u_h = \sum_i U_i \varphi_i$, but if we do so, we will have to solve the
problem
@f[
  U^T A = F^T,
@f]
where $U$ is the vector of expansion coefficients, i.e., we have to
solve the transpose problem of what we might have expected naively.

This is a point we made in the introduction of step-3. There, we argued that
to avoid this very kind of problem, one should get in the habit of always
multiplying with test functions <i>from the left</i> instead of from the right
to obtain the correct matrix right away. In order to obtain the form
of the linear system that we need, it is therefore best to rewrite the weak
formulation to
@f[
  (v_h + \delta \beta\cdot\nabla v_h, \beta \cdot \nabla u_h)_\Omega
  -
  (\beta\cdot {\mathbf n} v_h, u_h)_{\partial\Omega_-}
  =
  (v_h + \delta \beta\cdot\nabla v_h, f)_\Omega
  -
  (\beta\cdot {\mathbf n} v_h, g)_{\partial\Omega_-}
@f]
and then to obtain
@f[
  a_{ij} =
  (\varphi_i + \delta \beta \cdot \nabla \varphi_i,
   \beta\cdot\nabla \varphi_j)_\Omega
  -
  (\beta\cdot {\mathbf n} \varphi_i, \varphi_j)_{\partial\Omega_-},
@f]
as system matrix. We will assemble this matrix in the program.


<h3>Why is this method called "streamline diffusion"?</h3>

Looking at the bilinear form mentioned above, we see that the discrete
solution has to satisfy an equation of which the left hand side in
weak form has a domain term of the kind
@f[
  (v_h + \delta \beta\cdot\nabla v_h, \beta \cdot \nabla u_h)_\Omega,
@f]
or if we split this up, the form
@f[
  (v_h, \beta \cdot \nabla u_h)_\Omega
  +
  (\delta \beta\cdot\nabla v_h, \beta \cdot \nabla u_h)_\Omega.
@f]
If we wanted to see what strong form of the equation that would
correspond to, we need to integrate the second term. This yields the
following formulation, where for simplicity we'll ignore boundary
terms for now:
@f[
  (v_h, \beta \cdot \nabla u_h)_\Omega
  -
  \left(v_h, \delta \nabla \cdot \left[\beta \left(\beta \cdot \nabla
  u_h\right)\right]\right)_\Omega
  +
  \text{boundary terms}.
@f]
Let us assume for a moment that the wind field $\beta$ is
divergence-free, i.e., that $\nabla \cdot \beta = 0$. Then applying
the product rule to the derivative of the term in square brackets on
the right and using the divergence-freeness will give us the following:
@f[
  (v_h, \beta \cdot \nabla u_h)_\Omega
  -
  \left(v_h, \delta \left[\beta \cdot \nabla\right] \left[\beta \cdot \nabla
  \right]u_h\right)_\Omega
  +
  \text{boundary terms}.
@f]
That means that the strong form of the equation would be of the sort
@f[
  \beta \cdot \nabla u_h
  -
  \delta
  \left[\beta \cdot \nabla\right] \left[\beta \cdot \nabla
  \right] u_h.
@f]
What is important to recognize now is that $\beta\cdot\nabla$ is the
<em>derivative in direction $\beta$</em>. So, if we denote this by
$\beta\cdot\nabla=\frac{\partial}{\partial \beta}$ (in the same way as
we often write $\mathbf n\cdot\nabla=\frac{\partial}{\partial n}$ for
the derivative in normal direction at the boundary), then the strong
form of the equation is
@f[
  \beta \cdot \nabla u_h
  -
  \delta
  \frac{\partial^2}{\partial\beta^2} u_h.
@f]
In other words, the unusual choice of test function is equivalent to
the addition of term to the strong form that corresponds to a second
order (i.e., diffusion) differential operator in the direction of the wind
field $\beta$, i.e., in "streamline direction". A fuller account would
also have to explore the effect of the test function on boundary
values and why it is necessary to also use the same test function for
the right hand side, but the discussion above might make clear where
the name "streamline diffusion" for the method originates from.


<h3>Why is this method also called "Petrov-Galerkin"?</h3>

A "Galerkin method" is one where one obtains the weak formulation by
multiplying the equation by a test function $v$ (and then integrating
over $\Omega$) where the functions $v$ are from the same space as the
solution $u$ (though possibly with different boundary values). But
this is not strictly necessary: One could also imagine choosing the
test functions from a different set of functions, as long as that
different set has "as many dimensions" as the original set of
functions so that we end up with as many independent equations as
there are degrees of freedom (where all of this needs to be
appropriately defined in the infinite-dimensional case). Methods that
make use of this possibility (i.e., choose the set of test functions
differently than the set of solutions) are called "Petrov-Galerkin"
methods. In the current case, the test functions all have the form
$v+\beta\cdot\nabla v$ where $v$ is from the set of solutions.


<h3>Why is this method also called "streamline-upwind"?</h3>

[Upwind methods](https://en.wikipedia.org/wiki/Upwind_scheme) have a
long history in the derivation of stabilized schemes for advection
equations. Generally, the idea is that instead of looking at a
function "here", we look at it a small distance further "upstream" or "upwind",
i.e., where the information "here" originally came from. This might
suggest not considering $u(\mathbf x)$, but
something like $u(\mathbf x - \delta \beta)$. Or, equivalently upon
integration, we could evaluate $u(\mathbf x)$ and instead consider $v$
a bit downstream: $v(\mathbf x+\delta \beta)$. This would be cumbersome
for a variety of reasons: First, we would have to define what $v$
should be if $\mathbf x + \delta \beta$ happens to be outside
$\Omega$; second, computing integrals numerically would be much more
awkward since we no longer evaluate $u$ and $v$ at the same quadrature
points. But since we assume that $\delta$ is small, we can do a Taylor
expansion:
@f[
  v(\mathbf x + \delta \beta)
  \approx
  v(\mathbf x) + \delta \beta \cdot \nabla v(\mathbf x).
@f]
This form for the test function should by now look familiar.


<h3>Solving the linear system that corresponds to the advection equation</h3>

As the resulting matrix is no longer symmetric positive definite, we cannot
use the usual Conjugate Gradient method (implemented in the
SolverCG class) to solve the system. Instead, we use the GMRES (Generalized
Minimum RESidual) method (implemented in SolverGMRES) that is suitable
for problems of the kind we have here.


<h3>The test case</h3>

For the problem which we will solve in this tutorial program, we use
the following domain and functions (in $d=2$ space dimensions):
@f{eqnarray*}
  \Omega &=& [-1,1]^d \\
  \beta({\mathbf x})
  &=&
  \left(
    \begin{array}{c}2 \\ 1+\frac 45 \sin(8\pi x)\end{array}
  \right),
  \\
  s
  &=&
  0.1,
  \\
  f({\mathbf x})
  &=&
  \left\{
    \begin{array}{ll}
        \frac 1{10 s^d} &
        \mathrm{for}\ |{\mathbf x}-{\mathbf x}_0|<s, \\
        0 & \mathrm{else},
    \end{array}
  \right.
  \qquad\qquad
  {\mathbf x}_0
  =
  \left(
    \begin{array}{c} -\frac 34 \\ -\frac 34\end{array}
  \right),
  \\
  g
  &=&
  e^{5 (1 - |\mathbf x|^2)} \sin(16\pi|\mathbf x|^2).
@f}
For $d>2$, we extend $\beta$ and ${\mathbf x}_0$ by simply duplicating
the last of the components shown above one more time.

With all of this, the following comments are in order:
<ol>
<li> The advection field $\beta$ transports the solution roughly in
diagonal direction from lower left to upper right, but with a wiggle
structure superimposed.
<li> The right hand side adds to the field generated by the inflow
boundary conditions a blob in the lower left corner, which is then
transported along.
<li> The inflow boundary conditions impose a weighted sinusoidal
structure that is transported along with the flow field. Since
$|{\mathbf x}|\ge 1$ on the boundary, the weighting term never gets very large.
</ol>


<h3>A simple refinement criterion</h3>

In all previous examples with adaptive refinement, we have used an
error estimator first developed by Kelly et al., which assigns to each
cell $K$ the following indicator:
@f[
  \eta_K =
  \left(
    \frac {h_K}{24}
    \int_{\partial K}
      [\partial_n u_h]^2 \; d\sigma
  \right)^{1/2},
@f]
where $[\partial n u_h]$ denotes the jump of the normal derivatives
across a face $\gamma\subset\partial K$ of the cell $K$. It can be
shown that this error indicator uses a discrete analogue of the second
derivatives, weighted by a power of the cell size that is adjusted to
the linear elements assumed to be in use here:
@f[
  \eta_K \approx
  C h \| \nabla^2 u \|_K,
@f]
which itself is related to the error size in the energy norm.

The problem with this error indicator in the present case is that it
assumes that the exact solution possesses second derivatives. This is
already questionable for solutions to Laplace's problem in some cases,
although there most problems allow solutions in $H^2$. If solutions
are only in $H^1$, then the second derivatives would be singular in
some parts (of lower dimension) of the domain and the error indicators
would not reduce there under mesh refinement. Thus, the algorithm
would continuously refine the cells around these parts, i.e. would
refine into points or lines (in 2d).

However, for the present case, solutions are usually not even in $H^1$
(and this missing regularity is not the exceptional case as for
Laplace's equation), so the error indicator described above is not
really applicable. We will thus develop an indicator that is based on
a discrete approximation of the gradient. Although the gradient often
does not exist, this is the only criterion available to us, at least
as long as we use continuous elements as in the present
example. To start with, we note that given two cells $K$, $K'$ of
which the centers are connected by the vector ${\mathbf y}_{KK'}$, we can
approximate the directional derivative of a function $u$ as follows:
@f[
  \frac{{\mathbf y}_{KK'}^T}{|{\mathbf y}_{KK'}|} \nabla u
  \approx
  \frac{u(K') - u(K)}{|{\mathbf y}_{KK'}|},
@f]
where $u(K)$ and $u(K')$ denote $u$ evaluated at the centers of the
respective cells. We now multiply the above approximation by
${\mathbf y}_{KK'}/|{\mathbf y}_{KK'}|$ and sum over all neighbors $K'$ of $K$:
@f[
  \underbrace{
    \left(\sum_{K'} \frac{{\mathbf y}_{KK'} {\mathbf y}_{KK'}^T}
                         {|{\mathbf y}_{KK'}|^2}\right)}_{=:Y}
  \nabla u
  \approx
  \sum_{K'}
  \frac{{\mathbf y}_{KK'}}{|{\mathbf y}_{KK'}|}
  \frac{u(K') - u(K)}{|{\mathbf y}_{KK'}|}.
@f]
If the vectors ${\mathbf y}_{KK'}$ connecting $K$ with its neighbors span
the whole space (i.e. roughly: $K$ has neighbors in all directions),
then the term in parentheses in the left hand side expression forms a
regular matrix, which we can invert to obtain an approximation of the
gradient of $u$ on $K$:
@f[
  \nabla u
  \approx
  Y^{-1}
  \left(
    \sum_{K'}
    \frac{{\mathbf y}_{KK'}}{|{\mathbf y}_{KK'}|}
    \frac{u(K') - u(K)}{|{\mathbf y}_{KK'}|}
  \right).
@f]
We will denote the approximation on the right hand side by
$\nabla_h u(K)$, and we will use the following quantity as refinement
criterion:
@f[
  \eta_K = h^{1+d/2} |\nabla_h u_h(K)|,
@f]
which is inspired by the following (not rigorous) argument:
@f{eqnarray*}
  \|u-u_h\|^2_{L_2}
  &\le&
  C h^2 \|\nabla u\|^2_{L_2}
\\
  &\approx&
  C
  \sum_K
  h_K^2 \|\nabla u\|^2_{L_2(K)}
\\
  &\le&
  C
  \sum_K
  h_K^2 h_K^d \|\nabla u\|^2_{L_\infty(K)}
\\
  &\approx&
  C
  \sum_K
  h_K^{2+d} |\nabla_h u_h(K)|^2
@f}
