AMDiS  0.3
The Adaptive Multi-Dimensional Simulation Toolbox
TreeContainer.hpp
1 #pragma once
2 
3 #include <array>
4 #include <functional>
5 #include <type_traits>
6 #include <utility>
7 
8 #include <dune/common/indices.hh>
9 #include <dune/common/tuplevector.hh>
10 
11 #include <dune/typetree/treepath.hh>
12 
13 #include <amdis/common/Apply.hpp>
14 #include <amdis/common/TypeTraits.hpp>
15 #include <amdis/typetree/TreePath.hpp>
16 
17 // NOTE: backport of dune/typetree/treecontainer.hh
18 
19 namespace AMDiS {
20 namespace TypeTree {
21 
22 template <class Value>
24 {
25 public:
26  template <class V>
27  LeafNodeStorage(V&& value)
28  : value_(FWD(value))
29  {}
30 
32  : value_()
33  {}
34 
35  Value& value() { return value_; }
36  Value const& value() const { return value_; }
37 
38  bool operator==(LeafNodeStorage const& other) const
39  {
40  return value_ == other.value_;
41  }
42 
43 private:
44  Value value_;
45 };
46 
47 template <class Value>
48 LeafNodeStorage(Value const&)
50 
51 
52 template <class Value, class Container>
54 {
55 public:
56  template <class V, class C>
57  InnerNodeStorage(V&& value, C&& container)
58  : value_(FWD(value))
59  , container_(FWD(container))
60  {}
61 
63  : value_()
64  , container_()
65  {}
66 
67  template <class I>
68  auto& operator[](I const& i) { return container_[i]; }
69 
70  template <class I>
71  auto const& operator[](I const& i) const { return container_[i]; }
72 
73  Value& value() { return value_; }
74  Value const& value() const { return value_; }
75 
76  Container& container() { return container_; }
77  Container const& container() const { return container_; }
78 
79  bool operator==(InnerNodeStorage const& other) const
80  {
81  return value_ == other.value_ && container_ == other.container_;
82  }
83 
84 private:
85  Value value_;
86  Container container_;
87 };
88 
89 template <class Value, class Container>
90 InnerNodeStorage(Value const&, Container const&)
92 
93 
95 
105 template <class NodeToValue, bool leafOnly = false>
107 {
108 public:
110 
115  ContainerFactory(NodeToValue nodeToValue)
116  : nodeToValue_(std::move(nodeToValue))
117  {}
118 
120  template <class Node>
121  auto operator()(Node const& node) const
122  {
123  if constexpr (Node::isLeaf)
124  return LeafNodeStorage{nodeToValue_(node)};
125  else
126  if constexpr (Node::isPower) {
127  using TransformedChild = decltype((*this)(node.child(0)));
128  return makeInnerNodeStorage(node,
129  std::array<TransformedChild, Node::degree()>());
130  }
131  else
132  if constexpr (Node::isComposite) {
133  return makeInnerNodeStorage(node,
134  Ranges::applyIndices<Node::degree()>(
135  [&](auto... ii) { return Dune::makeTupleVector((*this)(node.child(ii))...); }));
136  }
137  else {
138  static_assert(Node::isLeaf || Node::isPower || Node::isComposite,
139  "Node must be one of leaf, power, composite.");
140  return;
141  }
142  }
143 
144  template <class Node, class Container>
145  auto makeInnerNodeStorage(Node const& node, Container&& container) const
146  {
147  if constexpr(!Node::isLeaf && leafOnly)
148  return FWD(container);
149  else
150  return InnerNodeStorage{nodeToValue_(node), FWD(container)};
151  }
152 
153 private:
154  NodeToValue nodeToValue_;
155 };
156 
159 
168 template <class Container>
170 {
171  using Self = TreeContainerStorage;
172 
173  template <class C>
174  static constexpr auto
175  accessByTreePath(C&& container, Dune::TypeTree::HybridTreePath<>) -> decltype(container.value())
176  {
177  return container.value();
178  }
179 
180  template <class C, class T0, class... T>
181  static constexpr decltype(auto)
182  accessByTreePath(C&& container, Dune::TypeTree::HybridTreePath<T0,T...> const& path)
183  {
184  auto head = Dune::TypeTree::treePathEntry(path,Dune::Indices::_0);
185  return accessByTreePath(container[head], pop_front(path));
186  }
187 
188 public:
191  : container_()
192  {}
193 
195  TreeContainerStorage(Container const& container)
196  : container_(container)
197  {}
198 
200  TreeContainerStorage(Container&& container)
201  : container_(std::move(container))
202  {}
203 
205  template <class... T>
206  decltype(auto) operator[](Dune::TypeTree::HybridTreePath<T...> const& path) const
207  {
208  return accessByTreePath(container_, path);
209  }
210 
212  template <class... T>
213  decltype(auto) operator[](Dune::TypeTree::HybridTreePath<T...> const& path)
214  {
215  return accessByTreePath(container_, path);
216  }
217 
219  Container const& data() const
220  {
221  return container_;
222  }
223 
225  Container& data()
226  {
227  return container_;
228  }
229 
231  bool operator==(TreeContainerStorage const& other) const
232  {
233  return container_ == other.container_;
234  }
235 
237  bool operator!=(TreeContainerStorage const& other) const
238  {
239  return container_ != other.container_;
240  }
241 
242 private:
243  Container container_;
244 };
245 
246 
247 
249 
263 template <bool leafOnly = false, class Tree, class NodeToValue>
264 auto treeContainer(Tree const& tree, NodeToValue nodeToValue)
265 {
266  auto factory = ContainerFactory<NodeToValue,leafOnly>{nodeToValue};
267  return TreeContainerStorage{factory(tree)};
268 }
269 
270 
272 
286 template <class Value, bool leafOnly = false, class Tree>
287 auto treeContainer(Tree const& tree)
288 {
289  return treeContainer<leafOnly>(tree, [](auto&&) { return Value{}; });
290 }
291 
292 template <template<class> class NodeData, bool leafOnly = false, class Tree>
293 auto treeContainer(Tree const& tree)
294 {
295  return treeContainer<leafOnly>(tree, [](auto&& node) { return NodeData<TYPEOF(node)>{}; });
296 }
297 
300 template <class Value, class Tree, bool leafOnly = false>
301 using UniformTreeContainer
302  = TYPEOF(treeContainer<Value,leafOnly>(std::declval<const Tree&>()));
303 
306 template <class Value, class RowTree, class ColTree = RowTree, bool leafOnly = false>
307 using UniformTreeMatrix
308  = UniformTreeContainer<UniformTreeContainer<Value,ColTree,leafOnly>,RowTree,leafOnly>;
309 
312 template <template <class Node> class NodeData, class Tree, bool leafOnly = false>
313 using TreeContainer
314  = TYPEOF(treeContainer<NodeData,leafOnly>(std::declval<const Tree&>()));
315 
316 
317 namespace Impl_ {
318 
319 template <template <class,class> class NodeData, class Tree, bool leafOnly>
321 {
322  template <class RowNode>
323  struct ColNodeData
324  {
325  template <class ColNode>
326  using type = NodeData<RowNode, ColNode>;
327  };
328 
329  template <class RowNode>
330  using type = TreeContainer<ColNodeData<RowNode>::template type, Tree, leafOnly>;
331 };
332 
333 } // end namespace Impl_
334 
337 template <template <class,class> class NodeData, class RowTree, class ColTree = RowTree, bool leafOnly = false>
338 using TreeMatrix
339  = TreeContainer<Impl_::RowNodeData<NodeData,ColTree,leafOnly>::template type,RowTree,leafOnly>;
340 
341 }} //namespace AMDiS::TypeTree
bool operator==(TreeContainerStorage const &other) const
Compare two containers for equality.
Definition: TreeContainer.hpp:231
TreeContainerStorage(Container const &container)
Construct the tree-container from a given container storage.
Definition: TreeContainer.hpp:195
bool operator!=(TreeContainerStorage const &other) const
Compare two containers for inequality.
Definition: TreeContainer.hpp:237
Container & data()
Obtain the container (mutable)
Definition: TreeContainer.hpp:225
Definition: AdaptiveGrid.hpp:373
Definition: TreeContainer.hpp:320
Definition: FieldMatVec.hpp:12
auto operator()(Node const &node) const
Return a container for storing the node content.
Definition: TreeContainer.hpp:121
Container const & data() const
Obtain the container (const)
Definition: TreeContainer.hpp:219
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
TreeContainerStorage(Container &&container)
Construct the tree-container from a given container storage.
Definition: TreeContainer.hpp:200
Definition: TreeContainer.hpp:53
Vector data-structure with tree-path index access and hierarchic structure given by the Container tem...
Definition: TreeContainer.hpp:169
auto pop_front(Dune::TypeTree::HybridTreePath< T0, T... > const &tp)
Extract the first entry in the treepath.
Definition: TreePath.hpp:191
TreeContainerStorage()
Default-construct the tree-container.
Definition: TreeContainer.hpp:190
ContainerFactory(NodeToValue nodeToValue)
Create ContainerFactory.
Definition: TreeContainer.hpp:115
A factory class creating a hybrid container compatible with a type tree.
Definition: TreeContainer.hpp:106
Definition: TreeContainer.hpp:23
Definition: TreeContainer.hpp:323