DUNE-FEM (unstable)

tuple.hh
1#ifndef DUNE_FEM_SPACE_SHAPEFUNCTIONSET_TUPLE_HH
2#define DUNE_FEM_SPACE_SHAPEFUNCTIONSET_TUPLE_HH
3
4#include <tuple>
5
7
8#include <dune/fem/common/forloop.hh>
10#include <dune/fem/common/utility.hh>
11
12#include <dune/fem/space/shapefunctionset/vectorial.hh>
13
14
15namespace Dune
16{
17
18 namespace Fem
19 {
20
21 // TupleShapeFunctionSet
22 // ---------------------
23
24 template< class ... ShapeFunctionSets >
25 class TupleShapeFunctionSet
26 {
27 typedef TupleShapeFunctionSet< ShapeFunctionSets ... > ThisType;
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
74 typedef typename ToNewDimRangeFunctionSpace< typename SubShapeFunctionSetType< 0 >::FunctionSpaceType, dimRange >::Type FunctionSpaceType;
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
160 std::tuple< ShapeFunctionSets... > shapeFunctionSetTuple_;
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: 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
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
A vector valued function space.
Definition: functionspace.hh:60
A dense n x m matrix.
Definition: fmatrix.hh:117
vector space out of a tensor product of fields.
Definition: fvector.hh:91
Contains utility classes which can be used with std::tuple.
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:132
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
typename Overloads::ScalarType< std::decay_t< V > >::type Scalar
Element type of some SIMD type.
Definition: interface.hh:235
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
STL namespace.
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 (Nov 21, 23:30, 2024)