diff --git a/src/amdis/typetree/TreeContainer.hpp b/src/amdis/typetree/TreeContainer.hpp index 4bad3c795fb8df1a029cddb988caf2a4d9c51319..4ecc70865e73012b5e9d36b36679bc83863e32d9 100644 --- a/src/amdis/typetree/TreeContainer.hpp +++ b/src/amdis/typetree/TreeContainer.hpp @@ -12,6 +12,7 @@ #include <amdis/common/Apply.hpp> #include <amdis/common/TypeTraits.hpp> +#include <amdis/typetree/TreePath.hpp> // NOTE: backport of dune/typetree/treecontainer.hh @@ -65,8 +66,9 @@ namespace AMDiS std::enable_if_t<Node::isComposite, int> = 0> auto operator()(const Node& node) { - return Tools::apply_indices([&](auto... indices) { return Dune::makeTupleVector((*this)(node.child(indices))...); }, - index_t<Node::degree()>{}); + return Tools::apply_indices([&](auto... indices) { + return Dune::makeTupleVector((*this)(node.child(indices))...); + }, index_t<Node::degree()>{}); } private: @@ -80,6 +82,8 @@ namespace AMDiS template<class Container> class TreeContainerVectorBackend { + using Self = TreeContainerVectorBackend; + template<class C> static constexpr decltype(auto) accessByTreePath(C&& container, const Dune::TypeTree::HybridTreePath<>& path) { @@ -90,23 +94,22 @@ namespace AMDiS static constexpr decltype(auto) accessByTreePath(C&& container, const Dune::TypeTree::HybridTreePath<T...>& path) { auto head = Dune::TypeTree::treePathEntry(path,Dune::Indices::_0); - auto tailPath = Tools::apply_indices([&](auto... i) - { - using namespace Dune::TypeTree; - return hybridTreePath(treePathEntry(path,index_t<i.value+1>{})...); - }, index_t<sizeof...(T)-1>{}); - return accessByTreePath(container[head], tailPath); + return accessByTreePath(container[head], pop_front(path)); } public: - TreeContainerVectorBackend(Container&& container) : - container_(std::move(container)) - {} + TreeContainerVectorBackend() = default; - TreeContainerVectorBackend(TreeContainerVectorBackend&& other) : - container_(std::move(other.container_)) + TreeContainerVectorBackend(Container&& container) + : container_(std::move(container)) {} + TreeContainerVectorBackend(const Self&) = default; + TreeContainerVectorBackend(Self&&) = default; + + Self& operator=(const Self&) = default; + Self& operator=(Self&&) = default; + template<class... T> decltype(auto) operator[](const Dune::TypeTree::HybridTreePath<T...>& path) const { @@ -129,6 +132,16 @@ namespace AMDiS return container_; } + bool operator==(TreeContainerVectorBackend const& other) const + { + return container_ == other.container_; + } + + bool operator!=(TreeContainerVectorBackend const& other) const + { + return container_ != other.container_; + } + private: Container container_; }; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ead7e40c7d76f7a36dae9fc4c700ee9340c7d2c3..cb7fe95362fbd8e216683ca45d472b4fa429b67b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -54,3 +54,6 @@ dune_add_test(SOURCES StringTest.cpp dune_add_test(SOURCES TreeDataTest.cpp LINK_LIBRARIES amdis) + +dune_add_test(SOURCES TreeContainerTest.cpp + LINK_LIBRARIES amdis) diff --git a/test/TreeContainerTest.cpp b/test/TreeContainerTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..26e4e20dc72cb54b44bb239a46102b604c80ff47 --- /dev/null +++ b/test/TreeContainerTest.cpp @@ -0,0 +1,58 @@ +#include <dune/grid/yaspgrid.hh> + +#include <dune/functions/functionspacebases/compositebasis.hh> +#include <dune/functions/functionspacebases/lagrangebasis.hh> +#include <dune/functions/functionspacebases/powerbasis.hh> + +#include <amdis/typetree/Traversal.hpp> +#include <amdis/typetree/TreeContainer.hpp> + +#include "Tests.hpp" + +using namespace AMDiS; + +int main () +{ + Dune::YaspGrid<2> grid({1.0,1.0}, {1,1}); + auto gridView = grid.leafGridView(); + + using namespace Dune::Functions::BasisFactory; + auto basis = makeBasis(gridView, + composite( + power<2>(lagrange<2>()), + lagrange<1>() + )); + + auto localView = basis.localView(); + auto const& tree = localView.tree(); + + auto c1 = makeTreeContainer<double>(tree); + auto c2 = makeTreeContainer<decltype(c1)>(tree); + auto c3 = makeTreeContainer(tree, [&](auto const&) { return makeTreeContainer<double>(tree); }); + + // fill 1d treeContainer with data + for_each_leaf_node(tree, [&](auto const& node, auto tp) { + c1[tp] = double(node.treeIndex()); + }); + + // copy construction + auto c4 = c1; + AMDIS_TEST(c4 == c1); + + // fill 2d treeContainer with data + for_each_leaf_node(tree, [&](auto const& row_node, auto row_tp) { + for_each_leaf_node(tree, [&](auto const& col_node, auto col_tp) { + c3[row_tp][col_tp] = double(row_node.treeIndex() + col_node.treeIndex()); + }); + }); + + // copy construction + auto c5 = c3; + AMDIS_TEST(c5 == c3); + + // copy-assignment of container + c2 = c3; + AMDIS_TEST(c2 == c3); + + return report_errors(); +}