AMDiS  0.3
The Adaptive Multi-Dimensional Simulation Toolbox
NodeCache.hpp
1 #pragma once
2 
3 #include <memory>
4 #include <tuple>
5 #include <vector>
6 
7 #include <dune/common/ftraits.hh>
8 #include <dune/common/hash.hh>
9 #include <dune/common/indices.hh>
10 
11 #include <dune/geometry/type.hh>
12 
13 #include <dune/typetree/leafnode.hh>
14 #include <dune/typetree/powernode.hh>
15 #include <dune/typetree/compositenode.hh>
16 
17 #include <amdis/common/ConcurrentCache.hpp>
18 
19 namespace AMDiS
20 {
21  namespace Impl
22  {
23  template <class Node, class NodeTag = typename Node::NodeTag>
24  struct NodeCacheFactory;
25 
26  } // end namespace Impl
27 
28 
30  template <class Node>
31  using NodeCache_t = typename Impl::NodeCacheFactory<Node>::type;
32 
34  template <class Node>
35  auto makeNodeCache (Node const& node)
36  {
37  return NodeCache_t<Node>::create(node);
38  }
39 
40 
43  template <class NodeType>
45  {
46  public:
47  using Node = NodeType;
48  using Element = typename Node::Element;
49 
50  public:
51  // Store a reference to the node
52  NodeWrapper (Node const& node)
53  : node_(&node)
54  {}
55 
57  Node const& node () const
58  {
59  assert(node_ != nullptr);
60  return *node_;
61  }
62 
64  Element const& element () const
65  {
66  return node_->element();
67  }
68 
70  auto localIndex (std::size_t i) const
71  {
72  return node_->localIndex(i);
73  }
74 
76  auto size () const
77  {
78  return node_->size();
79  }
80 
82  auto treeIndex () const
83  {
84  return node_->treeIndex();
85  }
86 
87  protected:
88  Node const* node_ = nullptr;
89  };
90 
91 
93 
101  template <class Node>
103  : public Dune::TypeTree::LeafNode
104  , public NodeWrapper<Node>
105  {
106  public:
107  using BasisNode = Node;
108 
109  using FiniteElement = typename Node::FiniteElement;
110  using LocalBasis = typename FiniteElement::Traits::LocalBasisType;
111 
112  using ShapeValues = std::vector<typename LocalBasis::Traits::RangeType>;
113  using ShapeGradients = std::vector<typename LocalBasis::Traits::JacobianType>;
114 
115  private:
116  using DomainType = typename LocalBasis::Traits::DomainType;
117 
118  // Pair of GeometryType and local coordinates
119  struct CoordKey
120  {
121  unsigned int id; // topologyId
122  DomainType local; // local coordinate
123 
124  struct hasher
125  {
126  std::size_t operator()(CoordKey const& t) const
127  {
128  std::size_t seed = 0;
129  Dune::hash_combine(seed, t.id);
130  Dune::hash_range(seed, t.local.begin(), t.local.end());
131  return seed;
132  }
133  };
134 
135  friend bool operator==(CoordKey const& lhs, CoordKey const& rhs)
136  {
137  return std::tie(lhs.id,lhs.local) == std::tie(rhs.id,rhs.local);
138  }
139  };
140 
141  private:
142  // Constructor storing a reference to the passed basis-node
143  LeafNodeCache (Node const& basisNode)
144  : NodeWrapper<Node>(basisNode)
145  {}
146 
147  public:
149  static LeafNodeCache create (Node const& basisNode)
150  {
151  return {basisNode};
152  }
153 
155  FiniteElement const& finiteElement () const
156  {
157  return this->node_->finiteElement();
158  }
159 
161  ShapeValues const& localBasisValuesAt (DomainType const& local) const
162  {
163  CoordKey key{this->element().type().id(), local};
164  return shapeValues_.get(key, [&](CoordKey const&)
165  {
166  ShapeValues data;
167  this->localBasis().evaluateFunction(local, data);
168  return data;
169  });
170  }
171 
173  ShapeGradients const& localBasisJacobiansAt (DomainType const& local) const
174  {
175  CoordKey key{this->element().type().id(), local};
176  return shapeGradients_.get(key, [&](CoordKey const&)
177  {
178  ShapeGradients data;
179  this->localBasis().evaluateJacobian(local, data);
180  return data;
181  });
182  }
183 
184  private:
186  LocalBasis const& localBasis () const
187  {
188  return this->node_->finiteElement().localBasis();
189  }
190 
191  private:
192  template <class Value>
193  using CoordCache = ConcurrentCache<CoordKey, Value, ConsecutivePolicy,
194  std::unordered_map<CoordKey, Value, typename CoordKey::hasher>>;
195 
196  CoordCache<ShapeValues> shapeValues_;
197  CoordCache<ShapeGradients> shapeGradients_;
198  };
199 
200 
201  template <class Node>
203  : public Impl::NodeCacheFactory<Node>::Base
204  , public NodeWrapper<Node>
205  {
206  using Self = PowerNodeCache;
207  using Super = typename Impl::NodeCacheFactory<Node>::Base;
208 
209  private:
210  PowerNodeCache (Node const& basisNode)
211  : NodeWrapper<Node>(basisNode)
212  {}
213 
214  public:
216  static auto create (Node const& basisNode)
217  {
218  Self cache{basisNode};
219  for (std::size_t i = 0; i < Super::degree(); ++i)
220  cache.setChild(i, Super::ChildType::create(basisNode.child(i)));
221  return cache;
222  }
223  };
224 
225 
226  template <class Node>
228  : public Impl::NodeCacheFactory<Node>::Base
229  , public NodeWrapper<Node>
230  {
231  using Self = CompositeNodeCache;
232  using Super = typename Impl::NodeCacheFactory<Node>::Base;
233 
234  private:
235  CompositeNodeCache (Node const& basisNode)
236  : NodeWrapper<Node>(basisNode)
237  {}
238 
239  public:
241  static auto create (Node const& basisNode)
242  {
243  using TT = typename Super::ChildTypes;
244  Self cache{basisNode};
245  Dune::Hybrid::forEach(std::make_index_sequence<Super::degree()>{}, [&](auto ii) {
246  cache.setChild(std::tuple_element_t<ii,TT>::create(basisNode.child(ii)), ii);
247  });
248  return cache;
249  }
250  };
251 
252  namespace Impl
253  {
254  template <class Node>
255  struct NodeCacheFactory<Node, Dune::TypeTree::LeafNodeTag>
256  {
257  using Base = Dune::TypeTree::LeafNode;
258  using type = LeafNodeCache<Node>;
259  };
260 
261  template <class Node>
262  struct NodeCacheFactory<Node, Dune::TypeTree::PowerNodeTag>
263  {
264  using Child = typename NodeCacheFactory<typename Node::ChildType>::type;
265  using Base = Dune::TypeTree::PowerNode<Child, Node::degree()>;
266  using type = PowerNodeCache<Node>;
267  };
268 
269  template <class Node>
270  struct NodeCacheFactory<Node, Dune::TypeTree::CompositeNodeTag>
271  {
272  template <class Indices> struct Childs;
273  template <std::size_t... i>
274  struct Childs<std::index_sequence<i...>> {
275  using type = Dune::TypeTree::CompositeNode<
276  typename NodeCacheFactory<typename Node::template Child<i>::type>::type...
277  >;
278  };
279 
280  using Base = typename Childs<std::make_index_sequence<Node::degree()>>::type;
281  using type = CompositeNodeCache<Node>;
282  };
283 
284  } // end namespace Impl
285 
286 } // end namespace AMDiS
auto size() const
Return the size of the index-set of the node.
Definition: NodeCache.hpp:76
Node const & node() const
Return the stored basis-node.
Definition: NodeCache.hpp:57
Element const & element() const
Return the bound grid element.
Definition: NodeCache.hpp:64
The class template ConcurrentCache describes an associative static container that allows the concurre...
Definition: ConcurrentCache.hpp:53
Definition: NodeCache.hpp:44
auto makeNodeCache(Node const &node)
Construct a new local-basis cache from a basis-node.
Definition: NodeCache.hpp:35
static auto create(Node const &basisNode)
Construct a new composite node by setting each child individually.
Definition: NodeCache.hpp:241
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
ShapeGradients const & localBasisJacobiansAt(DomainType const &local) const
Evaluate local basis jacobians at local coordinates.
Definition: NodeCache.hpp:173
typename Impl::NodeCacheFactory< Node >::type NodeCache_t
Defines the type of a node cache associated to a given Node.
Definition: NodeCache.hpp:31
Definition: NodeCache.hpp:124
FiniteElement const & finiteElement() const
Return the local finite-element of the stored basis-node.
Definition: NodeCache.hpp:155
Definition: NodeCache.hpp:227
Store cache in instance.
Definition: ConcurrentCache.hpp:16
auto localIndex(std::size_t i) const
Return the index of the i-th local basis function in the index-set of the whole tree.
Definition: NodeCache.hpp:70
static auto create(Node const &basisNode)
Construct a new power node by setting each child individually.
Definition: NodeCache.hpp:216
Cache of LocalBasis evaluations and jacobians at local points.
Definition: NodeCache.hpp:102
Definition: NodeCache.hpp:202
ShapeValues const & localBasisValuesAt(DomainType const &local) const
Evaluate local basis functions at local coordinates.
Definition: NodeCache.hpp:161
static LeafNodeCache create(Node const &basisNode)
Construct a new local-basis cache.
Definition: NodeCache.hpp:149
auto treeIndex() const
Return a unique index within the tree.
Definition: NodeCache.hpp:82