DUNE-FEM (unstable)

quadprovider.hh
1#ifndef DUNE_FEM_QUADPROVIDER_HH
2#define DUNE_FEM_QUADPROVIDER_HH
3
4#include <iostream>
5#include <memory>
6#include <map>
7#include <vector>
8
10#include <dune/fem/quadrature/quadratureimp.hh>
11#include <dune/fem/quadrature/idprovider.hh>
12#include <dune/fem/misc/mpimanager.hh>
13
14namespace Dune
15{
16
17 namespace Fem
18 {
19
26 {
27 int id_;
28
29 // something like maxOrder
30 static const int maxFirst = 25 ;
31 // something like different quadratures of the same order
32 static const int maxSecond = 10 ;
33 public:
35 FemQuadratureKey() : id_( -1 ) {}
36
38 FemQuadratureKey( const FemQuadratureKey& key ) = default;
39
40 // this may need to be adjusted in case more than 100 quadratures
41 // need to be stored
42 static const int highest_order = maxFirst * maxSecond ;
43
45 FemQuadratureKey( const int first, const int second )
46 : id_( second * maxFirst + first )
47 {
48 assert( first < maxFirst );
49 assert( second < maxSecond );
50 }
51
54 : id_( first )
55 {
56 assert( first < maxFirst );
57 }
58
60 operator int () const { return id_; }
61
63 int first () const { return id_ % highest_order ; }
65 int second () const { return id_ / highest_order ; }
66 };
67
68
78 template< unsigned int dummy >
80 {
82 template< class QuadImp, class QuadratureKey, unsigned int >
83 class QuadratureStorage;
84 private:
86 template< class QuadImp, class QuadratureKey >
87 class QuadratureStorage< QuadImp, QuadratureKey, dummy >
88 {
89 public:
90 typedef QuadImp QuadType;
91
92 protected:
93 struct Storage
94 {
95 typedef std :: map< QuadratureKey, std::unique_ptr< QuadType > > StorageType;
96 std::mutex mutex_;
97 StorageType storage_;
98
99 static QuadImp* create( const GeometryType &geometry, const QuadratureKey& key )
100 {
101 return instance().createImpl( geometry, key );
102 }
103
104 private:
105 static Storage& instance()
106 {
108 }
109
110 QuadImp* createImpl( const GeometryType &geometry, const QuadratureKey& key )
111 {
112 std::lock_guard< std::mutex > guard( mutex_ );
113
114 auto& quadPtr = storage_[ key ];
115 if( ! quadPtr )
116 {
117 quadPtr.reset( new QuadImp( geometry, key, IdProvider :: instance().newId() ) );
118 }
119
120 assert( quadPtr );
121 return quadPtr.operator->();
122 }
123 };
124
125 typedef std :: map< QuadratureKey, std::unique_ptr< QuadType, Dune::null_deleter<QuadType> > > PointerStorageType;
126 PointerStorageType quadPtrs_;
127
128 public:
129 QuadratureStorage () {}
130
131 QuadType &getQuadrature( const GeometryType &geometry, const QuadratureKey& key )
132 {
133 auto& quadPtr = quadPtrs_[ key ];
134 if( ! quadPtr )
135 {
136 // create is mutex protected
137 quadPtr.reset( Storage::create( geometry, key ) );
138 }
139
140 assert( quadPtr );
141 return *quadPtr;
142 }
143 };
144
146 template< class QuadImp>
147 class QuadratureStorage< QuadImp, int, dummy > // QuadratureKey == int
148 {
149 public:
150 typedef QuadImp QuadType;
151
152 protected:
153 struct Storage
154 {
155 std::mutex mutex_;
156
157 // vector storing the actual objects
158 std::vector< std::unique_ptr< QuadType > > storage_;
159 Storage() : storage_( QuadType :: maxOrder() + 1 )
160 {}
161
162 static QuadType* create( const GeometryType &geometry, int order )
163 {
164 return instance().createImpl( geometry, order );
165 }
166
167 private:
168 static Storage& instance()
169 {
171 }
172
173 QuadType* createImpl( const GeometryType &geometry, int order )
174 {
175 std::lock_guard< std::mutex > guard( mutex_ );
176
177 auto& quadPtr = storage_[ order ];
178 if( ! quadPtr )
179 {
180 quadPtr.reset( new QuadImp( geometry, order, IdProvider :: instance().newId() ) );
181 }
182 assert( quadPtr );
183 return quadPtr.operator ->();
184 }
185 };
186
187 typedef std::vector< QuadType* > QuadPointerVecType;
188 // store all the pointers for all threads separately to avoid race conditions
189 QuadPointerVecType quadPtrs_;
190
191 public:
192 QuadratureStorage ()
193 : quadPtrs_( QuadPointerVecType( QuadType :: maxOrder() + 1, nullptr ))
194 {
195 }
196
197 public:
198 QuadImp &getQuadrature( const GeometryType &geometry, int order )
199 {
200 if(order >= int(quadPtrs_.size()) )
201 {
202#ifndef NDEBUG
203 static thread_local bool showMessage = true ;
204 if( showMessage )
205 {
206 std::cerr << "WARNING: QuadratureStorage::getQuadrature: A quadrature of order " << order
207 << " is not implemented!" << std::endl
208 << "Choosing maximum order: " << quadPtrs_.size()-1 << std::endl << std::endl;
209 showMessage = false;
210 }
211#endif
212 order = quadPtrs_.size() - 1;
213 }
214
215 auto& quadPtr = quadPtrs_[ order ];
216 if( ! quadPtr )
217 {
218 // create is mutex protected
219 quadPtr = Storage::create( geometry, order );
220 }
221
222 assert( quadPtr );
223 return *( quadPtr );
224 }
225 }; // end class QuadratureStorage
226
228 template< class QuadImp >
229 class QuadratureStorage< QuadImp, FemQuadratureKey, dummy >
230 : public QuadratureStorage< QuadImp, int, dummy >
231 {
232 };
233
234 public:
240 template< class QuadImp, class QuadratureKey >
241 static const QuadImp &provideQuad( const GeometryType& geometry,
242 const QuadratureKey& key )
243 {
244 // QuadratureStorage stores only pointers to the quadratures that are
245 // created and stored by a singleton storage
246 static thread_local QuadratureStorage< QuadImp, QuadratureKey, dummy > storage;
247 return storage.getQuadrature( geometry, key );
248 }
249
256 template< class QuadImp, class QuadratureKey >
257 static const QuadImp &provideQuad( const GeometryType& geometry,
258 const QuadratureKey& key,
259 const int defaultOrder )
260 {
261 // this function should only be called for geometry types equal to none
262 assert( geometry.isNone() );
263 DUNE_THROW(NotImplemented,"provideQuad for polyhedral cells (defaultOrder = 0) not implemented for arbitrary QuadratureKey!");
264 QuadImp* ptr = nullptr;
265 return *ptr;
266 }
267
274 template< class QuadImp >
275 static const QuadImp &provideQuad( const GeometryType& geometry,
276 const int ,
277 const int defaultOrder )
278 {
279 assert( geometry.isNone() );
280 // QuadratureStorage stores only pointers to the quadratures that are
281 // created and stored by a singleton storage
282 static thread_local QuadratureStorage< QuadImp, int, dummy > storage;
283 return storage.getQuadrature( geometry, defaultOrder );
284 }
285 };
286
302 template< typename FieldImp, int dim, template< class, int > class IntegrationTraits >
304 {
305 public:
306 typedef FieldImp FieldType;
307
308 static const int dimension = dim;
309
310 private:
312
313 typedef IntegrationTraits< FieldType, dimension > QuadratureTraits;
314
315 // to be removed
316 typedef QuadratureTraits FactoryTraits;
317
318 template <class PointQuadrature, class QuadratureKey>
319 class PointQuadratureStorage : public PointQuadrature
320 {
321 public:
322 // only call IdProvider ::instance().newId() when object is created
323 PointQuadratureStorage( const GeometryType &geometry, const QuadratureKey& quadKey )
324 : PointQuadrature( geometry, quadKey, IdProvider::instance().newId() )
325 {}
326 };
327
328 public:
330 typedef typename QuadratureTraits::IntegrationPointListType QuadratureImplementationType;
331
333#if 0
334 template <class FactoryTraits>
335 static const QuadratureImplementationType &getQuadrature( const FactoryTraits traits,
336 const GeometryType &geometry,
337 const typename FactoryTraits::QuadratureKeyType& quadKey )
338#else
340 const typename FactoryTraits::QuadratureKeyType& quadKey )
341#endif
342 {
343 static_assert( std::is_same< QuadratureImplementationType,
344 typename FactoryTraits::IntegrationPointListType> :: value );
345
346 // for 0d point quadratures
347 if constexpr ( dimension == 0 )
348 {
349 typedef typename FactoryTraits :: PointQuadratureType PointQuadratureType;
350 typedef typename FactoryTraits :: QuadratureKeyType QuadratureKeyType;
351
352 typedef PointQuadratureStorage< PointQuadratureType, QuadratureKeyType > PointQuadratureStorageType;
353
354 assert( geometry.isCube() || geometry.isSimplex() );
355 return Singleton< PointQuadratureStorageType > :: instance( geometry, quadKey );
356 }
357 else // all other cases
358 {
359 // for 1d return LineQuadrature
360 if constexpr ( dimension == 1 )
361 {
362 typedef typename FactoryTraits::LineQuadratureType LineQuadratureType;
363 assert( geometry.isCube() || geometry.isSimplex() );
364 return QuadCreator< 0 > :: template provideQuad< LineQuadratureType > ( geometry, quadKey );
365 }
366
367 // for 2d Simplex and Cube
368 if constexpr ( dimension >= 2 )
369 {
370 typedef typename FactoryTraits::SimplexQuadratureType SimplexQuadratureType;
371 typedef typename FactoryTraits::CubeQuadratureType CubeQuadratureType;
372 if( geometry.isSimplex() )
373 {
374 return QuadCreator< 0 > ::
375 template provideQuad< SimplexQuadratureType > ( geometry, quadKey );
376 }
377
378 if( geometry.isCube() )
379 {
380 return QuadCreator< 1 > ::
381 template provideQuad< CubeQuadratureType > ( geometry, quadKey ) ;
382 }
383
384 if( geometry.isNone() )
385 {
386 // dummy return for polygonal grid cells, i.e. geometry type none
387 return QuadCreator< 1 > :: template provideQuad< CubeQuadratureType > ( geometry, 0 );
388 }
389
390 if constexpr ( dimension == 3 )
391 {
392 typedef typename FactoryTraits::PrismQuadratureType PrismQuadratureType;
393 typedef typename FactoryTraits::PyramidQuadratureType PyramidQuadratureType;
394
395 if( geometry.isPrism() )
396 return QuadCreator< 2 > :: template provideQuad< PrismQuadratureType >
397 ( geometry, quadKey );
398 if( geometry.isPyramid() )
399 return QuadCreator< 3 > :: template provideQuad< PyramidQuadratureType >
400 ( geometry, quadKey );
401 }
402 }
403
404 DUNE_THROW( RangeError, "Element type not available for dimension " << dimension );
405 // dummy return
406 if constexpr ( dimension == 1 )
407 {
408 typedef typename FactoryTraits::LineQuadratureType LineQuadratureType;
409 return QuadCreator< 0 > :: template provideQuad< LineQuadratureType > ( geometry, quadKey, 0 );
410 }
411 else
412 {
413 typedef typename FactoryTraits::SimplexQuadratureType SimplexQuadratureType;
414 return QuadCreator< 0 > :: template provideQuad< SimplexQuadratureType > ( geometry, quadKey, 0 );
415 }
416 } // else not dimension 0
417 }
418
419#if 0
421 template <class FactoryTraits>
422 static const QuadratureImplementationType &getQuadrature( const FactoryTraits traits,
423 const GeometryType &geometry,
424 const GeometryType &elementGeometry,
425 const typename FactoryTraits::QuadratureKeyType& quadKey )
426#else
429 const GeometryType &elementGeometry,
430 const typename FactoryTraits::QuadratureKeyType& quadKey )
431#endif
432 {
433 if constexpr ( dimension == 0 )
434 {
435 return getQuadrature(geometry, quadKey);
436 }
437 else
438 {
439 if constexpr ( dimension == 1 )
440 {
441 typedef typename FactoryTraits::LineQuadratureType LineQuadratureType;
442 assert( geometry.isCube() || geometry.isSimplex() );
443 // we need here to distinguish between the basic types
444 // otherwise the this won't work for UGGrid
445 return ( elementGeometry.isSimplex() ) ?
446 QuadCreator< 0 > :: template provideQuad< LineQuadratureType > ( geometry, quadKey ) :
447 QuadCreator< 1 > :: template provideQuad< LineQuadratureType > ( geometry, quadKey ) ;
448 }
449
450 if constexpr ( dimension == 2 )
451 {
452 typedef typename FactoryTraits::SimplexQuadratureType SimplexQuadratureType;
453 typedef typename FactoryTraits::CubeQuadratureType CubeQuadratureType;
454 assert( geometry.isCube() || geometry.isSimplex() );
455
456 // if geometry is simplex return simplex quadrature
457 if ( geometry.isSimplex() )
458 {
459 // check element geometry to provide quadratures with different ids
460 if( elementGeometry.isSimplex() )
461 return QuadCreator< 0 > :: template provideQuad< SimplexQuadratureType > ( geometry, quadKey ) ;
462 else if( elementGeometry.isCube() )
463 return QuadCreator< 1 > :: template provideQuad< SimplexQuadratureType > ( geometry, quadKey ) ;
464 else if( elementGeometry.isPrism() )
465 return QuadCreator< 2 > :: template provideQuad< SimplexQuadratureType > ( geometry, quadKey ) ;
466 else if( elementGeometry.isPyramid() )
467 return QuadCreator< 3 > :: template provideQuad< SimplexQuadratureType > ( geometry, quadKey ) ;
468 else
469 DUNE_THROW( RangeError, "Element type not available for dimension 3" );
470 }
471 else
472 {
473 // return cube quadrature
474 // check element geometry to provide quadratures with different ids
475 if( elementGeometry.isSimplex() )
476 return QuadCreator< 4 > :: template provideQuad< CubeQuadratureType > ( geometry, quadKey ) ;
477 else if( elementGeometry.isCube() )
478 return QuadCreator< 5 > :: template provideQuad< CubeQuadratureType > ( geometry, quadKey ) ;
479 else if( elementGeometry.isPrism() )
480 return QuadCreator< 6 > :: template provideQuad< CubeQuadratureType > ( geometry, quadKey ) ;
481 else if( elementGeometry.isPyramid() )
482 return QuadCreator< 7 > :: template provideQuad< CubeQuadratureType > ( geometry, quadKey ) ;
483 else
484 DUNE_THROW( RangeError, "Element type not available for dimension 3" );
485 }
486 }
487
488 if constexpr ( dimension >= 3 )
489 {
490 typedef typename FactoryTraits::SimplexQuadratureType SimplexQuadratureType;
491 DUNE_THROW( RangeError, "QuadProvider::getQuadrature not implemented for 3d face quadratures!" );
492 // dummy return
493 return QuadCreator< 0 > :: template provideQuad< SimplexQuadratureType >
494 ( geometry, quadKey, 0 );
495 }
496 }
497 }
498
499 QuadratureProvider() = delete;
500 QuadratureProvider( const ThisType& ) = delete;
501 QuadratureProvider &operator=( const ThisType& ) = delete;
502 };
503
504 } // namespace Fem
505
506} // namespace Dune
507
508#endif // #ifndef DUNE_FEM_QUADPROVIDER_HH
A simple quadrature key class for use FemPy.
Definition: quadprovider.hh:26
FemQuadratureKey(const FemQuadratureKey &key)=default
copy constructor
int first() const
return first component
Definition: quadprovider.hh:63
int second() const
return second component
Definition: quadprovider.hh:65
FemQuadratureKey()
empty constructor
Definition: quadprovider.hh:35
FemQuadratureKey(const int first)
constructor taking only order (fallback for standard Fem quadratures)
Definition: quadprovider.hh:53
FemQuadratureKey(const int first, const int second)
constructor taking to ids, like std::pair
Definition: quadprovider.hh:45
static IdProvider & instance()
Access to the singleton object.
Definition: idprovider.hh:21
the actual quadrature storage
Definition: quadprovider.hh:80
static const QuadImp & provideQuad(const GeometryType &geometry, const QuadratureKey &key, const int defaultOrder)
provide quadrature
Definition: quadprovider.hh:257
static const QuadImp & provideQuad(const GeometryType &geometry, const QuadratureKey &key)
provide quadrature
Definition: quadprovider.hh:241
static const QuadImp & provideQuad(const GeometryType &geometry, const int, const int defaultOrder)
provide quadrature
Definition: quadprovider.hh:275
provide a single instance pool of quadratures
Definition: quadprovider.hh:304
static const QuadratureImplementationType & getQuadrature(const GeometryType &geometry, const GeometryType &elementGeometry, const typename FactoryTraits::QuadratureKeyType &quadKey)
Access to the quadrature implementations.
Definition: quadprovider.hh:428
QuadratureTraits::IntegrationPointListType QuadratureImplementationType
type of integration point list implementation
Definition: quadprovider.hh:330
static const QuadratureImplementationType & getQuadrature(const GeometryType &geometry, const typename FactoryTraits::QuadratureKeyType &quadKey)
Access to the quadrature implementations.
Definition: quadprovider.hh:339
static DUNE_EXPORT Object & instance(Args &&... args)
return singleton instance of given Object type.
Definition: singleton.hh:123
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:114
constexpr bool isPyramid() const
Return true if entity is a pyramid.
Definition: type.hh:304
constexpr bool isPrism() const
Return true if entity is a prism.
Definition: type.hh:309
constexpr bool isCube() const
Return true if entity is a cube of any dimension.
Definition: type.hh:324
constexpr bool isNone() const
Return true if entity is a singular of any dimension.
Definition: type.hh:355
constexpr bool isSimplex() const
Return true if entity is a simplex of any dimension.
Definition: type.hh:319
Default exception for dummy implementations.
Definition: exceptions.hh:263
Default exception class for range errors.
Definition: exceptions.hh:254
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
Dune namespace.
Definition: alignedallocator.hh:13
This file implements several utilities related to std::shared_ptr.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)