Commit 51ab2756 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Rename gradientAtQp into gradientOf and similarly other expressions

parent 200b1e32
......@@ -14,7 +14,6 @@
#include <amdis/common/Concepts.hpp>
#include <amdis/common/TypeTraits.hpp>
#include <amdis/functions/ParallelGlobalBasis.hpp>
#include <amdis/gridfunctions/DiscreteFunction.hpp>
#include <amdis/typetree/TreePath.hpp>
namespace AMDiS
......@@ -86,50 +85,11 @@ namespace AMDiS
{}
/// Return the global basis
std::shared_ptr<GlobalBasis const> const& basis() const { return basis_; }
/// Transform the DOFVector into a DiscreteFunction
template <class... Indices>
auto discreteFunction(Indices... ii)
{
return DiscreteFunction{coefficients(), *basis_, makeTreePath(ii...)};
}
/// Transform the DOFVector into a DiscreteFunction
template <class... Indices>
auto discreteFunction(Indices... ii) const
{
return DiscreteFunction{coefficients(), *basis_, makeTreePath(ii...)};
}
/// Interpolation of GridFunction to DOFVector, assuming that there is no
/// reference to this DOFVector in the expression.
/// See \ref DiscreteFunction::interpolate_noalias
template <class Expr, class Tag = tag::average>
void interpolate_noalias(Expr&& expr, Tag strategy = {})
{
discreteFunction().interpolate_noalias(FWD(expr), strategy);
}
/// Interpolation of GridFunction to DOFVector.
/// See \ref DiscreteFunction::interpolate
template <class Expr, class Tag = tag::average>
void interpolate(Expr&& expr, Tag strategy = {})
std::shared_ptr<GlobalBasis const> const& basis() const
{
discreteFunction().interpolate(FWD(expr), strategy);
return basis_;
}
/// Interpolation of GridFunction to DOFVector.
/// See \ref DiscreteFunction::interpolate
template <class Expr>
DOFVector& operator<<(Expr&& expr)
{
discreteFunction().interpolate(FWD(expr));
return *this;
}
Coefficients const& coefficients() const
{
return static_cast<Coefficients const&>(*this);
......@@ -250,20 +210,6 @@ namespace AMDiS
return {FWD(basis), op};
}
/// A Generator for a mutable \ref DiscreteFunction
template <class GB, class T, class... Indices>
auto discreteFunction(DOFVector<GB,T>& dofVec, Indices... ii)
{
return dofVec.discreteFunction(ii...);
}
/// A Generator for a mutable \ref DiscreteFunction
template <class GB, class T, class... Indices>
auto discreteFunction(DOFVector<GB,T> const& dofVec, Indices... ii)
{
return dofVec.discreteFunction(ii...);
}
} // end namespace AMDiS
#include <amdis/DOFVector.inc.hpp>
......@@ -67,7 +67,7 @@ namespace AMDiS
{
test_exit_dbg(bool(oldSolution_),
"OldSolution need to be created. Call initialize with INIT_UH_OLD.");
return oldSolution_->discreteFunction(ii...);
return valueOf(*oldSolution_, ii...);
}
/// Implementation of \ref ProblemTimeInterface::transferInitialSolution().
......
......@@ -372,7 +372,7 @@ namespace AMDiS
auto solution(Indices... ii)
{
assert(bool(solution_) && "You have to call initialize() before.");
return solution_->discreteFunction(ii...);
return valueOf(*solution_, ii...);
}
/// Return a const view to a solution component
......@@ -380,7 +380,7 @@ namespace AMDiS
auto solution(Indices... ii) const
{
assert(bool(solution_) && "You have to call initialize() before.");
return solution_->discreteFunction(ii...);
return valueOf(*solution_, ii...);
}
......
......@@ -15,44 +15,56 @@ namespace AMDiS
{
namespace tag
{
struct jacobian {};
struct gradient {};
struct divergence {};
struct partial { std::size_t comp = 0; };
// register possible types for derivative traits
struct derivative_type : gradient, divergence, partial {};
struct derivative_type : jacobian, gradient, divergence, partial {};
}
template <class Sig, class Type>
struct DerivativeTraits;
template <class R, class D>
struct DerivativeTraits<R(D), tag::gradient>
struct DerivativeTraits<R(D), tag::jacobian>
: public Dune::Functions::DefaultDerivativeTraits<R(D)>
{};
template <class R, class D>
struct DerivativeTraits<R(D), tag::partial>
struct DerivativeTraits<R(D), tag::gradient>
: public Dune::Functions::DefaultDerivativeTraits<R(D)>
{};
template <class K, int n>
struct DerivativeTraits<K(Dune::FieldVector<K,n>), tag::gradient>
{
using Range = R;
using Range = Dune::FieldVector<K,n>;
};
template <class K, class D>
struct DerivativeTraits<K(D), tag::divergence>
template <class K, int n>
struct DerivativeTraits<Dune::FieldVector<K,1>(Dune::FieldVector<K,n>), tag::gradient>
{
// error
using Range = Dune::FieldVector<K,n>;
};
template <class K, int n, class D>
struct DerivativeTraits<Dune::FieldVector<K,n>(D), tag::divergence>
template <class R, class K, int n>
struct DerivativeTraits<R(Dune::FieldVector<K,n>), tag::partial>
{
using Range = R;
};
template <class K, int n>
struct DerivativeTraits<Dune::FieldVector<K,n>(Dune::FieldVector<K,n>), tag::divergence>
{
using Range = K;
};
template <class K, int n, int m, class D>
struct DerivativeTraits<Dune::FieldMatrix<K,n,m>(D), tag::divergence>
template <class K, int n, int m>
struct DerivativeTraits<Dune::FieldMatrix<K,n,m>(FieldVector<K,n>), tag::divergence>
{
using Range = Dune::FieldVector<K,m>;
};
} // end namespace AMDiS
\ No newline at end of file
} // end namespace AMDiS
......@@ -28,7 +28,7 @@ namespace AMDiS
/// The range type of the LocalFunction
using Range = R;
/// This LocalFunction has its own \ref derivative() function
/// This LocalFunction has its own \ref derivativeOf() function
enum { hasDerivative = true };
private:
......@@ -100,12 +100,12 @@ namespace AMDiS
* - The functor `F` must fulfill the concept \ref Concepts::HasDerivative
**/
template <class R, class D, class LC, class F, class Type>
auto derivative(AnalyticLocalFunction<R(D),LC,F> const& lf, Type const& type)
auto derivativeOf(AnalyticLocalFunction<R(D),LC,F> const& lf, Type const& type)
{
static_assert(Concepts::HasDerivative<F,Type>,
"No derivative(F,DerivativeType) defined for Functor F of AnalyticLocalFunction.");
auto df = derivative(lf.fct(), type);
auto df = derivativeOf(lf.fct(), type);
using RawSignature = typename Dune::Functions::SignatureTraits<R(D)>::RawSignature;
using DerivativeSignature = typename DerivativeTraits<RawSignature,Type>::Range(D);
......@@ -220,12 +220,12 @@ namespace AMDiS
* - Functor `F` must fulfill the concept \ref Concepts::HasDerivative<Type>
**/
template <class F, class GV, class Type>
auto derivative(AnalyticGridFunction<F,GV> const& gf, Type const& type)
auto derivativeOf(AnalyticGridFunction<F,GV> const& gf, Type const& type)
{
static_assert(Concepts::HasDerivative<F,Type>,
"No derivative(F,DerivativeType) defined for Functor of AnalyticLocalFunction.");
auto df = derivative(gf.fct(), type);
auto df = derivativeOf(gf.fct(), type);
return AnalyticGridFunction<decltype(df), GV>{df, gf.entitySet().gridView()};
}
......
......@@ -30,7 +30,7 @@ namespace AMDiS
/// The range type of the LocalFunction
using Range = R;
/// This LocalFunction has its own \ref derivative() function
/// This LocalFunction has its own \ref derivativeOf() function
enum { hasDerivative = true };
private:
......
......@@ -49,7 +49,7 @@ namespace AMDiS
return Dune::DiagonalMatrix<T,N>{T(1)};
}
};
friend Derivative derivative(CoordsFunction const& /*f*/, tag::gradient)
friend Derivative derivativeOf(CoordsFunction const& /*f*/, tag::gradient)
{
return Derivative{};
}
......@@ -106,7 +106,7 @@ namespace AMDiS
int comp_;
};
friend Derivative derivative(Self const& f, tag::gradient)
friend Derivative derivativeOf(Self const& f, tag::gradient)
{
return Derivative{f.comp_};
}
......
......@@ -11,7 +11,7 @@ namespace AMDiS
/// The derivative of a localfunction as localfunction itself
template <class LocalFunction, class Type,
REQUIRES(std::is_convertible_v<tag::derivative_type, Type>)>
auto derivative(LocalFunction const& lf, Type const& type)
auto derivativeOf(LocalFunction const& lf, Type const& type)
-> decltype(lf.makeDerivative(type))
{
return lf.makeDerivative(type);
......@@ -28,13 +28,13 @@ namespace AMDiS
struct HasDerivative
{
template <class F, class T>
auto require(F&& f, T&& t) -> decltype( derivative(f,t) );
auto require(F&& f, T&& t) -> decltype( derivativeOf(f,t) );
};
struct HasLocalFunctionDerivative
{
template <class F, class T>
auto require(F&& f, T&& t) -> decltype( derivative(localFunction(f),t) );
auto require(F&& f, T&& t) -> decltype( derivativeOf(localFunction(f),t) );
};
struct HasPartial
......@@ -46,7 +46,7 @@ namespace AMDiS
} // end namespace Definition
/// \brief GridFunction GF has free function `derivative(F)`
/// \brief GridFunction GF has free function `derivativeOf(F,type)`
template <class GF, class Type>
constexpr bool HasDerivative = models<Definition::HasDerivative(GF,Type)>;
......@@ -54,7 +54,7 @@ namespace AMDiS
using HasDerivative_t = models_t<Definition::HasDerivative(GF,Type)>;
/// \brief GridFunction GF has free function `derivative(localFunction(F))`
/// \brief GridFunction GF has free function `derivativeOf(localFunction(F))`
template <class GF, class Type>
constexpr bool HasLocalFunctionDerivative = models<Definition::HasLocalFunctionDerivative(GF,Type)>;
......
......@@ -48,7 +48,7 @@ namespace AMDiS
using RawSignature = typename Dune::Functions::SignatureTraits<GridFctRange(GridFctDomain)>::RawSignature;
using Traits = DerivativeTraits<RawSignature, Type>;
using LocalFunction = TYPEOF( derivative(localFunction(std::declval<GridFunction>()), std::declval<Type>()) ) ;
using LocalFunction = TYPEOF( derivativeOf(localFunction(std::declval<GridFunction>()), std::declval<Type>()) ) ;
using LocalFctRange = typename Traits::Range;
using LocalFctDomain = typename GridFunction::EntitySet::LocalCoordinate;
......@@ -96,7 +96,7 @@ namespace AMDiS
/// Return the derivative-localFunction of the GridFunction.
LocalFunction makeLocalFunction() const
{
return derivative(localFunction(gridFct_), type_);
return derivativeOf(localFunction(gridFct_), type_);
}
/// Return the \ref EntitySet of the \ref GridFunction.
......@@ -111,26 +111,26 @@ namespace AMDiS
};
/// \fn derivative
/// \fn derivativeOf
/// \brief Create a GridFunction representing the derivative of the given
/// Gridfunction.
/**
* A GridFunction can be differentiated if the corresponding LocalFunction
* provides a free function `derivative()`
* provides a free function `derivativeOf()`
*
* **Requirements:**
* - The type `GridFct` models the concept of a GridFunction
* - The `GridFct` has no own `derivative()` function, i.e. it holds
* - The `GridFct` has no own `derivativeOf()` function, i.e. it holds
* `GridFct::hasDerivative == false`.
* - The localFunction of the `GridFct` models `Concepts::HasDerivative`.
**/
template <class GridFct, class Type,
class LocalFct = decltype( localFunction(std::declval<GridFct>()) ),
REQUIRES(not GridFct::hasDerivative)>
auto derivative(GridFct const& gridFct, Type const& type)
auto derivativeOf(GridFct const& gridFct, Type const& type)
{
static_assert(Concepts::HasDerivative<LocalFct,Type>,
"derivative(LocalFunction,type) not defined!");
"derivativeOf(LocalFunction,type) not defined!");
return DerivativeGridFunction<GridFct,Type>{gridFct, type};
}
......@@ -146,7 +146,7 @@ namespace AMDiS
template <class GridView>
static auto create(Self const& self, GridView const& gridView)
{
return derivative(makeGridFunction(self.expr_, gridView), self.type_);
return derivativeOf(makeGridFunction(self.expr_, gridView), self.type_);
}
};
......@@ -163,7 +163,7 @@ namespace AMDiS
#endif
/// \fn gradientAtQP
/// \fn gradientOf
/// \brief Generator function for DerivativeGridFunction expressions.
/// \relates DerivativeGridFunction
/**
......@@ -172,25 +172,25 @@ namespace AMDiS
* See \ref DerivativeGridFunction.
*
* **Examples:**
* - `gradientAtQP(prob.solution(_0))`
* - `gradientAtQP(X(0) + X(1) + prob.solution(_0))`
* - `gradientOf(prob.solution(_0))`
* - `gradientOf(X(0) + X(1) + prob.solution(_0))`
**/
template <class Expr>
auto gradientAtQP(Expr const& expr)
auto gradientOf(Expr const& expr)
{
return DerivativePreGridFunction<Expr, tag::gradient>{expr};
}
/// Generates a Gridfunction representing the divergence of a vector-valued GridFunction.
template <class Expr>
auto divergenceAtQP(Expr const& expr)
auto divergenceOf(Expr const& expr)
{
return DerivativePreGridFunction<Expr, tag::divergence>{expr};
}
/// Generates a Gridfunction representing the partial derivative of a GridFunction.
template <class Expr>
auto partialAtQP(Expr const& expr, std::size_t i)
auto partialDerivativeOf(Expr const& expr, std::size_t i)
{
return DerivativePreGridFunction<Expr, tag::partial>{expr, tag::partial{i}};
}
......
......@@ -32,12 +32,6 @@ namespace AMDiS
class DiscreteFunction;
// deduction guide
template <class Coeff, class GB, class Path>
DiscreteFunction(Coeff&, GB const&, Path const& path)
-> DiscreteFunction<Coeff, GB, TYPEOF(makeTreePath(path))>;
/// A mutable view on the subspace of a DOFVector, \relates DiscreteFunction
template <class Coeff, class GB, class TreePath>
class DiscreteFunction
......@@ -72,7 +66,7 @@ namespace AMDiS
/**
* **Example:**
* ```
* auto v = discreteFunction(prob.solutionVector(),0);
* auto v = valueOf(prob.solutionVector(),0);
* v.interpolate_noalias([](auto const& x) { return x[0]; });
* ```
**/
......@@ -83,11 +77,11 @@ namespace AMDiS
/**
* **Example:**
* ```
* auto v = discreteFunction(prob.solutionVector(),0);
* auto v = valueOf(prob.solutionVector(),0);
* v.interpolate(v + [](auto const& x) { return x[0]; });
* ```
* Allows to have a reference to the DOFVector in the expression, e.g. as
* \ref DiscreteFunction or \ref gradientAtQP() of a DiscreteFunction.
* \ref DiscreteFunction or \ref gradientOf() of a DiscreteFunction.
**/
template <class Expr, class Tag = tag::average>
void interpolate(Expr&& expr, Tag strategy = {});
......@@ -261,6 +255,33 @@ namespace AMDiS
DiscreteFunction(DV&, Path...)
-> DiscreteFunction<std::remove_reference_t<Coeff>,std::decay_t<GB>,TP>;
// grid functions representing the DOFVector
// -----------------------------------------
/// A Generator for the childs of a mutable \ref DiscreteFunction
template <class Coeff, class GB, class... Path, class... Indices>
auto valueOf(DiscreteFunction<Coeff,GB,Path...>& df, Indices... ii)
{
return df.child(ii...);
}
/// A Generator for the childs of a const \ref DiscreteFunction
template <class Coeff, class GB, class... Path, class... Indices>
auto valueOf(DiscreteFunction<Coeff,GB,Path...> const& df, Indices... ii)
{
return df.child(ii...);
}
/// A Generator to transform a DOFVector into a \ref DiscreteFunction
template <class DV, class... Indices,
class = decltype(std::declval<DV>().coefficients()),
class = decltype(std::declval<DV>().basis())>
auto valueOf(DV& dofVec, Indices... ii)
{
return DiscreteFunction{dofVec.coefficients(), *dofVec.basis(), makeTreePath(ii...)};
}
} // end namespace AMDiS
#include "DiscreteLocalFunction.inc.hpp"
......
......@@ -113,14 +113,14 @@ namespace AMDiS
/// \brief Derivative of the LocalFunction of a FunctorGridFunction, utilizing
/// the chain-rule. Only available if the functor provides partial derivatives.
/**
* \f$ d_x(f(lf(x)...)) = \sum_i d_i(f)[lf(x)...] * derivative(lf[i]) \f$
* \f$ d_x(f(lf(x)...)) = \sum_i d_i(f)[lf(x)...] * derivativeOf(lf[i]) \f$
*
* **Requirements:**
* - The Functor `F` must model `Concepts::HasPartial`
**/
template <class Sig, class F, class... LFs, class Type,
REQUIRES(Concepts::HasPartial<F>)>
auto derivative(FunctorLocalFunction<Sig,F,LFs...> const& lf, Type const& type)
auto derivativeOf(FunctorLocalFunction<Sig,F,LFs...> const& lf, Type const& type)
{
auto index_seq = std::index_sequence_for<LFs...>{};
......@@ -133,10 +133,10 @@ namespace AMDiS
using std::get;
auto const& lgfs_i = *get<VALUE(_i)>(lf.localFcts());
return makeFunctorGridFunction(Operation::Multiplies{}, di_f, derivative(lgfs_i, type));
return makeFunctorGridFunction(Operation::Multiplies{}, di_f, derivativeOf(lgfs_i, type));
};
// sum_i [ d_i(f)[lgfs...] * derivative(lgfs_i)
// sum_i [ d_i(f)[lgfs...] * derivativeOf(lgfs_i)
auto gridFct = Tools::apply([&](auto const... _i)
{
return makeFunctorGridFunction(Operation::Plus{}, term_i(_i)...);
......
......@@ -145,9 +145,9 @@ namespace AMDiS
* - have the free-function \ref localFunction() to obtain a LocalFunction
* - its LocalFunctions have the free-function \ref order() to obtain the
* polynomial order of the Expression (if available)
* - its LocalFunctions have the free-function \ref derivative() to
* - its LocalFunctions have the free-function \ref derivativeOf() to
* differentiate the Expression with respect to global Coordinates.
* A derivative Expression can be created, using \ref gradientAtQP() that
* A derivative Expression can be created, using \ref gradientOf() that
* can be converted to a GridFunction afterwards.
**/
template <class PreGridFct, class GridView>
......
......@@ -46,7 +46,7 @@ namespace AMDiS
std::unique_ptr<FileWriterInterface>
create(std::string type, std::string prefix, Indices... ii) const
{
auto data = discreteFunction(*systemVector_, ii...);
auto data = valueOf(*systemVector_, ii...);
return create_impl(std::move(type), std::move(prefix), data, Dune::PriorityTag<42>{});
}
......
......@@ -55,19 +55,10 @@ The `value_type` is often the same as `T`, but might be just something similar,
Function | Descriptions
--------------------------------|---------------------------------------------
[*(constructor)*](#function-dofvectordofvector) | Construct the DOFVector
[`child`](#function-dofvectorchild) | Return a DiscreteFunction of a given sub-space
[`backup`](#function-dofvectorbackup) | Write DOFVector to file
[`restore`](#function-dofvectorrestore) | Read backup data from file
[`dataTransfer`](#function-dofvectordataTransfer) | Return the associated DataTransfer object
### Interpolation functions
Function | Descriptions
--------------------------------|---------------------------------------------
[`interpolate`](#function-dofvectorinterpolate) | Interpolation of GridFunction to DOFVector
[`interpolate_noalias`](#function-dofvectorinterpolate) | Interpolation of GridFunction to DOFVector assuming no aliasing
[`operator<<`](#function-dofvectorinterpolate) | Operator for the interpolation
??? seealso "Functions inherited from [`VectorFacade`](../MatVecFacade/#class-vectorfacade)"
Function | Descriptions
--------------------------------|---------------------------------------------
......@@ -126,37 +117,6 @@ DOFVector<Underlying_t<decltype(basis2)>> vec2(std::move(basis2));
- Generator function to construct a DOFVector: [`makeDOFVector()`](#function-makedofvector)
## function `DOFVector::discreteFunction`
```c++
template <class... Indices>
auto discreteFunction(Indices... ii) // (1)
template <class... Indices>
auto discreteFunction(Indices... ii) const // (2)
```
(1) Creates a mutable `DiscreteFunction` representing the sub-space w.r.t. the passed tree-path. The path `{ii...}` thereby
refers to the hierarchic global basis.
(2) Creates a constant `DiscreteFunction` representing the sub-space w.r.t. the passed tree-path. The path `{ii...}` thereby
refers to the hierarchic global basis.
#### Arguments
`Indices... ii`
: Components of the tree-path identifying the basis node
#### Example
```c++
DOFVector vec(basis);
auto vec_ = vec.discreteFunction();
auto vec_0 = vec.discreteFunction(_0);
auto vec_10 = vec.discreteFunction(_1,0);
auto vec_10_b = discreteFunction(vec,_1,0);
```
## function `DOFVector::backup`
```c++
void backup(std::string const& filename);
......@@ -182,42 +142,6 @@ Reads a backup of the DOFVector from file previously created using the [backup()
: The filename of the backup file to read from.
## function `DOFVector::interpolate,interpolate_noalias,operator<<` {: #function-dofvectorinterpolate }
```c++
// (1)
template <class Expr, class Tag = tag::average>
void interpolate_noalias(Expr&& expr, Tag strategy)
// (2)
template <class Expr, class Tag = tag::average>
void interpolate(Expr&& expr, Tag strategy)
// (3)
template <class Expr>
DOFVector& operator<<(Expr&& expr)
```
(1) Interpolation of a `GridFunction` (or Expression) to the DOFVector, assuming that there is no
reference to this DOFVector in the expression (no aliasing).
(2) Interpolation of a `GridFunction` (or Expression) to the DOFVector, allowing aliasing.
(3) Operator notation of (2) using averaging strategy.
In case *aliasing* is allowed, a temporary DOFVector is created first as copy of *this* and the interpolation
performed on the temporary using *noalias* interpolation (1). Then, this tempoary is moved back to *this*.
#### Arguments
`Expr expr`
: An Expression representing a `GridFunction`
`Tag strategy`
: An interpolation strategy, either `tag::average` or `tag::assign`.
The `average `strategy accumulates interpolation values on each dof and takes the average by
dividing by the number of assignees. The `assign` strategy diretly assigns an interpolation
value to a dof that might be overwritten in a subsequent interpolation step.
## function `makeDOFVector`
Defined in header [`<amdis/DOFVector.hpp>`](https://gitlab.mn.tu-dresden.de/amdis/amdis-core/blob/master/amdis/DOFVector.hpp)
......@@ -398,11 +322,13 @@ Returns the const (1) or mutable (2) sub-range view of the stored DOFVector.