Commit 37c7e1d3 authored by Praetorius, Simon's avatar Praetorius, Simon

Merge branch 'issue/discreteFunction' into 'master'

rename child() into discreteFunction()

See merge request !219
parents 4d4855f0 7f7d3d80
Pipeline #5092 canceled with stage
......@@ -82,20 +82,21 @@ namespace AMDiS
: DOFVector(std::make_shared<GB>(gridView, preBasisFactory), op)
{}
/// Return the global basis
std::shared_ptr<GlobalBasis const> const& basis() const { return basis_; }
template <class TreePath = RootTreePath>
auto child(TreePath const& path = {})
/// Transform the DOFVector into a DiscreteFunction
template <class... Indices>
auto discreteFunction(Indices... ii)
{
auto&& tp = makeTreePath(path);
return makeDiscreteFunction(coefficients(), *basis_, tp);
return DiscreteFunction{coefficients(), *basis_, makeTreePath(ii...)};
}
template <class TreePath = RootTreePath>
auto child(TreePath const& path = {}) const
/// Transform the DOFVector into a DiscreteFunction
template <class... Indices>
auto discreteFunction(Indices... ii) const
{
auto&& tp = makeTreePath(path);
return makeDiscreteFunction(coefficients(), *basis_, tp);
return DiscreteFunction{coefficients(), *basis_, makeTreePath(ii...)};
}
......@@ -105,7 +106,7 @@ namespace AMDiS
template <class Expr, class Tag = tag::average>
void interpolate_noalias(Expr&& expr, Tag strategy = {})
{
child().interpolate_noalias(FWD(expr), strategy);
discreteFunction().interpolate_noalias(FWD(expr), strategy);
}
/// Interpolation of GridFunction to DOFVector.
......@@ -113,7 +114,7 @@ namespace AMDiS
template <class Expr, class Tag = tag::average>
void interpolate(Expr&& expr, Tag strategy = {})
{
child().interpolate(FWD(expr), strategy);
discreteFunction().interpolate(FWD(expr), strategy);
}
/// Interpolation of GridFunction to DOFVector.
......@@ -121,7 +122,7 @@ namespace AMDiS
template <class Expr>
DOFVector& operator<<(Expr&& expr)
{
child().interpolate(FWD(expr));
discreteFunction().interpolate(FWD(expr));
return *this;
}
......@@ -247,17 +248,17 @@ namespace AMDiS
}
/// A Generator for a mutable \ref DiscreteFunction
template <class GB, class T, class Path = RootTreePath>
auto makeDiscreteFunction(DOFVector<GB,T>& dofVec, Path const& path = {})
template <class GB, class T, class... Indices>
auto discreteFunction(DOFVector<GB,T>& dofVec, Indices... ii)
{
return dofVec.child(path);
return dofVec.discreteFunction(ii...);
}
/// A Generator for a mutable \ref DiscreteFunction
template <class GB, class T, class Path = RootTreePath>
auto makeDiscreteFunction(DOFVector<GB,T> const& dofVec, Path const& path = {})
template <class GB, class T, class... Indices>
auto discreteFunction(DOFVector<GB,T> const& dofVec, Indices... ii)
{
return dofVec.child(path);
return dofVec.discreteFunction(ii...);
}
} // end namespace AMDiS
......
......@@ -130,7 +130,7 @@ namespace AMDiS
BoundarySubset<typename RB::GridView::Intersection> boundarySubset,
Values&& values)
{
return makeDirichletBC<Mat, Sol, Rhs>(rowBasis, treepath(), colBasis, treepath(),
return makeDirichletBC<Mat, Sol, Rhs>(rowBasis, makeTreePath(), colBasis, makeTreePath(),
std::move(boundarySubset), FWD(values));
}
......
......@@ -6,6 +6,7 @@
#include <amdis/LocalOperator.hpp>
#include <amdis/operations/Assigner.hpp>
#include <amdis/typetree/Traversal.hpp>
#include <amdis/typetree/TreePath.hpp>
#include <amdis/utility/AssembleOperators.hpp>
namespace AMDiS {
......
......@@ -161,7 +161,7 @@ namespace AMDiS
BoundarySubset<typename B::GridView::Intersection> boundarySubset,
Impl::FaceTrafo<B> trafo)
{
return makePeriodicBC<Mat, Sol, Rhs>(basis, treepath(), std::move(boundarySubset),
return makePeriodicBC<Mat, Sol, Rhs>(basis, makeTreePath(), std::move(boundarySubset),
std::move(trafo));
}
......
......@@ -62,12 +62,12 @@ namespace AMDiS
}
/// Return a const view to a oldSolution component
template <class TreePath = RootTreePath>
auto oldSolution(TreePath path = {}) const
template <class... Indices>
auto oldSolution(Indices... ii) const
{
test_exit_dbg(bool(oldSolution_),
"OldSolution need to be created. Call initialize with INIT_UH_OLD.");
return oldSolution_->child(path);
return oldSolution_->discreteFunction(ii...);
}
/// Implementation of \ref ProblemTimeInterface::transferInitialSolution().
......
......@@ -148,9 +148,9 @@ namespace AMDiS
*
* \param op A (pre-) local operator, \see LocalOperator, \see GridFunctionOperator
* \param row TreePath identifying the sub-basis in the global basis tree
* corresponding to the row basis. \see treepath()
* corresponding to the row basis. \see makeTreePath()
* \param col TreePath identifying the sub-basis in the global basis tree
* corresponding to the column basis. \see treepath()
* corresponding to the column basis. \see makeTreePath()
*
* Example:
* ```
......@@ -173,9 +173,9 @@ namespace AMDiS
* constructed from an integer. \see BoundaryType
* \param op A (pre-) local operator, \see LocalOperator, \see GridFunctionOperator
* \param row TreePath identifying the sub-basis in the global basis tree
* corresponding to the row basis. \see treepath()
* corresponding to the row basis. \see makeTreePath()
* \param col TreePath identifying the sub-basis in the global basis tree
* corresponding to the column basis. \see treepath()
* corresponding to the column basis. \see makeTreePath()
*
* Example:
* ```
......@@ -201,7 +201,7 @@ namespace AMDiS
*
* \param op A (pre-) local operator, \see LocalOperator, \see GridFunctionOperator
* \param path TreePath identifying the sub-basis in the global basis tree
* corresponding to the row basis. \see treepath()
* corresponding to the row basis. \see makeTreePath()
*
* Example:
* ```
......@@ -224,7 +224,7 @@ namespace AMDiS
* constructed from an integer. \see BoundaryType
* \param op A (pre-) local operator, \see LocalOperator, \see GridFunctionOperator
* \param path TreePath identifying the sub-basis in the global basis tree
* corresponding to the row basis. \see treepath()
* corresponding to the row basis. \see makeTreePath()
*
* Example:
* ```
......@@ -251,9 +251,9 @@ namespace AMDiS
* \param predicate Functor `bool(WorldVector)` returning true for all
* DOFs on the boundary that should be assigned a value.
* \param row TreePath identifying the sub-basis in the global basis tree
* corresponding to the row basis. \see treepath()
* corresponding to the row basis. \see makeTreePath()
* \param col TreePath identifying the sub-basis in the global basis tree
* corresponding to the column basis. \see treepath()
* corresponding to the column basis. \see makeTreePath()
* \param values Functor `Range(WorldVector)` or any \ref GridFunction
* that is evaluated in the DOFs identified by the predicate.
*
......@@ -368,19 +368,19 @@ namespace AMDiS
/// Return a mutable view to a solution component
template <class TreePath = RootTreePath>
auto solution(TreePath path = {})
template <class... Indices>
auto solution(Indices... ii)
{
assert(bool(solution_) && "You have to call initialize() before.");
return solution_->child(path);
return solution_->discreteFunction(ii...);
}
/// Return a const view to a solution component
template <class TreePath = RootTreePath>
auto solution(TreePath path = {}) const
template <class... Indices>
auto solution(Indices... ii) const
{
assert(bool(solution_) && "You have to call initialize() before.");
return solution_->child(path);
return solution_->discreteFunction(ii...);
}
......
......@@ -335,10 +335,10 @@ void ProblemStat<Traits>::
addPeriodicBC(BoundaryType id, WorldMatrix const& matrix, WorldVector const& vector)
{
auto localView = globalBasis_->localView();
auto basis = Dune::Functions::subspaceBasis(*globalBasis_, treepath());
auto basis = Dune::Functions::subspaceBasis(*globalBasis_, makeTreePath());
auto bc = makePeriodicBC<SystemMatrix, SolutionVector, SystemVector>(
std::move(basis), {*boundaryManager_, id}, {matrix, vector});
boundaryConditions_[treepath()][treepath()].push_back(makeUniquePtr(std::move(bc)));
boundaryConditions_[makeTreePath()][makeTreePath()].push_back(makeUniquePtr(std::move(bc)));
}
......
......@@ -28,23 +28,14 @@ namespace AMDiS
* **Requirements:**
* - GB models \ref Concepts::GlobalBasis
**/
template <class Coeff, class GB, class TreePath = Dune::TypeTree::HybridTreePath<>>
template <class Coeff, class GB, class TreePath>
class DiscreteFunction;
// deduction guide
template <class Coeff, class GB, class TreePath = RootTreePath>
DiscreteFunction(Coeff&, GB const&, TreePath = {})
-> DiscreteFunction<Coeff, GB, TreePath_t<TreePath>>;
/// A Generator for a mutable \ref DiscreteFunction
template <class Coeff, class GB, class Path = RootTreePath,
class = std::void_t<decltype(std::declval<GB>().localView())> >
auto makeDiscreteFunction(Coeff& coefficients, GB const& basis, Path const& path = {})
{
return DiscreteFunction<Coeff, GB, TreePath_t<Path>>{coefficients, basis, path};
}
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
......@@ -61,8 +52,8 @@ namespace AMDiS
public:
/// Constructor. Stores a pointer to the mutable `dofvector`.
template <class Path = TreePath>
DiscreteFunction(Coefficients& dofVector, GlobalBasis const& basis, Path const& path = {})
template <class Path>
DiscreteFunction(Coefficients& dofVector, GlobalBasis const& basis, Path const& path)
: Super(dofVector, basis, path)
, mutableCoeff_(&dofVector)
{}
......@@ -73,7 +64,7 @@ namespace AMDiS
/**
* **Example:**
* ```
* auto v = makeDiscreteFunction(prob.solutionVector(),0);
* auto v = discreteFunction(prob.solutionVector(),0);
* v.interpolate_noalias([](auto const& x) { return x[0]; });
* ```
**/
......@@ -84,7 +75,7 @@ namespace AMDiS
/**
* **Example:**
* ```
* auto v = makeDiscreteFunction(prob.solutionVector(),0);
* auto v = discreteFunction(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
......@@ -126,11 +117,11 @@ namespace AMDiS
/// Return the const DOFVector
using Super::coefficients;
template <class Path = RootTreePath>
auto child(Path const& path = {})
template <class... Indices>
auto child(Indices... ii)
{
auto tp = cat(this->treePath_, makeTreePath(path));
return makeDiscreteFunction(*mutableCoeff_, this->basis(), tp);
auto tp = cat(this->treePath_, makeTreePath(ii...));
return DiscreteFunction<Coeff, GB, TYPEOF(makeTreePath(tp))>{*mutableCoeff_, this->basis(), tp};
}
using Super::child;
......@@ -181,8 +172,8 @@ namespace AMDiS
public:
/// Constructor. Stores a pointer to the dofVector and a copy of the treePath.
template <class Path = TreePath>
DiscreteFunction(Coefficients const& coefficients, GlobalBasis const& basis, Path const& path = {})
template <class Path>
DiscreteFunction(Coefficients const& coefficients, GlobalBasis const& basis, Path const& path)
: coefficients_(&coefficients)
, basis_(&basis)
, treePath_(makeTreePath(path))
......@@ -223,11 +214,11 @@ namespace AMDiS
return *coefficients_;
}
template <class Path = RootTreePath>
auto child(Path const& path = {}) const
template <class... Indices>
auto child(Indices... ii) const
{
auto tp = cat(this->treePath_, makeTreePath(path));
return makeDiscreteFunction(*coefficients_, *basis_, tp);
auto tp = cat(this->treePath_, makeTreePath(ii...));
return DiscreteFunction<Coeff const, GB, TYPEOF(makeTreePath(tp))>{*coefficients_, *basis_, tp};
}
protected:
......
......@@ -40,13 +40,13 @@ namespace AMDiS
/**
* \param type String representing the type of the writer. One of {vtk, dune-vtk, gmsh, backup}
* \param prefix The initfile prefix tp configure the filewriter
* \param treePath Treepath to the component of the systemVector to be handled by the fileWriter.
* \param ii... Indices of the treepath to the component of the systemVector to be handled by the fileWriter.
**/
template <class TreePath = RootTreePath>
template <class... Indices>
std::unique_ptr<FileWriterInterface>
create(std::string type, std::string prefix, TreePath treePath = {}) const
create(std::string type, std::string prefix, Indices... ii) const
{
auto data = makeDiscreteFunction(*systemVector_, treePath);
auto data = discreteFunction(*systemVector_, ii...);
return create_impl(std::move(type), std::move(prefix), data, Dune::PriorityTag<42>{});
}
......
......@@ -260,7 +260,7 @@ namespace AMDiS
return ValueAndContainer{
value(node),
Tools::apply_indices<Node::degree()>(
[&](auto... i) { return Dune::makeTupleVector((*this)(node.child(i))...); })};
[&](auto... ii) { return Dune::makeTupleVector((*this)(node.child(ii))...); })};
}
else {
static_assert(Node::isLeaf || Node::isPower || Node::isComposite,
......
......@@ -23,29 +23,24 @@ namespace AMDiS
namespace Definition
{
template <class TP>
template <class Index>
struct IsPreTreePath
: std::is_integral<TP>
: std::is_integral<Index>
{};
template <int I>
struct IsPreTreePath<std::integral_constant<int, I>>
: std::true_type
template <class Index, Index I>
struct IsPreTreePath<std::integral_constant<Index, I>>
: std::is_integral<Index>
{};
template <std::size_t I>
struct IsPreTreePath<std::integral_constant<std::size_t, I>>
: std::true_type
{};
template <int... I>
struct IsPreTreePath<std::integer_sequence<int, I...>>
: std::true_type
template <class Index, Index... I>
struct IsPreTreePath<std::integer_sequence<Index, I...>>
: std::is_integral<Index>
{};
template <std::size_t... I>
struct IsPreTreePath<std::index_sequence<I...>>
: std::true_type
template <class... Indices>
struct IsPreTreePath<std::tuple<Indices...>>
: std::conjunction<std::is_integral<Indices>...>
{};
template <>
......@@ -65,24 +60,46 @@ namespace AMDiS
} // end namespace Concepts
namespace Impl
{
template <class Index,
std::enable_if_t<std::is_integral_v<Index>, int> = 0>
std::size_t treePathIndex(Index i)
{
return std::size_t(i);
}
template <class Index, Index i,
std::enable_if_t<std::is_integral_v<Index>, int> = 0>
auto treePathIndex(std::integral_constant<Index,i>)
{
return std::integral_constant<std::size_t,std::size_t(i)>{};
}
} // end namespace Impl
#ifdef DOXYGEN
/// \brief Converts a (pre)TreePath into a HybridTreePath
/// \brief Converts a sequence of indices into a HybridTreePath
/**
* Converts an integer, an integralconstant or a Dune TreePath into an
* \ref Dune::TypeTree::HybridTreePath that is used in GlobalBasis traversal.
* Converts an integer, an integralconstant, a sequence of those, or a TreePath
* into an \ref Dune::TypeTree::HybridTreePath that is used in GlobalBasis traversal.
*
* **Requirements:**
* - `PreTreePath` one of
* + integer type (`int, std::size_t`),
* + integral constant (`std::integral_constant<[int|std::size_t], i>`)
* + any Dune TreePath (`TreePath<std::size_t...>, DynamicTreePath, HybridTreePath<class... T>`)
* The arguments can be one or more of
* - integer type (`int, std::size_t`)
* - integral constant (`std::integral_constant<[int|std::size_t],i>, index_t<i>`)
* or one of dune treepath types, e.g.
* - any Dune TreePath (`TreePath<std::size_t...>, HybridTreePath<class... T>`)
* - a `std::tuple` type
*
* **Example:**
* ```
* makeTreePath(1),
* makeTreePath(int_<2>),
* makeTreePath(treepath(1, int_<2>))
* makeTreePath(0,1,2),
* makeTreePath(int_<2>, 0),
* makeTreePath(1, index_<2>),
* makeTreePath(hybridTreePath(0,1,2)),
* makeTreePath(std::tuple{0,index_<2>,2})
* ```
**/
template <class PreTreePath>
......@@ -90,35 +107,34 @@ namespace AMDiS
#else // DOXYGEN
inline auto makeTreePath(int i) { return Dune::TypeTree::hybridTreePath(std::size_t(i)); }
inline auto makeTreePath(std::size_t i) { return Dune::TypeTree::hybridTreePath(i); }
inline auto makeTreePath(RootTreePath) { return Dune::TypeTree::hybridTreePath(); }
template <int I>
auto makeTreePath(std::integral_constant<int,I>)
template <class... Indices>
auto makeTreePath(Indices... ii)
-> decltype( Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...) )
{
return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, std::size_t(I)>{});
return Dune::TypeTree::hybridTreePath(Impl::treePathIndex(ii)...);
}
template <int... I>
auto makeTreePath(std::integer_sequence<int, I...>)
inline auto makeTreePath()
{
return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, std::size_t(I)>{}...);
return Dune::TypeTree::hybridTreePath();
}
template <std::size_t I>
auto makeTreePath(std::integral_constant<std::size_t,I> _i)
inline auto makeTreePath(RootTreePath)
{
return Dune::TypeTree::hybridTreePath(_i);
return makeTreePath();
}
template <std::size_t... I>
auto makeTreePath(std::index_sequence<I...>)
template <class Index, Index... I>
auto makeTreePath(std::integer_sequence<Index, I...>)
{
return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...);
return makeTreePath(std::integral_constant<std::size_t, std::size_t(I)>{}...);
}
template <class... T>
auto makeTreePath(std::tuple<T...> const& tp)
{
return std::apply([](auto... ii) { return makeTreePath(ii...); }, tp);
}
template <class... T>
auto const& makeTreePath(Dune::TypeTree::HybridTreePath<T...> const& tp)
......@@ -140,18 +156,6 @@ namespace AMDiS
}
#endif
template <class TP>
auto makeTreePath(TP const&)
{
static_assert( Concepts::PreTreePath<TP>,
"Argument must be a valid treepath, or an integer/index-constant");
return Dune::TypeTree::hybridTreePath();
}
/// Type of the generated treepath
template <class PreTreePath>
using TreePath_t = TYPEOF(makeTreePath(std::declval<PreTreePath>()));
#endif // DOXYGEN
......@@ -200,19 +204,6 @@ namespace AMDiS
return {{0u}};
}
/// \brief Generate a TreePath from a sequence of integers and integral-constants
/**
* Converts a sequence of arguments to a \ref Dune::TypeTree::HybridTreePath.
* The arguments can be one of
* - integer type (`int, std::size_t`)
* - integral constant (`std::integral_constant<std::size_t,i>, index_t<i>`)
**/
template <class... T>
constexpr Dune::TypeTree::HybridTreePath<T...> treepath(T const&... t)
{
return Dune::TypeTree::HybridTreePath<T...>(t...);
}
namespace Impl
{
......
......@@ -126,33 +126,34 @@ DOFVector<Underlying_t<decltype(basis2)>> vec2(std::move(basis2));
- Generator function to construct a DOFVector: [`makeDOFVector()`](#function-makedofvector)
## function `DOFVector::child`
## function `DOFVector::discreteFunction`
```c++
template <class TreePath = RootTreePath>
auto child(TreePath const& path = {}) // (1)
template <class... Indices>
auto discreteFunction(Indices... ii) // (1)
template <class TreePath = RootTreePath>
auto child(TreePath const& path = {}) const // (2)
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` thereby
(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` thereby
(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
`TreePath path`
: A Treepath identifying a node in the basis tree.
`Indices... ii`
: Components of the tree-path identifying the basis node
#### Example
```c++
DOFVector vec(basis);
auto vec_ = vec.child();
auto vec_0 = vec.child(_0);
auto vec_10 = vec.child(treepath(_1,0));
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);
```
......@@ -342,9 +343,6 @@ only available for the const or mutable `is_const` template parameter specializa
: 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.
#### See Also
- Generator function to construct a DiscreteFunction: [`makeDiscreteFunction()`](#function-makediscretefunction)
## function `DiscreteFunction::entitySet`
```c++
......@@ -382,25 +380,25 @@ Returns the const (1) or mutable (2) coefficient vector.
## function `DiscreteFunction::child`
```c++
// (1)
template <class TreePath = RootTreePath>
auto child(TreePath const& path = {}) const
template <class... Indices>
auto child(Indices... ii) const
// (2)
template <class TreePath = RootTreePath>
auto child(TreePath const& path = {})
template <class... Indices>
auto child(Indices... ii)
```
Returns the const (1) or mutable (2) sub-range view of the stored DOFVector.
#### Arguments
`TreePath path`
: A Treepath identifying a node in the basis tree.
`Indices... ii`
: Components of the tree-path identifying a node in the basis tree.
#### Example
```c++
ParallelGlobalBasis basis(gridView, power<3>(lagrange<1>()));
auto vec = makeDOFVector(basis);
auto df = makeDiscreteFunction(vec);
auto df = discreteFunction(vec);
auto df1 = df.child();
auto df2 = df.child(0);
......@@ -462,8 +460,8 @@ Note, the range type of the expression must be compatible with the `Range` type
ParallelGlobalBasis basis(gridView, power<3>(lagrange<1>()));