DUNE-FEM (unstable)

tuple.hh
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
10#include <dune/fem/common/forloop.hh>
11
12#include <dune/geometry/type.hh>
13
14#include <dune/fem/common/utility.hh>
15
16#include <dune/fem/space/basisfunctionset/basisfunctionset.hh>
17#include <dune/fem/space/combinedspace/subobjects.hh>
18#include <dune/fem/storage/subvector.hh>
19
20namespace 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 {};
35 struct TupleSpaceSummation {};
36
37 template< class CombineOp, class ... BasisFunctionSets >
38 class TupleBasisFunctionSet
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
87 static_assert( Std::are_all_same< typename BasisFunctionSets::DomainType ... >::value,
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>
136 struct CombinationTraits;
137
138 template <int dummy>
139 struct CombinationTraits< dummy, TupleSpaceProduct >
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,
147 dimDomain, dimRange > FunctionSpaceType;
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>
164 struct CombinationTraits< dummy, TupleSpaceSummation >
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
184 typedef CombinationTraits< 0, CombineOp > CombinationType;
185
186 public:
187 // export type of i-th subbasisfunction set
188 template< int i >
189 struct SubBasisFunctionSet
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
215 static_assert( Std::are_all_same< typename BasisFunctionSets::EntityType ... >::value,
216 "TupleBasisFunctionSet needs common EntityType" );
218 typedef typename std::tuple_element< 0, BasisFunctionSetTupleType >::type::EntityType EntityType;
219
220 static_assert( Std::are_all_same< typename BasisFunctionSets::ReferenceElementType ... >::value,
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
280 const ReferenceElementType &referenceElement () const
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 >
412 const typename SubBasisFunctionSet< i >::type& subBasisFunctionSet() const
413 {
414 return std::get< i >( basisFunctionSetTuple_ );
415 }
416
418 std::size_t offset ( int i ) const
419 {
420 return offset_[ i ];
421 }
422
424 static int numSubBasisFunctionSets ()
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
ImplementationDefined EntityType
entity type
Definition: basisfunctionsets.hh:29
Definition: explicitfieldvector.hh:75
FunctionSpaceTraits::RangeType RangeType
Type of range vector (using type of range field) has a Dune::FieldVector type interface.
Definition: functionspaceinterface.hh:71
@ dimRange
dimension of range vector space
Definition: functionspaceinterface.hh:48
FunctionSpaceTraits::LinearMappingType JacobianRangeType
Intrinsic type used for the jacobian values has a Dune::FieldMatrix type interface.
Definition: functionspaceinterface.hh:75
FunctionSpaceTraits::DomainType DomainType
Type of domain vector (using type of domain field) has a Dune::FieldVector type interface.
Definition: functionspaceinterface.hh:67
FunctionSpaceTraits::RangeFieldType RangeFieldType
Intrinsic type used for values in the range field (usually a double)
Definition: functionspaceinterface.hh:63
A vector valued function space.
Definition: functionspace.hh:60
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:114
unspecified value type referenceElement(T &&... t)
Returns a reference element for the objects t....
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
A unique label for each type of element that can occur in a grid.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 27, 22:29, 2024)