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

add extended TreeContainer implementation and replace TreeData

parent 1f3895e9
...@@ -57,8 +57,6 @@ namespace AMDiS ...@@ -57,8 +57,6 @@ namespace AMDiS
, colBasis_(colBasis) , colBasis_(colBasis)
, updatePattern_(true) , updatePattern_(true)
{ {
operators_.init(*rowBasis_, *colBasis_);
auto const rowSize = rowBasis_->localView().maxSize(); auto const rowSize = rowBasis_->localView().maxSize();
auto const colSize = colBasis_->localView().maxSize(); auto const colSize = colBasis_->localView().maxSize();
elementMatrix_.resize(rowSize, colSize); elementMatrix_.resize(rowSize, colSize);
......
...@@ -20,13 +20,15 @@ addOperator(ContextTag contextTag, Expr const& expr, ...@@ -20,13 +20,15 @@ addOperator(ContextTag contextTag, Expr const& expr,
static_assert( Concepts::PreTreePath<ColTreePath>, static_assert( Concepts::PreTreePath<ColTreePath>,
"col must be a valid treepath, or an integer/index-constant"); "col must be a valid treepath, or an integer/index-constant");
auto i = child(this->rowBasis()->localView().tree(), makeTreePath(row)); auto i = makeTreePath(row);
auto j = child(this->colBasis()->localView().tree(), makeTreePath(col)); auto node_i = child(this->rowBasis()->localView().tree(), i);
auto j = makeTreePath(col);
auto node_j = child(this->colBasis()->localView().tree(), j);
using LocalContext = typename ContextTag::type; using LocalContext = typename ContextTag::type;
using Tr = DefaultAssemblerTraits<LocalContext, ElementMatrix>; using Tr = DefaultAssemblerTraits<LocalContext, ElementMatrix>;
auto op = makeLocalOperator<LocalContext>(expr, this->rowBasis()->gridView()); auto op = makeLocalOperator<LocalContext>(expr, this->rowBasis()->gridView());
auto localAssembler = makeUniquePtr(makeAssembler<Tr>(std::move(op), i, j)); auto localAssembler = makeUniquePtr(makeAssembler<Tr>(std::move(op), node_i, node_j));
operators_[i][j].push(contextTag, std::move(localAssembler)); operators_[i][j].push(contextTag, std::move(localAssembler));
updatePattern_ = true; updatePattern_ = true;
...@@ -47,9 +49,9 @@ assemble(RowLocalView const& rowLocalView, ColLocalView const& colLocalView) ...@@ -47,9 +49,9 @@ assemble(RowLocalView const& rowLocalView, ColLocalView const& colLocalView)
auto const& element = rowLocalView.element(); auto const& element = rowLocalView.element();
auto geometry = element.geometry(); auto geometry = element.geometry();
for_each_node(rowLocalView.tree(), [&](auto const& rowNode, auto) { for_each_node(rowLocalView.tree(), [&](auto const& rowNode, auto rowTp) {
for_each_node(colLocalView.tree(), [&](auto const& colNode, auto) { for_each_node(colLocalView.tree(), [&](auto const& colNode, auto colTp) {
auto& matOp = operators_[rowNode][colNode]; auto& matOp = operators_[rowTp][colTp];
if (matOp) { if (matOp) {
matOp.bind(element, geometry); matOp.bind(element, geometry);
assembleOperators(gv, element, matOp, makeMatrixAssembler(rowNode, colNode, elementMatrix_)); assembleOperators(gv, element, matOp, makeMatrixAssembler(rowNode, colNode, elementMatrix_));
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <list> #include <list>
#include <memory> #include <memory>
#include <amdis/typetree/TreeData.hpp> #include <amdis/typetree/TreeContainer.hpp>
namespace AMDiS namespace AMDiS
{ {
...@@ -48,6 +48,8 @@ namespace AMDiS ...@@ -48,6 +48,8 @@ namespace AMDiS
/// Container for storing shared pointers to boundary conditions indexed by their position in /// Container for storing shared pointers to boundary conditions indexed by their position in
/// the basis tree, see \ref MatrixData. /// the basis tree, see \ref MatrixData.
template <class Mat, class Sol, class Rhs, class RB, class CB> template <class Mat, class Sol, class Rhs, class RB, class CB>
using BoundaryConditions = MatrixData<RB, CB, BCData<Mat, Sol, Rhs>::template type>; using BoundaryConditions
= TreeMatrix<BCData<Mat, Sol, Rhs>::template type,
typename RB::LocalView::Tree, typename CB::LocalView::Tree>;
} // end namespace AMDiS } // end namespace AMDiS
...@@ -44,8 +44,6 @@ namespace AMDiS ...@@ -44,8 +44,6 @@ namespace AMDiS
: Super(*basis) : Super(*basis)
, basis_(basis) , basis_(basis)
{ {
operators_.init(*basis);
auto const localSize = basis->localView().maxSize(); auto const localSize = basis->localView().maxSize();
elementVector_.resize(localSize); elementVector_.resize(localSize);
} }
......
...@@ -18,12 +18,13 @@ addOperator(ContextTag contextTag, Expr const& expr, TreePath path) ...@@ -18,12 +18,13 @@ addOperator(ContextTag contextTag, Expr const& expr, TreePath path)
static_assert( Concepts::PreTreePath<TreePath>, static_assert( Concepts::PreTreePath<TreePath>,
"path must be a valid treepath, or an integer/index-constant"); "path must be a valid treepath, or an integer/index-constant");
auto i = child(this->basis()->localView().tree(), makeTreePath(path)); auto i = makeTreePath(path);
auto node = child(this->basis()->localView().tree(), i);
using LocalContext = typename ContextTag::type; using LocalContext = typename ContextTag::type;
using Tr = DefaultAssemblerTraits<LocalContext, ElementVector>; using Tr = DefaultAssemblerTraits<LocalContext, ElementVector>;
auto op = makeLocalOperator<LocalContext>(expr, this->basis()->gridView()); auto op = makeLocalOperator<LocalContext>(expr, this->basis()->gridView());
auto localAssembler = makeUniquePtr(makeAssembler<Tr>(std::move(op), i)); auto localAssembler = makeUniquePtr(makeAssembler<Tr>(std::move(op), node));
operators_[i].push(contextTag, std::move(localAssembler)); operators_[i].push(contextTag, std::move(localAssembler));
} }
...@@ -41,8 +42,8 @@ assemble(LocalView const& localView) ...@@ -41,8 +42,8 @@ assemble(LocalView const& localView)
auto const& element = localView.element(); auto const& element = localView.element();
auto geometry = element.geometry(); auto geometry = element.geometry();
for_each_node(localView.tree(), [&](auto const& node, auto) { for_each_node(localView.tree(), [&](auto const& node, auto tp) {
auto& rhsOp = operators_[node]; auto& rhsOp = operators_[tp];
if (rhsOp) { if (rhsOp) {
rhsOp.bind(element, geometry); rhsOp.bind(element, geometry);
assembleOperators(gv, element, rhsOp, makeVectorAssembler(node, elementVector_)); assembleOperators(gv, element, rhsOp, makeVectorAssembler(node, elementVector_));
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include <amdis/BoundarySubset.hpp> #include <amdis/BoundarySubset.hpp>
#include <amdis/AssemblerInterface.hpp> #include <amdis/AssemblerInterface.hpp>
#include <amdis/typetree/TreeData.hpp> #include <amdis/typetree/TreeContainer.hpp>
namespace AMDiS namespace AMDiS
{ {
...@@ -141,10 +141,15 @@ namespace AMDiS ...@@ -141,10 +141,15 @@ namespace AMDiS
template <class RowBasis, class ColBasis, class ElementMatrix> template <class RowBasis, class ColBasis, class ElementMatrix>
using MatrixOperators using MatrixOperators
= MatrixData<RowBasis, ColBasis, OperatorLists<typename RowBasis::GridView,ElementMatrix>::template MatData>; = TreeMatrix<
OperatorLists<typename RowBasis::GridView,ElementMatrix>::template MatData,
typename RowBasis::LocalView::Tree,
typename ColBasis::LocalView::Tree>;
template <class GlobalBasis, class ElementVector> template <class Basis, class ElementVector>
using VectorOperators using VectorOperators
= VectorData<GlobalBasis, OperatorLists<typename GlobalBasis::GridView,ElementVector>::template VecData>; = TreeContainer<
OperatorLists<typename Basis::GridView,ElementVector>::template VecData,
typename Basis::LocalView::Tree>;
} // end namespace AMDiS } // end namespace AMDiS
...@@ -197,7 +197,7 @@ auto PeriodicBC<Mat, Sol, Rhs, Basis, TP>:: ...@@ -197,7 +197,7 @@ auto PeriodicBC<Mat, Sol, Rhs, Basis, TP>::
coords(Node const& tree, std::vector<std::size_t> const& localIndices) const coords(Node const& tree, std::vector<std::size_t> const& localIndices) const
{ {
std::vector<Domain> dofCoords(localIndices.size()); std::vector<Domain> dofCoords(localIndices.size());
for_each_leaf_node(tree, [&](auto const& node, auto const& tp) for_each_leaf_node(tree, [&](auto const& node, auto&&)
{ {
std::size_t size = node.finiteElement().size(); std::size_t size = node.finiteElement().size();
auto geometry = node.element().geometry(); auto geometry = node.element().geometry();
......
...@@ -33,17 +33,12 @@ ...@@ -33,17 +33,12 @@
#include <amdis/ProblemStatBase.hpp> #include <amdis/ProblemStatBase.hpp>
#include <amdis/ProblemStatTraits.hpp> #include <amdis/ProblemStatTraits.hpp>
#include <amdis/StandardProblemIteration.hpp> #include <amdis/StandardProblemIteration.hpp>
#include <amdis/common/SharedPtr.hpp> #include <amdis/common/SharedPtr.hpp>
#include <amdis/common/TupleUtility.hpp> #include <amdis/common/TupleUtility.hpp>
#include <amdis/common/TypeTraits.hpp> #include <amdis/common/TypeTraits.hpp>
#include <amdis/GridFunctions.hpp> #include <amdis/GridFunctions.hpp>
#include <amdis/gridfunctions/DiscreteFunction.hpp> #include <amdis/gridfunctions/DiscreteFunction.hpp>
#include <amdis/io/FileWriterBase.hpp> #include <amdis/io/FileWriterBase.hpp>
#include <amdis/typetree/TreeData.hpp>
#include <amdis/typetree/TreePath.hpp> #include <amdis/typetree/TreePath.hpp>
namespace AMDiS namespace AMDiS
...@@ -305,7 +300,7 @@ namespace AMDiS ...@@ -305,7 +300,7 @@ namespace AMDiS
bool storeMatrixData = false) override; bool storeMatrixData = false) override;
/// Implementation of \ref ProblemStatBase::estimate. /// Implementation of \ref ProblemStatBase::estimate.
void estimate(AdaptInfo& adaptInfo) override { /* do nothing. */ } void estimate(AdaptInfo& /*adaptInfo*/) override { /* do nothing. */ }
/// Implementation of \ref ProblemStatBase::refineMesh. /// Implementation of \ref ProblemStatBase::refineMesh.
Flag adaptGrid(AdaptInfo& adaptInfo) override; Flag adaptGrid(AdaptInfo& adaptInfo) override;
......
...@@ -209,10 +209,7 @@ void ProblemStat<Traits>::createGlobalBasisImpl(std::false_type) ...@@ -209,10 +209,7 @@ void ProblemStat<Traits>::createGlobalBasisImpl(std::false_type)
template <class Traits> template <class Traits>
void ProblemStat<Traits>::initGlobalBasis() void ProblemStat<Traits>::initGlobalBasis() {}
{
boundaryConditions_.init(*globalBasis_, *globalBasis_);
}
template <class Traits> template <class Traits>
...@@ -227,7 +224,7 @@ void ProblemStat<Traits>::createMatricesAndVectors() ...@@ -227,7 +224,7 @@ void ProblemStat<Traits>::createMatricesAndVectors()
rhs_ = std::make_shared<SystemVector>(globalBasis_); rhs_ = std::make_shared<SystemVector>(globalBasis_);
auto localView = globalBasis_->localView(); auto localView = globalBasis_->localView();
for_each_node(localView.tree(), [&,this](auto const& node, auto treePath) -> void for_each_node(localView.tree(), [&,this](auto&&, auto treePath) -> void
{ {
std::string i = to_string(treePath); std::string i = to_string(treePath);
estimates_[i].resize(globalBasis_->gridView().indexSet().size(0)); estimates_[i].resize(globalBasis_->gridView().indexSet().size(0));
...@@ -255,7 +252,7 @@ void ProblemStat<Traits>::createMarker() ...@@ -255,7 +252,7 @@ void ProblemStat<Traits>::createMarker()
{ {
marker_.clear(); marker_.clear();
auto localView = globalBasis_->localView(); auto localView = globalBasis_->localView();
for_each_node(localView.tree(), [&,this](auto const& node, auto treePath) -> void for_each_node(localView.tree(), [&,this](auto&&, auto treePath) -> void
{ {
std::string componentName = name_ + "->marker[" + to_string(treePath) + "]"; std::string componentName = name_ + "->marker[" + to_string(treePath) + "]";
...@@ -358,7 +355,7 @@ addPeriodicBC(BoundaryType id, WorldMatrix const& matrix, WorldVector const& vec ...@@ -358,7 +355,7 @@ addPeriodicBC(BoundaryType id, WorldMatrix const& matrix, WorldVector const& vec
template <class Traits> template <class Traits>
void ProblemStat<Traits>:: void ProblemStat<Traits>::
solve(AdaptInfo& adaptInfo, bool createMatrixData, bool storeMatrixData) solve(AdaptInfo& /*adaptInfo*/, bool createMatrixData, bool storeMatrixData)
{ {
Dune::Timer t; Dune::Timer t;
...@@ -449,7 +446,7 @@ globalRefine(int n) ...@@ -449,7 +446,7 @@ globalRefine(int n)
template <class Traits> template <class Traits>
Flag ProblemStat<Traits>:: Flag ProblemStat<Traits>::
adaptGrid(AdaptInfo& adaptInfo) adaptGrid(AdaptInfo& /*adaptInfo*/)
{ {
Dune::Timer t; Dune::Timer t;
...@@ -470,9 +467,9 @@ buildAfterAdapt(AdaptInfo& /*adaptInfo*/, Flag /*flag*/, bool asmMatrix, bool as ...@@ -470,9 +467,9 @@ buildAfterAdapt(AdaptInfo& /*adaptInfo*/, Flag /*flag*/, bool asmMatrix, bool as
Dune::Timer t2; Dune::Timer t2;
auto localView = globalBasis_->localView(); auto localView = globalBasis_->localView();
for_each_node(localView.tree(), [&,this](auto const& rowNode, auto rowTp) -> void { for_each_node(localView.tree(), [&](auto&&, auto rowTp) -> void {
for_each_node(localView.tree(), [&,this](auto const& colNode, auto colTp) -> void { for_each_node(localView.tree(), [&](auto&&, auto colTp) -> void {
for (auto bc : boundaryConditions_[rowNode][colNode]) for (auto bc : boundaryConditions_[rowTp][colTp])
bc->init(); bc->init();
}); });
}); });
...@@ -509,10 +506,10 @@ buildAfterAdapt(AdaptInfo& /*adaptInfo*/, Flag /*flag*/, bool asmMatrix, bool as ...@@ -509,10 +506,10 @@ buildAfterAdapt(AdaptInfo& /*adaptInfo*/, Flag /*flag*/, bool asmMatrix, bool as
t2.reset(); t2.reset();
solution_->resize(sizeInfo(*globalBasis_)); solution_->resize(sizeInfo(*globalBasis_));
for_each_node(localView.tree(), [&,this](auto const& rowNode, auto row_tp) -> void { for_each_node(localView.tree(), [&](auto&&, auto rowTp) -> void {
for_each_node(localView.tree(), [&,this](auto const& colNode, auto col_tp) -> void { for_each_node(localView.tree(), [&](auto&&, auto colTp) -> void {
// finish boundary condition // finish boundary condition
for (auto bc : boundaryConditions_[rowNode][colNode]) for (auto bc : boundaryConditions_[rowTp][colTp])
bc->apply(*systemMatrix_, *solution_, *rhs_); bc->apply(*systemMatrix_, *solution_, *rhs_);
}); });
}); });
......
...@@ -5,6 +5,5 @@ install(FILES ...@@ -5,6 +5,5 @@ install(FILES
RangeType.hpp RangeType.hpp
Traversal.hpp Traversal.hpp
TreeContainer.hpp TreeContainer.hpp
TreeData.hpp
TreePath.hpp TreePath.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/typetree) DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/typetree)
...@@ -18,20 +18,217 @@ ...@@ -18,20 +18,217 @@
namespace AMDiS namespace AMDiS
{ {
/// \brief Vector data-structure with tree-path index access and hierarchic structure
/// given by the `Container` template type
/**
* This Vector container is parametrized with the actual container type that is stored
* internally. Access to the elements of the container is possible by using a tree-path
* index.
*
* The internal container is constructed by the \ref ContainerFactory, storing for each
* tree node a corresponding array or tuple plus a value. The data-structure to hold
* both, the value and the container is defined in \ref ValueAndContainer.
**/
template <class Container>
class TreeContainerStorage
{
using Self = TreeContainerStorage;
template <class C>
static constexpr decltype(auto)
accessByTreePath(C&& container, Dune::TypeTree::HybridTreePath<> const&)
{
return container.value();
}
template <class C, class... T>
static constexpr decltype(auto)
accessByTreePath(C&& container, Dune::TypeTree::HybridTreePath<T...> const& path)
{
auto head = Dune::TypeTree::treePathEntry(path,Dune::Indices::_0);
return accessByTreePath(container[head], pop_front(path));
}
public:
/// \brief Default-construct the tree-container
TreeContainerStorage()
: container_()
{}
TreeContainerStorage(Container const& container)
: container_(container)
{}
/// \brief Construct the tree-container from a given container storage
TreeContainerStorage(Container&& container)
: container_(std::move(container))
{}
/// \brief Access a (const) element of the container by treepath
template <class... T>
decltype(auto) operator[](Dune::TypeTree::HybridTreePath<T...> const& path) const
{
return accessByTreePath(container_, path);
}
/// \brief Access a (mutable) element of the container by treepath
template <class... T>
decltype(auto) operator[](Dune::TypeTree::HybridTreePath<T...> const& path)
{
return accessByTreePath(container_, path);
}
/// \brief Obtain the container (const)
Container const& data() const
{
return container_;
}
/// \brief Obtain the container (mutable)
Container& data()
{
return container_;
}
/// \brief Compare two containers for equality
bool operator==(TreeContainerStorage const& other) const
{
return container_ == other.container_;
}
/// \brief Compare two containers for inequality
bool operator!=(TreeContainerStorage const& other) const
{
return container_ != other.container_;
}
private:
Container container_;
};
namespace Impl namespace Impl
{ {
template <class Value, class Container>
class ValueAndContainer
{
public:
template <class V, class C>
ValueAndContainer(V&& value, C&& container)
: value_(FWD(value))
, container_(FWD(container))
{}
ValueAndContainer()
: value_()
, container_()
{}
template <class I>
auto& operator[](I const& i) { return container_[i]; }
template <class I>
auto const& operator[](I const& i) const { return container_[i]; }
Value& value() { return value_; }
Value const& value() const { return value_; }
Container& container() { return container_; }
Container const& container() const { return container_; }
bool operator==(ValueAndContainer const& other) const
{
return value_ == other.value_ && container_ == other.container_;
}
private:
Value value_;
Container container_;
};
template <class Value>
class ValueAndContainer<Value,void>
{
public:
template <class V, Dune::disableCopyMove<ValueAndContainer,V> = 0>
ValueAndContainer(V&& value)
: value_(FWD(value))
{}
ValueAndContainer()
: value_()
{}
Value& value() { return value_; }
Value const& value() const { return value_; }
bool operator==(ValueAndContainer const& other) const
{
return value_ == other.value_;
}
private:
Value value_;
};
struct Ignore{};
template <class Container>
class ValueAndContainer<Ignore,Container>
{
public:
template <class C>
ValueAndContainer(Ignore, C&& container)
: container_(FWD(container))
{}
ValueAndContainer()
: container_()
{}
template <class I>
auto& operator[](I const& i) { return container_[i]; }
template <class I>
auto const& operator[](I const& i) const { return container_[i]; }
Ignore value() { return {}; }
Ignore value() const { return {}; }
Container& container() { return container_; }
Container const& container() const { return container_; }
bool operator==(ValueAndContainer const& other) const
{
return container_ == other.container_;
}
private:
Container container_;
};
template <class Value, class Container>
ValueAndContainer(Value const&, Container const&)
-> ValueAndContainer<Value,Container>;
template <class Value>
ValueAndContainer(Value const&)
-> ValueAndContainer<Value,void>;
/// \brief A factory class creating a hybrid container compatible with a type tree /// \brief A factory class creating a hybrid container compatible with a type tree
/** /**
* * This class allows to create a nested hybrid container having the same structure
* This class allows to create a nested hybrid container having the same structure * as a given type tree. Power nodes are represented as std::array's while composite
* as a given type tree. Power nodes are represented as std::array's while composite * nodes are represented as Dune::TupleVector's. The stored values for the leaf nodes
* nodes are represented as Dune::TupleVector's. The stored values for the leaf nodes * are creating using a given predicate. Once created, the factory provides an
* are creating using a given predicate. Once created, the factory provides an * operator() creating the container for the tree given as argument.
* operator() creating the container for the tree given as argument. *
* * \tparam NodeToValue Type of a predicate that determines the stored values at the
* \tparam LeafToValue Type of a predicate that determines the stored values at the leafs * leafs
*/ **/
template <class LeafToValue> template <class NodeToValue, bool leafOnly = false>
class ContainerFactory class ContainerFactory
{ {
public: public:
...@@ -41,25 +238,29 @@ namespace AMDiS ...@@ -41,25 +238,29 @@ namespace AMDiS
* *
* \param A predicate used to generate the stored values for the leaves * \param A predicate used to generate the stored values for the leaves
*/ */
ContainerFactory(LeafToValue leafToValue) ContainerFactory(NodeToValue nodeToValue)
: leafToValue_(std::move(leafToValue)) : nodeToValue_(std::move(nodeToValue))
{} {}
/// \brief Return a container for storing the node content /// \brief Return a container for storing the node content
template <class Node> template <class Node>
auto operator() (Node const& node) const auto operator()(Node const& node) const
{ {
if constexpr (Node::isLeaf) if constexpr (Node::isLeaf)
return leafToValue_(node); return ValueAndContainer{value(node)};