KASKADE 7 development version
quadrature.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2014-2019 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
14#ifndef QUADRATURE_HH
15#define QUADRATURE_HH
16
17#include <map>
18#include <mutex>
19
20#include "dune/geometry/quadraturerules.hh"
21
23
24namespace Kaskade
25{
33 template <class QuadRule>
35 {
36 typedef QuadRule Rule;
37
38 static Rule const& rule(const Dune::GeometryType& t, int p)
39 {
40 return instance().rl;
41 }
42
43 private:
44 static QuadratureTraits& instance()
45 {
46 static QuadratureTraits instance;
47 return instance;
48 }
49
50 QuadRule const rl;
51 };
52
62 template<class ctype, int dim>
63 struct QuadratureTraits<Dune::QuadratureRule<ctype, dim>>
64 {
66
67 QuadratureTraits(): cacheP(-1), cacheRule(nullptr)
68 {
69 }
70
76 Rule const& rule(Dune::GeometryType const& t, int p)
77 {
78 // The higher performance is based
79 // (i) caching the previous rule
80 // (ii) using smaller std::maps by one map for each order (results in fewer comparisons if multiple orders are used)
81 // (iii) avoiding the dumb double look-up done in Dune
82 // (iv) using one cache per thread in order to avoid locking (which is necessary for the Dune::QuadratureRules singleton)
83
84 assert(p>=0);
85
86 // Check if the previously returned rule satisfies the needs (this is a frequent case)
87 if (p==cacheP && t==cacheT)
88 {
89 return *cacheRule;
90 }
91
92 // Not immediately available - look for the wanted rule
93 if (p<=pmax)
94 {
95 // Low order rule - look in the specialized maps
96 typename DirectMap::const_iterator i = rules[p].find(t);
97 if (i == rules[p].end())
98 {
99 // Rule is not yet in our own map - fetch from Dune and remember here.
100 // Remember to acquire a lock, as the Dune factory is not thread-safe.
101 std::lock_guard<std::mutex> lock(Kaskade::DuneQuadratureRulesMutex);
102 cacheRule = &Dune::QuadratureRules<ctype, dim>::rule(t,p);
103 rules[p][t] = cacheRule;
104 }
105 else
106 cacheRule = i->second;
107 }
108 else
109 {
110 // High order rule - look in the fallback map
111 typename OverspillMap::const_iterator i = ruleOverspill.find(std::make_pair(t,p));
112 if (i==ruleOverspill.end())
113 {
114 // Rule is not yet in our own map - fetch from Dune and remember here
115 // Remember to acquire a lock, as the Dune factory is not thread-safe.
116 std::lock_guard<std::mutex> lock(Kaskade::DuneQuadratureRulesMutex);
117 cacheRule = &Dune::QuadratureRules<ctype, dim>::rule(t,p);
118 ruleOverspill[std::make_pair(t,p)] = cacheRule;
119 }
120 else
121 cacheRule = i->second;
122 }
123
124 // cache the result
125 cacheT = t;
126 cacheP = p;
127
128 return *cacheRule;
129 }
130
131 private:
132 static int const pmax = 8;
133
134 // One would assume that due to frequent lookup and rare insertion, a boost::container::flat_map would
135 // provide better performance. However, this appears not to be the case.
136 //typedef boost::container::flat_map<Dune::GeometryType,Rule const*> DirectMap;
137 //typedef boost::container::flat_map<std::pair<Dune::GeometryType,int>,Rule const*> OverspillMap;
138 typedef std::map<Dune::GeometryType,Rule const*> DirectMap;
139 typedef std::map<std::pair<Dune::GeometryType,int>,Rule const*> OverspillMap;
140 DirectMap rules[pmax+1];
141 OverspillMap ruleOverspill;
142
143 Dune::GeometryType cacheT;
144 int cacheP;
145 Rule const* cacheRule;
146 };
147
148
149}
150
151#endif
std::mutex DuneQuadratureRulesMutex
A global lock for the Dune::QuadratureRules factory, which is not thread-safe as of 2015-01-01.
Rule const & rule(Dune::GeometryType const &t, int p)
Returns a quadrature rule for the given geometry type and integration order.
Definition: quadrature.hh:76
A cache that stores suitable quadrature rules for quick retrieval.
Definition: quadrature.hh:35
static Rule const & rule(const Dune::GeometryType &t, int p)
Definition: quadrature.hh:38