Commit 5c70d545 authored by Praetorius, Simon's avatar Praetorius, Simon

dune-functions globalBasis is now basis of problemStat

parent f9a757d2
......@@ -7,6 +7,7 @@
#include <dune/common/fvector.hh>
#include <dune/amdis/LinearAlgebra.hpp>
#include <dune/amdis/Operator.hpp>
#include <dune/amdis/common/Mpl.hpp>
#include <dune/amdis/common/TypeDefs.hpp>
......@@ -18,47 +19,37 @@ namespace AMDiS
/// The grid view the global FE basis lives on
using GridView = typename GlobalBasis::GridView;
using SystemMatrixType = SystemMatrix<GlobalBasis>;
using SystemVectorType = SystemVector<GlobalBasis>;
using TypeTree = typename GlobalBasis::LocalView::Tree;
using
public:
/// Constructor, stores a shared-pointer to the feSpaces
Assembler(std::shared_ptr<GlobalBasis> const& globalBasis, bool asmMatrix, bool asmVector)
Assembler(GlobalBasis& globalBasis,
MatrixOperators<GlobalBasis>& matrixOperators,
VectorOperators<GlobalBasis>& rhsOperators)
: globalBasis_(globalBasis)
, asmMatrix_(asmMatrix)
, asmVector_(asmVector)
, matrixOperators_(matrixOperators)
, rhsOperators_(rhsOperators)
{}
void update(GridView const& gv)
{
globalBasis_.update(gv);
}
/// Assemble the linear system
template <class MatrixOperators, class VectorOperators>
template <class SystemMatrixType, class SystemVectorType>
void assemble(
GridView const& gv,
SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
MatrixOperators& matrixOperators,
VectorOperators& rhsOperators);
bool asmMatrix, bool asmVector);
private:
/// Sets the system to zero and initializes all operators and boundary conditions
template <class MatrixOperators, class VectorOperators>
template <class SystemMatrixType, class SystemVectorType>
void initMatrixVector(
SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
MatrixOperators& matrixOperators,
VectorOperators& rhsOperators) const;
template <class MatrixOperators, class VectorOperators>
void assembleElement(
SystemMatrixType& matrix,
SystemVectorType& rhs,
MatrixOperators& matrixOperators,
VectorOperators& rhsOperators) const;
bool asmMatrix, bool asmVector) const;
template <class ElementContainer, class Container, class Operators, class... Bases>
......@@ -71,26 +62,32 @@ namespace AMDiS
/// Finish insertion into the matrix and assembles boundary conditions
/// Return the number of nonzeros assembled into the matrix
template <class MatrixOperators, class VectorOperators>
template <class SystemMatrixType, class SystemVectorType>
std::size_t finishMatrixVector(
SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
MatrixOperators& matrixOperators,
VectorOperators& rhsOperators) const;
bool asmMatrix, bool asmVector) const;
/// Return whether the matrix-block needs to be assembled
template <class LocalView0, class... LovalViews>
auto const& getElement(LocalView0 const& localView, LovalViews const&...) const
{
return localView.element();
}
/// Return whether the matrix-block needs to be assembled
template <class Basis0, class... Bases>
auto getElement(Basis0 const& basis0, Bases const&... bases) const
template <class LocalView0, class... LovalViews>
auto const& getGridView(LocalView0 const& localView, LovalViews const&...) const
{
return basis0.localView().element();
return globalBasis_.gridView();
}
private:
std::shared_ptr<GlobalBasis> globalBasis_;
bool asmMatrix_;
bool asmVector_;
GlobalBasis& globalBasis_;
MatrixOperators<GlobalBasis>& matrixOperators_;
VectorOperators<GlobalBasis>& rhsOperators_;
};
} // end namespace AMDiS
......
#pragma once
#include <dune/functions/functionspacebases/subspacebasis.hh>
#include <dune/typetree/treepath.hh>
#include <dune/amdis/utility/Visitor.hpp>
namespace AMDiS {
template <class GlobalBasis>
template <class MatrixOperators, class VectorOperators>
template <class SystemMatrixType, class SystemVectorType>
void Assembler<GlobalBasis>::assemble(
GridView const& gv,
SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
MatrixOperators& matrixOperators,
VectorOperators& rhsOperators)
bool asmMatrix, bool asmVector)
{
// 1. Update global bases
globalBasis_.update(gv);
// 1. init matrix and rhs vector and initialize dirichlet boundary conditions
initMatrixVector(matrix, solution, rhs, asmMatrix, asmVector);
auto localView = globalBasis_.localView();
auto localIndexSet = globalBasis_.localIndexSet();
// 2. init matrix and rhs vector and initialize dirichlet boundary conditions
initMatrixVector(matrix, solution, rhs, matrixOperators, rhsOperators);
// 2. create a local matrix and vector
std::size_t localSize = localView.maxSize();
mtl::dense2D<double> elementMatrix(localSize, localSize);
set_to_zero(elementMatrix);
mtl::dense_vector<double> elementVector(localSize);
set_to_zero(elementVector);
// 3. traverse grid and assemble operators on the elements
for (auto const& element : elements(globalBasis_.gridView()))
{
globalBasis_.bind(element);
assembleElement(matrix, rhs, matrixOperators, rhsOperators);
globalBasis_.unbind();
localView.bind(element);
// traverse type-tree of global-basis
forEachNode(localView.tree(), [&,this](auto const& rowNode, auto rowTreePath)
{
auto rowBasis = Dune::Functions::subspaceBasis(globalBasis_, rowTreePath);
auto rowLocalView = rowBasis.localView();
rowLocalView.bind(element); // NOTE: Is this necessary
auto& rhsOp = rhsOperators_[rowNode];
if (rhsOp.assemble(asmVector) && !rhsOp.empty())
assembleElementOperators(elementVector, rhs, rhsOp, rowLocalView);
forEachNode(localView.tree(), [&,this](auto const& colNode, auto colTreePath)
{
auto& matOp = matrixOperators_[rowNode][colNode];
if (matOp.assemble(asmMatrix) && !matOp.empty()) {
auto colBasis = Dune::Functions::subspaceBasis(globalBasis_, colTreePath);
auto colLocalView = colBasis.localView();
colLocalView.bind(element); // NOTE: Is this necessary
assembleElementOperators(elementMatrix, matrix, matOp, rowLocalView, colLocalView);
}
});
});
localIndexSet.bind(localView);
// add element-matrix to system-matrix
for (std::size_t i = 0; i < localView.size(); ++i) {
auto const row = localIndexSet.index(i);
for (std::size_t j = 0; j < localView.size(); ++j) {
auto const col = localIndexSet.index(j);
matrix(row,col) += elementMatrix(i,j);
}
}
// add element-vector to system-vector
for (std::size_t i = 0; i < localView.size(); ++i) {
auto const idx = localIndexSet.index(i);
rhs[idx] += elementVector[i];
}
localIndexSet.unbind();
localView.unbind();
}
// 4. finish matrix insertion and apply dirichlet boundary conditions
std::size_t nnz = finishMatrixVector(matrix, solution, rhs, matrixOperators, rhsOperators);
std::size_t nnz = finishMatrixVector(matrix, solution, rhs, asmMatrix, asmVector);
msg("fillin of assembled matrix: ", nnz);
}
template <class GlobalBasis>
template <class MatrixOperators, class VectorOperators>
template <class SystemMatrixType, class SystemVectorType>
void Assembler<GlobalBasis>::initMatrixVector(
SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
MatrixOperators& matrixOperators,
VectorOperators& rhsOperators) const
bool asmMatrix, bool asmVector) const
{
matrix.init(globalBasis_);
solution.init(globalBasis_);
rhs.init(globalBasis_);
matrix.init(asmMatrix);
solution.compress();
rhs.compress();
auto localView = globalBasis_.localView();
forEachNode(localView.tree(), [&,this](auto const& rowNode, auto rowTreePath)
{
if (rowNode.isLeaf)
msg(globalBasis_.size(rowTreePath), " DOFs for Basis[", Dune::TypeTree::treePathIndex(rowTreePath), "]");
msg(0, " DOFs for Basis[", 1, "]"); // TODO: add right values
auto rowBasis = Dune::Functions::subspaceBasis(globalBasis_, rowTreePath);
if (rhsOperators[rowNode].assemble(asmVector_))
rhsOperators[rowNode].init(rowBasis);
if (rhsOperators_[rowNode].assemble(asmVector))
rhsOperators_[rowNode].init(rowBasis);
forEachNode(localView.tree(), [&,this](auto const& colNode, auto colTreePath)
{
auto colBasis = Dune::Functions::subspaceBasis(globalBasis_, colTreePath);
if (matrixOperators[rowNode][colNode].assemble(asmMatrix_))
matrixOperators[rowNode][colNode].init(rowBasis, colBasis);
if (matrixOperators_[rowNode][colNode].assemble(asmMatrix))
matrixOperators_[rowNode][colNode].init(rowBasis, colBasis);
// init boundary condition
// for (int c = 0; c < nComponents; ++c)
......@@ -72,61 +124,21 @@ void Assembler<GlobalBasis>::initMatrixVector(
template <class GlobalBasis>
template <class MatrixOperators, class VectorOperators>
void Assembler<GlobalBasis>::assembleElement(
SystemMatrixType& matrix,
SystemVectorType& rhs,
MatrixOperators& matrixOperators,
VectorOperators& rhsOperators) const
{
auto localView = globalBasis_.localView();
forEachNode(localView.tree(), [&,this](auto const& rowNode, auto rowTreePath)
{
auto rowBasis = Dune::Functions::subspaceBasis(globalBasis_, rowTreePath);
auto& rhsOp = rhsOperators[rowNode];
if (rhsOp.assemble(asmVector_) && !rhsOp.empty()) {
auto elementVector = makeElementVector(rowNode);
set_to_zero(elementVector);
assembleElementOperators(elementVector, rhs, rhsOp, rowBasis);
}
forEachNode(localView.tree(), [&,this](auto const& colNode, auto colTreePath)
{
auto& matOp = matrixOperators[rowNode][colNode];
if (matOp.assemble(asmMatrix_) && !matOp.empty()) {
auto colBasis = Dune::Functions::subspaceBasis(globalBasis_, colTreePath);
auto elementMatrix = makeElementMatrix(rowNode, colNode);
set_to_zero(elementMatrix);
assembleElementOperators(elementMatrix, matrix, matOp, rowBasis, colBasis);
}
});
});
}
template <class GlobalBasis>
template <class ElementContainer, class Container, class Operators, class... Bases>
template <class ElementContainer, class Container, class Operators, class... LocalViews>
void Assembler<GlobalBasis>::assembleElementOperators(
ElementContainer& elementContainer,
Container& container,
Operators& operators,
Bases const&... subBases) const
LocalViews const&... localViews) const
{
if (operators.empty())
return false;
auto const& element = getElement(subBases...);
auto const& gridView = subBasis.gridView();
auto const& element = getElement(localViews...);
auto const& gridView = getGridView(localViews...);
bool add = false;
auto assemble_operators = [&](auto const& context, auto& operator_list) {
for (auto scaled : operator_list) {
bool add_op = scaled.op->assemble(gridView, context, subBases.localView()..., elementContainer, scaled.factor);
bool add_op = scaled.op->assemble(context, localViews..., elementContainer, scaled.factor);
add = add || add_op;
}
};
......@@ -145,36 +157,30 @@ void Assembler<GlobalBasis>::assembleElementOperators(
assemble_operators(intersection, operators.intersection);
}
}
if (!add)
return;
elementContainer.apply(subBases.localIndexSet()..., container);
}
template <class GlobalBasis>
template <class MatrixOperators, class VectorOperators>
template <class SystemMatrixType, class SystemVectorType>
std::size_t Assembler<GlobalBasis>::finishMatrixVector(
SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
MatrixOperators& matrixOperators,
VectorOperators& rhsOperators) const
bool asmMatrix, bool asmVector) const
{
matrix.finish();
auto localView = globalBasis_.localView();
forEachNode(localView.tree(), [&,this](auto const& rowNode, auto rowTreePath)
forEachNode(localView.tree(), [&,this](auto const& rowNode, auto /*rowTreePath*/)
{
auto& rhsOp = rhsOperators[rowNode];
if (rhsOp.assemble(asmVector_))
auto& rhsOp = rhsOperators_[rowNode];
if (rhsOp.assemble(asmVector))
rhsOp.assembled = true;
forEachNode(localView.tree(), [&,this](auto const& colNode, auto colTreePath)
forEachNode(localView.tree(), [&,this](auto const& colNode, auto /*colTreePath*/)
{
auto& matOp = matrixOperators[rowNode][colNode];
if (matOp.assemble(asmMatrix_))
auto& matOp = matrixOperators_[rowNode][colNode];
if (matOp.assemble(asmMatrix))
matOp.assembled = true;
// finish boundary condition
......
......@@ -11,8 +11,8 @@ dune_add_library("duneamdis" NO_EXPORT
ProblemInstat.cpp
ProblemStat.cpp
StandardProblemIteration.cpp
linear_algebra/istl/SystemMatrix.cpp
linear_algebra/istl/SystemVector.cpp
#linear_algebra/istl/SystemMatrix.cpp
#linear_algebra/istl/SystemVector.cpp
linear_algebra/mtl/SystemMatrix.cpp
linear_algebra/mtl/SystemVector.cpp
utility/Filesystem.cpp
......
......@@ -21,17 +21,16 @@ namespace AMDiS
{
private: // typedefs and static constants
using Mesh = typename Traits::Mesh;
using MeshView = typename Mesh::LeafGridView;
using MeshView = typename Traits::GridView;
/// Dimension of the mesh
static constexpr int dim = Traits::dim;
static constexpr int dim = MeshView::dimension;
/// Dimension of the world
static constexpr int dow = Traits::dow;
static constexpr int dow = MeshView::dimensionworld;
/// Number of problem components
static constexpr int nComponents = Traits::nComponents;
static constexpr int nComponents = 1;
public:
......@@ -62,7 +61,7 @@ namespace AMDiS
// copy dofvector to vertex data
forEach(range_<0, nComponents>, [this, &solutions](const auto _i)
{
this->dofVector2vertexVector(solutions[_i], std::get<_i>(data_vectors));
this->dofVector2vertexVector(solutions, std::get<_i>(data_vectors));
vtkSeqWriter->addVertexData(std::get<_i>(data_vectors), names[_i]);
});
vtkSeqWriter->write(time/*, Dune::VTK::appendedraw*/);
......@@ -77,7 +76,7 @@ namespace AMDiS
// copy dofvector to vertex data
forEach(range_<0, nComponents>, [this, &solutions](const auto _i)
{
this->dofVector2vertexVector(solutions[_i], std::get<_i>(data_vectors));
this->dofVector2vertexVector(solutions, std::get<_i>(data_vectors));
vtkWriter->addVertexData(std::get<_i>(data_vectors), names[_i]);
});
vtkWriter->pwrite(filename, dir, "" /*, Dune::VTK::appendedraw*/);
......@@ -99,7 +98,7 @@ namespace AMDiS
auto localView = feSpace.localView();
auto localIndexSet = feSpace.localIndexSet();
#if 0
// copy data to P1-vector
for (auto const& element : elements(meshView)) {
localView.bind(element);
......@@ -125,6 +124,7 @@ namespace AMDiS
}
}
}
#endif
}
private:
......
......@@ -2,6 +2,8 @@
#include <vector>
#include <dune/typetree/nodetags.hh>
#include <dune/amdis/LocalAssembler.hpp>
#include <dune/amdis/common/Mpl.hpp>
#include <dune/amdis/common/TypeDefs.hpp>
......@@ -35,15 +37,24 @@ namespace AMDiS
// tag dispatching for FirstOrderType...
template <class Operator, class RowView, class ColView>
void calculateElementMatrix(Operator& op, RowView const& rowView, ColView const& colView, ElementMatrix& elementMatrix)
void calculateElementMatrix(Operator& op,
RowView const& rowView, ColView const& colView,
ElementMatrix& elementMatrix, double fac)
{
calculateElementMatrix(op, rowView, colView, elementMatrix, FirstOrderType_<type>);
using RowNode = typename RowView::Tree;
using ColNode = typename ColView::Tree;
calculateElementMatrix(op, rowView, colView, elementMatrix, fac,
typename RowNode::NodeTag{}, typename ColNode::NodeTag{}, FirstOrderType_<type>);
}
template <class Operator, class RowView>
void calculateElementVector(Operator& op, RowView const& rowView, ElementVector& elementVector)
void calculateElementVector(Operator& op,
RowView const& rowView,
ElementVector& elementVector, double fac)
{
calculateElementVector(op, rowView, elementVector, FirstOrderType_<type>);
using RowNode = typename RowView::Tree;
calculateElementVector(op, rowView, elementVector, fac,
typename RowNode::NodeTag{}, FirstOrderType_<type>);
}
......@@ -52,6 +63,9 @@ namespace AMDiS
RowView const& rowView,
ColView const& colView,
ElementMatrix& elementMatrix,
double fac,
Dune::TypeTree::LeafNodeTag,
Dune::TypeTree::LeafNodeTag,
FirstOrderType_t<GRD_PHI>)
{
auto geometry = rowView.element().geometry();
......@@ -69,7 +83,7 @@ namespace AMDiS
const auto jacobian = geometry.jacobianInverseTransposed(quadPos);
// The multiplicative factor in the integral transformation formula
const double factor = quad_geometry.integrationElement(quad[iq].position()) * quad[iq].weight();
const double factor = quad_geometry.integrationElement(quad[iq].position()) * quad[iq].weight() * fac;
std::vector<Dune::FieldVector<double,1> > rowShapeValues;
rowLocalBasis.evaluateFunction(quadPos, rowShapeValues);
......@@ -94,12 +108,14 @@ namespace AMDiS
}
}
template <class Operator, class RowView, class ColView>
void calculateElementMatrix(Operator& op,
RowView const& rowView,
ColView const& colView,
ElementMatrix& elementMatrix,
double fac,
Dune::TypeTree::LeafNodeTag,
Dune::TypeTree::LeafNodeTag,
FirstOrderType_t<GRD_PSI>)
{
auto geometry = rowView.element().geometry();
......@@ -117,7 +133,7 @@ namespace AMDiS
const auto jacobian = geometry.jacobianInverseTransposed(quadPos);
// The multiplicative factor in the integral transformation formula
const double factor = quad_geometry.integrationElement(quad[iq].position()) * quad[iq].weight();
const double factor = quad_geometry.integrationElement(quad[iq].position()) * quad[iq].weight() * fac;
// The gradients of the shape functions on the reference element
std::vector<Dune::FieldMatrix<double,1,dim> > rowReferenceGradients;
......@@ -142,11 +158,21 @@ namespace AMDiS
}
}
template <class Operator, class RowView, class ColView, class RowNodeTag, class ColNodeTag, class FOT>
void calculateElementMatrix(Operator& op,
RowView const& rowView,
ColView const& colView,
ElementMatrix& elementMatrix,
double fac,
RowNodeTag, ColNodeTag, FOT)
{}
template <class Operator, class RowView>
void calculateElementVector(Operator& op,
RowView const& rowView,
ElementVector& elementVector,
double fac,
Dune::TypeTree::LeafNodeTag,
FirstOrderType_t<GRD_PSI>)
{
auto geometry = rowView.element().geometry();
......@@ -163,7 +189,7 @@ namespace AMDiS
const auto jacobian = geometry.jacobianInverseTransposed(quadPos);
// The multiplicative factor in the integral transformation formula
const double factor = quad_geometry.integrationElement(quad[iq].position()) * quad[iq].weight();
const double factor = quad_geometry.integrationElement(quad[iq].position()) * quad[iq].weight() * fac;
// The gradients of the shape functions on the reference element
std::vector<Dune::FieldMatrix<double,1,dim> > rowReferenceGradients;
......@@ -181,6 +207,14 @@ namespace AMDiS
}
}
}
template <class Operator, class RowView, class NodeTag, class FOT>
void calculateElementVector(Operator& op,
RowView const& rowView,
ElementVector& elementVector,
double fac,
NodeTag, FOT)
{}
};
} // end namespace AMDiS
......@@ -4,6 +4,8 @@
#include <vector>
#include <dune/geometry/type.hh>
#include <dune/typetree/typetree.hh>
#include <dune/functions/common/treedata.hh>
#include <dune/amdis/OperatorTermBase.hpp>
#include <dune/amdis/ZeroOrderAssembler.hpp>
......@@ -13,6 +15,7 @@
#include <dune/amdis/common/TypeDefs.hpp>
#include <dune/amdis/utility/GetDegree.hpp>
#include <dune/amdis/utility/TreeData.hpp>
namespace AMDiS
{
......@@ -24,9 +27,9 @@ namespace AMDiS
using Self = Operator;
using OperatorTermType = OperatorTerm<LocalContext>;
template <class, class> friend class ZeroOrderAssembler;
template <class, class, FirstOrderType> friend class FirstOrderAssembler;
template <class, class> friend class SecondOrderAssembler;
template <class,class> friend class ZeroOrderAssembler;
template <class,class, FirstOrderType> friend class FirstOrderAssembler;
template <class,class> friend class SecondOrderAssembler;
public:
/// \brief Add coefficients for zero-order operator < C(phi), psi >.
......@@ -129,7 +132,6 @@ namespace AMDiS
// assemble matrix operator
template <class RowView, class ColView, class ElementMatrix>
bool assemble(
GridView const& gv,
LocalContext const& element,
RowView const& rowView,
ColView const& colView,
......@@ -139,7 +141,6 @@ namespace AMDiS
// assemble vector operator
template <class LocalView, class ElementVector>
bool assemble(
GridView const& gv,
LocalContext const& element,
LocalView const& localView,
ElementVector& elementVector,
......@@ -254,23 +255,13 @@ namespace AMDiS
std::size_t lastMatrixIndex = 0;
std::size_t lastVectorIndex = 0;
ElementMatrix cachedElementMatrix;
ElementVector cachedElementVector;
};
template <class GlobalBasis>
class TreeOperators
template <class GridView>
struct OperatorLists
{
protected:
using GridView = typename GlobalBasis::GridView;
using Element = GridView::template Codim<0>::Entity;
using ElementOperator = Operator<GridView, Element>;
using IntersectionOperator = Operator<GridView, typename GridView::Intersection>;
using Tree = typename Basis::LocalView::Tree;
using Element = typename GridView::template Codim<0>::Entity;
template <class OperatorType>
struct Scaled
......@@ -284,6 +275,9 @@ namespace AMDiS
template <class Node>
struct NodeData
{
using ElementOperator = Operator<GridView, Element>;
using IntersectionOperator = Operator<GridView, typename GridView::Intersection>;
std::list<Scaled<ElementOperator>> element;
std::list<Scaled<IntersectionOperator>> boundary;
std::list<Scaled<IntersectionOperator>> intersection;
......@@ -291,7 +285,7 @@ namespace AMDiS
bool assembled = false; // if false, do reassemble
bool changing = false; // if true, or assembled false, do reassemble
template <class.. Bases>
template <class... Bases>
void init(Bases&&... bases)
{
for (auto scaled : element)
......@@ -314,90 +308,12 @@ namespace AMDiS
};
};
template <class GlobalBasis>
class MatrixOperators
: public TreeOperators<GlobalBasis>
{
using Tree = typename TreeOperators<GlobalBasis>::Tree;
using NodeData = typename TreeOperators<GlobalBasis>::NodeData;
template <class Node>
using RowNodeData = Dune::Functions::TreeData<Tree, NodeData, false>;
using Data = Dune::Functions::TreeData<Tree, RowNodeData, false>;
public:
MatrixOperators(GlobalBasis const& globalBasis)
{
auto localView = globalBasis.localView();
data_.init(localView.tree());
forEachNode(localView.tree(), [&,this](auto const& node, auto const treePath)
{
data_[node].init(localView.tree());
});
}
template <class Node>
auto& operator[](Node const& node)
{
return data_[node];
}
template <class Node>
auto const& operator[](Node const& node) const
{
return data_[node];
}
template <class RowNode, class ColNode>
auto& operator()(RowNode const& rowNode, ColNode const& colNode)
{
return data_[rowNode][colNode];
}
template <class RowNode, class ColNode>
auto const& operator()(RowNode const& rowNode, ColNode const& colNode) const
{
return data_[rowNode][colNode];
}
private:
Data data_;
};
template <class GlobalBasis>
class VectorOperators
: public TreeOperators<GlobalBasis>
{
using Tree = typename TreeOperators<GlobalBasis>::Tree;
using NodeData = typename TreeOperators<GlobalBasis>::NodeData;
using Data = Dune::Functions::TreeData<Tree, NodeData, false>;