1#ifndef DUNE_FEM_SPACE_SHAPEFUNCTIONSET_TUPLE_HH
2#define DUNE_FEM_SPACE_SHAPEFUNCTIONSET_TUPLE_HH
8#include <dune/fem/common/forloop.hh>
10#include <dune/fem/common/utility.hh>
12#include <dune/fem/space/shapefunctionset/vectorial.hh>
24 template<
class ... ShapeFunctionSets >
25 class TupleShapeFunctionSet
27 typedef TupleShapeFunctionSet< ShapeFunctionSets ... > ThisType;
32 typedef std::tuple< std::integral_constant< int, I > ... > RangeSizeTuple;
35 static constexpr int size () {
return std::tuple_element< j, RangeSizeTuple >::type::value; }
38 static constexpr std::integer_sequence< int, size< j >() ... > sizes ( std::integer_sequence< int, j ... > )
40 return std::integer_sequence< int, size< j >() ... >();
44 static constexpr int offset ()
46 return sum( sizes( std::make_integer_sequence< int, i >() ) );
51 static constexpr int sum ( std::integer_sequence< int, j ... > )
53 return Std::sum( j ... );
56 static constexpr int sum ( std::integer_sequence< int > ) {
return 0; }
59 typedef std::array< std::size_t,
sizeof ... ( ShapeFunctionSets ) +1 > Offset;
61 template<
int I >
struct Offsets;
62 template<
class Functor,
class Value,
int I >
struct FunctorWrapper;
64 template<
int I >
struct EvaluateEach;
65 template<
int I >
struct JacobianEach;
66 template<
int I >
struct HessianEach;
68 static const std::size_t dimRange = Std::sum(
static_cast< int >( ShapeFunctionSets::FunctionSpaceType::dimRange ) ... );
71 template< std::
size_t i >
72 using SubShapeFunctionSetType = std::tuple_element_t< i, std::tuple< ShapeFunctionSets... > >;
74 typedef typename ToNewDimRangeFunctionSpace< typename SubShapeFunctionSetType< 0 >::FunctionSpaceType, dimRange >::Type
FunctionSpaceType;
81 TupleShapeFunctionSet () : offset_( {{ 0 }} ) {
84 TupleShapeFunctionSet ( GeometryType type )
85 : shapeFunctionSetTuple_( makeGeometryTypeTuple( type,
std::index_sequence_for< ShapeFunctionSets ... >() ) )
88 Fem::ForLoop< Offsets, 0,
sizeof ... ( ShapeFunctionSets ) -1 >::apply( shapeFunctionSetTuple_, offset_ );
91 template<
class ... Args >
92 TupleShapeFunctionSet ( Args && ... args )
93 : shapeFunctionSetTuple_(
std::forward< Args >( args ) ... )
96 Fem::ForLoop< Offsets, 0,
sizeof ... ( ShapeFunctionSets ) -1 >::apply( shapeFunctionSetTuple_, offset_ );
99 explicit TupleShapeFunctionSet (
const std::tuple< ShapeFunctionSets... > &shapeFunctionSetTuple )
100 : shapeFunctionSetTuple_( shapeFunctionSetTuple )
103 Fem::ForLoop< Offsets, 0,
sizeof ... ( ShapeFunctionSets ) -1 >::apply( shapeFunctionSetTuple_, offset_ );
106 int order ()
const {
return order( std::index_sequence_for< ShapeFunctionSets ... >() ); }
108 std::size_t
size ()
const {
return size( std::index_sequence_for< ShapeFunctionSets ... >() ); }
110 template<
class Po
int,
class Functor >
111 void evaluateEach (
const Point &x, Functor functor )
const
113 Fem::ForLoop< EvaluateEach, 0,
sizeof ... ( ShapeFunctionSets ) -1 >::apply( shapeFunctionSetTuple_, offset_, x, functor );
116 template<
class Po
int,
class Functor >
117 void jacobianEach (
const Point &x, Functor functor )
const
119 Fem::ForLoop< JacobianEach, 0,
sizeof ... ( ShapeFunctionSets ) -1 >::apply( shapeFunctionSetTuple_, offset_, x, functor );
122 template<
class Po
int,
class Functor >
123 void hessianEach (
const Point &x, Functor functor )
const
125 Fem::ForLoop< HessianEach, 0,
sizeof ... ( ShapeFunctionSets ) -1 >::apply( shapeFunctionSetTuple_, offset_, x, functor );
128 template< std::
size_t i >
129 const SubShapeFunctionSetType< i > &subShapeFunctionSet ( std::integral_constant< std::size_t, i > = {} )
const
131 return std::get< i >( shapeFunctionSetTuple_ );
135 template< std::size_t ... I >
136 int order ( std::index_sequence< I ... > )
const
138 return Std::max( std::get< I >( shapeFunctionSetTuple_ ).order() ... );
141 template< std::size_t ... I >
142 std::size_t
size ( std::index_sequence< I ... > )
const
144 return Std::sum( std::get< I >( shapeFunctionSetTuple_ ).
size() ... );
148 static GeometryType makeGeometryType ( GeometryType type )
153 template< std::size_t ... I >
154 static std::tuple< decltype( makeGeometryType< I >( std::declval< GeometryType >() ) ) ... >
155 makeGeometryTypeTuple ( GeometryType type, std::index_sequence< I ... > )
157 return std::make_tuple( makeGeometryType< I >( type ) ... );
160 std::tuple< ShapeFunctionSets... > shapeFunctionSetTuple_;
169 template<
class ... ShapeFunctionSets >
171 struct TupleShapeFunctionSet< ShapeFunctionSets ... >::Offsets
173 template<
class Tuple >
174 static void apply (
const Tuple &tuple, Offset &offset )
176 offset[ I + 1 ] = offset[ I ] + std::get< I >( tuple ).size();
185 template<
class ... ShapeFunctionSets >
186 template<
class Functor,
class Value,
int I >
187 struct TupleShapeFunctionSet< ShapeFunctionSets ... >::FunctorWrapper
189 static const int rangeOffset = RangeOffsets< ShapeFunctionSets::FunctionSpaceType::dimRange ... >::template offset< I >();
191 explicit FunctorWrapper (
const Functor &functor,
const Offset &offset )
192 : functor_( functor ), offset_( offset ) {}
194 template<
class Scalar >
195 void operator() (
const std::size_t i,
const Scalar &subValue )
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 );
205 MakeVectorialExpression< Dune::FieldVector< K, 1 >, Value > value( rangeOffset, subValue[ 0 ] );
206 functor_( offset_[ I ] + i, value );
209 template<
class K,
int n >
212 MakeVectorialExpression< Dune::FieldMatrix< K, 1, n >, Value > value( rangeOffset, subValue[ 0 ] );
213 functor_( offset_[ I ] + i, value );
216 template<
class Scalar,
class Vectorial >
217 void operator() (
const std::size_t i,
const MakeVectorialExpression< Scalar, Vectorial > &subValue )
219 MakeVectorialExpression< Scalar, Value > value( subValue.component() + rangeOffset, subValue.scalar() );
220 functor_( offset_[ I ] + i, value );
225 const Offset &offset_;
233 template<
class ... ShapeFunctionSets >
235 struct TupleShapeFunctionSet< ShapeFunctionSets ... >::EvaluateEach
237 template<
class Tuple,
class Po
int,
class Functor >
238 static void apply (
const Tuple &tuple,
const Offset &offset,
const Point &x, Functor functor )
240 FunctorWrapper< Functor, RangeType, I > functorWrapper( functor, offset );
241 std::get< I >( tuple ).evaluateEach( x, functorWrapper );
250 template<
class ... ShapeFunctionSets >
252 struct TupleShapeFunctionSet< ShapeFunctionSets ... >::JacobianEach
254 template<
class Tuple,
class Po
int,
class Functor >
255 static void apply (
const Tuple &tuple,
const Offset &offset,
const Point &x, Functor functor )
257 FunctorWrapper< Functor, JacobianRangeType, I > functorWrapper( functor, offset );
258 std::get< I >( tuple ).jacobianEach( x, functorWrapper );
267 template<
class ... ShapeFunctionSets >
269 struct TupleShapeFunctionSet< ShapeFunctionSets ... >::HessianEach
271 template<
class Tuple,
class Po
int,
class Functor >
272 static void apply (
const Tuple &tuple,
const Offset &offset,
const Point &x, Functor functor )
274 FunctorWrapper< Functor, HessianRangeType, I > functorWrapper( functor, offset );
275 std::get< I >( tuple ).hessianEach( x, functorWrapper );
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
A unique label for each type of element that can occur in a grid.