DUNE-FEM (unstable)

evaluatecaller.hh
1#ifndef DUNE_FEM_EVALUATECALLER_HH
2#define DUNE_FEM_EVALUATECALLER_HH
3
4#include <cstdlib>
5#include <iostream>
6#include <memory>
7#include <vector>
8
11
12#include <dune/fem/space/basisfunctionset/evaluatecallerdeclaration.hh>
13
14#include <dune/fem/misc/threads/threadsafevalue.hh>
15#include <dune/fem/common/utility.hh>
16#include <dune/fem/quadrature/quadrature.hh>
17
18//#ifdef USE_BASEFUNCTIONSET_CODEGEN
19//#ifndef DUNE_FEM_INCLUDE_AUTOGENERATEDCODE_FILENAME_SPEC
20// default filename for autogenerated code is simply autogeneratedcode.hh
21// this filename is overloaded by the codegeneration for the python modules
22//#include <autogeneratedcode.hh>
23//#endif
24
25#ifdef DUNE_FEM_INCLUDE_AUTOGENERATEDCODE_FILENAME_SPEC
26#define CODEGEN_INCLUDEMAXNUMS
27// include max number definitions
28#include DUNE_FEM_INCLUDE_AUTOGENERATEDCODE_FILENAME_SPEC
29#undef CODEGEN_INCLUDEMAXNUMS
30#endif
31
33//
34// pre-define these values for faster compilation
35//
37#ifndef MAX_NUMBER_OF_QUAD_POINTS
38#define MAX_NUMBER_OF_QUAD_POINTS 20
39#endif
40
41#ifndef MAX_NUMBER_OF_BASE_FCT
42#define MAX_NUMBER_OF_BASE_FCT 20
43#endif
44
45#ifndef MIN_NUMBER_OF_QUAD_POINTS
46#define MIN_NUMBER_OF_QUAD_POINTS 1
47#endif
48
49#ifndef MIN_NUMBER_OF_BASE_FCT
50#define MIN_NUMBER_OF_BASE_FCT 1
51#endif
52
53#include <dune/fem/space/basisfunctionset/evaluatecallerdefaultimpl.hh>
54
55#ifdef DUNE_FEM_INCLUDE_AUTOGENERATEDCODE_FILENAME_SPEC
56// defined in evaluatecaller.hh
57#include DUNE_FEM_INCLUDE_AUTOGENERATEDCODE_FILENAME_SPEC
58#endif // DUNE_FEM_INCLUDE_AUTOGENERATEDCODE_FILENAME_SPEC
59
60namespace Dune
61{
62 namespace Fem
63 {
64 namespace Codegen
65 {
66
67 // forward declaration
68 template <class Traits,
69 int quadNop,
70 int numBaseFct >
71 class EvaluateCaller;
72
73 template< class QuadratureImp,
74 class FactorImp,
75 class LocalDofVectorImp,
76 class GeometryImp = EmptyGeometry >
77 struct EvaluateCallerInterfaceTraits
78 {
79 typedef QuadratureImp QuadratureType;
80 typedef FactorImp FactorType;
81 typedef LocalDofVectorImp LocalDofVectorType;
82 typedef GeometryImp Geometry;
83 };
84
85 template <class Traits,
86 class BaseFunctionSet,
87 class RangeVectorImp>
88 struct EvaluateCallerTraits
89 {
90 typedef Traits BaseTraits;
91 typedef typename Traits :: QuadratureType QuadratureType ;
92 typedef typename Traits :: FactorType FactorType ;
93 typedef typename Traits :: LocalDofVectorType LocalDofVectorType ;
94 typedef typename Traits :: Geometry Geometry ;
95
96 typedef BaseFunctionSet BaseFunctionSetType;
97 typedef RangeVectorImp RangeVectorType;
98 };
99
100
101 //- base function evaluation interface
102 template <class Traits>
103 class EvaluateCallerInterface
104 {
105 typedef EvaluateCallerInterface< Traits > ThisType;
106 public:
107 typedef std::unique_ptr< ThisType > StoragePointerType;
108
109 protected:
110 static const int maxNumBaseFunctions = MAX_NUMBER_OF_BASE_FCT;
111 static const int minNumBaseFunctions = MIN_NUMBER_OF_BASE_FCT;
112
113 static const int maxQuadNop = MAX_NUMBER_OF_QUAD_POINTS;
114 static const int minQuadNop = MIN_NUMBER_OF_QUAD_POINTS;
115
116 // maximal number of different quadratures we can use here
117 static const int maxQuadratures = 25;
118
119 class EvaluatorStorage
120 {
121 class Item : public std::pair< bool, StoragePointerType >
122 {
123 typedef std::pair< bool, StoragePointerType > BaseType;
124
125 public:
126 Item() : BaseType(false, StoragePointerType() ) {}
127 };
128
129 protected:
130 std::vector< Item > storage_;
131 public:
132 EvaluatorStorage() :
133 storage_( maxQuadratures ) {}
134
135 Item& get( const size_t id )
136 {
137 if( id >= storage_.size() )
138 {
139 storage_.resize( id + 10 );
140 }
141 return storage_[ id ];
142 }
143 };
144
145
146 EvaluateCallerInterface() {}
147
148 public:
149 typedef typename Traits :: QuadratureType QuadratureType ;
150 typedef typename Traits :: FactorType FactorType ;
151 typedef typename Traits :: LocalDofVectorType LocalDofVectorType ;
152 typedef typename Traits :: Geometry Geometry ;
153
154 virtual ~EvaluateCallerInterface() {}
155
156 virtual void* storageAddress () const = 0;
157 virtual size_t storageSize () const = 0;
158
159 virtual void axpyRanges( const QuadratureType&,
160 const FactorType& ,
161 LocalDofVectorType & ) const = 0;
162
163 virtual void evaluateRanges( const QuadratureType& quad,
164 const LocalDofVectorType & dofs,
165 FactorType& factors) const = 0;
166
167 virtual void axpyJacobians( const QuadratureType&,
168 const Geometry&,
169 const FactorType& ,
170 LocalDofVectorType & ) const = 0;
171
172 virtual void evaluateJacobians( const QuadratureType&,
173 const Geometry&,
174 const LocalDofVectorType&,
175 FactorType&) const = 0;
176
177 template < class BaseFunctionSet, class Storage >
178 static const StoragePointerType& storage(const BaseFunctionSet& baseSet,
179 const Storage& dataCache,
180 const QuadratureType& quad)
181 {
182 // static vector holding all evaluator instances
183 static ThreadSafeValue< EvaluatorStorage > evaluatorStorage;
184 EvaluatorStorage& evaluators = *evaluatorStorage;
185
186 // check if object already created
187 const size_t quadId = quad.id();
188 auto& item = evaluators.get( quadId );
189 if( ! item.first )
190 {
191 const int nop = quad.nop();
192 static const int dimRange = BaseFunctionSet :: FunctionSpaceType:: dimRange;
193 const int numBaseFct = baseSet.size() / dimRange;
194
195 typedef EvaluateCallerTraits< Traits, BaseFunctionSet, Storage> NewTraits;
196
197#if 0 // NDEBUG
198 if( quad.isInterpolationQuadrature( numBaseFct ) )
199 std::cout << "EvaluateCallerInterface::storage: Not creating implementation because of interpolation feature!" <<std::endl;
200#endif
201
202 // if quadrature points or number of basis functions are not within
203 // the range of generated code snippets then don't search for
204 // a matching combination
205 // do not create an evaluation if the quadrature is an interpolation
206 // quadrature and matches the number of shape functions
207 if( (nop >= minQuadNop && nop <= maxQuadNop) &&
208 (numBaseFct >= minNumBaseFunctions && numBaseFct <= maxNumBaseFunctions) &&
209 ! quad.isInterpolationQuadrature( numBaseFct ) )
210 {
211 item.second.reset(
212 EvaluateCaller< NewTraits, maxQuadNop, maxNumBaseFunctions >
213 :: create( dataCache , nop, numBaseFct ) );
214 }
215
216 // if pointer was checked, set flag to true, pointer may still be a nullptr
217 item.first = true;
218 }
219
220 // this can be a nullptr (in this case the default implementation is used)
221 return item.second;
222 }
223 };
224
225 template <class Traits,
226 int dimRange,
227 int quadNop,
228 int numBaseFct >
229 class EvaluateRealImplementation
230 : public EvaluateCallerInterface< typename Traits :: BaseTraits >
231 {
232 protected:
233 typedef typename Traits :: BaseFunctionSetType BaseFunctionSetType;
234 typedef typename Traits :: QuadratureType QuadratureType ;
235 typedef typename Traits :: FactorType FactorType ;
236 typedef typename Traits :: LocalDofVectorType LocalDofVectorType ;
237 typedef typename Traits :: Geometry Geometry ;
238 typedef typename Traits :: RangeVectorType RangeVectorType ;
239 typedef typename RangeVectorType :: value_type :: field_type FieldType;
240
241 typedef EvaluateRealImplementation< Traits, dimRange, quadNop, numBaseFct > ThisType;
242 typedef EvaluateCallerInterface< typename Traits :: BaseTraits > BaseType;
243
244 // A copy is made of the storage here, otherwise strange memory corruptions happen
245 // TODO: needs further investigation
246 RangeVectorType rangeStorage_; // basis function evaluations
247
248 std::vector< std::vector< FieldType > > rangeStorageTransposed_;
249 std::vector< std::vector< FieldType > > rangeStorageFlat_;
250 mutable std::vector< std::vector< std::vector< FieldType > > > rangeStorageTwisted_;
251
252 template <class K>
253 int getDim( const DenseVector< K >& vec) const
254 {
255 return vec.size();
256 }
257
258 template <class K>
259 int getDim( const DenseMatrix< K >& mat) const
260 {
261 // dimRange == rows which is 1 for basis storage
262 return getDim( mat[ 0 ] );
263 }
264
265 // initialize storage for ranges (i.e. scalar)
266 void initRangeStorageTransposed( const std::integral_constant< bool, true > )
267 {
268 assert( rangeStorage_[ 0 ].size() == 1 );
269 {
270 const int quadPoints = rangeStorage_.size() / numBaseFct;
271 const int faces = quadPoints / quadNop;
272 rangeStorageTransposed_.resize( faces );
273 for( int f=0; f<faces; ++f )
274 {
275 auto& rangeStorageTransposed = rangeStorageTransposed_[ f ];
276
277 // rearrange such that we store for one basis functions all
278 // evaluations for all quadrature points, i.e. numBaseFct * quadNop
279 rangeStorageTransposed.resize( numBaseFct * quadNop );
280 for( int i=0; i<numBaseFct; ++i )
281 {
282 const int idx = i * quadNop;
283 for( int j=0; j<quadNop; ++j )
284 {
285 int qp = f * quadNop + j ;
286 assert( j*numBaseFct + i < int(rangeStorage_.size()) );
287 // copy and transpose
288 rangeStorageTransposed[ idx + j ] = rangeStorage_[ qp*numBaseFct + i ][ 0 ];
289 }
290 }
291 }
292 }
293 }
294
295 // initialize storage for jacobians (i.e. vectors)
296 void initRangeStorageTransposed( const std::integral_constant< bool, false > )
297 {
298 const int dim = rangeStorage_[ 0 ][ 0 ].size();
299 {
300 const int quadPoints = rangeStorage_.size() / numBaseFct;
301 const int faces = quadPoints / quadNop;
302 rangeStorageTransposed_.resize( faces );
303 rangeStorageFlat_.resize( faces );
304 for( int f=0; f<faces; ++f )
305 {
306 auto& rangeStorageTransposed = rangeStorageTransposed_[ f ];
307 auto& rangeStorageFlat = rangeStorageFlat_[ f ];
308
309 // rearrange such that we store for one basis functions all
310 // evaluations for all quadrature points, i.e. numBaseFct * quadNop
311 rangeStorageTransposed.resize( numBaseFct * quadNop * dim );
312 rangeStorageFlat.resize( numBaseFct * quadNop * dim );
313 for( int i=0; i<numBaseFct; ++i )
314 {
315 const int idx = i * (quadNop * dim);
316 for( int j=0; j<quadNop; ++j )
317 {
318 int qp = f * quadNop + j ;
319 for( int d=0; d<dim; ++d )
320 {
321 rangeStorageFlat[ j*numBaseFct*dim + (i * dim) + d ] = rangeStorage_[ qp*numBaseFct + i ][ 0 ][ d ];
322 rangeStorageTransposed[ idx + (j * dim) + d ] = rangeStorage_[ qp*numBaseFct + i ][ 0 ][ d ];
323 }
324 }
325 }
326 }
327 }
328 }
329
330 template <class Quadrature>
331 //const DynamicArray< FieldType >&
332 const std::vector< FieldType >&
333 getTwistedStorage( const Quadrature& quad ) const
334 {
335 // for evaluation the range storage dimension should be 1 and therefore
336 // rangeStorageTransposed should have been filled
337 assert( ! rangeStorageTransposed_.empty() );
338
339 // if we are in the ranges cases then basis can be stored transposed
340 // quadrature points is the outer loop
341 if constexpr ( Quadrature::twisted() )
342 {
343 if( quad.twistId() == 4 ) // no twist
344 return rangeStorageTransposed_[ quad.localFaceIndex() ];
345
346 auto& rangeStorageTwisted = rangeStorageTwisted_[ quad.twistId() ];
347 if( rangeStorageTwisted.empty() )
348 {
349 const int quadPoints = rangeStorage_.size() / numBaseFct;
350 const int faces = quadPoints / quadNop;
351 rangeStorageTwisted.resize( faces );
352 }
353
354 const int f = quad.localFaceIndex() ;
355 auto& rangeStorageFace = rangeStorageTwisted[ f ];
356 if( rangeStorageFace.empty() )
357 {
358 // either 1 or dim of grid
359 const int dim = getDim( rangeStorage_[ 0 ] );
360
361 const auto& rangeStorageTransposed = rangeStorageTransposed_[ f ];
362
363 // rearrange such that we store for one basis functions all
364 // evaluations for all quadrature points including the twisted mapping
365 rangeStorageFace.resize( rangeStorageTransposed.size() );
366 for( int i=0; i<numBaseFct; ++i )
367 {
368 const int idx = i * (quadNop * dim);
369 for( int j=0; j<quadNop; ++j )
370 {
371 const int qp = quad.localCachingPoint( j );
372 for( int d=0; d<dim; ++d )
373 {
374 rangeStorageFace[ idx + (j * dim) + d ] = rangeStorageTransposed[ idx + (qp * dim) + d ];
375 }
376 }
377 }
378 } // end if( rangeStorageTwisted.empty() )
379 return rangeStorageFace;
380 }
381 else // no twist (i.e. twist = 0 and twistId == 4 (-4 is mapped to 0))
382 {
383 return rangeStorageTransposed_[ quad.localFaceIndex() ];
384 }
385 }
386 public:
387 // type of interface class
388 typedef BaseType InterfaceType;
389
390 EvaluateRealImplementation( const RangeVectorType& rangeStorage )
391 : rangeStorage_( rangeStorage ), rangeStorageTwisted_( 8 ) // 8 different twists
392 {
393 initRangeStorageTransposed( std::integral_constant< bool,
394 std::is_same< typename RangeVectorType::value_type,
395 Dune::FieldVector< double, 1 > > :: value > () );
396 }
397
398 virtual void* storageAddress() const { return (void *) &rangeStorage_ ; }
399 virtual size_t storageSize() const { return rangeStorage_.size() ; }
400
401 virtual void axpyRanges( const QuadratureType& quad,
402 const FactorType& rangeFactors,
403 LocalDofVectorType & dofs ) const
404 {
405 Codegen::AxpyRanges< BaseFunctionSetType, Geometry, dimRange, quadNop, numBaseFct > :: axpy
406 ( quad, rangeStorage_, rangeFactors, dofs );
407 }
408
409 virtual void evaluateRanges( const QuadratureType& quad,
410 const LocalDofVectorType & dofs,
411 FactorType& rangeFactors) const
412 {
413 Codegen::EvaluateRanges< BaseFunctionSetType, Geometry, dimRange, quadNop, numBaseFct >
414 :: eval ( quad, getTwistedStorage( quad ), dofs, rangeFactors );
415 }
416
417 virtual void axpyJacobians( const QuadratureType& quad,
418 const Geometry& geometry,
419 const FactorType& jacFactors,
420 LocalDofVectorType& dofs) const
421 {
422 Codegen::AxpyJacobians< BaseFunctionSetType, Geometry, dimRange, quadNop, numBaseFct > :: axpy
423 ( quad, geometry, rangeStorageFlat_[ quad.localFaceIndex() ], jacFactors, dofs );
424 }
425
426 virtual void evaluateJacobians( const QuadratureType& quad,
427 const Geometry& geometry,
428 const LocalDofVectorType& dofs,
429 FactorType& jacFactors) const
430 {
431 Codegen::EvaluateJacobians< BaseFunctionSetType, Geometry, dimRange, quadNop, numBaseFct > :: eval
432 ( quad, geometry, getTwistedStorage( quad ), dofs, jacFactors );
433 }
434
435 static InterfaceType* create( const RangeVectorType& rangeStorage )
436 {
437 return new ThisType( rangeStorage );
438 }
439 };
440
441 // The default EvaluateImplementation is empty
442 // to create this has to be specified and derived from EvaluateCallerDefault
443 template <class Traits,
444 int dimRange,
445 int quadNop,
446 int numBaseFct >
447 class EvaluateImplementation
448 : public EvaluateCallerInterface< typename Traits :: BaseTraits >
449 {
450 protected:
451 typedef typename Traits :: BaseFunctionSetType BaseFunctionSetType;
452 typedef typename Traits :: QuadratureType QuadratureType ;
453 typedef typename Traits :: FactorType FactorType ;
454 typedef typename Traits :: LocalDofVectorType LocalDofVectorType ;
455 typedef typename Traits :: Geometry Geometry ;
456 typedef typename Traits :: RangeVectorType RangeVectorType ;
457
458 typedef EvaluateImplementation< Traits, dimRange, quadNop, numBaseFct > ThisType;
459
460 typedef EvaluateCallerInterface< typename Traits :: BaseTraits > BaseType;
461 public:
462 // type of interface class
463 typedef BaseType InterfaceType;
464
465 EvaluateImplementation( const RangeVectorType& rangeStorage )
466 {}
467
468 virtual void axpyRanges( const QuadratureType& quad,
469 const FactorType& rangeFactors,
470 LocalDofVectorType & dofs ) const
471 {
472 std::cerr << "ERROR: EvaluateImplementation::axpyRanges not overloaded!" << std::endl;
473 std::abort();
474 }
475
476 virtual void axpyJacobians( const QuadratureType& quad,
477 const Geometry& geometry,
478 const FactorType& jacFactors,
479 LocalDofVectorType& dofs) const
480 {
481 std::cerr << "ERROR: EvaluateImplementation::axpyJacobians not overloaded!" << std::endl;
482 std::abort();
483 }
484
485 virtual void evaluateRanges( const QuadratureType& quad,
486 const LocalDofVectorType & dofs,
487 FactorType& rangeFactors) const
488 {
489 std::cerr << "ERROR: EvaluateImplementation::evaluateRanges not overloaded!" << std::endl;
490 std::abort();
491 }
492
493 virtual void evaluateJacobians( const QuadratureType& quad,
494 const Geometry& geometry,
495 const LocalDofVectorType& dofs,
496 FactorType& jacFactors) const
497 {
498 std::cerr << "ERROR: EvaluateImplementation::evaluateJacobians not overloaded!" << std::endl;
499 std::abort();
500 }
501
502 static InterfaceType* create( const RangeVectorType& )
503 {
504 #ifndef NDEBUG
505 std::cout << "Optimized EvaluateImplementation for < dimR="<<dimRange<< ", qp=" << quadNop << ", bases=" << numBaseFct << " > not created, falling back to default!" << std::endl;
506 //DUNE_THROW(NotImplemented,"EvaluateImplementation for < " << quadNop << " , " << numBaseFct << " > not created!");
507 //return (InterfaceType*) 0;
508 #endif
509 return nullptr;
510 }
511 };
512
513 template <class Traits,
514 int quadNop,
515 int numBaseFct >
516 class EvaluateCaller
517 {
518 protected:
519 typedef typename Traits :: BaseFunctionSetType BaseFunctionSetType;
520 static const int dimRange = BaseFunctionSetType :: FunctionSpaceType:: dimRange;
521 typedef typename Traits :: RangeVectorType RangeVectorType ;
522 typedef EvaluateCallerInterface< typename Traits :: BaseTraits > InterfaceType;
523 public:
524 static InterfaceType* createObj( const RangeVectorType& rangeStorage,
525 const size_t numbase )
526 {
527 if( numBaseFct == numbase )
528 return EvaluateImplementation< Traits, dimRange, quadNop, numBaseFct > :: create( rangeStorage );
529 else
530 return EvaluateCaller< Traits, quadNop, numBaseFct - 1 > :: createObj( rangeStorage, numbase );
531 }
532
533 static InterfaceType* create( const RangeVectorType& rangeStorage,
534 const size_t quadnop, const size_t numbase )
535 {
536 if( quadNop == quadnop )
537 return EvaluateCaller< Traits, quadNop, numBaseFct > :: createObj( rangeStorage, numbase );
538 else
539 return EvaluateCaller< Traits, quadNop - 1, numBaseFct > :: create( rangeStorage, quadnop, numbase );
540 }
541 };
542
543 template <class Traits,
544 int numBaseFct >
545 class EvaluateCaller< Traits, MIN_NUMBER_OF_QUAD_POINTS, numBaseFct >
546 {
547 protected:
548 typedef typename Traits :: BaseFunctionSetType BaseFunctionSetType;
549 static const int dimRange = BaseFunctionSetType :: FunctionSpaceType:: dimRange;
550 enum { quadNop = MIN_NUMBER_OF_QUAD_POINTS };
551 typedef typename Traits :: RangeVectorType RangeVectorType ;
552 typedef EvaluateCallerInterface< typename Traits :: BaseTraits > InterfaceType;
553 public:
554 static InterfaceType* createObj( const RangeVectorType& rangeStorage,
555 const size_t numbase )
556 {
557 if( numBaseFct == numbase )
558 return EvaluateImplementation< Traits, dimRange, quadNop, numBaseFct > :: create( rangeStorage );
559 else
560 return EvaluateCaller< Traits, quadNop, numBaseFct - 1 > :: createObj( rangeStorage, numbase );
561 }
562
563 static InterfaceType* create( const RangeVectorType& rangeStorage,
564 const size_t quadnop, const size_t numbase )
565 {
566 if( quadNop == quadnop )
567 return EvaluateCaller< Traits, quadNop, numBaseFct > :: createObj( rangeStorage, numbase );
568 else
569 {
570 std::cerr << "ERROR: EvaluateCaller< "<< quadNop << ", " << numBaseFct << " >::createObj: no working combination!" << std::endl;
571 std::abort();
572 }
573 }
574 };
575
576 template <class Traits,
577 int quadNop>
578 class EvaluateCaller< Traits, quadNop, MIN_NUMBER_OF_BASE_FCT >
579 {
580 protected:
581 typedef typename Traits :: BaseFunctionSetType BaseFunctionSetType;
582 static const int dimRange = BaseFunctionSetType :: FunctionSpaceType:: dimRange;
583 enum { numBaseFct = MIN_NUMBER_OF_BASE_FCT };
584 typedef typename Traits :: RangeVectorType RangeVectorType ;
585 typedef EvaluateCallerInterface< typename Traits :: BaseTraits > InterfaceType;
586 public:
587 static InterfaceType* createObj( const RangeVectorType& rangeStorage,
588 const size_t numbase )
589 {
590 if( numBaseFct == numbase )
591 return EvaluateImplementation< Traits, dimRange, quadNop, numBaseFct > :: create( rangeStorage );
592 else
593 {
594 std::cerr << "ERROR: EvaluateCaller< "<< quadNop << ", " << numBaseFct << " >::createObj: no working combination!" << std::endl;
595 std::abort();
596 }
597 }
598
599 static InterfaceType* create( const RangeVectorType& rangeStorage,
600 const size_t quadnop, const size_t numbase )
601 {
602 if( quadNop == quadnop )
603 return EvaluateCaller< Traits, quadNop, numBaseFct > :: createObj( rangeStorage, numbase );
604 else
605 {
606 return EvaluateCaller< Traits, quadNop - 1, numBaseFct > :: create( rangeStorage, quadnop, numbase );
607 }
608 }
609 };
610
611 template <class Traits>
612 class EvaluateCaller< Traits, MIN_NUMBER_OF_QUAD_POINTS, MIN_NUMBER_OF_BASE_FCT>
613 {
614 protected:
615 typedef typename Traits :: BaseFunctionSetType BaseFunctionSetType;
616 static const int dimRange = BaseFunctionSetType :: FunctionSpaceType:: dimRange;
617 enum { quadNop = MIN_NUMBER_OF_QUAD_POINTS };
618 enum { numBaseFct = MIN_NUMBER_OF_BASE_FCT };
619 typedef typename Traits :: RangeVectorType RangeVectorType ;
620 typedef EvaluateCallerInterface< typename Traits :: BaseTraits > InterfaceType;
621 public:
622 static InterfaceType* createObj( const RangeVectorType& rangeStorage,
623 const size_t numbase )
624 {
625 if( numBaseFct == numbase )
626 return EvaluateImplementation< Traits, dimRange, quadNop, numBaseFct > :: create( rangeStorage );
627 else
628 {
629 std::cerr << "ERROR: EvaluateCaller< "<< quadNop << ", " << numBaseFct << " >::createObj: no working combination!" << std::endl;
630 std::abort();
631 }
632 }
633
634 static InterfaceType* create( const RangeVectorType& rangeStorage,
635 const size_t quadnop, const size_t numbase )
636 {
637 if( quadNop == quadnop )
638 return EvaluateCaller< Traits, quadNop, numBaseFct > :: createObj( rangeStorage, numbase );
639 else
640 {
641 std::cerr << "ERROR: EvaluateCaller< "<< quadNop << ", " << numBaseFct << " >::create: no working combination!" << std::endl;
642 std::abort();
643 }
644 }
645 };
646
647 } // namespace Codegen
648
649 } // namespace Fem
650
651} // namespace Dune
652
653#ifdef DUNE_FEM_INCLUDE_AUTOGENERATEDCODE_FILENAME_SPEC
654#define CODEGEN_INCLUDEEVALCALLERS
655// include specializations of EvaluateImplementation
656#include DUNE_FEM_INCLUDE_AUTOGENERATEDCODE_FILENAME_SPEC
657#undef CODEGEN_INCLUDEEVALCALLERS
658#endif
659#endif // #ifndef DUNE_FEM_EVALUATECALLER_HH
vector space out of a tensor product of fields.
Definition: fvector.hh:91
actual interface class for quadratures
A few common exception classes.
Implements a matrix constructed from a given type representing a field and compile-time given number ...
InterfaceType
Parameter to be used for the communication functions.
Definition: gridenums.hh:86
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
constexpr auto get(std::integer_sequence< T, II... >, std::integral_constant< std::size_t, pos >={})
Return the entry at position pos of the given sequence.
Definition: integersequence.hh:22
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)