AMDiS  0.1
The Adaptive Multi-Dimensional Simulation Toolbox
Traversal.hpp
1 #pragma once
2 
3 #include <dune/common/rangeutilities.hh>
4 
5 #include <dune/typetree/nodetags.hh>
6 #include <dune/typetree/treepath.hh>
7 
8 #include <amdis/common/ForEach.hpp>
9 #include <amdis/common/TypeTraits.hpp>
10 
11 // NOTE: backport of dune/typetree/traversal.hpp from Dune 2.7
12 
13 namespace AMDiS
14 {
15  namespace Impl
16  {
18 
27  template <bool dynamic = true, class Tree>
28  auto traversalDegree(Tree const& tree)
29  {
30  if constexpr (dynamic && Tree::isPower)
31  return std::size_t(tree.degree());
32  else if constexpr (Tree::isPower || Tree::isComposite)
33  return std::integral_constant<std::size_t, Tree::degree()>{};
34  else
35  return tree.degree();
36  }
37 
47  template <class Tree, class TreePath, class PreFunc, class LeafFunc, class PostFunc>
48  void for_each_node(Tree&& tree, TreePath treePath, PreFunc&& preFunc, LeafFunc&& leafFunc, PostFunc&& postFunc)
49  {
50  using TreeType = std::decay_t<Tree>;
51  if constexpr (TreeType::isLeaf) {
52  // If we have a leaf tree just visit it using the leaf function.
53  leafFunc(tree, treePath);
54  } else {
55  // Otherwise visit the tree with the pre function,
56  // visit all children using a static or dynamic loop, and
57  // finally visit the tree with the post function.
58  preFunc(tree, treePath);
59  Dune::Hybrid::forEach(Dune::range(traversalDegree(tree)), [&](auto i) {
60  auto childTreePath = push_back(treePath, i);
61  Impl::for_each_node(tree.child(i), childTreePath, preFunc, leafFunc, postFunc);
62  });
63  postFunc(tree, treePath);
64  }
65  }
66 
67  } // end namespace Impl
68 
69 
71 
80  template <class Tree, class PreFunc, class LeafFunc, class PostFunc>
81  void for_each_node(Tree&& tree, PreFunc&& preFunc, LeafFunc&& leafFunc, PostFunc&& postFunc)
82  {
83  auto root = Dune::TypeTree::hybridTreePath();
84  Impl::for_each_node(tree, root, preFunc, leafFunc, postFunc);
85  }
86 
88 
96  template <class Tree, class InnerFunc, class LeafFunc>
97  void for_each_node(Tree&& tree, InnerFunc&& innerFunc, LeafFunc&& leafFunc)
98  {
99  auto root = Dune::TypeTree::hybridTreePath();
100  Impl::for_each_node(tree, root, innerFunc, leafFunc, NoOp{});
101  }
102 
104 
111  template <class Tree, class NodeFunc>
112  void for_each_node(Tree&& tree, NodeFunc&& nodeFunc)
113  {
114  auto root = Dune::TypeTree::hybridTreePath();
115  Impl::for_each_node(tree, root, nodeFunc, nodeFunc, NoOp{});
116  }
117 
119 
126  template <class Tree, class LeafFunc>
127  void for_each_leaf_node(Tree&& tree, LeafFunc&& leafFunc)
128  {
129  auto root = Dune::TypeTree::hybridTreePath();
130  Impl::for_each_node(tree, root, NoOp{}, leafFunc, NoOp{});
131  }
132 
133 } // end namespace AMDiS
void for_each_leaf_node(Tree &&tree, LeafFunc &&leafFunc)
Traverse tree and visit each leaf node.
Definition: Traversal.hpp:127
A functor with no operation.
Definition: TypeTraits.hpp:99
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
void for_each_node(Tree &&tree, PreFunc &&preFunc, LeafFunc &&leafFunc, PostFunc &&postFunc)
Traverse tree and visit each node.
Definition: Traversal.hpp:81