7#ifndef DUNE_FUFEM_FORMS_SHAPEFUNCTIONCACHE_HH
8#define DUNE_FUFEM_FORMS_SHAPEFUNCTIONCACHE_HH
20#if DUNE_VERSION_GTE(DUNE_FUNCTIONS, 2, 11)
23#include <dune/typetree/treepath.hh>
31namespace Dune::Fufem::Forms::Impl {
33 template<
class C,
class... T>
34 static constexpr decltype(
auto) accessByTreePath(C&& container,
const Dune::Fufem::Impl::TreePath<T...>& path)
36 if constexpr (
sizeof...(T)==0)
39 return accessByTreePath(container[path.front()],
pop_front(path));
42 template<
class ReferenceJacobian,
class GeometryJacobianInverse>
43 struct GlobalJacobianTraits
45 using GeometryField =
typename GeometryJacobianInverse::field_type;
46 using ReferenceJacobianField =
typename ReferenceJacobian::field_type;
48 static constexpr int dimWorld = GeometryJacobianInverse::cols;
52 template<
class GeometryJacobianInverse,
class JF,
int dimRange,
int dim>
53 struct GlobalJacobianTraits<
Dune::FieldMatrix<JF, dimRange, dim>, GeometryJacobianInverse>
55 using GeometryField =
typename GeometryJacobianInverse::field_type;
56 using ReferenceJacobianField = JF;
58 static constexpr int dimWorld = GeometryJacobianInverse::cols;
106 template<
class Node,
class CT=
double,
class Dummy=
void>
111 template<
class Node,
class CT>
113 Dune::Fufem::Impl::Concept::LeafTreeNode<Node>
116 using GeometryJacobianInverse =
typename Node::Element::Geometry::JacobianInverse;
121 using FEValue =
typename Node::FiniteElement::Traits::LocalBasisType::Traits::RangeType;
122 using FEJacobian =
typename Node::FiniteElement::Traits::LocalBasisType::Traits::JacobianType;
123 using FEGlobalJacobian =
typename Impl::GlobalJacobianTraits<FEJacobian, GeometryJacobianInverse>::type;
141 ShapeFunctionCache(
const Node& node) :
147 ShapeFunctionCache(
const ShapeFunctionCache& other) =
default;
149 ShapeFunctionCache() =
default;
154 valueCache_.resize(rule_->size());
155 jacobianCache_.resize(rule_->size());
156 globalJacobianCache_.resize(rule_->size());
157 valueCache_[0].clear();
158 jacobianCache_[0].clear();
159 globalJacobianCache_[0].clear();
162 void setTree(
const Node& node)
172 const QuadratureRule& rule()
const
183 valueCache_[0].clear();
184 jacobianCache_[0].clear();
186 globalJacobianCache_[0].clear();
189 decltype(
auto)
operator[](
const Dune::Fufem::Impl::TreePath<>& treePath)
const
194 decltype(
auto)
operator[](
const Dune::Fufem::Impl::TreePath<>& treePath)
199 const auto& getValues()
201 if (valueCache_[0].
empty())
203 if (node_->size() == 0)
205 const auto& localBasis = node_->finiteElement().localBasis();
207 localBasis.evaluateFunction((*rule_)[k].position(), valueCache_[k]);
212 const auto& getJacobians()
214 if (jacobianCache_[0].
empty())
216 if (node_->size() == 0)
217 return jacobianCache_;
218 const auto& localBasis = node_->finiteElement().localBasis();
220 localBasis.evaluateJacobian((*rule_)[k].position(), jacobianCache_[k]);
222 return jacobianCache_;
225 const auto& getGlobalJacobians()
227 if (globalJacobianCache_[0].
empty())
229 if (node_->size() == 0)
230 return globalJacobianCache_;
231 const auto& geometry = node_->element().geometry();
232 const auto& jacobians = getJacobians();
235 globalJacobianCache_[k].resize(jacobians[k].
size());
236 const auto& jacobianInverse = geometry.jacobianInverse((*rule_)[k].position());
238 globalJacobianCache_[k][i] = jacobians[k][i] * jacobianInverse;
241 return globalJacobianCache_;
245 const QuadratureRule* rule_ =
nullptr;
246 const Node* node_ =
nullptr;
247 ValueCache valueCache_;
248 JacobianCache jacobianCache_;
249 GlobalJacobianCache globalJacobianCache_;
250 bool isNonAffine_ =
false;
255 template<
class Node,
class CT>
256 class ShapeFunctionCache<Node, CT,
std::enable_if_t<
257 Dune::Fufem::Impl::Concept::UniformInnerTreeNode<Node>
261 using ChildCache = ShapeFunctionCache<ChildNode, CT>;
266 ShapeFunctionCache(
const QuadratureRule& rule,
const Node& node) :
267 childCache_(rule, node.
child(0))
270 ShapeFunctionCache(
const QuadratureRule& rule) :
274 ShapeFunctionCache(
const Node& node) :
275 childCache_(node.
child(0))
278 ShapeFunctionCache(
const ShapeFunctionCache& other) =
default;
280 ShapeFunctionCache() =
default;
282 void setRule(
const QuadratureRule& rule)
284 childCache_.setRule(rule);
287 void setTree(
const Node& node)
289 childCache_.setTree(node.child(0));
294 childCache_.setNonAffine();
297 const QuadratureRule& rule()
const
299 return childCache_.rule();
304 childCache_.invalidate();
309 assert(i<Node::degree());
315 assert(i<Node::degree());
320 decltype(
auto)
operator[](
const Dune::Fufem::Impl::TreePath<T...>& treePath)
const
322 return Impl::accessByTreePath(*
this, treePath);
326 decltype(
auto)
operator[](
const Dune::Fufem::Impl::TreePath<T...>& treePath)
328 return Impl::accessByTreePath(*
this, treePath);
333 return Node::degree();
337 ChildCache childCache_;
344 template<
class List,
class CT>
345 struct TupleVectorOfShapeFunctionCaches
348 template<
class CT,
template<
class...>
class ListType,
class... Args>
349 struct TupleVectorOfShapeFunctionCaches<ListType<Args...>, CT>
354 template<
class List,
class CT>
355 using TupleVectorOfShapeFunctionCaches_t =
typename TupleVectorOfShapeFunctionCaches<List, CT>::type;
361 template<
class Node,
class CT>
362 class ShapeFunctionCache<Node, CT,
std::enable_if_t<
363 Dune::Fufem::Impl::Concept::StaticDegreeInnerTreeNode<Node>
364 and not Dune::Fufem::Impl::Concept::UniformInnerTreeNode<Node>
366 :
public Impl::TupleVectorOfShapeFunctionCaches_t<Dune::Fufem::Impl::Children<Node>, CT>
368 using Base = Impl::TupleVectorOfShapeFunctionCaches_t<Dune::Fufem::Impl::Children<Node>, CT>;
373 ShapeFunctionCache(
const QuadratureRule& rule,
const Node& node)
379 ShapeFunctionCache(
const QuadratureRule& rule)
384 ShapeFunctionCache(
const Node& node)
390 ShapeFunctionCache(
const ShapeFunctionCache& other) =
default;
392 ShapeFunctionCache() =
default;
394 void setRule(
const QuadratureRule& rule)
397 childCache.setRule(rule);
401 void setTree(
const Node& node)
404 (*this)[i].setTree(node.child(i));
411 (*this)[i].setNonAffine();
415 const QuadratureRule& rule()
const
420 using Base::operator[];
423 decltype(
auto)
operator[](
const Dune::Fufem::Impl::TreePath<T...>& treePath)
const
425 return Impl::accessByTreePath(*
this, treePath);
429 decltype(
auto)
operator[](
const Dune::Fufem::Impl::TreePath<T...>& treePath)
431 return Impl::accessByTreePath(*
this, treePath);
436 childCache.invalidate();
469 using CT =
typename Cache::QuadratureRule::CoordType;
470 constexpr static int dimension = Cache::QuadratureRule::d;
489 auto facet = key.second;
490 auto&& type = key.first.geometryType();
491 auto facetGeometryType = Dune::referenceElement<CT,dimension>(type).type(facet, 1);
492 auto facetQuadratureRuleKey = key.first;
493 facetQuadratureRuleKey.setGeometryType(facetGeometryType);
499 return facetQuadratureRules_.back();
504 Cache makeCache(
const Key& key)
506 auto cache = Cache(prototype_);
507 cache.setRule(getRule(key));
514 auto it = elementCacheMap_.find(key);
515 if (it == elementCacheMap_.end())
516 return (elementCacheMap_.insert(
std::make_pair(key, makeCache(key)))).first->second;
522 auto it = facetCacheMap_.find(facetKey);
523 if (it == facetCacheMap_.end())
524 return (facetCacheMap_.insert(
std::make_pair(facetKey, makeCache(facetKey)))).first->second;
537 elementCacheMap_.clear();
538 facetCacheMap_.clear();
539 facetQuadratureRules_.clear();
575 Base(&t,
std::type_index(typeid(T)))
613 template<
class CT,
int dimension>
623 class TypeErasedCache
628 void(*invalidate_)(
void*);
635 return members_.toRawPtr_(members_.impl_);
641 TypeErasedCache(Impl&& impl)
645 [](
void* impl) {
static_cast<Impl*
>(impl)->
invalidate(); },
648 , rawPtr_(toRawPtr())
651 TypeErasedCache(TypeErasedCache&& other)
652 : members_(std::move(other.members_))
653 , rawPtr_(toRawPtr())
656 TypeErasedCache(
const TypeErasedCache& other)
657 : members_(other.members_)
658 , rawPtr_(toRawPtr())
661 TypeErasedCache(TypeErasedCache& other)
662 : members_(other.members_)
663 , rawPtr_(toRawPtr())
668 members_.invalidate_(rawPtr_);
673 members_.setRule_(rawPtr_,
rule);
679 return *
static_cast<Impl*
>(rawPtr_);
752 template<
class Cache>
755 auto it = cacheIndex_.
find(uniqueCacheId);
756 if (it == cacheIndex_.
end())
759 cacheIndex_[uniqueCacheId] = caches_.
size()-1;
760 return caches_.
size()-1;
776 template<
class Cache>
779 return caches_[
index].template get<Cache>();
791 template<
class CT,
int dimension>
806 template<
class CT,
int dimension,
class V>
817 isNonAffine_(isNonAffine)
825 valueCache_.resize(rule_->size());
868 bool isEmpty_ =
true;
869 bool isNonAffine_ =
false;
This header provides fallback implementations for dune-typetree<2.11.
reference operator[](size_type i)
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
constexpr void forEach(Range &&range, F &&f)
std::ptrdiff_t index() const
decltype(auto) child(Node &&node, TreePath< Indices... > treePath)
typename Impl::ChildTraits< Node, indices... >::type Child
constexpr auto get(std::integer_sequence< T, II... >, std::integral_constant< std::size_t, pos >={})
constexpr index_constant< 0 > _0
Definition baseclass.hh:22
decltype(std::declval< T1 >()+std::declval< T2 >()) PromotedType
A hierarchic cache for storing shape function evaluations for a tree.
Definition shapefunctioncache.hh:107
A cache providing multiple versions for different quadrature rules.
Definition shapefunctioncache.hh:467
Cache & operator[](const QuadratureRuleKey &key)
Definition shapefunctioncache.hh:513
Cache & operator[](const FacetKey &facetKey)
Definition shapefunctioncache.hh:521
void clear()
Definition shapefunctioncache.hh:534
Cache & prototype()
Definition shapefunctioncache.hh:529
Objects of this class are used to uniquely identifies a cache.
Definition shapefunctioncache.hh:569
UniqueCacheId(const T &t)
Definition shapefunctioncache.hh:574
A class for managing caches of different types.
Definition shapefunctioncache.hh:615
auto & getCache(size_type index)
Obtain a registered cache.
Definition shapefunctioncache.hh:777
CacheManager(const CacheManager &other)=default
void invalidate()
Invalidate all stores caches.
Definition shapefunctioncache.hh:727
CacheManager & operator=(const CacheManager &)=delete
size_type registerCache(UniqueCacheId uniqueCacheId, Cache &&cache)
Register a new cache.
Definition shapefunctioncache.hh:753
void report() const
Definition shapefunctioncache.hh:734
void setRule(const QuadratureRule &rule)
Set the associated quadrature rule for all stored caches.
Definition shapefunctioncache.hh:717
CacheManager(CacheManager &&other)=default
const QuadratureRule & rule() const
Obtain the associated quadrature rule.
Definition shapefunctioncache.hh:709
void clear()
Clear all stored data.
Definition shapefunctioncache.hh:699
A simple cache implementation storing values.
Definition shapefunctioncache.hh:808
auto & getValues()
Definition shapefunctioncache.hh:855
SimpleCache(bool isNonAffine)
Definition shapefunctioncache.hh:816
bool isEmpty()
Definition shapefunctioncache.hh:845
void setEmpty(bool isEmpty)
Definition shapefunctioncache.hh:850
V Value
Definition shapefunctioncache.hh:813
void invalidate()
Definition shapefunctioncache.hh:839
void setNonAffine()
Definition shapefunctioncache.hh:834
const QuadratureRule & rule() const
Definition shapefunctioncache.hh:829
void setRule(const QuadratureRule &rule)
Definition shapefunctioncache.hh:822
SimpleCache(const SimpleCache &other)=default
const auto & getValues() const
Definition shapefunctioncache.hh:860
typename std::vector< Value > ValueCache
Definition shapefunctioncache.hh:814
A token that specifies a quadrature rule.
Definition quadraturerulecache.hh:39
Definition quadraturerulecache.hh:190
static const Dune::QuadratureRule< coord_type, dim > & rule(const Dune::GeometryType >, const int order, int refinement)
Definition quadraturerulecache.hh:196
Quadrature rule for a subentity of some given geometry type.
Definition subentityquadraturerule.hh:31