# Operators

Function Descriptions
makeOperator() Constructs a GridFunctionOperator
zot() Constructs a zero-order GridFunctionOperator
fot() Constructs a first-order GridFunctionOperator
sot() Constructs a second-order GridFunctionOperator
sot_ij() Constructs a second-order GridFunctionOperator with partial derivatives
convectionDiffusion() Constructs a ConvectionDiffusionOperator

## function makeOperator()

Defined in header <amdis/GridFunctionOperator.hpp>

template <class Tag, class Expr, class... QuadratureArgs>
auto makeOperator(Tag tag, Expr&& expr, QuadratureArgs&&... args)


Constructs a GridFunctionOperator that can be passed to a ProblemStat in the member functions addMatrixOperator() or addVectorOperator(). The tag therby identifies which type of operator to create, the expr is used as a coefficient function in the operator and the optional quadrature arguments are used to determine a quadrature rule for the integration of the operator on an element.

#### Arguments

Tag tag
An identifier tag to select the type of operator. Several predefined tags are put into the namespace tag::. The tag determines the derivative order of the operator and which part is differentiated. So, it essentially distinguishes between zero-order terms, first-order terms, and second-order terms. See the examples below.
Expr expr
An Expression is anything, a GridFunction can be created from, sometimes also called PreGridFunction. It includes constants, functors callable with GlobalCoordinates, and any combination of GridFunctions.
QuadratureArgs args...
Arguments that are passed to a quadrature creator. Anything that needs a quadrature formula needs to determine the (approximative) polynomial degree of the GridFunctions. If the GridFunction builds a polynomial expression, it can be deduced automatically, i.e. if it includes constants, DOFVectors, and arithmetic operator operator+, operator-, or operator*. If the polynomial order can not be deduced, the compiler gives an error. Then, this functions accept an additional argument, to provide either the polynomial degree of the expression, or a quadrature rule explicitly. See the examples below.

#### Requirements

• Expr models the Concepts::PreGridFunction

#### Return value

Returns a so-called PreGridFunctionOperator, i.e. a container storing the tag, expression, and quadrature arguments, to be bound to a GridView in the function makeLocalOperator(). The result of this is a GridFunctionOperator, i.e., a local operator parametrized with a grid function.

### Tags

In the following examples we use the notation $\psi$... scalar testfunction, $\Psi$... vector testfunction, $\phi$... scalar trialfunction, $\Phi$... vector trialfunction, $A$... matrix coefficient, $\mathbf{b}$... vector coefficient, $c$... scalar coefficient.

#### Bilinear forms

Tag Descriptions
tag::divtestvec_trial first-order operator $\langle\nabla\cdot\Psi, c\,\phi\rangle$
tag::gradtest_trial first-order operator $\langle\nabla\psi, \mathbf{b}\,\phi\rangle$
tag::gradtest_trialvec first-order operator $\langle\nabla\psi, c\,\Phi\rangle$
tag::partialtest_trial{ i } first-order operator $\langle\partial_i\psi, c\,\phi\rangle$
tag::test_divtrialvec first-order operator $\langle\psi, c\,\nabla\cdot\Phi\rangle$
tag::test_gradtrial first-order operator $\langle\psi, \mathbf{b}\cdot\nabla\phi\rangle$
tag::test_partialtrial{ i } first-order operator $\langle\psi, c\,\partial_i\phi\rangle$
tag::testvec_gradtrial first-order operator $\langle\Psi, c\,\nabla\phi\rangle$
tag::divtestvec_divtrialvec second-order operator $\langle\nabla\cdot\Psi, c\,\nabla\cdot\Phi\rangle$
tag::gradtest_gradtrial second-order operator $\langle\nabla\psi, c\,\nabla\phi\rangle$, or $\langle\nabla\psi, A\,\nabla\phi\rangle$
tag::partialtest_partialtrial{ i, j } second-order operator $\langle\partial_i\psi, c\,\partial_j\phi\rangle$
tag::test_trial zero-order operator $\langle\psi, c\,\phi\rangle$
tag::test_trialvec zero-order operator $\langle\psi, \mathbf{b}\cdot\Phi\rangle$
tag::testvec_trial zero-order operator $\langle\Psi, \mathbf{b}\,\phi\rangle$
tag::testvec_trialvec zero-order operator $\langle\Psi, c\,\Phi\rangle$, or $\langle\Psi, A\,\Phi\rangle$

There are also complex operator terms, like the tag::stokes operator specific to a special basis, like a taylor-hood basis.

#### Linear forms

Tag Descriptions
tag::divtestvec first-order operator $\langle\nabla\cdot\Psi, c\rangle$
tag::gradtest first-order operator $\langle\nabla\psi, \mathbf{b}\rangle$
tag::partialtest{ i } first-order operator $\langle\partial_i\psi, c\rangle$
tag::test zero-order vector-operator $\langle \psi, c\rangle$
tag::testvec zero-order vector-operator $\langle \Psi, \mathbf{b}\rangle$

### Examples

#### Tags and expressions

The general procedure to describe a PDE is to decompose it into individual terms and add all of them to a ProblemStat:

using Grid = /* any dune grid type */;
using Traits = TaylorHoodBasis<Grid>;
ProblemStat<Traits> prob("prob");
prob.initialize(INIT_ALL);

// define a matrix operator <1/tau * Psi, Phi>
auto op1 = makeOperator(tag::testvec_trialvec{}, 1.0/tau);

// define a vector operator <1/tau * Psi, U^old>
auto op2 = makeOperator(tag::testvec{}, 1.0/tau * prob.solution(0_c));

// define an operator <grad(psi), grad(phi)> added to all velocity components
for (std::size_t i = 0; i < Grid::dimensionworld; ++i)


In the following examples B stands for an arbitrary tag and prob for a ProblemStat created before.

// automatic deduction of quadrature rule
auto op1 = makeOperator(B, 1.0 + pow<2>(prob.solution(_0)));
// explicit polynomial order
auto op2 = makeOperator(B, sin(X(0)), 4);
// provide a quadrature rule directly
auto op3 = makeOperator(B, sin(X(0)), Dune::QuadratureRules(Dune::GeometryType::simplex, 4));


## function zot()

Defined in header <amdis/localoperators/ZeroOrderTestTrial.hpp>

template <class Expr, class... QuadratureArgs>
auto zot(Expr&& expr, QuadratureArgs&&... args)


Creates a zero-order term. This is a shortcut for makeOperator() with the explicit tags tag::test or tag::test_trial. All other parameters are the same as for makeOperator().

## function fot()

template <class Expr, class... QuadratureArgs>
auto fot(Expr&& expr, tag::grad_test, QuadratureArgs&&... args)        // (1)

template <class Expr, class... QuadratureArgs>
auto fot(Expr&& expr, tag::grad_trial, QuadratureArgs&&... args)       // (2)

template <class Expr, class... QuadratureArgs>
auto fot(Expr&& expr, tag::partial_test t, QuadratureArgs&&... args)   // (3)

template <class Expr, class... QuadratureArgs>
auto fot(Expr&& expr, tag::partial_trial t, QuadratureArgs&&... args)  // (4)


Creates a first-order term. This is a shortcut for makeOperator() with the explicit tags tag::gradtest_trial (1), tag::test_gradtrial (2), tag::partialtest_trial{ i } (3), or tag::test_partialtrial{ i } (4). All other parameters are the same as for makeOperator().

The second argument identifies whether to differentiate the test or trial function and whether it is a full gradient or just the partial derivative.

## function sot()

Defined in header <amdis/localoperators/SecondOrderGradTestGradTrial.hpp>

template <class Expr, class... QuadratureArgs>
auto sot(Expr&& expr, QuadratureArgs&&... args)


Creates a second-order term. This is a shortcut for makeOperator() with the explicit tags tag::gradtest_gradtrial. All other parameters are the same as for makeOperator().

## function sot_ij()

template <class Expr, class... QuadratureArgs>
auto sot_ij(Expr&& expr, std::size_t i, std::size_t j, QuadratureArgs&&... args)


Creates a second-order term of partial derivatives. This is a shortcut for makeOperator() with the explicit tags tag::partialtest_partialtrial{ i, j }. All other parameters are the same as for makeOperator().

## function convectionDiffusion()

Defined in header <amdis/localoperators/ConvectionDiffusionOperator.hpp>

template <class A, class B, class C, class F, bool conserving = true>
auto convectionDiffusion(A const& a, B const& b, C const& c, F const& f, bool_t<conserving> = {})


Creates a convection-diffusion operator that implements either - $\langle\nabla v, A \nabla u\rangle - \langle\nabla v, \mathbf{b} u\rangle + \langle v, c u\rangle = \langle v, f\rangle$ (conserving) or - $\langle\nabla v, A \nabla u\rangle + \langle v, \mathbf{b}\cdot\nabla u\rangle + \langle v, c u\rangle = \langle v, f\rangle$ (non conserving).

The operator provides a matrix and vector operator, so it can be assigned to both sides of a problem.

#### Example

using Grid = /* any dune grid type */;
using Traits = LagrangeBasis<Grid,1>;
ProblemStat<Traits> prob("prob");
prob.initialize(INIT_ALL);

// define a convection-diffusion operator
auto op = convectionDiffusion(/*A=*/1.0, /*b=*/0.0, /*c=*/1.0, /*f=*/1.0);

See also an example of usage in the examples folder examples/convection_diffusion.cc