AMDiS 2.11-git
The Adaptive Multi-Dimensional Simulation Toolbox
 
Loading...
Searching...
No Matches
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#include <dune/common/typetree/childaccess.hh>
11
12#include <dune/geometry/type.hh>
13
14#include <dune/typetree/compositenode.hh>
15#include <dune/typetree/dynamicpowernode.hh>
16#include <dune/typetree/leafnode.hh>
17#include <dune/typetree/powernode.hh>
18
19#include <amdis/common/ConcurrentCache.hpp>
20#include <amdis/typetree/NodeTags.hpp>
21
22namespace AMDiS
23{
24 namespace Impl
25 {
26 template <class Node, class NodeTag = AMDiS::NodeTag_t<Node>>
27 struct NodeCacheFactory;
28
29 } // end namespace Impl
30
31
33 template <class Node>
34 using NodeCache_t = typename Impl::NodeCacheFactory<Node>::type;
35
37 template <class Node>
38 auto makeNodeCache (Node const& node)
39 {
40 return NodeCache_t<Node>::create(node);
41 }
42
43
46 template <class NodeType>
48 {
49 public:
50 using Node = NodeType;
51 using Element = typename Node::Element;
52
53 public:
55 NodeWrapper (Node const& node)
56 : node_(&node)
57 {}
58
60 Node const& node () const
61 {
62 assert(node_ != nullptr);
63 return *node_;
64 }
65
67 Element const& element () const
68 {
69 return node_->element();
70 }
71
73 auto localIndex (std::size_t i) const
74 {
75 return node_->localIndex(i);
76 }
77
79 auto size () const
80 {
81 return node_->size();
82 }
83
85 auto treeIndex () const
86 {
87 return node_->treeIndex();
88 }
89
90 protected:
91 Node const* node_ = nullptr;
92 };
93
94
96
104 template <class Node>
106 : public Dune::TypeTree::LeafNode
107 , public NodeWrapper<Node>
108 {
109 public:
110 using BasisNode = Node;
111
112 using FiniteElement = typename Node::FiniteElement;
113 using LocalBasis = typename FiniteElement::Traits::LocalBasisType;
114
115 using ShapeValues = std::vector<typename LocalBasis::Traits::RangeType>;
116 using ShapeGradients = std::vector<typename LocalBasis::Traits::JacobianType>;
117
118 private:
119 using DomainType = typename LocalBasis::Traits::DomainType;
120
121 // Pair of GeometryType and local coordinates
122 struct CoordKey
123 {
124 unsigned int id; // topologyId
125 DomainType local; // local coordinate
126
127 struct hasher
128 {
129 std::size_t operator()(CoordKey const& t) const
130 {
131 std::size_t seed = 0;
132 Dune::hash_combine(seed, t.id);
133 Dune::hash_range(seed, t.local.begin(), t.local.end());
134 return seed;
135 }
136 };
137
138 friend bool operator==(CoordKey const& lhs, CoordKey const& rhs)
139 {
140 return std::tie(lhs.id,lhs.local) == std::tie(rhs.id,rhs.local);
141 }
142 };
143
144 private:
145 // Constructor storing a reference to the passed basis-node
146 LeafNodeCache (Node const& basisNode)
147 : NodeWrapper<Node>(basisNode)
148 {}
149
150 public:
152 static LeafNodeCache create (Node const& basisNode)
153 {
154 return {basisNode};
155 }
156
158 FiniteElement const& finiteElement () const
159 {
160 return this->node_->finiteElement();
161 }
162
164 ShapeValues const& localBasisValuesAt (DomainType const& local) const
165 {
166 CoordKey key{this->element().type().id(), local};
167 return shapeValues_.get(key, [&](CoordKey const&)
168 {
169 ShapeValues data;
170 this->localBasis().evaluateFunction(local, data);
171 return data;
172 });
173 }
174
176 ShapeGradients const& localBasisJacobiansAt (DomainType const& local) const
177 {
178 CoordKey key{this->element().type().id(), local};
179 return shapeGradients_.get(key, [&](CoordKey const&)
180 {
181 ShapeGradients data;
182 this->localBasis().evaluateJacobian(local, data);
183 return data;
184 });
185 }
186
187 private:
189 LocalBasis const& localBasis () const
190 {
191 return this->node_->finiteElement().localBasis();
192 }
193
194 private:
195 template <class Value>
196 using CoordCache = ConcurrentCache<CoordKey, Value, ConsecutivePolicy,
197 std::unordered_map<CoordKey, Value, typename CoordKey::hasher>>;
198
199 CoordCache<ShapeValues> shapeValues_;
200 CoordCache<ShapeGradients> shapeGradients_;
201 };
202
203
204 template <class Node>
206 : public Impl::NodeCacheFactory<Node>::Base
207 , public NodeWrapper<Node>
208 {
209 using Self = PowerNodeCache;
210 using Super = typename Impl::NodeCacheFactory<Node>::Base;
211
212 private:
213 PowerNodeCache (Node const& basisNode)
214 : NodeWrapper<Node>(basisNode)
215 {}
216
217 public:
219 static auto create (Node const& basisNode)
220 {
221 Self cache{basisNode};
222 for (std::size_t i = 0; i < std::size_t(basisNode.degree()); ++i)
223 cache.setChild(i, Dune::TypeTree::Child<Super,0>::create(basisNode.child(i)));
224 return cache;
225 }
226 };
227
228
229 template <class Node>
231 : public Impl::NodeCacheFactory<Node>::Base
232 , public NodeWrapper<Node>
233 {
235 using Super = typename Impl::NodeCacheFactory<Node>::Base;
236
237 private:
238 DynamicPowerNodeCache (Node const& basisNode)
239 : Super(basisNode.degree())
240 , NodeWrapper<Node>(basisNode)
241 {}
242
243 public:
245 static auto create (Node const& basisNode)
246 {
247 Self cache{basisNode};
248 for (std::size_t i = 0; i < std::size_t(basisNode.degree()); ++i)
249 cache.setChild(i, Dune::TypeTree::Child<Super,0>::create(basisNode.child(i)));
250 return cache;
251 }
252 };
253
254
255 template <class Node>
257 : public Impl::NodeCacheFactory<Node>::Base
258 , public NodeWrapper<Node>
259 {
260 using Self = CompositeNodeCache;
261 using Super = typename Impl::NodeCacheFactory<Node>::Base;
262
263 private:
264 CompositeNodeCache (Node const& basisNode)
265 : NodeWrapper<Node>(basisNode)
266 {}
267
268 public:
270 static auto create (Node const& basisNode)
271 {
272 Self cache{basisNode};
273 Dune::Hybrid::forEach(std::make_index_sequence<std::size_t(Node::degree())>{}, [&](auto ii) {
274 cache.setChild(Dune::TypeTree::Child<Super,ii>::create(basisNode.child(ii)), ii);
275 });
276 return cache;
277 }
278 };
279
280 namespace Impl
281 {
282 template <class Node>
283 struct NodeCacheFactory<Node, AMDiS::LeafNodeTag>
284 {
285 using Base = Dune::TypeTree::LeafNode;
286 using type = LeafNodeCache<Node>;
287 };
288
289 template <class Node>
290 struct NodeCacheFactory<Node, AMDiS::PowerNodeTag>
291 {
292 using Child = typename NodeCacheFactory<Dune::TypeTree::Child<Node,0>>::type;
293 using Base = Dune::TypeTree::PowerNode<Child, std::size_t(Node::degree())>;
294 using type = PowerNodeCache<Node>;
295 };
296
297 template <class Node>
298 struct NodeCacheFactory<Node, AMDiS::DynamicPowerNodeTag>
299 {
300 using Child = typename NodeCacheFactory<Dune::TypeTree::Child<Node,0>>::type;
301 using Base = Dune::TypeTree::DynamicPowerNode<Child>;
302 using type = DynamicPowerNodeCache<Node>;
303 };
304
305 template <class Node>
306 struct NodeCacheFactory<Node, AMDiS::CompositeNodeTag>
307 {
308 template <class Indices> struct Childs;
309 template <std::size_t... i>
310 struct Childs<std::index_sequence<i...>> {
311 using type = Dune::TypeTree::CompositeNode<
312 typename NodeCacheFactory<Dune::TypeTree::Child<Node,i>>::type...
313 >;
314 };
315
316 using Base = typename Childs<std::make_index_sequence<std::size_t(Node::degree())>>::type;
317 using type = CompositeNodeCache<Node>;
318 };
319
320 } // end namespace Impl
321
322} // end namespace AMDiS
Definition NodeCache.hpp:259
static auto create(Node const &basisNode)
Construct a new composite node by setting each child individually.
Definition NodeCache.hpp:270
Definition NodeCache.hpp:233
static auto create(Node const &basisNode)
Construct a new power node by setting each child individually.
Definition NodeCache.hpp:245
Cache of LocalBasis evaluations and jacobians at local points.
Definition NodeCache.hpp:108
static LeafNodeCache create(Node const &basisNode)
Construct a new local-basis cache.
Definition NodeCache.hpp:152
FiniteElement const & finiteElement() const
Return the local finite-element of the stored basis-node.
Definition NodeCache.hpp:158
ShapeValues const & localBasisValuesAt(DomainType const &local) const
Evaluate local basis functions at local coordinates.
Definition NodeCache.hpp:164
ShapeGradients const & localBasisJacobiansAt(DomainType const &local) const
Evaluate local basis jacobians at local coordinates.
Definition NodeCache.hpp:176
Wrapper around a basis-node storing just a pointer and providing some essential functionality like si...
Definition NodeCache.hpp:48
NodeWrapper(Node const &node)
Store a reference to the node.
Definition NodeCache.hpp:55
auto size() const
Return the size of the index-set of the node.
Definition NodeCache.hpp:79
Node const & node() const
Return the stored basis-node.
Definition NodeCache.hpp:60
Element const & element() const
Return the bound grid element.
Definition NodeCache.hpp:67
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:73
auto treeIndex() const
Return a unique index within the tree.
Definition NodeCache.hpp:85
Definition NodeCache.hpp:208
static auto create(Node const &basisNode)
Construct a new power node by setting each child individually.
Definition NodeCache.hpp:219
Definition NodeCache.hpp:128