7#include <dune/common/ftraits.hh>
8#include <dune/common/hash.hh>
9#include <dune/common/indices.hh>
11#include <dune/geometry/type.hh>
13#include <dune/typetree/leafnode.hh>
14#include <dune/typetree/powernode.hh>
15#include <dune/typetree/compositenode.hh>
17#include <amdis/common/ConcurrentCache.hpp>
23 template <
class Node,
class NodeTag =
typename Node::NodeTag>
24 struct NodeCacheFactory;
31 using NodeCache_t =
typename Impl::NodeCacheFactory<Node>::type;
35 auto makeNodeCache (Node
const& node)
37 return NodeCache_t<Node>::create(node);
43 template <
class NodeType>
47 using Node = NodeType;
48 using Element =
typename Node::Element;
59 assert(node_ !=
nullptr);
66 return node_->element();
72 return node_->localIndex(i);
84 return node_->treeIndex();
88 Node
const* node_ =
nullptr;
101 template <
class Node>
103 :
public Dune::TypeTree::LeafNode
107 using BasisNode = Node;
109 using FiniteElement =
typename Node::FiniteElement;
110 using LocalBasis =
typename FiniteElement::Traits::LocalBasisType;
112 using ShapeValues = std::vector<typename LocalBasis::Traits::RangeType>;
113 using ShapeGradients = std::vector<typename LocalBasis::Traits::JacobianType>;
116 using DomainType =
typename LocalBasis::Traits::DomainType;
126 std::size_t operator()(CoordKey
const& t)
const
128 std::size_t seed = 0;
129 Dune::hash_combine(seed, t.id);
130 Dune::hash_range(seed, t.local.begin(), t.local.end());
135 friend bool operator==(CoordKey
const& lhs, CoordKey
const& rhs)
137 return std::tie(lhs.id,lhs.local) == std::tie(rhs.id,rhs.local);
157 return this->node_->finiteElement();
163 CoordKey key{this->
element().type().id(), local};
164 return shapeValues_.get(key, [&](CoordKey
const&)
167 this->localBasis().evaluateFunction(local, data);
175 CoordKey key{this->
element().type().id(), local};
176 return shapeGradients_.get(key, [&](CoordKey
const&)
179 this->localBasis().evaluateJacobian(local, data);
186 LocalBasis
const& localBasis ()
const
188 return this->node_->finiteElement().localBasis();
192 template <
class Value>
193 using CoordCache = ConcurrentCache<CoordKey, Value, ConsecutivePolicy,
194 std::unordered_map<CoordKey, Value, typename CoordKey::hasher>>;
196 CoordCache<ShapeValues> shapeValues_;
197 CoordCache<ShapeGradients> shapeGradients_;
201 template <
class Node>
203 :
public Impl::NodeCacheFactory<Node>::Base
207 using Super =
typename Impl::NodeCacheFactory<Node>::Base;
216 static auto create (Node
const& basisNode)
218 Self cache{basisNode};
219 for (std::size_t i = 0; i < std::size_t(basisNode.degree()); ++i)
220 cache.setChild(i, Super::ChildType::create(basisNode.child(i)));
226 template <
class Node>
228 :
public Impl::NodeCacheFactory<Node>::Base
232 using Super =
typename Impl::NodeCacheFactory<Node>::Base;
241 static auto create (Node
const& basisNode)
243 using TT =
typename Super::ChildTypes;
244 Self cache{basisNode};
245 Dune::Hybrid::forEach(std::make_index_sequence<std::size_t(Node::degree())>{}, [&](
auto ii) {
246 cache.setChild(std::tuple_element_t<ii,TT>::create(basisNode.child(ii)), ii);
254 template <
class Node>
255 struct NodeCacheFactory<Node, Dune::TypeTree::LeafNodeTag>
257 using Base = Dune::TypeTree::LeafNode;
258 using type = LeafNodeCache<Node>;
261 template <
class Node>
262 struct NodeCacheFactory<Node, Dune::TypeTree::PowerNodeTag>
264 using Child =
typename NodeCacheFactory<typename Node::ChildType>::type;
265 using Base = Dune::TypeTree::PowerNode<Child, std::size_t(Node::degree())>;
266 using type = PowerNodeCache<Node>;
269 template <
class Node>
270 struct NodeCacheFactory<Node, Dune::TypeTree::CompositeNodeTag>
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...
280 using Base =
typename Childs<std::make_index_sequence<std::size_t(Node::degree())>>::type;
281 using type = CompositeNodeCache<Node>;
Definition: NodeCache.hpp:230
static auto create(Node const &basisNode)
Construct a new composite node by setting each child individually.
Definition: NodeCache.hpp:241
Cache of LocalBasis evaluations and jacobians at local points.
Definition: NodeCache.hpp:105
static LeafNodeCache create(Node const &basisNode)
Construct a new local-basis cache.
Definition: NodeCache.hpp:149
FiniteElement const & finiteElement() const
Return the local finite-element of the stored basis-node.
Definition: NodeCache.hpp:155
ShapeValues const & localBasisValuesAt(DomainType const &local) const
Evaluate local basis functions at local coordinates.
Definition: NodeCache.hpp:161
ShapeGradients const & localBasisJacobiansAt(DomainType const &local) const
Evaluate local basis jacobians at local coordinates.
Definition: NodeCache.hpp:173
Wrapper around a basis-node storing just a pointer and providing some essential functionality like si...
Definition: NodeCache.hpp:45
NodeWrapper(Node const &node)
Store a reference to the node.
Definition: NodeCache.hpp:52
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
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
auto treeIndex() const
Return a unique index within the tree.
Definition: NodeCache.hpp:82
Definition: NodeCache.hpp:205
static auto create(Node const &basisNode)
Construct a new power node by setting each child individually.
Definition: NodeCache.hpp:216
Definition: NodeCache.hpp:125