dune-fem  2.8-git
space/shapefunctionset/tuple.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_SPACE_SHAPEFUNCTIONSET_TUPLE_HH
2 #define DUNE_FEM_SPACE_SHAPEFUNCTIONSET_TUPLE_HH
3 
4 #include <tuple>
5 
6 #include <dune/geometry/type.hh>
7 
9 #include <dune/common/tupleutility.hh>
11 
13 
14 
15 namespace Dune
16 {
17 
18  namespace Fem
19  {
20 
21  // TupleShapeFunctionSet
22  // ---------------------
23 
24  template< class ... ShapeFunctionSets >
26  {
28 
29  template< int ... I >
30  struct RangeOffsets
31  {
32  typedef std::tuple< std::integral_constant< int, I > ... > RangeSizeTuple;
33 
34  template< int j >
35  static constexpr int size () { return std::tuple_element< j, RangeSizeTuple >::type::value; }
36 
37  template< int ... j >
38  static constexpr std::integer_sequence< int, size< j >() ... > sizes ( std::integer_sequence< int, j ... > )
39  {
40  return std::integer_sequence< int, size< j >() ... >();
41  }
42 
43  template< int i >
44  static constexpr int offset ()
45  {
46  return sum( sizes( std::make_integer_sequence< int, i >() ) );
47  }
48 
49  private:
50  template< int ... j >
51  static constexpr int sum ( std::integer_sequence< int, j ... > )
52  {
53  return Std::sum( j ... );
54  }
55 
56  static constexpr int sum ( std::integer_sequence< int > ) { return 0; }
57  };
58 
59  typedef std::array< std::size_t, sizeof ... ( ShapeFunctionSets ) +1 > Offset;
60 
61  template< int I > struct Offsets;
62  template< class Functor, class Value, int I > struct FunctorWrapper;
63 
64  template< int I > struct EvaluateEach;
65  template< int I > struct JacobianEach;
66  template< int I > struct HessianEach;
67 
68  static const std::size_t dimRange = Std::sum( static_cast< int >( ShapeFunctionSets::FunctionSpaceType::dimRange ) ... );
69 
70  public:
71  template< std::size_t i >
72  using SubShapeFunctionSetType = std::tuple_element_t< i, std::tuple< ShapeFunctionSets... > >;
73 
75 
76  typedef typename FunctionSpaceType::DomainType DomainType;
77  typedef typename FunctionSpaceType::RangeType RangeType;
78  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
79  typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
80 
81  TupleShapeFunctionSet () : offset_( {{ 0 }} ) {
82  }
83 
84  TupleShapeFunctionSet ( GeometryType type )
85  : shapeFunctionSetTuple_( makeGeometryTypeTuple( type, std::index_sequence_for< ShapeFunctionSets ... >() ) )
86  {
87  offset_[ 0 ] = 0;
88  Fem::ForLoop< Offsets, 0, sizeof ... ( ShapeFunctionSets ) -1 >::apply( shapeFunctionSetTuple_, offset_ );
89  }
90 
91  template< class ... Args >
92  TupleShapeFunctionSet ( Args && ... args )
93  : shapeFunctionSetTuple_( std::forward< Args >( args ) ... )
94  {
95  offset_[ 0 ] = 0;
96  Fem::ForLoop< Offsets, 0, sizeof ... ( ShapeFunctionSets ) -1 >::apply( shapeFunctionSetTuple_, offset_ );
97  }
98 
99  explicit TupleShapeFunctionSet ( const std::tuple< ShapeFunctionSets... > &shapeFunctionSetTuple )
100  : shapeFunctionSetTuple_( shapeFunctionSetTuple )
101  {
102  offset_[ 0 ] = 0;
103  Fem::ForLoop< Offsets, 0, sizeof ... ( ShapeFunctionSets ) -1 >::apply( shapeFunctionSetTuple_, offset_ );
104  }
105 
106  int order () const { return order( std::index_sequence_for< ShapeFunctionSets ... >() ); }
107 
108  std::size_t size () const { return size( std::index_sequence_for< ShapeFunctionSets ... >() ); }
109 
110  template< class Point, class Functor >
111  void evaluateEach ( const Point &x, Functor functor ) const
112  {
113  Fem::ForLoop< EvaluateEach, 0, sizeof ... ( ShapeFunctionSets ) -1 >::apply( shapeFunctionSetTuple_, offset_, x, functor );
114  }
115 
116  template< class Point, class Functor >
117  void jacobianEach ( const Point &x, Functor functor ) const
118  {
119  Fem::ForLoop< JacobianEach, 0, sizeof ... ( ShapeFunctionSets ) -1 >::apply( shapeFunctionSetTuple_, offset_, x, functor );
120  }
121 
122  template< class Point, class Functor >
123  void hessianEach ( const Point &x, Functor functor ) const
124  {
125  Fem::ForLoop< HessianEach, 0, sizeof ... ( ShapeFunctionSets ) -1 >::apply( shapeFunctionSetTuple_, offset_, x, functor );
126  }
127 
128  template< std::size_t i >
129  const SubShapeFunctionSetType< i > &subShapeFunctionSet ( std::integral_constant< std::size_t, i > = {} ) const
130  {
131  return std::get< i >( shapeFunctionSetTuple_ );
132  }
133 
134  protected:
135  template< std::size_t ... I >
136  int order ( std::index_sequence< I ... > ) const
137  {
138  return Std::max( std::get< I >( shapeFunctionSetTuple_ ).order() ... );
139  }
140 
141  template< std::size_t ... I >
142  std::size_t size ( std::index_sequence< I ... > ) const
143  {
144  return Std::sum( std::get< I >( shapeFunctionSetTuple_ ).size() ... );
145  }
146 
147  template< int >
148  static GeometryType makeGeometryType ( GeometryType type )
149  {
150  return type;
151  }
152 
153  template< std::size_t ... I >
154  static std::tuple< decltype( makeGeometryType< I >( std::declval< GeometryType >() ) ) ... >
155  makeGeometryTypeTuple ( GeometryType type, std::index_sequence< I ... > )
156  {
157  return std::make_tuple( makeGeometryType< I >( type ) ... );
158  }
159 
161  Offset offset_;
162  };
163 
164 
165 
166  // TupleShapeFunctionSet::Offsets
167  // ------------------------------
168 
169  template< class ... ShapeFunctionSets >
170  template< int I >
171  struct TupleShapeFunctionSet< ShapeFunctionSets ... >::Offsets
172  {
173  template< class Tuple >
174  static void apply ( const Tuple &tuple, Offset &offset )
175  {
176  offset[ I + 1 ] = offset[ I ] + std::get< I >( tuple ).size();
177  }
178  };
179 
180 
181 
182  // TupleShapeFunctionSet::FunctorWrapper
183  // -------------------------------------
184 
185  template< class ... ShapeFunctionSets >
186  template< class Functor, class Value, int I >
187  struct TupleShapeFunctionSet< ShapeFunctionSets ... >::FunctorWrapper
188  {
189  static const int rangeOffset = RangeOffsets< ShapeFunctionSets::FunctionSpaceType::dimRange ... >::template offset< I >();
190 
191  explicit FunctorWrapper ( const Functor &functor, const Offset &offset )
192  : functor_( functor ), offset_( offset ) {}
193 
194  template< class Scalar >
195  void operator() ( const std::size_t i, const Scalar &subValue )
196  {
197  Value value( typename FieldTraits< Value >::field_type( 0.0 ) );
198  std::copy( subValue.begin(), subValue.end(), value.begin() + rangeOffset );
199  functor_( offset_[ I ] + i, value );
200  }
201 
202  template< class K >
203  void operator () ( const std::size_t i, const Dune::FieldVector< K, 1 > &subValue )
204  {
205  MakeVectorialExpression< Dune::FieldVector< K, 1 >, Value > value( rangeOffset, subValue[ 0 ] );
206  functor_( offset_[ I ] + i, value );
207  }
208 
209  template< class K, int n >
210  void operator () ( const std::size_t i, const Dune::FieldMatrix< K, 1, n > &subValue )
211  {
212  MakeVectorialExpression< Dune::FieldMatrix< K, 1, n >, Value > value( rangeOffset, subValue[ 0 ] );
213  functor_( offset_[ I ] + i, value );
214  }
215 
216  template< class Scalar, class Vectorial >
217  void operator() ( const std::size_t i, const MakeVectorialExpression< Scalar, Vectorial > &subValue )
218  {
219  MakeVectorialExpression< Scalar, Value > value( subValue.component() + rangeOffset, subValue.scalar() );
220  functor_( offset_[ I ] + i, value );
221  }
222 
223  private:
224  Functor functor_;
225  const Offset &offset_;
226  };
227 
228 
229 
230  // TupleShapeFunctionSet::EvaluateEach
231  // -----------------------------------
232 
233  template< class ... ShapeFunctionSets >
234  template< int I >
235  struct TupleShapeFunctionSet< ShapeFunctionSets ... >::EvaluateEach
236  {
237  template< class Tuple, class Point, class Functor >
238  static void apply ( const Tuple &tuple, const Offset &offset, const Point &x, Functor functor )
239  {
240  FunctorWrapper< Functor, RangeType, I > functorWrapper( functor, offset );
241  std::get< I >( tuple ).evaluateEach( x, functorWrapper );
242  }
243  };
244 
245 
246 
247  // TupleShapeFunctionSet::JacobianEach
248  // -----------------------------------
249 
250  template< class ... ShapeFunctionSets >
251  template< int I >
252  struct TupleShapeFunctionSet< ShapeFunctionSets ... >::JacobianEach
253  {
254  template< class Tuple, class Point, class Functor >
255  static void apply ( const Tuple &tuple, const Offset &offset, const Point &x, Functor functor )
256  {
257  FunctorWrapper< Functor, JacobianRangeType, I > functorWrapper( functor, offset );
258  std::get< I >( tuple ).jacobianEach( x, functorWrapper );
259  }
260  };
261 
262 
263 
264  // TupleShapeFunctionSet::HessianEach
265  // ----------------------------------
266 
267  template< class ... ShapeFunctionSets >
268  template< int I >
269  struct TupleShapeFunctionSet< ShapeFunctionSets ... >::HessianEach
270  {
271  template< class Tuple, class Point, class Functor >
272  static void apply ( const Tuple &tuple, const Offset &offset, const Point &x, Functor functor )
273  {
274  FunctorWrapper< Functor, HessianRangeType, I > functorWrapper( functor, offset );
275  std::get< I >( tuple ).hessianEach( x, functorWrapper );
276  }
277  };
278 
279 
280  } // namespace Fem
281 
282 } // namespace Dune
283 
284 #endif // #ifndef DUNE_FEM_SPACE_SHAPEFUNCTIONSET_TUPLE_HH
Definition: bindguard.hh:11
static constexpr T max(T a)
Definition: utility.hh:77
static constexpr std::decay_t< T > sum(T a)
Definition: utility.hh:33
Definition: forloop.hh:17
convert functions space to space with new dim range
Definition: functionspace.hh:250
interface class representing a family of shape function sets
Definition: shapefunctionsets.hh:33
Definition: space/shapefunctionset/tuple.hh:26
int order() const
Definition: space/shapefunctionset/tuple.hh:106
std::tuple< ShapeFunctionSets... > shapeFunctionSetTuple_
Definition: space/shapefunctionset/tuple.hh:160
TupleShapeFunctionSet(GeometryType type)
Definition: space/shapefunctionset/tuple.hh:84
FunctionSpaceType::JacobianRangeType JacobianRangeType
Definition: space/shapefunctionset/tuple.hh:78
FunctionSpaceType::RangeType RangeType
Definition: space/shapefunctionset/tuple.hh:77
TupleShapeFunctionSet()
Definition: space/shapefunctionset/tuple.hh:81
Offset offset_
Definition: space/shapefunctionset/tuple.hh:161
void evaluateEach(const Point &x, Functor functor) const
Definition: space/shapefunctionset/tuple.hh:111
FunctionSpaceType::DomainType DomainType
Definition: space/shapefunctionset/tuple.hh:76
static GeometryType makeGeometryType(GeometryType type)
Definition: space/shapefunctionset/tuple.hh:148
static std::tuple< decltype(makeGeometryType< I > std::declval< GeometryType >))) ... > makeGeometryTypeTuple(GeometryType type, std::index_sequence< I ... >)
Definition: space/shapefunctionset/tuple.hh:155
TupleShapeFunctionSet(const std::tuple< ShapeFunctionSets... > &shapeFunctionSetTuple)
Definition: space/shapefunctionset/tuple.hh:99
ToNewDimRangeFunctionSpace< typename SubShapeFunctionSetType< 0 >::FunctionSpaceType, dimRange >::Type FunctionSpaceType
Definition: space/shapefunctionset/tuple.hh:74
std::size_t size() const
Definition: space/shapefunctionset/tuple.hh:108
FunctionSpaceType::HessianRangeType HessianRangeType
Definition: space/shapefunctionset/tuple.hh:79
void hessianEach(const Point &x, Functor functor) const
Definition: space/shapefunctionset/tuple.hh:123
std::tuple_element_t< i, std::tuple< ShapeFunctionSets... > > SubShapeFunctionSetType
Definition: space/shapefunctionset/tuple.hh:72
TupleShapeFunctionSet(Args &&... args)
Definition: space/shapefunctionset/tuple.hh:92
int order(std::index_sequence< I ... >) const
Definition: space/shapefunctionset/tuple.hh:136
const SubShapeFunctionSetType< i > & subShapeFunctionSet(std::integral_constant< std::size_t, i >={}) const
Definition: space/shapefunctionset/tuple.hh:129
std::size_t size(std::index_sequence< I ... >) const
Definition: space/shapefunctionset/tuple.hh:142
void jacobianEach(const Point &x, Functor functor) const
Definition: space/shapefunctionset/tuple.hh:117