\chapter{Examples}
\label{sec:examples}
\index{examples}

The following examples illustrate basic usage of the form language for
the definition of a collection of standard multilinear forms. We
assume that \texttt{dx} has been declared as an integral over the
interior of $\Omega$ and that both \texttt{i} and \texttt{j} have
been declared as a free \texttt{Index}, which is always the case if
the command-line interface is used.

The examples presented below can all be found in the subdirectory
\texttt{src/demo} of the \ffc{} source tree.

%------------------------------------------------------------------------------
\section{The mass matrix}
\index{mass matrix}

As a first example, consider the bilinear form corresponding to a
mass matrix,
\begin{equation}
  a(v, U) = \int_{\Omega} v \, U \dx,
\end{equation}
which can be implemented in \ffc{} as follows:
\begin{code}
 element = FiniteElement("Lagrange", "triangle", 1)

 v = BasisFunction(element)
 U = BasisFunction(element)
    
 a = v*U*dx
\end{code}

This example is implemented in the file \texttt{Mass.form} in the
collection of demonstration forms included with the \ffc{} source
distribution.

%------------------------------------------------------------------------------
\section{Poisson's equation}
\index{Poisson's equation}

The bilinear and linear forms form for Poisson's equation,
\begin{eqnarray}
  a(v, U) &=& \int_{\Omega} \nabla v \cdot \nabla U \dx, \\
  L(v)    &=& \int_{\Omega} v \, f \dx,
\end{eqnarray}
can be implemented as follows:
\begin{code}
 element = FiniteElement("Lagrange", "triangle", 1)

 v = BasisFunction(element)
 U = BasisFunction(element)
 f = Function(element)
  
 a = dot(grad(v), grad(U))*dx
 L = v*f*dx
\end{code}
Alternatively, index notation can be used to express the scalar
product:
\begin{code}
 a = D(v, i)*D(U, i)*dx
\end{code}

This example is implemented in the file \texttt{Poisson.form} in the
collection of demonstration forms included with the \ffc{} source
distribution.

%------------------------------------------------------------------------------
\section{Vector-valued Poisson}
\index{vector-valued Poisson}

The bilinear and linear forms for a system of (independent) Poisson
equations,
\begin{eqnarray}
  a(v, U) &=& \int_{\Omega} \nabla v : \nabla U \dx, \\
  L(v)    &=& \int_{\Omega} v \cdot f \dx,
\end{eqnarray}
with $v$, $U$ and $f$ vector-valued can be implemented as follows:
\begin{code}
 element = FiniteElement(``Vector Lagrange'', ``triangle'', 1)
  
 v = BasisFunction(element)
 U = BasisFunction(element)
 f = Function(element)
 
 a = dot(grad(v), grad(U))*dx
 L = dot(v, f)*dx
\end{code}
Alternatively, index notation may be used:
\begin{code}
 a = D(v[i], j)*D(U[i], j)*dx
 L = v[i]*f[i]*dx
\end{code}

This example is implemented in the file \texttt{PoissonSystem.form} in
the collection of demonstration forms included with the \ffc{} source
distribution.

%------------------------------------------------------------------------------
\section{The strain-strain term of linear elasticity}
\index{elasticity}
\index{linear elasticity}
\index{strain}

The strain-strain term of linear elasticity,
\begin{equation}
  a(v, U) = \int_{\Omega} \epsilon(v) : \epsilon(U) \dx,
\end{equation}
where
\begin{equation}
  \epsilon(v) = \frac{1}{2}(\nabla v + (\nabla v)^{\top})
\end{equation}
can be implemented as follows:
\begin{code}
 element = FiniteElement("Vector Lagrange", "tetrahedron", 1)
  
 v = BasisFunction(element)
 U = BasisFunction(element)
  
 def epsilon(v):
     return 0.5*(grad(v) + transp(grad(v)))

 a = dot(epsilon(v), epsilon(U))*dx
\end{code}
Alternatively, index notation can be used to define the form:
\begin{code}
 a = 0.25*(D(v[i], j) + D(v[j], i))* \\
          (D(U[i], j) + D(U[j], i))*dx
\end{code}

This example is implemented in the file \texttt{Elasticity.form} in
the collection of demonstration forms included with the \ffc{} source
distribution.

%------------------------------------------------------------------------------
\section{The nonlinear term of Navier--Stokes}
\index{Navier-Stokes}
\index{fixed-point iteration}

The bilinear form for fixed-point iteration on the nonlinear term of
the incompressible Navier--Stokes equations,
\begin{equation}
  a(v, U) = \int_{\Omega} v \cdot ((w \cdot \nabla) U) \dx,
\end{equation}
with $w$ the frozen velocity from a previous iteration, can be
conveniently implemented using index notation as follows:
\begin{code}
 element = FiniteElement("Vector Lagrange", "tetrahedron", 1)
  
 v = BasisFunction(element)
 U = BasisFunction(element)
 w = Function(element)

 a = v[i]*w[j]*D(U[i], j)*dx
\end{code}

This example is implemented in the file \texttt{NavierStokes.form} in
the collection of demonstration forms included with the \ffc{} source
distribution.

%------------------------------------------------------------------------------
\section{The heat equation}
\index{heat equation}
\index{time-stepping}
\index{backward Euler}

Discretizing the heat equation,
\begin{equation}
  \dot{u} - \nabla \cdot (c \nabla u) = f,
\end{equation}
in time using the $\mathrm{dG}(0)$ method (backward Euler), we
obtain the following variational problem for the discrete solution $U
= U(x, t)$: Find $U^n = U(\cdot, t_n)$ with
$U^{n-1} = U(\cdot, t_{n-1})$ given such that
\begin{equation}
  \frac{1}{k_n} \int_{\Omega} (U^n - U^{n-1}) \, v \dx +
  \int_{\Omega} c \, \nabla U^n \cdot \nabla v \dx =
  \int_{\Omega} f^n \, v \dx
\end{equation}
for all test functions $v$, where $k = t_n - t_{n-1}$ denotes the time
step . In the example below, we implement this variational problem
with piecewise linear test and trial functions, but other choices are
possible (just choose another finite element).

Rewriting the variational problem in the standard form $a(v, U) =
L(v)$ for all $v$, we obtain the following pair of bilinear and linear
forms:
\begin{eqnarray}
  a(v, U^n) &=& \int_{\Omega} v \, U^n \dx +
  k_n \int_{\Omega} c \, v \cdot \nabla U^n \dx, \\
  L(v) &=& \int_{\Omega} v \, U^{n-1} \dx + k_n \int_{\Omega} v \, f^n \dx,
\end{eqnarray}
which can be implemented as follows:
\begin{code}
 element = FiniteElement("Lagrange", "triangle", 1)

 v  = BasisFunction(element) # Test function
 U1 = BasisFunction(element) # Value at t_n
 U0 = Function(element)      # Value at t_n-1
 c  = Function(element)      # Heat conductivity
 f  = Function(element)      # Heat source
 k  = Constant()             # Time step

 a = v*U1*dx + k*c*dot(grad(v), grad(U1))*dx
 L = v*U0*dx + k*v*f*dx
\end{code}

%------------------------------------------------------------------------------
\section{Mixed formulation of Stokes}
\index{Stokes' equations}
\index{mixed formulation}
\index{Taylor-Hood element}

To solve Stokes' equations,
\begin{eqnarray}
  - \Delta u + \nabla p &=& f, \\
  \nabla \cdot u &=& 0,
\end{eqnarray}
we write the variational problem in standard form
$a(v, U) = L(v)$ for all $v$ to obtain the following pair of bilinear
and linear forms:
\begin{eqnarray}
  a(v, (U,P)) &=& \int_{\Omega} \nabla v : \nabla U - (\nabla \cdot v) \, P +
  q \, (\nabla \cdot U) \dx, \\
  L(v) &=& \int_{\Omega} v \cdot f \dx.
\end{eqnarray}
Using a mixed formulation with Taylor-Hood elements, this can be
implemented as follows:
\begin{code}
 P2 = FiniteElement("Vector Lagrange", "triangle", 2)
 P1 = FiniteElement("Lagrange", "triangle", 1)
 TH = P2 + P1

 (v, q) = BasisFunctions(TH)
 (U, P) = BasisFunctions(TH)
  
 f = Function(P2)
  
 a = (dot(grad(v), grad(U)) - div(v)*P + q*div(U))*dx
 L = dot(v, f)*dx
\end{code}
