dune-fem  2.4.1-rc
caching.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_SPACE_SHAPEFUNCTIONSET_CACHING_HH
2 #define DUNE_FEM_SPACE_SHAPEFUNCTIONSET_CACHING_HH
3 
4 // C++ includes
5 #include <cstddef>
6 #include <vector>
7 #include <type_traits>
8 
9 // dune-fem includes
10 #include <dune/fem/misc/functor.hh>
15 
16 namespace Dune
17 {
18 
19  namespace Fem
20  {
21 
22  // CachingShapeFunctionSet
23  // -----------------------
24 
25  template< class ShapeFunctionSet >
28  {
30 
31  public:
33 
38 
39  typedef std::vector< RangeType > RangeVectorType ;
40  typedef std::vector< JacobianRangeType > JacobianRangeVectorType ;
41 
42  typedef std::vector< RangeVectorType > ValueCacheVectorType;
43  typedef std::vector< JacobianRangeVectorType > JacobianCacheVectorType;
44 
45  explicit CachingShapeFunctionSet ( const GeometryType &type,
46  const ShapeFunctionSet &shapeFunctionSet = ShapeFunctionSet() )
47  : type_( type ),
48  shapeFunctionSet_( shapeFunctionSet ),
49  localRangeCache_(),
50  localJacobianCache_()
51  {
53  }
54 
56  CachingShapeFunctionSet ( const ThisType& ) = delete;
57  const ThisType& operator= ( const ThisType& ) = delete;
58 
59  int order () const
60  {
61  return shapeFunctionSet_.order();
62  }
63 
64  std::size_t size () const
65  {
66  return shapeFunctionSet_.size();
67  }
68 
69  template< class Point, class Functor >
70  void evaluateEach ( const Point &x, Functor functor ) const
71  {
72  return shapeFunctionSet_.evaluateEach( x, functor );
73  }
74 
75  template< class Quadrature, class Functor >
76  void evaluateEach ( const QuadraturePointWrapper< Quadrature > &x, Functor functor ) const
77  {
78  const bool cacheable = std::is_convertible< Quadrature, CachingInterface >::value;
79  evaluateEach( x.quadrature(), x.point(), functor, std::integral_constant< bool, cacheable >() );
80  }
81 
82  template< class Point, class Functor >
83  void jacobianEach ( const Point &x, Functor functor ) const
84  {
85  return shapeFunctionSet_.jacobianEach( x, functor );
86  }
87 
88  template< class Quadrature, class Functor >
89  void jacobianEach ( const QuadraturePointWrapper< Quadrature > &x, Functor functor ) const
90  {
91  const bool cacheable = std::is_convertible< Quadrature, CachingInterface >::value;
92  jacobianEach( x.quadrature(), x.point(), functor, std::integral_constant< bool, cacheable >() );
93  }
94 
95  template< class Point, class Functor >
96  void hessianEach ( const Point &x, Functor functor ) const
97  {
98  return shapeFunctionSet_.hessianEach( x, functor );
99  }
100 
101  GeometryType type () const { return type_; }
102 
103  template < class QuadratureType >
104  const RangeVectorType& rangeCache( const QuadratureType& quadrature ) const
105  {
106  return ReturnCache< QuadratureType, std::is_convertible< QuadratureType, CachingInterface >::value > ::
107  ranges( *this, quadrature, valueCaches_, *localRangeCache_ );
108  }
109 
110  template < class QuadratureType >
111  const JacobianRangeVectorType& jacobianCache( const QuadratureType& quadrature ) const
112  {
113  return ReturnCache< QuadratureType, std::is_convertible< QuadratureType, CachingInterface >::value > ::
114  jacobians( *this, quadrature, jacobianCaches_, *localJacobianCache_ );
115  }
116 
117  private:
118  template< class Quad, bool cacheable >
119  struct ReturnCache
120  {
121  static const RangeVectorType&
122  ranges( const ThisType& shapeFunctionSet,
123  const Quad& quad,
124  const ValueCacheVectorType&,
125  RangeVectorType& storage )
126  {
127  // evaluate all basis functions and multiply with dof value
128  const unsigned int nop = quad.nop();
129  const unsigned int size = shapeFunctionSet.size();
130 
131  // make sure cache has the appropriate size
132  storage.resize( size * nop );
133  RangeType* data = storage.data();
134 
135  for( unsigned int qp = 0 ; qp < nop; ++ qp )
136  {
137  const int cacheQp = quad.cachingPoint( qp );
138  AssignFunctor< RangeType* > funztor( data + (cacheQp * size) );
139  shapeFunctionSet.evaluateEach( quad[ qp ], funztor );
140  }
141  return storage;
142  }
143 
144  static const JacobianRangeVectorType&
145  jacobians( const ThisType& shapeFunctionSet,
146  const Quad& quad,
147  const JacobianCacheVectorType&,
148  JacobianRangeVectorType& storage )
149  {
150  // evaluate all basis functions and multiply with dof value
151  const unsigned int nop = quad.nop();
152  const unsigned int size = shapeFunctionSet.size();
153 
154  // make sure cache has the appropriate size
155  storage.resize( size * nop );
156  JacobianRangeType* data = storage.data();
157 
158  for( unsigned int qp = 0 ; qp < nop; ++ qp )
159  {
160  const int cacheQp = quad.cachingPoint( qp );
161  AssignFunctor< JacobianRangeType* > funztor( data + ( cacheQp * size ) );
162  shapeFunctionSet.jacobianEach( quad[ qp ], funztor );
163  }
164  return storage;
165  }
166  };
167 
168  template< class Quad >
169  struct ReturnCache< Quad, true >
170  {
171  static const RangeVectorType&
172  ranges( const ThisType& shapeFunctionSet,
173  const Quad& quad,
174  const ValueCacheVectorType& cache,
175  const RangeVectorType& )
176  {
177  return cache[ quad.id() ];
178  }
179 
180  static const JacobianRangeVectorType&
181  jacobians( const ThisType& shapeFunctionSet,
182  const Quad& quad,
183  const JacobianCacheVectorType& cache,
184  const JacobianRangeVectorType& )
185  {
186  return cache[ quad.id() ];
187  }
188  };
189 
190 
191  template< class Quadrature, class Functor >
192  void evaluateEach ( const Quadrature &quadrature, std::size_t pt, Functor functor,
193  std::integral_constant< bool, false > ) const
194  {
195  evaluateEach( quadrature.point( pt ), functor );
196  }
197 
198  template< class Quadrature, class Functor >
199  void evaluateEach ( const Quadrature &quadrature, std::size_t pt, Functor functor,
200  std::integral_constant< bool, true > ) const;
201 
202  template< class Quadrature, class Functor >
203  void jacobianEach ( const Quadrature &quadrature, std::size_t pt, Functor functor,
204  std::integral_constant< bool, false > ) const
205  {
206  jacobianEach( quadrature.point( pt ), functor );
207  }
208 
209  template< class Quadrature, class Functor >
210  void jacobianEach ( const Quadrature &quadrature, std::size_t pt, Functor functor,
211  std::integral_constant< bool, true > ) const;
212 
213 
214  void cacheQuadrature( std::size_t id, std::size_t codim, std::size_t size );
215 
216  template< class PointVector >
217  void cachePoints ( std::size_t id, const PointVector &points );
218 
219  GeometryType type_;
220  ShapeFunctionSet shapeFunctionSet_;
221  ValueCacheVectorType valueCaches_;
222  JacobianCacheVectorType jacobianCaches_;
223 
224  // local caches are used when a quadrature that is not a caching quadrature
225  // is used and the cache is requested by the autogenerated axpy methods
226  // in shared memory runs these might be accessed by different threads at
227  // the same time
228  mutable ThreadSafeValue< RangeVectorType > localRangeCache_ ;
229  mutable ThreadSafeValue< JacobianRangeVectorType > localJacobianCache_;
230  };
231 
232 
233 
234  // Implementation of CachingShapeFunctionSet
235  // -----------------------------------------
236 
237  template< class ShapeFunctionSet >
239  {
241  }
242 
243 
244  template< class ShapeFunctionSet >
245  template< class Quadrature, class Functor >
247  ::evaluateEach ( const Quadrature &quadrature, std::size_t pt, Functor functor,
248  std::integral_constant< bool, true > ) const
249  {
250  assert( (quadrature.id() < valueCaches_.size()) && !valueCaches_[ quadrature.id() ].empty() );
251  const RangeType *cache = valueCaches_[ quadrature.id() ].data();
252 
253  const unsigned int numShapeFunctions = size();
254  const unsigned int cpt = quadrature.cachingPoint( pt );
255  for( unsigned int i = 0; i < numShapeFunctions; ++i )
256  functor( i, cache[ cpt*numShapeFunctions + i ] );
257  }
258 
259 
260  template< class ShapeFunctionSet >
261  template< class Quadrature, class Functor >
263  ::jacobianEach ( const Quadrature &quadrature, std::size_t pt, Functor functor,
264  std::integral_constant< bool, true > ) const
265  {
266  assert( (quadrature.id() < jacobianCaches_.size()) && !jacobianCaches_[ quadrature.id() ].empty() );
267  const JacobianRangeType *cache = jacobianCaches_[ quadrature.id() ].data();
268 
269  const unsigned int numShapeFunctions = size();
270  const unsigned int cpt = quadrature.cachingPoint( pt );
271  for( unsigned int i = 0; i < numShapeFunctions; ++i )
272  functor( i, cache[ cpt*numShapeFunctions + i ] );
273  }
274 
275 
276  template< class ShapeFunctionSet >
278  ::cacheQuadrature( std::size_t id, std::size_t codim, std::size_t size )
279  {
280  if( id >= valueCaches_.size() )
281  {
282  valueCaches_.resize( id+1, RangeVectorType() );
283  jacobianCaches_.resize( id+1, JacobianRangeVectorType() );
284  }
285 
286  assert( valueCaches_[ id ].empty() == jacobianCaches_[ id ].empty() );
287 
288  if( valueCaches_[ id ].empty() )
289  {
290  typedef typename FunctionSpaceType::DomainFieldType ctype;
291  const int dim = FunctionSpaceType::dimDomain;
292  switch( codim )
293  {
294  case 0:
295  cachePoints( id, PointProvider< ctype, dim, 0 >::getPoints( id, type_ ) );
296  break;
297 
298  case 1:
299  cachePoints( id, PointProvider< ctype, dim, 1 >::getPoints( id, type_ ) );
300  break;
301 
302  default:
303  DUNE_THROW( NotImplemented, "Caching for codim > 1 not implemented." );
304  }
305  }
306  }
307 
308 
309  template< class ShapeFunctionSet >
310  template< class PointVector >
312  ::cachePoints ( std::size_t id, const PointVector &points )
313  {
314  const unsigned int numShapeFunctions = size();
315  const unsigned int numPoints = points.size();
316 
317  RangeVectorType& values = valueCaches_[ id ];
318  values.resize( numShapeFunctions * numPoints );
319 
320  JacobianRangeVectorType& jacobians = jacobianCaches_[ id ];
321  jacobians.resize( numShapeFunctions * numPoints );
322 
323  if( values.empty() || jacobians.empty() )
324  DUNE_THROW( OutOfMemoryError, "Unable to allocate shape function set caches." );
325 
326  for( unsigned int pt = 0; pt < numPoints; ++pt )
327  {
328  evaluateEach( points[ pt ], AssignFunctor< RangeType * >( values.data() + pt*numShapeFunctions ) );
329  jacobianEach( points[ pt ], AssignFunctor< JacobianRangeType * >( jacobians.data() + pt*numShapeFunctions ) );
330  }
331  }
332 
333  } // namespace Fem
334 
335 } // namespace Dune
336 
337 #endif // #ifndef DUNE_FEM_SPACE_SHAPEFUNCTIONSET_CACHING_HH
FunctionSpaceType::JacobianRangeType JacobianRangeType
jacobian range type
Definition: shapefunctionset/shapefunctionset.hh:44
~CachingShapeFunctionSet()
Definition: caching.hh:238
int order() const
return order of shape functions
FunctionSpaceType::RangeType RangeType
range type
Definition: shapefunctionset/shapefunctionset.hh:42
FunctionSpaceType::HessianRangeType HessianRangeType
hessian range type
Definition: shapefunctionset/shapefunctionset.hh:46
std::size_t size() const
return number of shape functions
std::vector< JacobianRangeVectorType > JacobianCacheVectorType
Definition: caching.hh:43
const RangeVectorType & rangeCache(const QuadratureType &quadrature) const
Definition: caching.hh:104
A vector valued function space.
Definition: functionspace.hh:16
wrapper for a (Quadrature,int) pair
Definition: quadrature.hh:40
const QuadratureType & quadrature() const
Definition: quadrature.hh:65
Definition: caching.hh:26
Definition: shapefunctionset/shapefunctionset.hh:33
void jacobianEach(const QuadraturePointWrapper< Quadrature > &x, Functor functor) const
Definition: caching.hh:89
static void registerStorage(StorageInterface &storage)
Definition: registry.hh:69
dimension of domain vector space
Definition: functionspaceinterface.hh:45
void evaluateEach(const Point &x, Functor functor) const
evalute each shape function
unsigned int point() const
Definition: quadrature.hh:70
int order() const
Definition: caching.hh:59
const JacobianRangeVectorType & jacobianCache(const QuadratureType &quadrature) const
Definition: caching.hh:111
Definition: misc/functor.hh:30
VectorSpaceTraits< DomainField, RangeField, dimD, dimR >::DomainFieldType DomainFieldType
Intrinsic type used for values in the domain field (usually a double)
Definition: functionspaceinterface.hh:59
Definition: coordinate.hh:4
GeometryType type() const
Definition: caching.hh:101
std::vector< JacobianRangeType > JacobianRangeVectorType
Definition: caching.hh:40
size_t id() const
obtain the identifier of the integration point list
Definition: quadrature.hh:258
const CoordinateType & point(size_t i) const
obtain coordinates of i-th integration point
Definition: quadrature.hh:242
std::vector< RangeVectorType > ValueCacheVectorType
Definition: caching.hh:42
void hessianEach(const Point &x, Functor functor) const
evalute hessian of each shape function
ShapeFunctionSet::FunctionSpaceType FunctionSpaceType
Definition: caching.hh:32
ShapeFunctionSet::JacobianRangeType JacobianRangeType
Definition: caching.hh:36
void jacobianEach(const Point &x, Functor functor) const
Definition: caching.hh:83
void evaluateEach(const Point &x, Functor functor) const
Definition: caching.hh:70
void evaluateEach(const QuadraturePointWrapper< Quadrature > &x, Functor functor) const
Definition: caching.hh:76
FunctionSpaceType::DomainType DomainType
domain type
Definition: shapefunctionset/shapefunctionset.hh:40
void jacobianEach(const Point &x, Functor functor) const
evalute jacobian of each shape function
ShapeFunctionSet::DomainType DomainType
Definition: caching.hh:34
const ThisType & operator=(const ThisType &)=delete
static void unregisterStorage(StorageInterface &storage)
Definition: registry.hh:83
Definition: pointprovider.hh:21
ShapeFunctionSet::HessianRangeType HessianRangeType
Definition: caching.hh:37
CachingShapeFunctionSet(const GeometryType &type, const ShapeFunctionSet &shapeFunctionSet=ShapeFunctionSet())
Definition: caching.hh:45
void hessianEach(const Point &x, Functor functor) const
Definition: caching.hh:96
std::vector< RangeType > RangeVectorType
Definition: caching.hh:39
ShapeFunctionSet::RangeType RangeType
Definition: caching.hh:35
std::size_t size() const
Definition: caching.hh:64
actual interface class for quadratures
Definition: quadrature.hh:320