GridFunctions
Summary
GridFunctions are objects that can be evaluated in global coordinates and can be
restricted to grid elements and evaluated there in local coordinates. A GridFunction in AMDiS
models the concept Dune::Functions::GridFunction, i.e., it provides the types Domain, Range,
and EntitySet, a member function entitySet(), and a free function localFunction(gf).
If additionally the grid view is accessible via gf.entitySet().gridView(), it models the
concept GridViewFunction (see Concepts::GridFunction and Concepts::GridViewFunction in
amdis/gridfunctions/GridFunction.hpp).
ProblemStat<Traits> prob("name");
prob.initialize(INIT_ALL);
// create a grid function
auto gridFct = makeGridFunction(EXPRESSION, prob.gridView());
// eval GridFunction at global coordinates
auto global = Dune::FieldVector<double,2>{1.0, 2.0};
auto value = gridFct(global);
// create a local representation of the grid function
auto localFct = localFunction(gridFct);
for (auto const& element : elements(prob.gridView()))
{
// bind the local function to a grid element
localFct.bind(element);
// eval LocalFunction at local coordinates
auto geometry = element.geometry();
auto local = geometry.local(geometry.center());
value = localFct(local);
localFct.unbind();
}
GridFunctions are build from expressions that are a composition of some
elementary terms. The function makeGridFunction(expr, gridView) (header
amdis/gridfunctions/GridFunction.hpp) binds an expression to a grid view. If expr is
already a GridFunction, it is returned unchanged.
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 named prob is already
created and initialized.
1. Discrete Functions
Components of a solution vector are discrete functions, i.e. grid function build by a linear combination of local basis functions with a vector of coefficients, see DiscreteFunction.
auto expr1 = prob.solution(0);
auto expr1a = valueOf(*prob.solutionVector(), 0);
2. Constants and functions
Constant values (or reference to values) and functions of global coordinates are expressions
auto expr2 = 1.0;
auto expr2a = constant(1.0);
double var = 1.0;
auto expr3 = reference(var);
auto expr4 = [](auto const& x) { return x[0] + x[1]; };
auto expr4a = evalAtQP(expr4);
Constants can be arithmetic types, Dune::FieldVector, Dune::FieldMatrix, or Dune::DiagonalMatrix.
A functor of global coordinates is converted into a GridFunction automatically, when passed to
makeGridFunction(). In order to combine it with other expressions, it has to be wrapped
by evalAtQP().
Warning
Combining std::ref and constant expressions could result in unexpected
behavior. Note that a reference wrapper implicitly converts to the underlying
data type and thus std::ref<double> + double results in double and the
reference is gone. Use a lambda function and a function wrapper instead.
3. Composition of expressions
Combining expressions using arithmetic operations or some mathematical functions build a new expressions:
auto expr5 = prob.solution(0) + 1.0;
auto expr6 = max(evalAtQP(expr4), expr3);
This works, if at least one of the expressions involved is already a grid functions, so one can not simply add two lambda functions
// ERROR:
auto no_expr = expr4 + 1.0;
Examples of usage
In the following examples, an Expression is anything a GridFunction can
be created from, sometimes also called PreGridFunction. It includes constants,
functors callable with global coordinates, and any combination of GridFunctions.
1. Usage of GridFunctions to build Operators:
ProblemStat<Traits> prob("name");
prob.initialize(INIT_ALL);
auto opB = makeOperator(BiLinearForm, Expression);
prob.addMatrixOperator(opB, Row, Col);
auto opL = makeOperator(LinearForm, Expression);
prob.addVectorOperator(opL, Row);
2. Usage of GridFunctions in BoundaryConditions:
prob.addDirichletBC(Predicate, Row, Col, Expression);
3. Interpolate a GridFunction to a DOFVector:
prob.solution(_0).interpolate(Expression);
prob.solution() << Expression;
4. Integrate a GridFunction on a GridView:
auto value = integrate(Expression, prob.gridView());
auto value2 = integrate(Expression, prob.gridView(), 4); // with explicit quadrature order
List of Grid Functions and Expressions
| Function | Descriptions |
|---|---|
evalAtQP(f) |
Evaluates a functor in global coordinates. |
gradientOf(gf) |
Differentiate a grid function w.r.t. global coords |
divergenceOf(gf) |
Divergence of a vector-valued grid function, see gradientOf() |
partialDerivativeOf(gf,i) |
Partial derivative w.r.t. the i-th global coordinate, see gradientOf() |
invokeAtQP(f,gf_0,gf_1...) |
Apply a functor to the evaluated grid functions |
X(), X(comp) |
Return (component of) the global coordinate |
constant(value) |
Any (constant) scalar value or FieldVector or FieldMatrix |
valueOf(dofVector,ii...) |
A DiscreteFunction of a DOFVector |
reference(variable) |
A reference to an lvalue object |
+, -, *, / |
Arithmetic expressions |
get(gf,i), get<i>(gf) |
Retrieve the i-th component of a vector expression: |
| cmath Function | Descriptions |
|---|---|
max(gf_0,gf_1) |
Maximum of two grid functions: |
min(gf_0,gf_1) |
Minimum of two grid functions: |
abs_max(gf_0,gf_1) |
Maximum of the absolute value of two grid functions: |
abs_min(gf_0,gf_1) |
Minimum of the absolute value of two grid functions: |
clamp(gf,a,b) |
A grid functions clamped btween two values a and b: |
abs(gf) |
The absolute value of a grid functions: |
signum(gf) |
The sign of a grid function: |
sqr(gf) |
The square value of a grid functions: |
pow(gf,p), pow<p>(gf) |
A grid functions taken to the power of p (a double or an int template parameter): |
tanh(gf) |
The hyperbolic tangent of a grid function: |
| vector/matrix Function | Descriptions |
|---|---|
sum(gf) |
The sum of the components of a vector-valued GridFunction: |
unary_dot(gf) |
The inner product of a vector-valued GridFunction with itself: |
one_norm(gf) |
The 1-norm of a vector-valued GridFunction: |
two_norm(gf) |
The 2-norm of a vector-valued GridFunction: |
p_norm<p>(gf) |
The p-norm of a vector-valued GridFunction: |
infty_norm(gf) |
The infty-norm of a vector-valued GridFunction: |
trans(gf) |
The transposed of a matrix-valued GridFunction: |
dot(gf_0,gf_1) |
The inner product of two vector-valued GridFunctions: |
distance(gf_0,gf_1) |
The euclidean distance of two vector-valued GridFunctions: |
outer(gf_0,gf_1) |
The outer product of two vector-valued GridFunctions: |
cross(gf_0,gf_1) |
The cross product of two vector-valued GridFunctions: |
mv(gf_0,gf_1) |
The matrix-vector product of a matrix-valued and a vector-valued GridFunction: |
mtv(gf_0,gf_1) |
The transposed matrix-vector product: |
Note
The arithmetic operators and the functions above are defined in the header
amdis/gridfunctions/Operations.hpp (included by amdis/GridFunctions.hpp) and are only
selected if at least one argument is a GridFunction or an expression that can be converted to a
GridFunction. The arithmetic operator overloads for Dune::FieldVector and Dune::FieldMatrix
in the Dune:: namespace have been removed.
function evalAtQP()
Defined in header <amdis/gridfunctions/AnalyticGridFunction.hpp>
template <class Function>
auto evalAtQP(Function const& f);
Creates an expression (a PreGridFunction) that evaluates a functor in global coordinates. It is bound to a
grid view, e.g., by makeGridFunction().
Arguments
Function f- A callable object that can be called with global coordinates, i.e. typically
FieldVector<double, dow>wheredowis the world dimension. The range-type of the function determines the range-type of the expression.
Requirements
FunctionmodelsConcepts::CallableDomain
function X()
Defined in header <amdis/gridfunctions/CoordsGridFunction.hpp>
inline auto X(); // (1)
inline auto X(int comp); // (2)
An expression that evaluates to the global coordinates (1) or a component of the global coordinates (2).
Arguments
int comp- The component of the global coordinate vector. Should be
0 <= comp < dowwheredowis the world dimension.
function gradientOf()
Defined in header <amdis/gridfunctions/DerivativeGridFunction.hpp>
template <class Expr>
auto gradientOf(Expr const& expr);
template <class Expr>
auto divergenceOf(Expr const& expr);
template <class Expr>
auto partialDerivativeOf(Expr const& expr, std::size_t i);
Creates an expression representing the gradient, the divergence, or the partial derivative
w.r.t. the i-th global coordinate of the wrapped expression. If expr is a GridViewFunction
(e.g. a DiscreteFunction), the result is directly a GridViewFunction on the same grid view, otherwise
it is a PreGridFunction that needs to be bound to a grid view.
Arguments
Expr expr- An expression that can be transformed into a grid function
Requirements
- The
GridFunctionofgf = makeGridFunction(expr, gridView)with some GridView modelsConcepts::GridFunctionand itsLocalFunctionhas a derivative, i.e. the expressionderivativeOf(localFunction(gf),tag::gradient{})does not fail (resp.tag::divergence{},tag::partial{i}).
Examples
We assume there is a ProblemStat with the name prob.
gradientOf(prob.solution(_0))
gradientOf(X(0) + X(1) + prob.solution(_0))
divergenceOf(prob.solution(_0)) // if the sub-tree _0 is vector-valued
partialDerivativeOf(prob.solution(_0), 1)
function invokeAtQP()
Defined in header <amdis/gridfunctions/ComposerGridFunction.hpp>
template <class Functor, class... Exprs>
auto invokeAtQP(Functor const& f, Exprs&&... g_i);
Creates an expression that applies a functor to the evaluated expressions.
It creates a composition of GridFunctions g_i by applying a functor f locally, i.e.
locally it is evaluated
Arguments
Functor f- A Functor that accepts as many arguments as there are grid functions
Exprs g_i...- A number of expressions that can be transformed into grid functions
Requirements
arity(f) == sizeof...(Exprs)arity(g_i) == arity(g_j) for i != jg_imodels conceptConcepts::GridFunction
Note
The composition of grid functions can be differentiated using gradientOf()
if all the grid functions are differentiable and the functor is differentiable, i.e.
there exist valid functions derivativeOf(g_i,type) and partial(f, i).
Examples
invokeAtQP([](Dune::FieldVector<double, 2> const& x) { return two_norm(x); }, X());
invokeAtQP([](double u, auto const& x) { return u + x[0]; }, 1.0, X());
invokeAtQP(Operation::Plus{}, X(0), X(1));