Commit a2b0f4b5 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Merge branch 'feature/update_doc' into 'master'

Feature/update doc

See merge request !216
parents ba55e182 00898fc5
Pipeline #4954 passed with stage
in 64 minutes and 2 seconds
......@@ -18,7 +18,6 @@ namespace AMDiS
* to a row and column global basis.
*
* \tparam T The coefficient type of the matrix
* \tparam Pattern The type of the sparsity pattern
* \tparam MatrixImpl A linear-algebra backend for the matrix storage
**/
template <class T, template <class> class MatrixImpl>
......
......@@ -3,7 +3,7 @@
The class [`DOFVector`](#class-dofvector) acts as a container for storing the coefficients of the solution discrete function.
It is attached to a global basis to give its coefficients a meaning. A [`DiscreteFunction`](#class-discretefunction) goes
one step further and transforms a DOFVector or subspaces of a DOFVector (with respecto to a sub basis)
into a [`GridFunction`](/reference/GridFunctions) that allows to use it like a function defined on a grid.
into a [`GridFunction`](../GridFunctions) that allows to use it like a function defined on a grid.
Let $`\{\phi_i\}`$ be the set of basis functions of a finite-element space $`V`$. A function $`u\in V`$ can be represented
as
......@@ -23,12 +23,12 @@ The pair $`\{(u_i),\{\phi_i\}\}`$ is called `DOFVector` and the function $`u=u(\
## class `DOFVector`
Defined in header [`<amdis/DOFVector.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/src/amdis/DOFVector.hpp)
Defined in header [`<amdis/DOFVector.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/amdis/DOFVector.hpp)
```c++
template <class GB,
class T = double,
class Traits = BackendTraits<GB,T>>
class Traits = BackendTraits<GB>>
class DOFVector
: public VectorFacade<T, Traits::template VectorImpl>
```
......@@ -68,37 +68,41 @@ The `value_type` is often the same as `T`, but might be just something similar,
[`interpolate_noalias`](#function-dofvectorinterpolate) | Interpolation of GridFunction to DOFVector assuming no aliasing
[`operator<<`](#function-dofvectorinterpolate) | Operator for the interpolation
??? seealso "Functions inherited from [`VectorFacade`](/reference/MatVecBase/#class-vectorfacade)"
??? seealso "Functions inherited from [`VectorFacade`](../MatVecFacade/#class-vectorfacade)"
Function | Descriptions
--------------------------------|---------------------------------------------
[`basis`](/reference/MatVecBase#function-vectorbasebasis) | Return the GlobalBasis associated with the vector
[`backend`](/reference/MatVecBase#function-vectorbasebackend) | Return the backend vector wrapper implementing the actual algebra
[`localSize,globalSize`](/reference/MatVecBase#function-vectorbasesize) | The number of entries in the local part of the vector
[`resize,resizeZero`](/reference/MatVecBase#function-vectorbaseglobalSize)| Resize the vector to the size of the basis
[`init`](/reference/MatVecBase#function-vectorbaseglobalSize) | Prepare the vector for insertion of values
[`finish`](/reference/MatVecBase#function-vectorbaseglobalSize) | Finish the insertion of values
[`at`](/reference/MatVecBase#function-vectorbaseat) | Return the value of the vector at the given local index
[`insert,set,add`](/reference/MatVecBase#function-vectorbaseinsert) | Insert a single value into the matrix
[`gather`](/reference/MatVecBase#function-vectorbasegather) | Extract values from the vector referring to the given local indices
[`scatter`](/reference/MatVecBase#function-vectorbasescatter) | Insert a block of values into the vector
[`copy`](/reference/MatVecBase#function-vectorbasescatter) | Copies a block of values into the vector
[`forEach`](/reference/MatVecBase#function-vectorbasescatter) | Apply a functor to each value at given indices
[`impl`](../MatVecFacade#function-vectorbasebackend) | Return the backend vector wrapper implementing the actual algebra
[`localSize,globalSize`](../MatVecFacade#function-vectorbasesize) | The number of entries in the local part of the vector
[`resize,resizeZero`](../MatVecFacade#function-vectorbaseglobalSize)| Resize the vector to the size of the basis
[`init`](../MatVecFacade#function-vectorbaseglobalSize) | Prepare the vector for insertion of values
[`finish`](../MatVecFacade#function-vectorbaseglobalSize) | Finish the insertion of values
[`at`](../MatVecFacade#function-vectorbaseat) | Return the value of the vector at the given local index
[`insert,set,add`](../MatVecFacade#function-vectorbaseinsert) | Insert a single value into the matrix
[`gather`](../MatVecFacade#function-vectorbasegather) | Extract values from the vector referring to the given local indices
[`scatter`](../MatVecFacade#function-vectorbasescatter) | Insert a block of values into the vector
[`forEach`](../MatVecFacade#function-vectorbasescatter) | Apply a functor to each value at given indices
## function `DOFVector::DOFVector`
```c++
template <class Basis>
DOFVector(Basis&& basis, DataTransferOperation op = INTERPOLATE)
template <class GV, class PBF>
DOFVector(GV const& gridView, PBF const& preBasisFactory, DataTransferOperation op = INTERPOLATE)
```
Constructs the DOFVector from a given global basis and optionally a DataTransferOperation that
defines how the DOFVector is handled during grid adaption.
Constructs the DOFVector from a given global basis or a grid view and a basis factory, and optionally a DataTransferOperation that defines how the DOFVector is handled during grid adaption.
#### Arguments
`Basis basis`
: Either a `shared_ptr` to the `GlobalBasis` type or anything that can be converted to that, e.g. a
reference or a `unique_ptr` or a dune-functions `DefaultGlobalBasis`. References to lavlues are
wrapped into non-destroying `shared_ptr`s whereas rvalue-references are moved into new basis objects.
: Either a `shared_ptr` to the `GlobalBasis` type or anything that can be converted to that, e.g. a reference or a `unique_ptr`. References to lvalues are wrapped into non-destroying `shared_ptr`s whereas rvalue-references are moved into new basis objects.
`GV gridView`
: A grid view provided by the grid
`PBF preBasisFactory`
: A factory to create a pre-basis, see [the ref page on GlobalBasis](../GlobalBasis#making-a-prebasis)
`DataTransferOperation op`
: The operation performed during data-transfer, either `DataTransferOperation::INTERPOLATE` or `DataTransferOperation::NO_OPERATION`
......@@ -214,7 +218,7 @@ performed on the temporary using *noalias* interpolation (1). Then, this tempoar
## function `makeDOFVector`
Defined in header [`<amdis/DOFVector.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/src/amdis/DOFVector.hpp)
Defined in header [`<amdis/DOFVector.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/amdis/DOFVector.hpp)
```c++
template <class T = double,
......@@ -261,7 +265,7 @@ auto vec2 = makeDOFVector(basis2, DataTransferOperation::NO_OPERATION);
## class `DiscreteFunction`
Defined in header [`<amdis/gridfunctions/DiscreteFunction.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/src/amdis/gridfunctions/DiscreteFunction.hpp)
Defined in header [`<amdis/gridfunctions/DiscreteFunction.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/amdis/gridfunctions/DiscreteFunction.hpp)
```c++
template <class Coefficients,
......@@ -316,10 +320,10 @@ A `DiscreteFunction` is the interpretation of a `DOFVector` as grid function.
## function `DiscreteFunction::DiscreteFunction`
```c++
// (1)
DiscreteFunction(DOFVector<GlobalBasis,T> const& dofVector,
DiscreteFunction(DOFVector<GlobalBasis,T> const& dofVector, GlobalBasis const& basis,
TreePath const& treePath = {})
// (2)
DiscreteFunction(DOFVector<GlobalBasis,T>& dofVector,
DiscreteFunction(DOFVector<GlobalBasis,T>& dofVector, GlobalBasis const& basis,
TreePath const& treePath = {})
```
......@@ -331,6 +335,9 @@ only available for the const or mutable `is_const` template parameter specializa
: The container storing the global coefficients. Is stored as pointer in the DiscreteFunction and thus must have a longer lifetime
than the DiscreteFunction.
`GlobalBasis const& basis`
: The global basis associated with the dofvector.
`TreePath treePath`
: A `Dune::TypeTree::HybridTreePath<...>` representing the coordinates of a node in the basis tree this DiscreteFunction is
defined on. The type of the treePath also defines the `Range` type of the DiscreteFunction.
......@@ -421,7 +428,7 @@ DiscreteFunction& operator+=(Expr&& expr)
// (5)
template <class Expr>
DiscreteFunction& operator+=(Expr&& expr)
DiscreteFunction& operator-=(Expr&& expr)
```
(1) Interpolation of a `GridFunction` (or Expression) to the subtree of the DOFVector, assuming that there is no
......@@ -467,18 +474,20 @@ df2 += 42.0;
## function `makeDiscreteFunction`
Defined in header [`<amdis/gridfunctions/DiscreteFunction.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/src/amdis/gridfunctions/DiscreteFunction.hpp)
Defined in header [`<amdis/gridfunctions/DiscreteFunction.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/amdis/gridfunctions/DiscreteFunction.hpp)
```c++
// (1)
template <class GlobalBasis, class ValueType,
class PreTreePath = Dune::TypeTree::HybridTreePath<>>
auto makeDiscreteFunction(DOFVector<GlobalBasis, ValueType> const& dofVector,
GlobalBasis const& basis,
PreTreePath const& preTreePath = {})
// (2)
template <class GlobalBasis, class ValueType,
class PreTreePath = Dune::TypeTree::HybridTreePath<>>
auto makeDiscreteFunction(DOFVector<GlobalBasis, ValueType>& dofVector,
GlobalBasis const& basis,
PreTreePath const& preTreePath = {})
```
......@@ -491,6 +500,9 @@ can be constructed from.
: The container storing the global coefficients. Is stored as pointer in the DiscreteFunction and thus must have a longer lifetime
than the DiscreteFunction.
`GlobalBasis const& basis`
: The global basis associated to dofVector.
`PreTreePath preTreePath`
: A pree-tree path, a `Dune::TypeTree::HybridTreePath<...>` can be created from.
......
# Global Basis {: #group-globalbasis }
## Summary
In the context of the finite-element method we use a finite-element space $`V`$ with the set of basis functions $`\{\phi_i\}`$. Within AMDiS this concept is realized by the class `ParallelGlobalBasis`, contained in the header file `amdis/functions/ParallelGlobalBasis.hpp`. This extends the interface of the underlying `Dune::Functions::DefaultGlobalBasis<Impl>` with an automatic update mechanism used in several places within AMDiS. We strongly advice to always use an `AMDiS::ParallelGlobalBasis` or a user-defined derived class instead of the DUNE data structure for the update mechanism to work properly.
For more information on the class interface visit the API documentation.
## PreBasis classes and basis trees
Many finite-element spaces in applications can be constructed as a product of simple spaces $`V = V_1 \times V_2 \times \dots \times V_k`$. For example the Taylor-Hood-Element can be constructed as $`V_{TH} = V_{v} \times V_{p}`$ with the space of velocity functions $`V_v`$ and pressure functions $`V_p`$. The velocity space can again be decomposed into the vector components $`V_v = V_{v_1} \times \dots \times V_{v_n}`$. If we use second-degree lagrange basis functions for the velocity space and first-order lagrange basis functions for the pressure we get a decomposition $`V_{TH} = V_{v_1} \times V_{v_n} \times V_p = L_2^n \times L_1`$.
The underlying numerics environment of AMDiS, DUNE, attempts to model the situation above. Hence a `ParallelGlobalBasis` in AMDiS can be defined by a tree structure using the Dune-PreBasis class, which itself is composed of nodes in a tree. The leaf nodes in this tree contain the implementation details of the simple basis, while inner nodes indicate composition of either identical children (called power nodes) or arbitrary children (called composite nodes).
### Making a PreBasis
When we want to build a `PreBasis` we must first identify the structure of the basis we want to construct with a tree. We can then build that structure in AMDiS by nesting the functions `Dune::Functions::BasisFactory::composite(Nodes...[, MergingStrategy])` for composite nodes, `Dune::Functions::BasisFactory::power(Node[, MergingStrategy])` for power nodes and implementations (e.g. `Dune::Functions::BasisFactory::lagrange<k>())`). The second optional argument `MergingStrategy` provides merging strategies to the inner nodes, specifying how the indices of the simple leaf basis should be merged to obtain the indexing of the global basis. Currently only flat indexing is supported by AMDiS.
The following code snippet shows how a PreBasisFactory for a Taylor-Hood-Element is constructed, that can later be used to build a global basis.
```c++
using namespace Dune::Functions::BasisFactory;
const int dow = 2; // world dimension
const int k = 1; // order parameter
auto taylorHoodPreBasisFactory =
composite(
power<dow>(
lagrange<k+1>()
),
lagrange<k>()
);
auto taylorHoodPreBasisFactoryWithMergingStrategy =
composite(
power<dow>(
lagrange<k+1>(),
flatInterleaved()
),
lagrange<k>(),
flatLexicographic()
);
```
## Making a global basis
Using a PreBasisFactory we can easily make a global basis by defining the set of grid elements on which the basis functions of the FE-space should live. This can be done by providing a GridView and using the `ParallelGlobalBasis` constructors. An optional name can be provided that can be used to pass initfile parameters to the parallel communication class.
```c++
// Name, Grid and Dune::DefaultGlobalBasis arguments
template <class... Args>
ParallelGlobalBasis(std::string const& name, Grid const& grid, Args&&... args);
// As above with name defaulting to ""
template <class... Args>
ParallelGlobalBasis(Grid const& grid, Args&&... args);
// Name, GridView and PreBasisFactory
template <class PBF>
ParallelGlobalBasis(std::string const& name, GridView const& gridView, PBF const& preBasisFactory);
// As above with name defaulting to ""
template <class PBF>
ParallelGlobalBasis(GridView const& gridView, PBF const& preBasisFactory);
```
If we use a ProblemStat object most of the work will be done automatically for us. The PreBasis is specified via a Traits template parameter with the most frequently used cases already included in `amdis/ProblemStatTraits.hpp`. Those include
```c++
// Composition of any number of lagrange bases with any degree
template <class Grid, int... degrees>
struct LagrangeBasis;
// As above but a structured grid is chosen
template <int dim, int... degrees>
struct YaspGridBasis;
// The taylor-hood basis as discussed above
template <class Grid, int k = 1>
struct TaylorHoodBasis;
```
If one of the above traits class is provided ProblemStat will create a new global basis on a call to `ProblemStat::initialize`. Afterwards a pointer to the basis can be obtained using the function `ProblemStat::globalBasis`.
```c++
using Grid = Dune::YaspGrid<2>; // 2-dimensional structured grid
ProblemStat<TaylorHoodBasis<Grid>> prob("myProblem");
prob.initialize(INIT_ALL);
auto& basis = *prob.globalBasis();
```
## Using the global basis
The `ParallelGlobalBasis` provides access to element indices and basis functions in the same way as a Dune-basis does, it is even derived from the Dune::DefaultGlobalBasis.
### Getting the total number of DOFs
If we are simple interested in getting the total number of DOFs the basis contains we can simply call `basis.dimension()`. This can be useful for preparing matrices and vectors for insertion.
```c++
std::size_t maxSize = basis.dimension();
std::vector<double> dofs;
dofs.resize(maxSize);
```
### Access to local basis functions using a LocalView
Within that interface we are restricted to elementwise access using a `LocalView`. This provides us with a way to work with the local basis functions on one grid element. We show a typical use in the following snippet. Note how we first need to bind the `LocalView` before we can use it.
```c++
auto localView = basis.localView();
for (const auto& e : elements(basis.gridView())) // loop over all grid elements the basis is defined on
{
localView.bind(e); // a LocalView must be bound to an element before being used
// do something
localView.unbind();
}
```
A bound LocalView has the method `LocalView::index(size_type)` mapping a local index to a global index. In other words it maps a local basis function defined on an element to its corresponding global basis function. We can use that to build a global stiffness matrix from local contributions on a single element and then insert those into a single matrix in global indices.
Another method is `LocalView::tree()` that returns the root node of the local basis tree. The main method all nodes share is `Node::localIndex(size_type)` which maps a leaf node index to the local index within the local basis tree.
#### The for_each_node and for_each_leaf_node helper functions
Quite often we want to perform operations on certain nodes of the tree other than the root node. This can be useful if we want to work with the actual implementations wich are usually leaf nodes. For this we can use the helper functions `for_each_node` and `for_each_leaf_node` defined in `amdis/typetree/Traversal.hpp`. Those functions traverse the tree and call the given function on every (leaf) node with the node and a type of tree index we shall explain later as arguments. we show the usage with the following example using the Taylor-Hood-Basis defined above. Here we assume to have a `LocalView` `localView` that is bound to an element.
```c++
auto root = localView.tree();
for_each_leaf_node(root, [&](auto const& node, auto const& tp) {
// do something on node
});
```
#### Working on specific nodes using a TreePath {: #globalbasis-using-treepath }
There are cases when we want to address a certain tree node. To come back to our Taylor-Hood example we might want to add an operator that only acts on the velocity vector or the pressure, or even just a single component of the velocity vector. For this end a type of node index exists, called `TreePath`. This defines a list of indices specifying which path to take from the root at each node on the way. For technical reasons the index type is either an `int` (for power nodes) or `std::integral_constant<std::size_t, i>` for composite nodes. For convenience we can use `Dune::Indices::_0` instead of writing `std::integral_constant<std::size_t, 0>`. Note how indices always start at 0 and follow the order we specify when creating the `PreBasis`.
Using once again the Taylor-Hood basis we can use the `treepath(Args...)` function to convert indices into a `TreePath` for certain nodes.
```c++
auto tp_v = treepath(Dune::Indices::_0); // velocity vector
auto tp_p = treepath(Dune::Indices::_1); // pressure
auto tp_v2 = treepath(Dune::Indices::_0, 1); // second component of the velocity vector
auto tp_root = treepath(); // root
```
Recall that `localView.tree()` returns the root of the basis tree. Using a `TreePath` we can access a specific node using the free funtion `Dune::TypeTree::child(Node, TreePath)`.
```c++
auto root = localView.tree();
auto node_v = Dune::TypeTree::child(root, tp_v); // power node representing the velocity vector
auto node_p = Dune::TypeTree::child(root, tp_p); // lagrange node representing the pressure
```
### Using the lagrange (pre-)basis
Many applications require only lagrange elements or compositions, for example a Navier-Stokes problem may use the Taylor-Hood basis we introduced above that consists of `dim` second order lagrange elements and one first order lagrange element. For that reason we will now take a closer look at the implementation of those lagrange elements in AMDiS.
AMDiS borrows the implementation from the underlying DUNE-functions module. This defines lagrange elements of a given order `k`. Recall that we can add lagrange nodes to a (pre-)basis using `Dune::Functions::BasisFactory::lagrange<k>()`. In the previous section we have seen how we can access the leaf nodes of a basis. With that we can get the implementation of the local finite element with the function `Dune::Functions::LagrangeNode::finiteElement()`.
We shall show the usage of the local finite element class handed out by the function above. Its interface defines the functions `size()`, `localCoefficients()`, `localInterpolation()` and `localBasis()`. We shall explain those with an example. Assume we have `localView` bound to an element and have vectors `dofs` and `dofs2` that store the coefficients of some grid function with global indexing (e.g. a solution vector). `Domain` is the type used for local coordinates of the reference element.
```c++
auto root = localView.tree();
for_each_leaf_node(root, [&](auto const& node, auto const& tp) {
// Extract some types from the node
using Node = Underlying_t<decltype(node)>;
using LocalFunction = typename Node::FiniteElement::Traits::LocalInterpolationType::FunctionType;
using Domain = typename LocalFunction::Traits::DomainType;
using Range = typename LocalFunction::Traits::RangeType;
auto const& fe = node.finiteElement();
auto feSize = fe.size();
// get information about the position of a basis function in the element
auto const& localCoefficients = fe.localCoefficients();
for (std::size_t i = 0; i < feSize; ++i)
{
auto const& localKey = localCoefficients.localKey(i);
// do something
}
// interpolate a local function onto an element
auto f_ = [](Domain const& x) -> Range { return x[0] + x[1]; };
auto f = functionFromCallable<Range(Domain)>(f_);
std::vector<Range> localCoeff;
fe.localInterpolation().interpolate(f, localCoeff); // interpolate f onto the local basis
for (std::size_t i = 0; i < feSize; ++i)
{
std::size_t globalIndex = localView.index(node.localIndex(i)); // get the global index
dofs[globalIndex] = localCoeff[i]; // set global coefficient to the local coefficient
}
// evaluate at a local coordinate
std::vector<Range> localContrib(feSize);
fe.localBasis().evaluateFunction({0.2, 0.2}, localContrib); // get contributions of local basis functions at a given local coordinate
Range sum = 0;
for (std::size_t i = 0; i < feSize; ++i)
{
std::size_t globalIndex = localView.index(node.localIndex(i)); // get the global index
sum += dofs2[globalIndex] * localContrib[i]; // add contribution from i-th local basis function
}
});
```
### Keeping indices and data updated when the grid changes
Within an adaptive simulation we may want to add or remove grid elements by refinement or coarsening. When this happens the number of total elements or their relative position may change. Therefore the indexing scheme used by the global basis must be updated when changes to the underlying grid happen.
For this purpose the update method exists, which takes a GridView of the Grid after it has been changed as its only argument.
```c++
void update(GridView const& gv)
```
Usually we do not need to call this function - out of the box AMDiS with a ProblemStat doing most of the work will automatically call it for us. If user code is working with the underlying Dune-Grid directly there is no way for AMDiS to detect if any changes happen to it, therefore update must be called manually in such a scenario.
### The globalRefineCallback function
Certain grid managers support the use of a callback function when doing global refinement. Using a ParallelGlobalBasis in this context is currently not supported.
......@@ -35,7 +35,7 @@ elementary terms.
### Examples of expressions
Before we give examples where and how to use GridFunctions, we demonstrate what an
`Expression` could be, to create a GridFunction from. In the following examples,
we assume that a [ProblemStat](reference/Problem#class-problemstat) named `prob` is already
we assume that a [ProblemStat](../Problem#class-problemstat) named `prob` is already
created and initialized.
#### 1. Discrete Functions
......@@ -95,7 +95,7 @@ prob.addMatrixOperator(opB, Row, Col);
auto opL = makeOperator(LinearForm, Expression);
prob.addVectorOperator(opL, Row);
```
See also [makeOperator()](reference/Operators#function-makeoperator).
See also [makeOperator()](../Operators#function-makeoperator).
#### 2. Usage of GridFunctions in BoundaryConditions:
```c++
......@@ -152,7 +152,7 @@ auto value = integrate(Expression, prob.gridView());
## function `evalAtQP()`
Defined in header [`<amdis/gridfunctions/AnalyticGridFunction.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/src/amdis/gridfunctions/AnalyticGridFunction.hpp)
Defined in header [`<amdis/gridfunctions/AnalyticGridFunction.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/amdis/gridfunctions/AnalyticGridFunction.hpp)
```c++
template <class Function>
......@@ -172,7 +172,7 @@ Creates a `GridFunction` that evaluates a functor in global coordinates.
## function `X()`
Defined in header [`<amdis/gridfunctions/CoordsGridFunction.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/src/amdis/gridfunctions/CoordsGridFunction.hpp)
Defined in header [`<amdis/gridfunctions/CoordsGridFunction.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/amdis/gridfunctions/CoordsGridFunction.hpp)
```c++
inline auto X(); // (1)
......@@ -190,7 +190,7 @@ global coordinates (2).
## function `gradientAtQP()`
Defined in header [`<amdis/gridfunctions/DerivativeGridFunction.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/src/amdis/gridfunctions/DerivativeGridFunction.hpp)
Defined in header [`<amdis/gridfunctions/DerivativeGridFunction.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/amdis/gridfunctions/DerivativeGridFunction.hpp)
```c++
template <class Expr>
......@@ -218,7 +218,7 @@ gradientAtQP(X(0) + X(1) + prob.solution(_0))
## function `invokeAtQP()`
Defined in header [`<amdis/gridfunctions/FunctorGridFunction.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/src/amdis/gridfunctions/FunctorGridFunction.hpp)
Defined in header [`<amdis/gridfunctions/FunctorGridFunction.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/amdis/gridfunctions/FunctorGridFunction.hpp)
```c++
template <class Functor, class... Exprs>
......
# Parameter file {: #group-initfile }
## Summary
Many functionalities of an `AMDiS` program can be controlled using a parameter file. This file is passed as first argument to the `AMDiS` executable. If we want to run the `ellipt.2d` example using the parameter file `init/ellipt.dat.2d` we can do so using the following console command in the examples directory:
```
./ellipt.2d init/ellipt.dat.2d [other arguments]
```
We will give a list of possible parameters at the [end of this document](#list-of-parameters-and-values).
## Structure of a parameter file
Parameters in the parameter file have keys in the form of strings separated by `->`. This allows grouping of parameters that are related to the same things. High-level classes like `ProblemStat` have a string constructor argument where a name can be provided that relates to an initfile key.
```c++
examples/ellipt.cc:
using Param = LagrangeBasis<Grid, 2>;
ProblemStat<Param> prob("ellipt"); // make a ProblemStat with the name 'ellipt'
```
```
examples/init/ellipt.dat.2d:
ellipt->mesh: elliptMesh % name of the mesh created by 'ellipt'
elliptMesh->num cells: 8 8 % size of the mesh 'elliptMesh'
ellipt->solver: pcg % solver type used by 'ellipt'
ellipt->solver->max iteration: 10000 % solver parameter related to 'ellipt->solver'
```
As we saw above, parameters are separated from the keys with the `:` character and can be strings and numbers. Anything following a `%` character is considered a comment.
## Reading from a parameter file
In the section above we learned that `AMDiS` classes can be given names that can then be used to specify parameters in the parameter file. In addition to the options `AMDiS` classes already provide we can add user-defined parameters. For this we simply have to add a `key: value` pair to the parameter file as we would do with the built-in options and read the value somewhere in our program using the function `Parameters::get<T>`:
```c++
// (1) Overwrites 'value' with the value related to 'key' if found
template <class T>
static void get(std::string const& key, T& value);
// (2) Returns a std::optional containing the value related to 'key' if found
template <class T>
static std::optional<T> get(std::string const& key);
```
We will now give an example of reading an `int` parameter called `myParameter` from an initfile that defaults to `3` if no parameter file containing the key is provided.
```
// example parameter file entry
myParameter: 42
```
```c++
// using (1)
int i = 3;
Parameters::get("myParameter", i);
// using (2)
int i = Parameters::get<int>("myParameter").value_or(3);
```
## Writing to a parameter file
It is possible to change to value of a parameter given in a parameter file using the function
```c++
template <class T>
static void set(std::string const& key, T const& value);
```
This can be useful if we want to override certain values within our program.
## List of parameters and values
In the following section `<prefix>` denotes a placeholder for the name given to the class instance. `<treepath>` is a (possibly empty) comma-separated list of integers specifying a [`TreePath`](../GlobalBasis#globalbasis-using-treepath).
### ProblemStat
key | type | values | default value
------------------------------|--------|--------------------------------|-------------
`<prefix>->mesh` | string | Prefix used by the mesh | `mesh`
`<prefix>->restore->grid` | string | Filename of the grid file | Not optional<sup>1</sup>
`<prefix>->restore->solution` | string | Filename of the solution file | Not optional<sup>1</sup>
`<prefix>->symmetry` | string | Symmetry of the stiffness matrix, one of:<br> `spd`,<br> `symmetric`,<br>`hermitian`,<br>`structurally_symmetric`,<br>`unknown` | `unknown`
`<prefix>->solver` | string | Solver type, see [Solvers and Preconditioners](#solvers-and-preconditioners) | `default`
`<prefix>->marker[<treepath>]`| string | Prefix for marker parameters, see [Markers](#markers) | None<sup>2</sup>
`<prefix>->output[<treepath>]`| string | Prefix for filewriter parameters, see [Filewriters](#filewriters)| None<sup>3</sup>
`<prefix>->output` | string | as `<prefix>->output[]` | None<sup>3</sup>
<sup>1</sup>Only required when `ProblemStat::restore` is called<br>
<sup>2</sup>No marker will be set up if the `->strategy` subkey is not specified<br>
<sup>3</sup>No filewriter will be set up if the `->format` subkey is not specified<br>
### Markers
key | type | values | default value
-------------------------------------|--------|----------------------------------|-------------
`<prefix>->strategy` | string | Marking strategy, one of:<br>`0` (no marking),<br>`1` (global refinement),<br>`2` (maximum strategy),<br>`3` (equidistribution strategy),<br>`4` (guaranteed error reduction strategy) | Not optional
`<prefix>->info` | int | Verbosity | `0`
`<prefix>->max refinement level` | int | Maximum refinement level | No maximum
`<prefix>->min refinement level` | int | Minimum refinement level | `0`
`<prefix>->p`<sup>123</sup> | double | Power in estimator norm | `2.0`
`<prefix>->MSGamma`<sup>1</sup> | double | Marking parameter | `0.5`
`<prefix>->MSGammaC`<sup>1</sup> | double | Marking parameter | `0.1`
`<prefix>->ESTheta`<sup>2</sup> | double | Marking parameter | `0.9`
`<prefix>->EsThetaC`<sup>2</sup> | double | Marking parameter | `0.2`
`<prefix>->GERSThetaStar`<sup>3</sup>| double | Marking parameter | `0.6`
`<prefix>->GERSNu`<sup>3</sup> | double | Marking parameter | `0.1`
`<prefix>->GERSThetaC`<sup>3</sup> | double | Marking parameter | `0.1`
<sup>1</sup>Only for maximum strategy<br>
<sup>2</sup>Only for equidistribution strategy<br>
<sup>3</sup>Only for guaranteed error reduction strategy<br>
### Solvers and Preconditioners
#### Parameters used by the SolverInfo class
key | type | values | default value
-------------------------------------|--------|----------------------------------|-------------
`<prefix>->info` | int | Solver verbosity level | `0`
`<prefix>->break if tolerance not reached`|bool| If `true` throw an error if tolerance could not be reached| `false`
#### PETSc
key | type | values | default value
--------------------------------|---------|----------------------------------|-------------
`<prefix>->info` | int | Verbosity, one of:<br>`0` (no convergence information),<br>`1` (minimal output, print residual every 10th iteration),<br>`2` (full convergence output) | `0`
`<prefix>->ksp` | string | Name of a PETSc Krylov method<sup>a</sup>| `default`
`<prefix>` | string | alternative to `<prefix>->ksp` when not set | as above
`<prefix>->max it` |PetscInt | Verbosity | `PETSC_DEFAULT`
`<prefix>->rtol` |PetscReal| Relative convergence tolerance<sup>b</sup>| `PETSC_DEFAULT`
`<prefix>->atol` |PetscReal| Absolute convergence tolerance<sup>b</sup>| `PETSC_DEFAULT`
`<prefix>->divtol` |PetscReal| Divergence tolerance<sup>b</sup> | `PETSC_DEFAULT`
`<prefix>->prefix` | string | The options prefix for the solver<sup>c</sup> | No prefix set
`<prefix>->mat solver` | string | Sets the software that is used to perform the factorization <sup>d</sup>| `umfpack` (sequential matrix) or `mumps` (otherwise)
`<prefix>->pc` | string | The preconditioner type<sup>e</sup>| `default`
`<prefix>->pc->mat solver`<sup>1</sup>|string| Solver used by the LU preconditioner<sup>d</sup>| None
`<prefix>->pc->prefix` | string | The options prefix for the preconditioner<sup>f</sup>|No prefix set
`<prefix>->scale`<sup>2</sup> |PetscReal| Damping factor used by richardson solver | `1.0`
`<prefix>->restart`<sup>3</sup> |PetscInt | Number of iterations until restart | `30`
`<prefix>->gramschmidt`<sup>3</sup>|string| Orthogonalization routine used by gmres solvers<sup>g</sup>: `classical` or `modified` | Use PETSc default
`<prefix>->restart`<sup>3</sup> | string | Type of iterative refinement to use in the classical Gram Schmidt orthogonalization<sup>h</sup>, one of:<br>`never` (never refine),<br>`ifneeded` (refine if needed),<br>`always` (always refine)| Use PETSc default
`<prefix>->ell`<sup>4</sup> |PetscReal| Number of search directions in BiCGStab_ell| Use PETSc default
`<prefix>->restart`<sup>5</sup> |PetscInt | Number of iterations until restart | Use PETSc default
<sup>1</sup>Only for `lu` preconditioner<br>
<sup>2</sup>Only for richardson solver<br>
<sup>3</sup>Only for gmres solver types<br>
<sup>4</sup>Only for BiCGStab_ell solver<br>
<sup>5</sup>Only for GCR solver<br>
<sup>a</sup>See [PETSc documentation for Krylov methods](https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/KSP/KSPType.html)<br>
<sup>b</sup>See [PETSc documentation for Krylov method tolerances](https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/KSP/KSPSetTolerances.html)<br>
<sup>c</sup>See [PETSc documentation for Krylov method options](https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/KSP/KSPSetOptionsPrefix.html)<br>
<sup>d</sup>See [PETSc documentation for preconditioners](https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/PC/PCFactorSetMatSolverType.html)<br>
<sup>e</sup>See [PETSc documentation for preconditioners](https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/PC/PCType.html)<br>
<sup>f</sup>See [PETSc documentation for preconditioners](https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/PC/PCSetOptionsPrefix.html)<br>
<sup>g</sup>See [PETSc documentation for GMRes solver](https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/KSP/KSPGMRESSetOrthogonalization.html)<br>
<sup>h</sup>See [PETSc documentation for GMRes solver](https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/KSP/KSPGMRESSetCGSRefinementType.html)<br>
#### EIGEN
key | type | values | default value
-------------------------------------|----------|-------------------------------------|----------
`<prefix>` | string | Solver type, one of:<br>`cg` (conjugate gradient solver),<br>`bicgstab` (bi-conjugate gradient stabilized solver),<br>`bcgs` (same as `bicgstab`),<br>`minres` (minimal residual algorithm for symmetric matrices),<br>`gmres` (generalized minimal residual algorithm),<br>`dgmres` (restarted gmres with deflation),<br>`default` (same as `gmres`),<br>`umfpack`<sup>1</sup> (sparse LU factorization based on UmfPack),<br>`superlu`<sup>2</sup> (sparse LU factorization based on SuperLU library),<br>`direct` (same as `umfpack` or `superlu`) | `default`
`<prefix>->reuse pattern` | bool | Reuse matrix pattern if `true` | `false`
`<prefix>->relative tolerance` |RealScalar| Tolerance threshold used by the stopping criteria| floating-point epsilon
`<prefix>->max iteration` | int | Maximum number of iterations | `500`
`<prefix>->restart`<sup>34</sup> | int | Number of iterations until restart | `30`
`<prefix>->num eigenvalues`<sup>4</sup>| int | Number of eigenvalues to deflate at each restart| `0`
`<prefix>->max num eigenvalues`<sup>4</sup>|int | Maximum size of the deflation subspace| `5`
`<prefix>->precon->name`<sup>5</sup> | string | Preconditioner, one of:<br>`no` (no preconditioner),<br>`diag` (diagonal preconditioner),<br>`jacobi` (diagonal preconditioner),<br>`ilu` (incomplete LU factorization),<br>`ic` (incomplete Choleski factorization) | `no`
`<prefix>->precon->ordering`<sup>6</sup>|string | Ordering used in Choleski factorization: `amd` or `natural` | `amd`
`<prefix>->precon->drop tolerance`<sup>7</sup>|double| Drop any element whose magnitude is less than this tolerance| `1e-15l`
`<prefix>->precon->fill factor`<sup>7</sup>|int | This is used to compute the number of largest elements to keep on each row| `10`
<sup>1</sup>Requires UmfPack<br>
<sup>2</sup>Requires SuperLU<br>
<sup>3</sup>Only for `gmres` solver<br>
<sup>4</sup>Only for `dgmres` solver<br>
<sup>5</sup>Does not apply to `umfpack` or `superlu` solvers<br>
<sup>6</sup>Only for incomplete Choleski factorization<br>
<sup>7</sup>Only for `ilu` solver<br>
#### MTL
key | type | values | default value
-------------------------------------|--------|----------------------------------|-------------
`<prefix>` | string | Solver type, one of:<br>`cg` (conjugate gradient method),<br>`cgs` (stabilized conjugate gradient method),<br>`bicg` (BiCG method),<br>`bcgs` (stabilized BiCG(1) method),<br>`bicgstab` (as `bcgs`),<br>`bcgs2` (stabilized BiCG(2) method),<br>`bicgstab2` (as `bcgs2`),<br>`qmr` (quasi-minimal residual method),<br>`tfqmr` (transposed-free quasi-minimal residual method),<br>`bcgsl` (stabilized BiCG(ell) method),<br>`bicgstab_ell` (as `bcgsl`),<br>`gmres` (generalized minimal residual method),<br>`fgmres` (flexible gmres),<br>`minres` (minimal residual method),<br>`idrs` (induced dimension reduction method),<br>`gcr` (generalized conjugate residual method),<br>`preonly` (just apply a preconditioner),<br>`default` (as `gmres`),<br>`umfpack`<sup>1</sup> (external UMFPACK solver),<br>`direct` (as `umfpack`) | `default`
`<prefix>->absolute tolerance`<sup>2</sup>| type of matrix values | Absolute solver tolerance: ∥b-Ax∥ < `absolute tolerance` | `0`
`<prefix>->relative tolerance`<sup>2</sup>| type of matrix values | Relative solver tolerance: ∥b-Ax∥ / ∥b-Ax<sub>0</sub>∥ < `relative tolerance` | `1.e-6`