DUNE-FEM (unstable)

tuple.hh
1#ifndef DUNE_FEM_SPACE_DISCONTINUOUSGALERKIN_TUPLE_HH
2#define DUNE_FEM_SPACE_DISCONTINUOUSGALERKIN_TUPLE_HH
3
4#include <tuple>
5#include <type_traits>
6#include <utility>
7
8#include <dune/common/hybridutilities.hh>
9
10#include <dune/fem/common/hybrid.hh>
11#include <dune/fem/common/utility.hh>
12#include <dune/fem/function/localfunction/converter.hh>
13#include <dune/fem/space/combinedspace/tuplelocalrestrictprolong.hh>
14#include <dune/fem/space/common/defaultcommhandler.hh>
15#include <dune/fem/space/common/localinterpolation.hh>
16#include <dune/fem/space/discontinuousgalerkin/generic.hh>
17#include <dune/fem/space/discontinuousgalerkin/basisfunctionsets.hh>
18#include <dune/fem/space/shapefunctionset/tuple.hh>
19#include <dune/fem/storage/subvector.hh>
20
21
22namespace Dune
23{
24
25 namespace Fem
26 {
27
28 // Internal Forward Declarations
29 // -----------------------------
30
31 template< class... DFS >
32 class TupleDiscontinuousGalerkinSpace;
33
34
35
36 // TupleLocalInterpolation
37 // -----------------------
38
39 template< class SFS, class... I >
40 class TupleLocalInterpolation
41 {
42 typedef TupleLocalInterpolation< SFS, I... > ThisType;
43
44 public:
45 typedef SFS ShapeFunctionSetType;
46
47 static const int dimRange = ShapeFunctionSetType::RangeType::dimension;
48
49 private:
50 template< std::size_t i >
51 using SubRangeType = typename ShapeFunctionSetType::template SubShapeFunctionSetType< i >::RangeType;
52
53 template< std::size_t... i >
54 static constexpr int sumDimSubRange ( std::index_sequence< i... > )
55 {
56 return Std::sum( SubRangeType< i >::dimension ... );
57 }
58
59 static constexpr int sumDimSubRange ( std::index_sequence<> ) { return 0; }
60
61 template< std::size_t i >
62 struct RangeConverter
63 {
64 template< class T >
65 FieldVector< T, SubRangeType< i >::dimension > operator() ( const FieldVector< T, dimRange > &in ) const
66 {
68 for( int j = 0; j < SubRangeType< i >::dimension; ++j )
69 out[ j ] = in[ j + sumDimSubRange( std::make_index_sequence< i >() ) ];
70 return out;
71 }
72
73 template< class T, int cols >
74 FieldMatrix< T, SubRangeType< i >::dimension, cols > operator() ( const FieldMatrix< T, dimRange, cols > &in ) const
75 {
76 FieldMatrix< T, SubRangeType< i >::dimension, cols > out;
77 for( int j = 0; j < SubRangeType< i >::dimension; ++j )
78 out[ j ] = in[ j + sumDimSubRange( std::make_index_sequence< i >() ) ];
79 return out;
80 }
81 };
82
83 public:
84 template< class... Args >
85 explicit TupleLocalInterpolation ( ShapeFunctionSetType shapeFunctionSet, Args &&... args )
86 : shapeFunctionSet_( std::move( shapeFunctionSet ) ),
87 interpolations_( std::forward< Args >( args )... )
88 {}
89
90 template< class LocalFunction, class LocalDofVector >
91 void operator() ( const LocalFunction &lf, LocalDofVector &ldv ) const
92 {
93 std::size_t offset = 0;
94 Hybrid::forEach( std::index_sequence_for< I... >(), [ this, &lf, &ldv, &offset ] ( auto i ) {
95 const std::size_t size = shapeFunctionSet_.subShapeFunctionSet( i ).size();
96 SubVector< LocalDofVector, OffsetSubMapper > subLdv( ldv, OffsetSubMapper( size, offset ) );
97 std::get< i >( interpolations_ ) ( localFunctionConverter( lf, RangeConverter< i >() ), subLdv );
98 offset += size;
99 } );
100 }
101
102 void unbind() {}
103
104 protected:
105 ShapeFunctionSetType shapeFunctionSet_;
106 std::tuple< I... > interpolations_;
107 };
108
109
110
111 // TupleDiscontinuousGalerkinSpaceBasisFunctionSets
112 // ------------------------------------------------
113
114 template< class... DFS >
115 class TupleDiscontinuousGalerkinSpaceBasisFunctionSets
116 {
117 typedef TupleDiscontinuousGalerkinSpaceBasisFunctionSets< DFS... > ThisType;
118
119 static_assert( sizeof...( DFS ) > 0, "TupleDiscontinuousGalerkinSpace requires at least on space." );
120
121 static_assert( Std::are_all_same< typename DFS::GridPartType... >::value, "TupleDiscontinuousGalerkinSpace only works on spaces with identical GridPart." );
122
123 template< class E, class SFS >
124 static std::true_type isDefaultBasisFunctionSet ( DefaultBasisFunctionSet< E, SFS > );
125
126 static std::false_type isDefaultBasisFunctionSet ( ... );
127
128 template< class BFS >
129 struct IsDefaultBasisFunctionSet
130 : public decltype( isDefaultBasisFunctionSet( std::declval< BFS >() ) )
131 {};
132
133 static_assert( Std::And( IsDefaultBasisFunctionSet< typename DFS::BasisFunctionSetType >::value... ), "TupleDiscontinuousGalerkinSpace only works on spaces with DefaultBasisFunctionSets." );
134
135 public:
136 template< std::size_t i >
137 using SubDiscreteFunctionSpaceType = std::tuple_element_t< i, std::tuple< DFS... > >;
138
139 typedef typename SubDiscreteFunctionSpaceType< 0 >::GridPartType GridPartType;
140
141 typedef TupleShapeFunctionSet< typename DFS::BasisFunctionSetType::ShapeFunctionSetType... > ShapeFunctionSetType;
142
143 static const int codimension = GridPartType::dimension - ShapeFunctionSetType::DomainType::dimension;
144 typedef typename GridPartType::template Codim< codimension >::EntityType EntityType;
145
146 typedef DefaultBasisFunctionSet< EntityType, ShapeFunctionSetType > BasisFunctionSetType;
147
148 TupleDiscontinuousGalerkinSpaceBasisFunctionSets ( GridPartType &gridPart, InterfaceType commInterface, CommunicationDirection commDirection )
149 : subDiscreteFunctionSpaces_( DFS( gridPart, commInterface, commDirection )... )
150 {}
151
152 int order () const { return order( std::index_sequence_for< DFS... >() ); }
153 int order ( const EntityType &entity ) const { return order( entity, std::index_sequence_for< DFS... >() ); }
154
155 BasisFunctionSetType basisFunctionSet ( const EntityType &entity ) const { return BasisFunctionSetType( entity, shapeFunctionSet( entity ) ); }
156 ShapeFunctionSetType shapeFunctionSet ( const EntityType &entity ) const { return shapeFunctionSet( entity, std::index_sequence_for< DFS... >() ); }
157
158 template< std::size_t i >
159 const SubDiscreteFunctionSpaceType< i > &subDiscreteFunctionSpace ( std::integral_constant< std::size_t, i > = {} ) const
160 {
161 return std::get< i >( subDiscreteFunctionSpaces_ );
162 }
163
164 protected:
165 template< class SFS >
166 static auto shapeFunctionSet ( const DefaultBasisFunctionSets< GridPartType, SFS > &basisFunctionSets, const EntityType &entity )
167 {
168 return basisFunctionSets.shapeFunctionSets().shapeFunctionSet( entity.type() );
169 }
170
171 template< class BFS >
172 static auto shapeFunctionSet ( const BFS &basisFunctionSets, const EntityType &entity )
173 {
174 return basisFunctionSets.basisFunctionSet( entity ).shapeFunctionSet();
175 }
176
177 template< std::size_t... i >
178 int order ( std::index_sequence< i... > ) const
179 {
180 return Std::max( subDiscreteFunctionSpace< i >().order()... );
181 }
182
183 template< std::size_t... i >
184 int order ( const EntityType &entity, std::index_sequence< i... > ) const
185 {
186 return Std::max( subDiscreteFunctionSpace< i >().order( entity )... );
187 }
188
189 template< std::size_t... i >
190 ShapeFunctionSetType shapeFunctionSet ( const EntityType &entity, std::index_sequence< i... > ) const
191 {
192 return ShapeFunctionSetType( shapeFunctionSet( subDiscreteFunctionSpace< i >().basisFunctionSets(), entity )... );
193 }
194
195 private:
196 std::tuple< DFS... > subDiscreteFunctionSpaces_;
197 };
198
199
200
201 // TaylorHoodDiscontinuousGalerkinSpaceTraits
202 // ------------------------------------------
203
204 template< class... DFS >
205 struct TupleDiscontinuousGalerkinSpaceTraits
206 {
207 typedef TupleDiscontinuousGalerkinSpace< DFS... > DiscreteFunctionSpaceType;
208
209 typedef TupleDiscontinuousGalerkinSpaceBasisFunctionSets< DFS... > BasisFunctionSetsType;
210
211 typedef typename BasisFunctionSetsType::GridPartType GridPartType;
212 typedef typename BasisFunctionSetsType::BasisFunctionSetType BasisFunctionSetType;
213
215
216 static const int codimension = BasisFunctionSetsType::codimension;
217
218 typedef Hybrid::CompositeIndexRange< typename DFS::LocalBlockIndices... > LocalBlockIndices;
219
220 static const int polynomialOrder = Std::max( static_cast< int >( DFS::polynomialOrder )... );
221
222 typedef CodimensionMapper< GridPartType, codimension > BlockMapperType;
223
224 template< class DiscreteFunction, class Operation = DFCommunicationOperation::Copy >
225 struct CommDataHandle
226 {
227 typedef Operation OperationType;
228 typedef DefaultCommunicationHandler< DiscreteFunction, Operation > Type;
229 };
230 };
231
232
233
234 // TaylorHoodDiscontinuousGalerkinSpace
235 // ------------------------------------
236
237 template< class... DFS >
238 class TupleDiscontinuousGalerkinSpace
239 : public GenericDiscontinuousGalerkinSpace< TupleDiscontinuousGalerkinSpaceTraits< DFS... > >
240 {
241 typedef TupleDiscontinuousGalerkinSpace< DFS... > ThisType;
242 typedef GenericDiscontinuousGalerkinSpace< TupleDiscontinuousGalerkinSpaceTraits< DFS... > > BaseType;
243
244 public:
245 typedef TupleDiscontinuousGalerkinSpaceTraits< DFS... > Traits;
246
247 typedef typename BaseType::BasisFunctionSetType BasisFunctionSetType;
248 typedef typename BaseType::BasisFunctionSetsType BasisFunctionSetsType;
249 typedef typename BaseType::EntityType EntityType;
250 typedef typename BaseType::GridPartType GridPartType;
251
252 template< std::size_t i >
253 using SubDiscreteFunctionSpaceType = typename BasisFunctionSetsType::template SubDiscreteFunctionSpaceType< i >;
254
255 typedef TupleLocalInterpolation< typename BasisFunctionSetsType::ShapeFunctionSetType, typename DFS::InterpolationImplType... > InterpolationImplType;
256 typedef LocalInterpolationWrapper< ThisType > InterpolationType;
257
258 using BaseType::basisFunctionSets;
259
260 TupleDiscontinuousGalerkinSpace ( GridPartType &gridPart, InterfaceType commInterface = InteriorBorder_All_Interface, CommunicationDirection commDirection = ForwardCommunication )
261 : BaseType( gridPart, BasisFunctionSetsType( gridPart, commInterface, commDirection ), commInterface, commDirection )
262 {}
263
264 InterpolationType interpolation () const { return InterpolationType( *this ); }
265
266 [[deprecated]]
267 InterpolationImplType interpolation ( const EntityType &entity ) const { return localInterpolation( entity ); }
268
269 InterpolationImplType localInterpolation ( const EntityType &entity ) const { return localInterpolation( entity, std::index_sequence_for< DFS... >() ); }
270
271 template< std::size_t i >
272 const SubDiscreteFunctionSpaceType< i > &subDiscreteFunctionSpace ( std::integral_constant< std::size_t, i > = {} ) const
273 {
274 return basisFunctionSets().subDiscreteFunctionSpace( std::integral_constant< std::size_t, i >() );
275 }
276
277 private:
278 template< std::size_t... i >
279 InterpolationImplType localInterpolation ( const EntityType &entity, std::index_sequence< i... > ) const
280 {
281 return InterpolationImplType( basisFunctionSets().shapeFunctionSet( entity ), subDiscreteFunctionSpace< i >().localInterpolation( entity )... );
282 }
283 };
284
285
286
287 // DifferentDiscreteFunctionSpace
288 // ------------------------------
289
290 template< class... DFS, class NewFunctionSpace >
291 struct DifferentDiscreteFunctionSpace< TupleDiscontinuousGalerkinSpace< DFS... >, NewFunctionSpace >
292 {
293 static_assert( NewFunctionSpace::dimRange % TupleDiscontinuousGalerkinSpace< DFS... >::dimRange == 0,
294 "DifferentDiscreteFunctionSpace can only be applied to TupleDiscontinuousGalerkinSpace, if new dimRange is a multiple of the original one." );
295
296 private:
297 static const int factor = (NewFunctionSpace::dimRange / TupleDiscontinuousGalerkinSpace< DFS... >::dimRange);
298
299 template< int dimRange >
300 using NewSubFunctionSpace = typename ToNewDimRangeFunctionSpace< NewFunctionSpace, factor*dimRange >::Type;
301
302 public:
303 typedef TupleDiscontinuousGalerkinSpace< typename DifferentDiscreteFunctionSpace< DFS, NewSubFunctionSpace< DFS::dimRange > >::Type... > Type;
304 };
305
306
307
308 // DefaultLocalRestrictProlong
309 // ---------------------------
310
311 template< class... DFS >
312 class DefaultLocalRestrictProlong< TupleDiscontinuousGalerkinSpace< DFS... > >
313 : public TupleLocalRestrictProlong< DFS... >
314 {
315 typedef DefaultLocalRestrictProlong< TupleDiscontinuousGalerkinSpace< DFS... > > ThisType;
316 typedef TupleLocalRestrictProlong< DFS... > BaseType;
317
318 public:
319 typedef TupleDiscontinuousGalerkinSpace< DFS... > DiscreteFunctionSpaceType;
320
321 DefaultLocalRestrictProlong ( const DiscreteFunctionSpaceType &space )
322 : BaseType( subDiscreteFunctionSpaces( space, std::index_sequence_for< DFS... >() ) )
323 {}
324
325 private:
326 template< std::size_t... i >
327 static std::tuple< const DFS &... > subDiscreteFunctionSpaces ( const DiscreteFunctionSpaceType &space, std::index_sequence< i... > )
328 {
329 return std::tie( space.subDiscreteFunctionSpace( std::integral_constant< std::size_t, i >() )... );
330 }
331 };
332
333 } // namespace Fem
334
335} // namespace Dune
336
337#endif // #ifndef DUNE_FEM_SPACE_DISCONTINUOUSGALERKIN_TUPLE_HH
ToNewDimDomainFunctionSpace< LocalFunctionSpaceType, Geometry::coorddimension >::Type FunctionSpaceType
type of function space
Definition: default.hh:79
A vector valued function space.
Definition: functionspace.hh:60
BaseType::GridPartType GridPartType
type of underlying grid part
Definition: generic.hh:40
BaseType::EntityType EntityType
type of entity of codimension 0
Definition: generic.hh:42
BaseType::BasisFunctionSetType BasisFunctionSetType
type of basis function set of this space
Definition: generic.hh:49
Traits::BasisFunctionSetsType BasisFunctionSetsType
basis function sets
Definition: generic.hh:47
static constexpr int dimension
The size of this vector.
Definition: fvector.hh:100
CommunicationDirection
Define a type for communication direction parameter.
Definition: gridenums.hh:170
InterfaceType
Parameter to be used for the communication functions.
Definition: gridenums.hh:86
@ ForwardCommunication
communicate as given in InterfaceType
Definition: gridenums.hh:171
@ InteriorBorder_All_Interface
send interior and border, receive all entities
Definition: gridenums.hh:88
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
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.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 27, 22:29, 2024)