dune-fem  2.8-git
space/basisfunctionset/tuple.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_SPACE_BASISFUNCTIONSET_TUPLE_HH
2 #define DUNE_FEM_SPACE_BASISFUNCTIONSET_TUPLE_HH
3 
4 #include <algorithm>
5 #include <array>
6 #include <tuple>
7 #include <utility>
8 #include <vector>
9 
11 
12 #include <dune/geometry/type.hh>
13 
15 
19 
20 namespace Dune
21 {
22 
23  namespace Fem
24  {
25 
26  // TupleBasisFunctionSet
27  // ---------------------
28  //
29  // TupleDiscreteFunctionSpace combination operation
30  // describes the way in which the spaces have been combined, i.e.
31  // Product: V = V_1 x V_2 x ...
32  // Summation: V = V_1 + V_2 + ...
33 
34  struct TupleSpaceProduct {};
36 
37  template< class CombineOp, class ... BasisFunctionSets >
39  {
40  typedef TupleBasisFunctionSet< CombineOp, BasisFunctionSets ... > ThisType;
41 
42  // Functor Helper structs
43  template< int > struct ComputeOffset;
44  template< int > struct EvaluateAll;
45  template< int > struct JacobianAll;
46  template< int > struct HessianAll;
47  template< int > struct EvaluateAllRanges;
48  template< int > struct JacobianAllRanges;
49  template< int > struct HessianAllRanges;
50  template< int > struct Axpy;
51 
52  // helper class to compute static overall size and offsets
53  template< int ... i >
54  struct Indices
55  {
56  template< int j >
57  static constexpr int size () { return std::tuple_element< j, std::tuple< std::integral_constant< int, i > ... > >::type::value; }
58 
59  template< int ... j >
60  static constexpr std::integer_sequence< int, size< j >() ... > sizes ( std::integer_sequence< int, j ... > )
61  {
62  return std::integer_sequence< int, size< j >() ... >();
63  }
64 
65  template< int j >
66  static constexpr int offset ()
67  {
68  return mysum( sizes( std::make_integer_sequence< int, j >() ) );
69  }
70 
71  private:
72  template< int ... j >
73  static constexpr int mysum ( std::integer_sequence< int, j ... > )
74  {
75  return Std::sum( j ... );
76  }
77 
78  static constexpr int mysum ( std::integer_sequence< int > )
79  {
80  return 0;
81  }
82  };
83 
85  typedef std::tuple< BasisFunctionSets ... > BasisFunctionSetTupleType;
86 
88  "TupleBasisFunctionSet needs common DomainType" );
90  typedef typename std::tuple_element< 0, BasisFunctionSetTupleType >::type::FunctionSpaceType ContainedFunctionSpaceType;
91 
93  static const int dimDomain = ContainedFunctionSpaceType::dimDomain;
94 
96  static const int setSize = sizeof ... ( BasisFunctionSets );
97  static const int setIterationSize = sizeof ... ( BasisFunctionSets )-1;
98 
100  typedef std::array< std::size_t, setSize + 1 > OffsetType;
101 
102  // storage for i-th sub basisfunction
103  struct Storage
104  {
105  typedef std::tuple< std::vector< typename BasisFunctionSets::RangeType > ... > RangeStorageTupleType;
106  typedef std::tuple< std::vector< typename BasisFunctionSets::JacobianRangeType > ... > JacobianStorageTupleType;
107  typedef std::tuple< std::vector< typename BasisFunctionSets::HessianRangeType > ... > HessianStorageTupleType;
108 
109  Storage () {}
110 
111  template< int i >
112  typename std::tuple_element< i, RangeStorageTupleType >::type
113  & rangeStorage() const { return std::get< i >( rangeStorage_ ); }
114 
115  template< int i >
116  typename std::tuple_element< i, JacobianStorageTupleType >::type
117  & jacobianStorage() const { return std::get< i >( jacobianStorage_ ); }
118 
119  template< int i >
120  typename std::tuple_element< i, HessianStorageTupleType >::type
121  & hessianStorage() const { return std::get< i >( hessianStorage_ ); }
122 
123  private:
124  mutable RangeStorageTupleType rangeStorage_;
125  mutable JacobianStorageTupleType jacobianStorage_;
126  mutable HessianStorageTupleType hessianStorage_;
127  };
128 
129 
130  public:
132  typedef Indices< BasisFunctionSets::FunctionSpaceType::dimRange ... > RangeIndices;
133 
134  protected:
135  template <int dummy, class CombOp>
137 
138  template <int dummy>
140  {
142  static constexpr const int dimRange = Std::sum( static_cast< int >( BasisFunctionSets::FunctionSpaceType::dimRange ) ... );
143 
145  typedef FunctionSpace< typename ContainedFunctionSpaceType::DomainFieldType,
146  typename ContainedFunctionSpaceType::RangeFieldType,
148 
149  template <class ThisRange, class Range>
150  static void apply(const int rangeOffset, const ThisRange& thisRange, Range& values)
151  {
152  // scatter result to correct place in larger result vector
153  std::copy( thisRange.begin(), thisRange.end(), values.begin() + rangeOffset );
154  }
155 
156  template< int i >
157  static constexpr int rangeOffset ()
158  {
159  return RangeIndices::template offset< i >();
160  }
161  };
162 
163  template <int dummy>
165  {
167  typedef ContainedFunctionSpaceType FunctionSpaceType;
168 
169  template <class ThisRange, class Range>
170  static void apply(const int rangeOffset, const ThisRange& thisRange, Range& values)
171  {
172  // sum results
173  values += thisRange;
174  }
175 
176  template< int j >
177  static constexpr int rangeOffset ()
178  {
179  return 0;
180  }
181  };
182 
183  // type of accumulation of result after loop over basis sets
185 
186  public:
187  // export type of i-th subbasisfunction set
188  template< int i >
190  {
191  typedef typename std::tuple_element< i, BasisFunctionSetTupleType >::type type;
192  };
193 
195  typedef typename CombinationType :: FunctionSpaceType FunctionSpaceType;
196 
198  static const int dimRange = FunctionSpaceType::dimRange;
199 
201  typedef typename FunctionSpaceType::DomainType DomainType;
202 
204  typedef typename FunctionSpaceType::RangeType RangeType;
205 
207  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
208 
210  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
211 
213  typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
214 
216  "TupleBasisFunctionSet needs common EntityType" );
218  typedef typename std::tuple_element< 0, BasisFunctionSetTupleType >::type::EntityType EntityType;
219 
221  "TupleBasisFunctionSet needs ReferenceElementType" );
223  typedef typename std::tuple_element< 0, BasisFunctionSetTupleType >::type::ReferenceElementType ReferenceElementType;
224 
225  // default constructor, needed by localmatrix
226  TupleBasisFunctionSet () : offset_( {{ 0 }} ) {}
227 
228  // constructor taking a pack of basisFunctionSets
229  TupleBasisFunctionSet ( const BasisFunctionSets & ... basisFunctionSets )
230  : basisFunctionSetTuple_( basisFunctionSets ... ),
231  offset_()
232  {
233  offset_[ 0 ] = 0;
234  Fem::ForLoop< ComputeOffset, 0, setIterationSize >::apply( offset_, basisFunctionSetTuple_ );
235  }
236 
237  // constructor taking a tuple of basisfunction sets
238  TupleBasisFunctionSet ( const BasisFunctionSetTupleType &basisFunctionSetTuple )
239  : basisFunctionSetTuple_( basisFunctionSetTuple ),
240  offset_()
241  {
242  offset_[ 0 ] = 0;
243  Fem::ForLoop< ComputeOffset, 0, setIterationSize >::apply( offset_, basisFunctionSetTuple_ );
244  }
245 
246  // Basis Function Set Interface Methods
247  // ------------------------------------
248 
250  int order () const
251  {
252  return order( std::index_sequence_for< BasisFunctionSets ... >() );
253  }
254 
256  std::size_t size () const
257  {
258  return size( std::index_sequence_for< BasisFunctionSets ... >() );
259  }
260 
262  Dune::GeometryType type () const
263  {
264  return std::get< 0 >( basisFunctionSetTuple_ ).type();
265  }
266 
268  bool valid () const
269  {
270  return std::get< 0 >( basisFunctionSetTuple_ ).valid();
271  }
272 
274  const EntityType &entity () const
275  {
276  return std::get< 0 >( basisFunctionSetTuple_ ).entity();
277  }
278 
281  {
282  return std::get< 0 >( basisFunctionSetTuple_ ).referenceElement();
283  }
284 
286  template< class Point, class DofVector >
287  void evaluateAll ( const Point &x, const DofVector &dofs, RangeType &value ) const
288  {
289  Fem::ForLoop< EvaluateAll, 0, setIterationSize >::apply( x, dofs, value, offset_, basisFunctionSetTuple_ );
290  }
291 
293  template< class Point, class RangeArray >
294  void evaluateAll ( const Point &x, RangeArray &values ) const
295  {
296  assert( values.size() >= size() );
297  Fem::ForLoop< EvaluateAllRanges, 0, setIterationSize >::apply( x, values, storage_, offset_, basisFunctionSetTuple_ );
298  }
299 
301  template< class QuadratureType, class DofVector, class RangeArray >
302  void evaluateAll ( const QuadratureType &quad, const DofVector &dofs, RangeArray &ranges ) const
303  {
304  const int nop = quad.nop();
305  for( int qp = 0; qp < nop; ++qp )
306  evaluateAll( quad[ qp ], dofs, ranges[ qp ] );
307  }
308 
310  template< class Point, class DofVector >
311  void jacobianAll ( const Point &x, const DofVector &dofs, JacobianRangeType &jacobian ) const
312  {
313  Fem::ForLoop< JacobianAll, 0, setIterationSize >::apply( x, dofs, jacobian, offset_, basisFunctionSetTuple_ );
314  }
315 
317  template< class Point, class JacobianRangeArray >
318  void jacobianAll ( const Point &x, JacobianRangeArray &jacobians ) const
319  {
320  assert( jacobians.size() >= size() );
321  Fem::ForLoop< JacobianAllRanges, 0, setIterationSize >::apply( x, jacobians, storage_, offset_, basisFunctionSetTuple_ );
322  }
323 
325  template< class QuadratureType, class DofVector, class JacobianArray >
326  void jacobianAll ( const QuadratureType &quad, const DofVector &dofs, JacobianArray &jacobians ) const
327  {
328  const int nop = quad.nop();
329  for( int qp = 0; qp < nop; ++qp )
330  jacobianAll( quad[ qp ], dofs, jacobians[ qp ] );
331  }
332 
334  template< class Point, class DofVector >
335  void hessianAll ( const Point &x, const DofVector &dofs, HessianRangeType &hessian ) const
336  {
337  Fem::ForLoop< HessianAll, 0, setIterationSize >::apply( x, dofs, hessian, offset_, basisFunctionSetTuple_ );
338  }
339 
341  template< class QuadratureType, class DofVector, class HessianArray >
342  void hessianAll ( const QuadratureType &quad, const DofVector &dofs, HessianArray &hessians ) const
343  {
344  const int nop = quad.nop();
345  for( int qp = 0; qp < nop; ++qp )
346  hessianAll( quad[ qp ], dofs, hessians[ qp ] );
347  }
348 
350  template< class Point, class HessianRangeArray >
351  void hessianAll ( const Point &x, HessianRangeArray &hessians ) const
352  {
353  assert( hessians.size() >= size() );
354  Fem::ForLoop< HessianAllRanges, 0, setIterationSize >::apply( x, hessians, storage_, offset_, basisFunctionSetTuple_ );
355  }
356 
358  template< class QuadratureType, class Vector, class DofVector >
359  void axpy ( const QuadratureType &quad, const Vector &values, DofVector &dofs ) const
360  {
361  // call axpy method for each entry of the given vector, e.g. rangeVector or jacobianVector
362  const unsigned int nop = quad.nop();
363  for( unsigned int qp = 0; qp < nop; ++qp )
364  axpy( quad[ qp ], values[ qp ], dofs );
365  }
366 
368  template< class QuadratureType, class VectorA, class VectorB, class DofVector >
369  void axpy ( const QuadratureType &quad, const VectorA &valuesA, const VectorB &valuesB, DofVector &dofs ) const
370  {
371  // call axpy method for each entry of the given vector, e.g. rangeVector or jacobianVector
372  const unsigned int nop = quad.nop();
373  for( unsigned int qp = 0; qp < nop; ++qp )
374  {
375  axpy( quad[ qp ], valuesA[ qp ], dofs );
376  axpy( quad[ qp ], valuesB[ qp ], dofs );
377  }
378  }
379 
381  template< class Point, class DofVector >
382  void axpy ( const Point &x, const RangeType &valueFactor, DofVector &dofs ) const
383  {
384  Fem::ForLoop< Axpy, 0, setIterationSize >::apply( x, valueFactor, dofs, offset_, basisFunctionSetTuple_ );
385  }
386 
388  template< class Point, class DofVector >
389  void axpy ( const Point &x, const JacobianRangeType &jacobianFactor, DofVector &dofs ) const
390  {
391  Fem::ForLoop< Axpy, 0, setIterationSize >::apply( x, jacobianFactor, dofs, offset_, basisFunctionSetTuple_ );
392  }
393 
395  template< class Point, class DofVector >
396  void axpy ( const Point &x, const HessianRangeType &hessianFactor, DofVector &dofs ) const
397  {
398  Fem::ForLoop< Axpy, 0, setIterationSize >::apply( x, hessianFactor, dofs, offset_, basisFunctionSetTuple_ );
399  }
400 
402  template< class Point, class DofVector >
403  void axpy ( const Point &x, const RangeType &valueFactor, const JacobianRangeType &jacobianFactor, DofVector &dofs ) const
404  {
405  Fem::ForLoop< Axpy, 0, setIterationSize >::apply( x, valueFactor, jacobianFactor, dofs, offset_, basisFunctionSetTuple_ );
406  }
407 
408  /***** NON Interface methods ****/
409 
411  template< int i >
413  {
414  return std::get< i >( basisFunctionSetTuple_ );
415  }
416 
418  std::size_t offset ( int i ) const
419  {
420  return offset_[ i ];
421  }
422 
425  {
426  return setSize;
427  }
428 
429  protected:
430  // unroll index sequence and take maximal order
431  template< std::size_t ... i >
432  int order ( std::index_sequence< i ... > ) const
433  {
434  return Std::max( std::get< i >( basisFunctionSetTuple_ ).order() ... );
435  }
436 
437  // unroll index sequence and sum up sizes
438  template< std::size_t ... i >
439  std::size_t size ( std::index_sequence< i ... > ) const
440  {
441  return Std::sum( std::get< i >( basisFunctionSetTuple_ ).size() ... );
442  }
443 
444  private:
445  BasisFunctionSetTupleType basisFunctionSetTuple_;
446  OffsetType offset_;
447 
448  Storage storage_;
449  };
450 
451 
452 
453  // ComputeOffset
454  // -------------
455 
456  template< class CombineOp, class ... BasisFunctionSets >
457  template< int i >
458  struct TupleBasisFunctionSet< CombineOp, BasisFunctionSets ... >::
459  ComputeOffset
460  {
461  template< class Tuple >
462  static void apply ( OffsetType &offset, const Tuple &tuple )
463  {
464  offset[ i + 1 ] = offset[ i ] + std::get< i >( tuple ).size();
465  }
466  };
467 
468 
469  // EvaluateAll
470  // -----------
471 
472  template< class CombineOp, class ... BasisFunctionSets >
473  template< int i >
474  struct TupleBasisFunctionSet< CombineOp, BasisFunctionSets ... >::
475  EvaluateAll
476  {
477  // only needed for product spaces
478  static const int rangeOffset = CombinationType :: template rangeOffset< i >();
479 
480  template< class Point, class DofVector, class Tuple >
481  static void apply ( const Point &x, const DofVector &dofVector, RangeType &values, const OffsetType &offset, const Tuple &tuple )
482  {
483  // evaluateAll for this BasisFunctionSet, with View on DofVector
484  std::size_t size = std::get< i >( tuple ).size();
485  SubVector< const DofVector, OffsetSubMapper > subDofVector( dofVector, OffsetSubMapper( size, offset[ i ] ) );
486  typename std::tuple_element< i, BasisFunctionSetTupleType >::type::RangeType thisRange;
487  std::get< i >( tuple ).evaluateAll( x, subDofVector, thisRange );
488 
489  // distribute result to values
490  CombinationType::apply( rangeOffset, thisRange, values );
491  }
492  };
493 
494 
495  // JacobianAll
496  // -----------
497 
498  template< class CombineOp, class ... BasisFunctionSets >
499  template< int i >
500  struct TupleBasisFunctionSet< CombineOp, BasisFunctionSets ... >::
501  JacobianAll
502  {
503  // only needed for product spaces
504  static const int rangeOffset = CombinationType :: template rangeOffset< i >();
505 
506  template< class Point, class DofVector, class Tuple >
507  static void apply ( const Point &x, const DofVector &dofVector, JacobianRangeType &values, const OffsetType &offset, const Tuple &tuple )
508  {
509  // jacobianAll for this BasisFunctionSet, with View on DofVector
510  std::size_t size = std::get< i >( tuple ).size();
511  SubVector< const DofVector, OffsetSubMapper > subDofVector( dofVector, OffsetSubMapper( size, offset[ i ] ) );
512  typename std::tuple_element< i, BasisFunctionSetTupleType >::type::JacobianRangeType thisJacobian;
513  std::get< i >( tuple ).jacobianAll( x, subDofVector, thisJacobian );
514 
515  // distribute result to values
516  CombinationType::apply( rangeOffset, thisJacobian, values );
517  }
518  };
519 
520 
521  // HessianAll
522  // ----------
523 
524  template< class CombineOp, class ... BasisFunctionSets >
525  template< int i >
526  struct TupleBasisFunctionSet< CombineOp, BasisFunctionSets ... >::
527  HessianAll
528  {
529  // only needed for product spaces
530  static const int rangeOffset = CombinationType :: template rangeOffset< i >();
531 
532  template< class Point, class DofVector, class Tuple >
533  static void apply ( const Point &x, const DofVector &dofVector, HessianRangeType &values, const OffsetType &offset, const Tuple &tuple )
534  {
535  // hessianAll for this BasisFunctionSet, with View on DofVector
536  std::size_t size = std::get< i >( tuple ).size();
537  SubVector< const DofVector, OffsetSubMapper > subDofVector( dofVector, OffsetSubMapper( size, offset[ i ] ) );
538  typename std::tuple_element< i, BasisFunctionSetTupleType >::type::HessianRangeType thisHessian;
539  std::get< i >( tuple ).hessianAll( x, subDofVector, thisHessian );
540 
541  // distribute result to values
542  CombinationType::apply( rangeOffset, thisHessian, values );
543  }
544  };
545 
546 
547  // EvaluateAllRanges
548  // -----------------
549 
550  template< class CombineOp, class ... BasisFunctionSets >
551  template< int i >
552  struct TupleBasisFunctionSet< CombineOp, BasisFunctionSets ... >::
553  EvaluateAllRanges
554  {
555  typedef typename std::tuple_element< i, typename Storage::RangeStorageTupleType >::type ThisStorage;
556  static const int thisDimRange = std::tuple_element< i, BasisFunctionSetTupleType >::type::FunctionSpaceType::dimRange;
557 
558  // only needed for product spaces
559  static const int rangeOffset = CombinationType :: template rangeOffset< i >();
560 
561  template< class Point, class RangeArray, class Tuple >
562  static void apply ( const Point &x, RangeArray &values, const Storage &s, const OffsetType &offset, const Tuple &tuple )
563  {
564  std::size_t size = std::get< i >( tuple ).size();
565  ThisStorage &thisStorage = s.template rangeStorage< i >();
566  thisStorage.resize( size );
567 
568  std::get< i >( tuple ).evaluateAll( x, thisStorage );
569 
570  for( std::size_t j = 0; j < size; ++j )
571  {
572  values[ j + offset[ i ] ] = RangeType( 0.0 );
573  for( int r = 0; r < thisDimRange; ++r )
574  values[ j + offset[ i ] ][ r + rangeOffset ] = thisStorage[ j ][ r ];
575  }
576  }
577  };
578 
579 
580  // JacobianAllRanges
581  // -----------------
582 
583  template< class CombineOp, class ... BasisFunctionSets >
584  template< int i >
585  struct TupleBasisFunctionSet< CombineOp, BasisFunctionSets ... >::
586  JacobianAllRanges
587  {
588  typedef typename std::tuple_element< i, typename Storage::JacobianStorageTupleType >::type ThisStorage;
589  static const int thisDimRange = std::tuple_element< i, BasisFunctionSetTupleType >::type::FunctionSpaceType::dimRange;
590 
591  // only needed for product spaces
592  static const int rangeOffset = CombinationType :: template rangeOffset< i >();
593 
594  template< class Point, class RangeArray, class Tuple >
595  static void apply ( const Point &x, RangeArray &values, const Storage &s, const OffsetType &offset, const Tuple &tuple )
596  {
597  std::size_t size = std::get< i >( tuple ).size();
598  ThisStorage &thisStorage = s.template jacobianStorage< i >();
599  thisStorage.resize( size );
600 
601  std::get< i >( tuple ).jacobianAll( x, thisStorage );
602 
603  for( std::size_t j = 0; j < size; ++j )
604  {
605  values[ j + offset[ i ] ] = JacobianRangeType( RangeFieldType( 0.0 ) );
606  for( int r = 0; r < thisDimRange; ++r )
607  values[ j + offset[ i ] ][ r + rangeOffset ] = thisStorage[ j ][ r ];
608  }
609  }
610  };
611 
612 
613  // HessianAllRanges
614  // ----------------
615 
616  template< class CombineOp, class ... BasisFunctionSets >
617  template< int i >
618  struct TupleBasisFunctionSet< CombineOp, BasisFunctionSets ... >::
619  HessianAllRanges
620  {
621  typedef typename std::tuple_element< i, typename Storage::HessianStorageTupleType >::type ThisStorage;
622  static const int thisDimRange = std::tuple_element< i, BasisFunctionSetTupleType >::type::FunctionSpaceType::dimRange;
623 
624  // only needed for product spaces
625  static const int rangeOffset = CombinationType :: template rangeOffset< i >();
626 
627  template< class Point, class RangeArray, class Tuple >
628  static void apply ( const Point &x, RangeArray &values, const Storage &s, const OffsetType &offset, const Tuple &tuple )
629  {
630  std::size_t size = std::get< i >( tuple ).size();
631  ThisStorage &thisStorage = s.template hessianStorage< i >();
632  thisStorage.resize( size );
633 
634  std::get< i >( tuple ).hessianAll( x, thisStorage );
635 
636  for( std::size_t j = 0; j < size; ++j )
637  {
638  values[ j + offset[ i ] ] = typename HessianRangeType::value_type( 0.0 );
639  for( int r = 0; r < thisDimRange; ++r )
640  values[ j + offset[ i ] ][ r + rangeOffset ] = thisStorage[ j ][ r ];
641  }
642  }
643  };
644 
645 
646  // Axpy
647  // ----
648 
649  template< class CombineOp, class ... BasisFunctionSets >
650  template< int i >
651  struct TupleBasisFunctionSet< CombineOp, BasisFunctionSets ... >::
652  Axpy
653  {
654  typedef typename std::tuple_element< i, BasisFunctionSetTupleType >::type::RangeType ThisRangeType;
655  typedef typename std::tuple_element< i, BasisFunctionSetTupleType >::type::JacobianRangeType ThisJacobianRangeType;
656  typedef typename std::tuple_element< i, BasisFunctionSetTupleType >::type::HessianRangeType ThisHessianRangeType;
657 
658  // only needed for product spaces
659  static const int rangeOffset = CombinationType :: template rangeOffset< i >();
660 
661  typedef SubObject< const RangeType, const ThisRangeType, rangeOffset > SubRangeType;
662  typedef SubObject< const JacobianRangeType, const ThisJacobianRangeType, rangeOffset > SubJacobianRangeType;
663  typedef SubObject< const HessianRangeType, const ThisHessianRangeType, rangeOffset > SubHessianRangeType;
664 
665  // axpy with range type
666  template< class Point, class DofVector, class Tuple >
667  static void apply ( const Point &x, const RangeType &factor, DofVector &dofVector, const OffsetType &offset, const Tuple &tuple )
668  {
669  std::size_t size = std::get< i >( tuple ).size();
670  SubVector< DofVector, OffsetSubMapper > subDofVector( dofVector, OffsetSubMapper( size, offset[ i ] ) );
671  SubRangeType subFactor( factor );
672  std::get< i >( tuple ).axpy( x, (ThisRangeType) subFactor, subDofVector );
673  }
674 
675  // axpy with jacobian range type
676  template< class Point, class DofVector, class Tuple >
677  static void apply ( const Point &x, const JacobianRangeType &factor, DofVector &dofVector, const OffsetType &offset, const Tuple &tuple )
678  {
679  std::size_t size = std::get< i >( tuple ).size();
680  SubVector< DofVector, OffsetSubMapper > subDofVector( dofVector, OffsetSubMapper( size, offset[ i ] ) );
681  SubJacobianRangeType subFactor( factor );
682  std::get< i >( tuple ).axpy( x, (ThisJacobianRangeType) subFactor, subDofVector );
683  }
684 
685  // axpy with hessian range type
686  template< class Point, class DofVector, class Tuple >
687  static void apply ( const Point &x, const HessianRangeType &factor, DofVector &dofVector, const OffsetType &offset, const Tuple &tuple )
688  {
689  std::size_t size = std::get< i >( tuple ).size();
690  SubVector< DofVector, OffsetSubMapper > subDofVector( dofVector, OffsetSubMapper( size, offset[ i ] ) );
691  SubHessianRangeType subFactor( factor );
692  std::get< i >( tuple ).axpy( x, (ThisHessianRangeType) subFactor, subDofVector );
693  }
694 
695  // axpy with range and jacobian range type
696  template< class Point, class DofVector, class Tuple >
697  static void apply ( const Point &x, const RangeType &rangeFactor, const JacobianRangeType &jacobianFactor, DofVector &dofVector, const OffsetType &offset, const Tuple &tuple )
698  {
699  std::size_t size = std::get< i >( tuple ).size();
700  SubVector< DofVector, OffsetSubMapper > subDofVector( dofVector, OffsetSubMapper( size, offset[ i ] ) );
701  SubRangeType subRangeFactor( rangeFactor );
702  SubJacobianRangeType subJacobianFactor( jacobianFactor );
703  std::get< i >( tuple ).axpy( x, (ThisRangeType) subRangeFactor, (ThisJacobianRangeType) subJacobianFactor, subDofVector );
704  }
705  };
706 
707  } // namespace Fem
708 
709 } // namespace Dune
710 
711 #endif // #ifndef DUNE_FEM_SPACE_BASISFUNCTIONSET_TUPLE_HH
Definition: bindguard.hh:11
IteratorRange< typename DF::DofIteratorType > dofs(DF &df)
Iterates over all DOFs.
Definition: rangegenerators.hh:76
static constexpr T max(T a)
Definition: utility.hh:77
static constexpr std::decay_t< T > sum(T a)
Definition: utility.hh:33
static DUNE_PRIVATE void apply(Args &&... args)
Definition: forloop.hh:23
Definition: utility.hh:147
Definition: space/basisfunctionset/tuple.hh:34
Definition: space/basisfunctionset/tuple.hh:35
Definition: space/basisfunctionset/tuple.hh:39
static int numSubBasisFunctionSets()
return number of subBasisFunctionSets
Definition: space/basisfunctionset/tuple.hh:424
void hessianAll(const Point &x, const DofVector &dofs, HessianRangeType &hessian) const
Definition: space/basisfunctionset/tuple.hh:335
FunctionSpaceType::HessianRangeType HessianRangeType
type of Hessian Matrix
Definition: space/basisfunctionset/tuple.hh:213
void axpy(const Point &x, const HessianRangeType &hessianFactor, DofVector &dofs) const
Definition: space/basisfunctionset/tuple.hh:396
FunctionSpaceType::RangeFieldType RangeFieldType
type of Range Vector field
Definition: space/basisfunctionset/tuple.hh:207
TupleBasisFunctionSet(const BasisFunctionSetTupleType &basisFunctionSetTuple)
Definition: space/basisfunctionset/tuple.hh:238
TupleBasisFunctionSet(const BasisFunctionSets &... basisFunctionSets)
Definition: space/basisfunctionset/tuple.hh:229
CombinationType ::FunctionSpaceType FunctionSpaceType
type of analytical combined function space
Definition: space/basisfunctionset/tuple.hh:195
void evaluateAll(const QuadratureType &quad, const DofVector &dofs, RangeArray &ranges) const
Definition: space/basisfunctionset/tuple.hh:302
bool valid() const
return true if entity was set
Definition: space/basisfunctionset/tuple.hh:268
void evaluateAll(const Point &x, const DofVector &dofs, RangeType &value) const
Definition: space/basisfunctionset/tuple.hh:287
int order(std::index_sequence< i ... >) const
Definition: space/basisfunctionset/tuple.hh:432
void evaluateAll(const Point &x, RangeArray &values) const
Definition: space/basisfunctionset/tuple.hh:294
void jacobianAll(const Point &x, const DofVector &dofs, JacobianRangeType &jacobian) const
Definition: space/basisfunctionset/tuple.hh:311
int order() const
return order of basis function set, maximal order in the tupleset
Definition: space/basisfunctionset/tuple.hh:250
TupleBasisFunctionSet()
Definition: space/basisfunctionset/tuple.hh:226
FunctionSpaceType::RangeType RangeType
type of Range Vector
Definition: space/basisfunctionset/tuple.hh:204
void axpy(const Point &x, const JacobianRangeType &jacobianFactor, DofVector &dofs) const
Definition: space/basisfunctionset/tuple.hh:389
void jacobianAll(const Point &x, JacobianRangeArray &jacobians) const
Definition: space/basisfunctionset/tuple.hh:318
std::size_t offset(int i) const
return offset of the i-th subbasisfunctionSet in the whole set
Definition: space/basisfunctionset/tuple.hh:418
std::tuple_element< 0, BasisFunctionSetTupleType >::type::ReferenceElementType ReferenceElementType
type of reference element for this BasisFunctionSet
Definition: space/basisfunctionset/tuple.hh:221
void axpy(const QuadratureType &quad, const VectorA &valuesA, const VectorB &valuesB, DofVector &dofs) const
Definition: space/basisfunctionset/tuple.hh:369
const ReferenceElementType & referenceElement() const
return entity
Definition: space/basisfunctionset/tuple.hh:280
std::size_t size() const
return size of basis function set
Definition: space/basisfunctionset/tuple.hh:256
static const int dimRange
size of domain space
Definition: space/basisfunctionset/tuple.hh:198
const EntityType & entity() const
return entity
Definition: space/basisfunctionset/tuple.hh:274
void axpy(const Point &x, const RangeType &valueFactor, const JacobianRangeType &jacobianFactor, DofVector &dofs) const
Definition: space/basisfunctionset/tuple.hh:403
void axpy(const QuadratureType &quad, const Vector &values, DofVector &dofs) const
Definition: space/basisfunctionset/tuple.hh:359
void hessianAll(const QuadratureType &quad, const DofVector &dofs, HessianArray &hessians) const
evaluate the hessian of all basis functions and store the result in the hessians array
Definition: space/basisfunctionset/tuple.hh:342
void hessianAll(const Point &x, HessianRangeArray &hessians) const
Definition: space/basisfunctionset/tuple.hh:351
std::size_t size(std::index_sequence< i ... >) const
Definition: space/basisfunctionset/tuple.hh:439
const SubBasisFunctionSet< i >::type & subBasisFunctionSet() const
return i-th subbasisfunctionSet
Definition: space/basisfunctionset/tuple.hh:412
FunctionSpaceType::DomainType DomainType
type of Domain Vector
Definition: space/basisfunctionset/tuple.hh:201
Indices< BasisFunctionSets::FunctionSpaceType::dimRange ... > RangeIndices
helper class to compute static rangeoffsets
Definition: space/basisfunctionset/tuple.hh:132
std::tuple_element< 0, BasisFunctionSetTupleType >::type::EntityType EntityType
type of Entity the basis function set is initialized on
Definition: space/basisfunctionset/tuple.hh:216
FunctionSpaceType::JacobianRangeType JacobianRangeType
type of Jacobian Vector/Matrix
Definition: space/basisfunctionset/tuple.hh:210
Dune::GeometryType type() const
Definition: space/basisfunctionset/tuple.hh:262
void axpy(const Point &x, const RangeType &valueFactor, DofVector &dofs) const
Definition: space/basisfunctionset/tuple.hh:382
void jacobianAll(const QuadratureType &quad, const DofVector &dofs, JacobianArray &jacobians) const
evaluate the jacobian of all basis functions and store the result in the jacobians array
Definition: space/basisfunctionset/tuple.hh:326
CombinationTraits< 0, CombineOp > CombinationType
Definition: space/basisfunctionset/tuple.hh:184
Definition: space/basisfunctionset/tuple.hh:136
static constexpr int rangeOffset()
Definition: space/basisfunctionset/tuple.hh:157
FunctionSpace< typename ContainedFunctionSpaceType::DomainFieldType, typename ContainedFunctionSpaceType::RangeFieldType, dimDomain, dimRange > FunctionSpaceType
type of analytical combined product function space
Definition: space/basisfunctionset/tuple.hh:147
static void apply(const int rangeOffset, const ThisRange &thisRange, Range &values)
Definition: space/basisfunctionset/tuple.hh:150
static constexpr int rangeOffset()
Definition: space/basisfunctionset/tuple.hh:177
static void apply(const int rangeOffset, const ThisRange &thisRange, Range &values)
Definition: space/basisfunctionset/tuple.hh:170
ContainedFunctionSpaceType FunctionSpaceType
type of analytical is same as contained space since its a sum
Definition: space/basisfunctionset/tuple.hh:167
Definition: space/basisfunctionset/tuple.hh:190
std::tuple_element< i, BasisFunctionSetTupleType >::type type
Definition: space/basisfunctionset/tuple.hh:191
A vector valued function space.
Definition: functionspace.hh:60
interface class representing a family of basis function sets
Definition: discontinuousgalerkin/basisfunctionsets.hh:24