\chapter{Form language}
\label{sec:formlanguage}
\index{form language}

\ffc{} uses a flexible and extensible language to define and process
multilinear forms. In this chapter, we give the details of this form
language and present a number of examples to illustrate the use of the
form language in applications.

%------------------------------------------------------------------------------
\section{Overview}

A form is expressed using a combination of basic data types and
operators. \ffc{}
compiles a given multilinear form
\begin{equation}
  a : V_h^1 \times V_h^2 \times \cdots \times V_h^r \rightarrow \R
\end{equation}
into code that can be used to compute the corresponding tensor
\begin{equation}
  A_i = a(\phi_{i_1}^1, \phi_{i_2}^2, \ldots, \phi_{i_r}^r).
\end{equation}

In the form language, a multilinear form is defined by first
specifying the set of function spaces,
$V_h^1, V_h^2, \ldots, V_h^r$, and then expressing the multilinear form in
terms of the basis functions of these functions spaces.

A function space is defined in the form language through a
\texttt{FiniteElement}, and a corresponding basis function is
represented as a \texttt{BasisFunction}. The following code defines a
pair of basis functions \texttt{v} and \texttt{U} for a first-order
Lagrange finite element on triangles:
\begin{code}
 element = FiniteElement(``Lagrange'', ``triangle'', 1)
 v = BasisFunction(element)
 U = BasisFunction(element)
\end{code}
The two basis functions can now be used to define a bilinear form:
\begin{code}
 a = v*D(U, 0)*dx
\end{code}
corresponding to the mathematical notation
\begin{equation}
  a(v, U) = \int_{\Omega} v \, \frac{\partial U}{\partial x_0} \dx.
\end{equation}
Note the order of the argument list of the multilinear form is determined
by the order in which basis functions are declared, not by the order
in which they appear in the form. Thus, both \texttt{a = v*D(U, 0)*dx}
and \texttt{a = D(U, 0)*v*dx} define the same multilinear form.

The arity of a multilinear form is determined by the number of basis
functions appearing in the definition of the form. Thus,
\texttt{a = v*U*dx} defines a \textit{bilinear form}, namely
$a(v, U) = \int_{\Omega} v \, u \dx$, whereas \texttt{L = v*f*dx} defines
a \textit{linear form}, namely $L(v) = \int_{\Omega} v \, f \dx$.

In the case of a bilinear form, the first of the two basis functions
is referred to as the \textit{test function} and the second is
referred to as the \textit{trial function}.

Not every expression is a valid multilinear form. The following list
explains some of the basic rules that must be obeyed in the definition
of a form:
\begin{itemize}
\item
  A form must be linear in each of its arguments; otherwise it is not
  a multilinear form. Thus, \texttt{a = v*v*U*dx} is not a valid
  form, since it is quadratic in \texttt{v}.
\item
  The value of a form must be a scalar. Thus, if \texttt{v} is a
  vector-valued basis function (see below), then \texttt{L = v*dx} is
  not a valid form, since the value of the form is not a scalar.
\item
  The integrand of a form must be integrated exactly once. Thus,
  neither \texttt{a = v*u} nor \texttt{a = v*u*dx*dx} are valid forms.
\end{itemize}

%------------------------------------------------------------------------------
\section{The form language as a Python extension}
\index{Python}

The \ffc{} form language is built on top of Python.  This is true both
when calling \ffc{} as a compiler from the command-line or when
calling the \ffc{} compiler from within a Python program. Through the
addition of a collection of basic data types and operators, \ffc{}
allows a form to be specified in a language that is close to the
mathematical notation. Since the form language is built on top of
Python, any Python code is valid in the definition of a form (but not
all Python code defines a multilinear form). In particular, comments
(lines starting with \texttt{\#}) and functions (keyword \texttt{def},
see Section \ref{sec:user-defined} below) are allowed in the definition
of a form.

%------------------------------------------------------------------------------
\section{Basic data types}

\subsection{\texttt{FiniteElement}}
\index{finite elements}
\index{\texttt{FiniteElement}}
\index{Lagrange element}
\index{discontinuous Lagrange element}

The data type \texttt{FiniteElement} represents a finite element on a
triangle or tetrahedron. A \texttt{FiniteElement} is declared by
specifying the type of element, the underlying shape, the polynomial
order and, optionally, the number of vector components:
\small
\begin{code}
 element = FiniteElement(type, shape, <degree>, <num\_components>)
\end{code}
\normalsize

The argument \texttt{type} is a string and possible values include:
\begin{itemize}
\item
  \texttt{``Lagrange''}, representing a standard Lagrange
  finite element for continuous piecewise polynomial functions;
\item
  \texttt{``Discontinuous Lagrange''}, representing a discontinuous
  Lagrange finite element for discontinuous piecewise polynomial functions;
\item
  \texttt{``Vector Lagrange''}, representing a standard vector Lagrange
  finite element for continuous piecewise polynomial vector-valued functions;  
\item
  \texttt{``Discontinuous vector Lagrange''}, representing a discontinuous
  Lagrange finite element for discontinuous piecewise polynomial
  vector-valued functions.
\end{itemize}

The argument \texttt{shape} is a string and possible values include:
\begin{itemize}
\item
  \texttt{``triangle''}, representing a triangle in $\R^2$;
\item
  \texttt{``tetrahedron''}, representing a tetrahedron in $\R^3$.
\end{itemize}

The argument \texttt{order} is an integer specifying the polynomial
order of the finite element. Note that the minimal order for Lagrange
finite elements is one, whereas the minimal order for
discontinuous Lagrange finite elements is zero.

The argument \texttt{num\_components} is optional and specifies the
number of vector components for a vector-valued element. If not
specified, the number of vector components is assumed to be the same
the dimension $d$ of the underlying shape.

Note that more than one \texttt{FiniteElement} can be declared and
used in the definition of a form. The following example declares two
elements, one linear and one quadratic Lagrange finite element:
\begin{code}
 P1 = FiniteElement(``Lagrange'', ``tetrahedron'', 1)
 P2 = FiniteElement(``Lagrange'', ``tetrahedron'', 2)
\end{code}

\subsection{\texttt{MixedElement}}
\index{mixed finite elements}
\index{\texttt{MixedElement}}

The data type \texttt{MixedElement} represents a mixed finite element
on a triangle or tetrahedron. The function space of a mixed finite
element is defined as the direct sum of the function spaces of a
given list of elements. A \texttt{MixedElement} is declared by
specifying a \texttt{list} of \texttt{FiniteElement}s:
\begin{code}
 mixed_element = FiniteElement([e0, e1, ...])
\end{code}

Alternatively, a \texttt{MixedElement} can be created as the sum of a sequence of
\texttt{FiniteElement}s. The following example illustrates how to
create a Taylor-Hood element (quadratic velocity and linear pressure):
\begin{code}
 P2 = FiniteElement("Vector Lagrange", "triangle", 2)
 P1 = FiniteElement("Lagrange", "triangle", 1)
 TH = P2 + P1
\end{code}

\subsection{\texttt{BasisFunction}}
\index{basis functions}
\index{\texttt{BasisFunction}}
\index{\texttt{BasisFunctions}}

The data type \texttt{BasisFunction} represents a basis function on a
given finite element. A \texttt{BasisFunction} must be declared from a
previously declared \texttt{FiniteElement}:
\begin{code}
 v = BasisFunction(element)
\end{code}
Note that more than one \texttt{BasisFunction} can be declared from
the same \texttt{FiniteElement}.

Note that the order in which \texttt{BasisFunction}s are declared is
important. The order determines the order of arguments to the
multilinear form. Thus, for a bilinear form $a(v, U)$, the test
function $v$ should be declared before the trial function $U$:
\begin{code}
 v = BasisFunction(element)
 U = BasisFunction(element)
\end{code}

For a \texttt{MixedElement}, the function \texttt{BasisFunctions} can
be used to construct tuples of \texttt{BasisFunction}s, as illustrated here
for a mixed Taylor-Hood element:
\begin{code}
 (v, q) = BasisFunctions(TH)
 (U, P) = BasisFunctions(TH)
\end{code}

\subsection{\texttt{Function}}
\index{functions}
\index{\texttt{Function}}
\index{\texttt{Functions}}

The data type \texttt{Function} represents a function belonging to a
given finite element space, that is, a linear combination of basis
functions of the finite element space. A \texttt{Function} must be
declared from a previously declared \texttt{FiniteElement}:
\begin{code}
 f = Function(element)
\end{code}

Note that more than one \texttt{BasisFunction} can be declared from
the same \texttt{FiniteElement}. The following example declares two
\texttt{BasisFunction}s and one \texttt{Function} from the same
\texttt{FiniteElement}:
\begin{code}
 v = BasisFunction(element)
 U = BasisFunction(element)
 f = Function(element)
\end{code}

\texttt{Function} is used to represent user-defined functions,
including right-hand sides, variable coefficients and stabilization
terms. \ffc{} treats each \texttt{Function} as a linear combination of
basis functions with unknown coefficients. It is the responsibility of
the user or the system for which the form is compiled to supply the
values of the coefficients at run-time. In the case of \dolfin{}, the
coefficients are automatically computed from a given user-defined
function during the assembly of a form.

Note that the order in which \texttt{Function}s are declared is
important. The code generated by \ffc{} accepts as arguments a list of
functions that should correspond to the \texttt{Function}s appearing
in the form in the order they have been declared.

For a \texttt{MixedElement}, the function \texttt{Functions} can
be used to construct tuples of \texttt{Function}s, as illustrated here
for a mixed Taylor-Hood element:
\begin{code}
 (f, g) = Functions(TH)
\end{code}

\subsection{\texttt{Constant}}
\index{constants}
\index{\texttt{Constant}}

The data type \texttt{Constant} represents a constant scalar value
that is unknown at compile-time. A \texttt{Constant} is declared
without any arguments:
\begin{code}
 c = Constant()
\end{code}

Just as with \texttt{Function}s, it is the responsibility of the user
or the system for which the form is compiled to supply the value of
the constant at run-time. In the case of \dolfin{}, a constant is
automatically assigned a value from a given user-defined variable.

Note that the order in which \texttt{Constant}s are declared is
important. The code generated by \ffc{} accepts as arguments a list of
constants that should correspond to the \texttt{Constant}s appearing
in the form in the order they have been declared.

\subsection{\texttt{Index}}
\index{indices}
\index{\texttt{Index}}

The data type \texttt{Index} represents an index used for subscripting
derivatives or taking components of vector-valued functions.
If an \texttt{Index} is declared without any arguments,
\begin{code}
 i = Index()
\end{code}
a \textit{free} \texttt{Index} is created, representing an
\textit{index range} determined by the context; if used to subscript a
vector-valued \texttt{BasisFunction} or a \texttt{Function}, the range
is given by the number of vector dimensions $n$, and if used to subscript
a derivative, the range is given by the dimension $d$ of the underlying
shape of the finite element space. As we shall see below, indices can
be a powerful tool when used to define forms in tensor notation.

An \texttt{Index} can also be \textit{fixed}, meaning that the value
of the index remains constant:
\begin{code}
 i = Index(0)
\end{code}

When using the command-line interface to \ffc{}, a sequence of free
indices are automatically declared for convenience: \texttt{i},
\texttt{j}, \texttt{k}, \texttt{l}, \texttt{m}, \texttt{n}. Note
however that a user is free to declare new indices with other names or
even reuse these variables for other things than indices.

\subsection{\texttt{Identity}}
\index{identity matrix}
\index{\texttt{Identity}}

The data type \texttt{Identity} represents an $n\times n$ unit matrix
of given size $n$.  An \texttt{Identity} is declared by specifying the
dimension $n$:
\begin{code}
 I = Identity(n)
\end{code}

%------------------------------------------------------------------------------
\section{Scalar operators}
\index{scalar operators}

The basic operators used to define a form are scalar addition,
subtraction and multiplication. Note the absence of division
which is intentionally left out (but see the comment below).

\subsection{Scalar addition: \texttt{+}}
\index{addition}

Scalar addition is supported for all scalar-valued basic data types,
thus including \texttt{BasisFunction}, \texttt{Function},
\texttt{Constant} and expressions involving these data types.

In addition, unary plus is supported for all basic data types.

\subsection{Scalar subtraction: \texttt{-}}
\index{subtraction}

Scalar subtraction is supported for all scalar-valued basic data types,
thus including \texttt{BasisFunction}, \texttt{Function},
\texttt{Constant} and expressions involving these data types.

In addition, unary minus is supported for all basic data types.

\subsection{Scalar multiplication: \texttt{*}}
\index{multiplication}

Scalar multiplication is supported for all scalar-valued basic data types,
thus including \texttt{BasisFunction}, \texttt{Function},
\texttt{Constant} and expressions involving these data types.

\subsection{Scalar division: \texttt{/}}
\index{division}

Division is not allowed in the definition of a form. This is because
division by a \texttt{BasisFunction} in the definition of a form does
not result in a valid multilinear form, since a multilinear form must
be linear in each of its arguments. Division by \texttt{Function}s and
\texttt{Constant}s may be implemented in future versions of \ffc{}.

%------------------------------------------------------------------------------
\section{Vector operators}
\index{vector operators}

Vectors are defined in the form language using Python's built-in
\texttt{list} type. This means that all list operations such as
slicing, list comprehension etc. are supported. There is one exception
to this rule, namely vector-valued \texttt{BasisFunction}s and
\texttt{Function}s, which are not \texttt{list}s (but can be made into
\texttt{list}s using the operator \texttt{vec} discussed below).
The operators listed below support all objects which are logically
vectors, thus including both Python \texttt{list}s and vector-valued
expressions.

\subsection{Component access: \texttt{v[i]}}
\index{component access}
\index{subscripting}

Brackets \texttt{[]} are used to pick a given component of a logically
vector-valued expression. Thus, if \texttt{v} is a vector-valued
expression, then \texttt{v[0]} represents a function
corresponding to the first component of (the values of) \texttt{v}.
Similarly, if \texttt{i} is an \texttt{Index} (free or fixed), then
\texttt{v[i]} represents a function corresponding to component
\texttt{i} of (the values of) \texttt{v}.

\subsection{Scalar product: \texttt{dot(v, w)}}
\index{scalar product}
\index{\texttt{dot}}

The operator \texttt{dot} accepts as arguments two logically
vector-valued expressions and returns the scalar product (dot product)
of the two vectors:
\begin{equation}
  \mbox{\texttt{dot(v, w)}} \leftrightarrow v \cdot w =
  \sum_{i=0}^{n-1} v_i w_i.
\end{equation}
Note that this operator is only defined for vectors of equal length.

\subsection{Vector product: \texttt{cross(v, w)}}
\index{vector product}
\index{cross product}
\index{\texttt{cross}}

The operator \texttt{cross} accepts as arguments two logically
vector-valued expressions and returns a vector which is the cross
product (vector product) of the two vectors:
\begin{equation}
  \mbox{\texttt{cross(v, w)}} \leftrightarrow v \times w =
  (v_1 w_2 - v_2 w_1, v_2 w_0 - v_0 w_2, v_0 w_1 - v_1 w_0).
\end{equation}
Note that this operator is only defined for vectors of length three.

\subsection{Matrix product: \texttt{mult(A, B)}}
\index{matrix product}

The operator \texttt{mult} accepts as arguments two matrices (or more
generally, tensors) and returns the matrix (tensor) product.

\subsection{Transpose: \texttt{transp(A)}}
\index{transpose}
\index{\texttt{transp}}

The operator \texttt{transp} accept as argument a matrix and return
the transpose of the given matrix:
\begin{equation}
  \mbox{\texttt{transp(A)[i][j]}} \leftrightarrow (A^{\top})_{ij} = A_{ji}.
\end{equation}

\subsection{Trace: \texttt{trace(A)}}
\index{trace}
\index{\texttt{trace}}

The operator \texttt{trace} accepts as argument a square matrix \texttt{A}
and returns its trace, that is, the sum of its diagonal elements:
\begin{equation}
  \mbox{\texttt{trace}(A)} \leftrightarrow \mathrm{trace}(A) = \sum_{i=0}^{n-1} A_{ii}.
\end{equation}

\subsection{Vector length: \texttt{len(v)}}
\index{vector length}
\index{\texttt{len}}

The operator \texttt{len} accepts as argument a logically
vector-valued expression and returns its length (the number of vector
components).

\subsection{Rank: \texttt{rank(v)}}
\index{vector rank}
\index{\texttt{rank}}

The operator \texttt{rank} returns the rank of the given argument. The
rank of an expression is defined as the number of times the operator
\texttt{[]} can be applied to the expression before a scalar is
obtained. Thus, the rank of a scalar is zero, the rank of a vector is
one and the rank of a matrix is two.

\subsection{Vectorization: \texttt{vec(v)}}
\index{vectorization}
\index{\texttt{vec}}

The operator \texttt{vec} is used to create a Python \texttt{list}
object from a logically vector-valued expression. This operator has no
effect on expressions which are already \texttt{list}s. Thus, if
\texttt{v} is a vector-valued \texttt{BasisFunction}, then
\texttt{vec(v)} returns a list of the components of \texttt{v}. This
can be used to define forms in terms of standard Python \texttt{list}
operators or Python Numeric \texttt{array} operators.

The operator \texttt{vec} does not have to be used if the form is
defined only in terms of the basic operators of the form language.

%------------------------------------------------------------------------------
\section{Differential operators}
\index{differential operators}

\subsection{Scalar partial derivative: \texttt{D(v, i)}}
\index{partial derivative}
\index{\texttt{D}}

The basic differential operator is the scalar partial derivative
\texttt{D}. This differential operator accepts as arguments a scalar
or logically vector-valued expression \texttt{v} together with a
coordinate direction \texttt{i} and returns the partial derivative of
the expression in the given coordinate direction:
\begin{equation}
  \mbox{\texttt{D(v, i)}} \leftrightarrow \frac{\partial v}{\partial x_i}.
\end{equation}

Alternatively, the member function \texttt{dx} can be used. For
\texttt{v} an expression, the two expressions \texttt{D(v, i)} and
\texttt{v.dx(i)} are equivalent, but note that only the operator
\texttt{D} works on vector-valued expressions that are defined in
terms of Python lists.

\subsection{Gradient: \texttt{grad(v)}}
\index{gradient}
\index{\texttt{grad}}

The operator \texttt{grad} accepts as argument an expression
\texttt{v} and returns its gradient. If \texttt{v} is scalar, the
result is a vector containing the partial derivatives in the
coordinate directions:
\begin{equation}
  \mbox{\texttt{grad(v)}} \leftrightarrow \mathrm{grad(v)} = \nabla v = 
  (\frac{\partial v}{\partial x_0}, \frac{\partial v}{\partial x_1},
  \ldots, \frac{\partial v}{\partial x_{d-1}}).
\end{equation}
If \texttt{v} is logically vector-valued, the result is a matrix with
rows given by the gradients of each component:
\begin{equation}
  \mbox{\texttt{grad(v)}}[i][j] \leftrightarrow
  \left(\mathrm{grad(v)}\right)_{ij} =
  \left(\nabla v\right)_{ij} =
  \frac{\partial v_i}{\partial x_j}.
\end{equation}
Thus, if \texttt{v} is scalar-valued, then \texttt{grad(grad(v))}
returns the Hessian of \texttt{v}, and if \texttt{v} is vector-valued,
then \texttt{grad(v)} is the Jacobian of \texttt{v}.
\index{Hessian}\index{Jacobian}

\subsection{Divergence: \texttt{div(v)}}
\index{divergence}
\index{\texttt{div}}

The operator \texttt{div} accepts as argument a logically
vector-valued expression and returns its divergence:
\begin{equation}
  \mbox{\texttt{div(v)}} \leftrightarrow \mathrm{div}(v) = \nabla \cdot v =
  \sum_{i=0}^{d-1} \frac{\partial v_i}{\partial x_i}.
\end{equation}
Note that the length $n$ of the vector \texttt{v} must be equal to the
dimension $d$ of the underlying shape of the \texttt{FiniteElement}
defining the function space for~\texttt{v}.

\subsection{Rotation: \texttt{rot(v)}}
\index{rotation}
\index{\texttt{rot}}
\index{\texttt{curl}}

The operator \texttt{rot} accepts as argument a logically
vector-valued expression and returns its rotation:
\begin{equation}
  \mbox{\texttt{rot(v)}} \leftrightarrow \mathrm{rot}(v) = \nabla \times v
  = (\frac{\partial v_2}{\partial x_1} - \frac{\partial v_1}{\partial x_2},
  \frac{\partial v_0}{\partial x_2} - \frac{\partial v_2}{\partial x_0},
  \frac{\partial v_1}{\partial x_0} - \frac{\partial v_0}{\partial x_1}).
\end{equation}
Note that this operator is only defined for vectors of length three.

Alternatively, the name \texttt{curl} can be used for this operator.

%------------------------------------------------------------------------------
\section{Integrals}
\index{integrals}

Each term of a valid form expression must be a scalar-valued
expression integrated exactly once. Integrals are expressed through
multiplication with a measure, representing either an integral over
the interior of the domain $\Omega$ or the boundary $\partial \Omega$
of $\Omega$.

\subsection{Integration over the interior: \texttt{*dx}}
\index{interior measure}

A measure for integration over the interior of $\Omega$ is created as
follows:
\begin{code}
 dx = Integral(``interior'')
\end{code}
If \texttt{v} is a scalar-valued expression, then the integral of
\texttt{v} over the interior of $\Omega$ is written as \texttt{v*dx}.

When using the command-line interface to \ffc{}, the measure
\texttt{dx} is automatically declared as an integral over the interior
of $\Omega$. Note however that a user is free to declare measures with
other names or even reuse the variable \texttt{dx} for something else.

\subsection{Integration over the boundary: \texttt{*ds}}
\index{boundary measure}

A measure for integration over the boundary of $\Omega$ is created as
follows:
\begin{code}
 ds = Integral(``boundary'')
\end{code}
If \texttt{v} is a scalar-valued expression, then the integral of
\texttt{v} over the boundary of $\Omega$ is written as \texttt{v*ds}.

When using the command-line interface to \ffc{}, the measure
\texttt{ds} is automatically declared as an integral over the boundary
of $\Omega$. Note however that a user is free to declare measures with
other names or even reuse the variable \texttt{ds} for something else.

At this point, complete support has not been added to \ffc{} for
boundary integrals, which means that all boundary integrals are
currently evaluated to zero.

%------------------------------------------------------------------------------
\section{Index notation}
\index{index notation}

\ffc{} supports index notation, which is often a convenient way to
express forms. The basic principle of index notation is that summation
is implicit over indices repeated twice in each term of an expression.
The following examples illustrate the index notation, assuming that
each of the variables \texttt{i} and \texttt{j} have been declared as
a free \texttt{Index}:
\begin{eqnarray}
  \mbox{\texttt{v[i]*w[i]}} &\leftrightarrow& \sum_{i=0}^{n-1} v_i w_i, \\
  \mbox{\texttt{D(v, i)*D(w, i)}} &\leftrightarrow&
  \sum_{i=0}^{d-1}
  \frac{\partial v}{\partial x_i} 
  \frac{\partial w}{\partial x_i} = \nabla v \cdot \nabla w, \\
  \mbox{\texttt{D(v[i], i)}} &\leftrightarrow& \sum_{i=0}^{d-1}
  \frac{\partial v_i}{\partial x_i} = \nabla \cdot v, \\
  \mbox{\texttt{D(v[i], j)*D(w[i], j)}} &\leftrightarrow&
  \sum_{i=0}^{n-1} \sum_{j=0}^{d-1}
  \frac{\partial v_i}{\partial x_j} \frac{\partial w_i}{\partial x_j}.
\end{eqnarray}

Index notation is used internally by \ffc{} to represent multilinear
forms and in most cases, \ffc{} is capable of generating an efficient
tensor representation of any given expression. However, in some cases
index notation might generate more efficient code.

%------------------------------------------------------------------------------
\section{User-defined operators}
\label{sec:user-defined}
\index{user-defined operators}

A user may define new operators, using standard Python syntax. As an
example, consider the strain operator $\epsilon$ of linear elasticity,
defined by
\begin{equation}
  \epsilon(v) = \frac{1}{2} (\nabla v + (\nabla v)^{\top}).
\end{equation}
This operator can be implemented as a function using the Python \texttt{def}
keyword:
\begin{code}
 def epsilon(v):
     return 0.5*(grad(v) + transp(grad(v)))
\end{code}
Alternatively, using the shorthand \texttt{lambda} notation, the
strain operator may be defined as follows:
\begin{code}
 epsilon = lambda v: 0.5*(grad(v) + transp(grad(v)))
\end{code}
\index{def}\index{lambda}
