DUNE-FEM (unstable)

tuplespace.hh
1#ifndef DUNE_FEM_SPACE_COMBINEDSPACE_TUPLESPACE_HH
2#define DUNE_FEM_SPACE_COMBINEDSPACE_TUPLESPACE_HH
3
4#include <algorithm>
5#include <memory>
6#include <type_traits>
7#include <utility>
8
9#include <dune/common/hybridutilities.hh>
10#include <dune/common/math.hh>
11
13
14#include <dune/fem/common/memory.hh>
15#include <dune/fem/common/utility.hh>
16#include <dune/fem/space/basisfunctionset/tuple.hh>
17#include <dune/fem/space/combinedspace/generic.hh>
18#include <dune/fem/space/combinedspace/interpolation.hh>
19#include <dune/fem/space/combinedspace/tuplelocalrestrictprolong.hh>
20#include <dune/fem/space/combinedspace/tuplemapper.hh>
21#include <dune/fem/space/common/defaultcommhandler.hh>
22#include <dune/fem/space/mapper/nonblockmapper.hh>
23#include <dune/fem/space/common/localinterpolation.hh>
24#include <dune/fem/space/common/capabilities.hh>
25
26namespace Dune
27{
28
29 namespace Fem
30 {
31
32 // forward declaration
33 template< class CombineOp, class ... DiscreteFunctionSpaces >
34 class TupleDiscreteFunctionSpaceImpl;
35
36 // TupleDiscreteFunctionSpaceTraits
37 // --------------------------------
38
39 template< class CombineOp, class ... DiscreteFunctionSpaces >
40 struct TupleDiscreteFunctionSpaceTraits
41 {
42 static_assert( sizeof ... ( DiscreteFunctionSpaces ) > 0,
43 "You should provide at least one space to the TupleDiscreteFunctionSpace" );
44
45 // we need to store pointer to the spaces in the SpaceTuple, since space can not be copied.
46 typedef std::tuple< std::shared_ptr< DiscreteFunctionSpaces > ... > DiscreteFunctionSpaceTupleType;
47
48 public:
49 // helper struct to access contained sub spaces
50 template< int i >
51 struct SubDiscreteFunctionSpace
52 {
53 // type of i-th sub space
54 typedef typename std::tuple_element< i, DiscreteFunctionSpaceTupleType >::type::element_type Type;
55
56 // type of i-th sub BlockMapper
57 typedef typename Type::BlockMapperType BlockMapperType;
58
59 // we will unblock all mappers
60 typedef NonBlockMapper< BlockMapperType, Type::localBlockSize > NonBlockMapperType;
61
62 // access to a const ref of the i-th subspace
63 static const Type &subDiscreteFunctionSpace ( const DiscreteFunctionSpaceTupleType &tuple )
64 {
65 assert( std::get< i >( tuple ) );
66 return *( std::get< i >( tuple ) );
67 }
68
69 static BlockMapperType &subBlockMapper ( const DiscreteFunctionSpaceTupleType &tuple )
70 {
71 return subDiscreteFunctionSpace( tuple ).blockMapper();
72 }
73
74 static NonBlockMapperType subNonBlockMapper ( const DiscreteFunctionSpaceTupleType &tuple )
75 {
76 return NonBlockMapperType( subDiscreteFunctionSpace( tuple ).blockMapper() );
77 }
78 };
79
80 public:
81 static_assert( Std::are_all_same< typename DiscreteFunctionSpaces::GridPartType::template Codim< 0 >::EntityType ... >::value,
82 "TupleDiscreteFunctionSpace works only for GridPart's with the same entity type" );
83
84 static_assert( Std::are_all_same< std::integral_constant< int, DiscreteFunctionSpaces::Traits::codimension > ... >::value,
85 "TupleDiscreteFunctionSpace for spaces with different codimensions is not supported" );
86 static const int codimension = SubDiscreteFunctionSpace< 0 >::Type::Traits::codimension;
87
88 typedef typename SubDiscreteFunctionSpace< 0 >::Type::GridPartType GridPartType;
89 typedef typename GridPartType::GridType GridType;
90 typedef typename GridPartType::IndexSetType IndexSetType;
91 typedef typename GridPartType::template Codim< 0 >::IteratorType IteratorType;
92 typedef typename IteratorType::Entity EntityType;
93 typedef typename GridPartType::IntersectionType IntersectionType;
94
95 // type of this space
96 typedef TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > DiscreteFunctionSpaceType;
97
99 typedef TupleBasisFunctionSet< CombineOp, typename DiscreteFunctionSpaces::BasisFunctionSetType ... > BasisFunctionSetType;
100
101 // mapper
102 typedef TupleMapper< GridPartType, NonBlockMapper< typename DiscreteFunctionSpaces::BlockMapperType, DiscreteFunctionSpaces::localBlockSize > ... > BlockMapperType;
103
104 // in the most general case we will unroll all local blockings
105 typedef std::index_sequence< 0 > LocalBlockIndices;
106
107 // type functionspace
108 typedef typename BasisFunctionSetType::FunctionSpaceType FunctionSpaceType;
109
110 typedef TupleSpaceInterpolation< CombineOp, DiscreteFunctionSpaces ... > InterpolationImplType;
111
112 // review to make it work for all kind of combinations
113 template< class DiscreteFunction, class Operation = DFCommunicationOperation::Copy >
114 struct CommDataHandle
115 {
117 typedef DefaultCommunicationHandler< DiscreteFunction, Operation > Type;
119 typedef Operation OperationType;
120 };
121
122 // construct new instance of blockMapper
123 static BlockMapperType *getBlockMapper ( const DiscreteFunctionSpaceTupleType &spaceTuple )
124 {
125 return getBlockMapper( spaceTuple, std::index_sequence_for< DiscreteFunctionSpaces ... >() );
126 }
127
128 // create Tuple of contained subspaces
129 static DiscreteFunctionSpaceTupleType createSpaces ( GridPartType &gridPart, InterfaceType commInterface,
130 CommunicationDirection commDirection )
131 {
132 DiscreteFunctionSpaceTupleType tuple;
133 Hybrid::forEach( std::make_index_sequence< sizeof ... ( DiscreteFunctionSpaces ) >{},
134 [ & ]( auto i )
135 {
136 typedef typename SubDiscreteFunctionSpace< i >::Type Element;
137 std::get< i >( tuple ) = std::make_shared< Element >( gridPart, commInterface, commDirection );
138 } );
139 return tuple;
140 }
141
142 template< class Entity >
143 static BasisFunctionSetType getBasisFunctionSet ( const Entity &entity, const DiscreteFunctionSpaceTupleType &tuple )
144 {
145 return getBasisFunctionSet( entity, tuple, std::index_sequence_for< DiscreteFunctionSpaces ... >() );
146 }
147
148 template< class T, class F >
149 static T accumulate ( const DiscreteFunctionSpaceTupleType &tuple, T value, F &&f )
150 {
151 Hybrid::forEach( std::index_sequence_for< DiscreteFunctionSpaces... >{}, [ & ] ( auto &&idx ) {
152 const std::size_t i = std::decay_t< decltype( idx ) >::value;
153 value = f( value, SubDiscreteFunctionSpace< i >::subDiscreteFunctionSpace( tuple ) );
154 } );
155 return value;
156 }
157
158 protected:
159 template< std::size_t ... i >
160 static BlockMapperType *getBlockMapper ( const DiscreteFunctionSpaceTupleType &tuple, std::index_sequence< i ... > )
161 {
162 return new BlockMapperType( SubDiscreteFunctionSpace< 0 >::subDiscreteFunctionSpace( tuple ).gridPart(),
163 SubDiscreteFunctionSpace< i >::subNonBlockMapper( tuple ) ... );
164 }
165
166 template< class Entity, std::size_t ... i >
167 static BasisFunctionSetType getBasisFunctionSet ( const Entity &entity, const DiscreteFunctionSpaceTupleType &tuple,
168 std::index_sequence< i ... > )
169 {
170 return BasisFunctionSetType( SubDiscreteFunctionSpace< i >::subDiscreteFunctionSpace( tuple ).basisFunctionSet( entity ) ... );
171 }
172 };
173
174
175
190 template< class CombineOp, class ... DiscreteFunctionSpaces >
191 class TupleDiscreteFunctionSpaceImpl
192 : public GenericCombinedDiscreteFunctionSpace< TupleDiscreteFunctionSpaceTraits< CombineOp, DiscreteFunctionSpaces ... > >
193 {
194 typedef TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > ThisType;
195 typedef GenericCombinedDiscreteFunctionSpace< TupleDiscreteFunctionSpaceTraits< CombineOp, DiscreteFunctionSpaces ... > > BaseType;
196
197 public:
198 typedef decltype ( std::index_sequence_for< DiscreteFunctionSpaces ... >() ) Sequence;
199 typedef typename BaseType::Traits Traits;
200 typedef typename BaseType::GridPartType GridPartType;
201 typedef typename BaseType::EntityType EntityType;
202
203 typedef typename Traits::InterpolationImplType InterpolationImplType;
204
205 typedef LocalInterpolationWrapper< ThisType > InterpolationType;
206 typedef typename Traits::DiscreteFunctionSpaceTupleType DiscreteFunctionSpaceTupleType;
207
215 template <class GP,
216 typename = std::enable_if_t<(... &&
217 std::is_constructible<DiscreteFunctionSpaces, GP&>::value)> >
218 TupleDiscreteFunctionSpaceImpl ( GP &gridPart,
219 const InterfaceType commInterface = InteriorBorder_All_Interface,
220 const CommunicationDirection commDirection = ForwardCommunication )
221 : BaseType( gridPart, commInterface, commDirection )
222 {}
223
231 TupleDiscreteFunctionSpaceImpl ( DiscreteFunctionSpaces &&... spaces )
232 : BaseType( std::make_tuple( std::make_shared( std::move( spaces ) )... ) )
233 {}
234
242 TupleDiscreteFunctionSpaceImpl ( const DiscreteFunctionSpaces &... spaces )
243 : BaseType( std::make_tuple( referenceToSharedPtr( spaces )... ) )
244 {}
245
253 TupleDiscreteFunctionSpaceImpl ( std::shared_ptr< const DiscreteFunctionSpaces >... spaces )
254 : BaseType( std::make_tuple( std::move( spaces )... ) )
255 {}
256
264 explicit TupleDiscreteFunctionSpaceImpl ( DiscreteFunctionSpaceTupleType spaceTuple )
265 : BaseType( std::move( spaceTuple ) )
266 {}
267
268 TupleDiscreteFunctionSpaceImpl ( const ThisType & ) = delete;
269 ThisType &operator= ( const ThisType & ) = delete;
270
272 std::tuple< const DiscreteFunctionSpaces & ... > spaceTuple () const
273 {
274 return spaceTuple( std::index_sequence_for< DiscreteFunctionSpaces ... >() );
275 }
276
277 InterpolationType interpolation() const
278 {
279 return InterpolationType( *this );
280 }
281
282 [[deprecated]]
283 InterpolationImplType interpolation ( const EntityType &entity ) const
284 {
285 return localInterpolation( entity );
286 }
287
288 InterpolationImplType localInterpolation ( const EntityType &entity ) const
289 {
290 return localInterpolation( entity, std::index_sequence_for< DiscreteFunctionSpaces ... >() );
291 }
292
293 typedef int KeyType;
294 KeyType getMark( const EntityType &entity ) const
295 {
296 DUNE_THROW(NotImplemented,"TupleDiscreteFunctionSpaceImpl::getMark: This method has to be called on the subspaces!");
297 return KeyType(-1);
298 }
299
300 void mark( const KeyType& key, const EntityType &entity ) const
301 {
302 DUNE_THROW(NotImplemented,"TupleDiscreteFunctionSpaceImpl::mark: This method has to be called on the subspaces!");
303 }
304
305 protected:
306 template< std::size_t ... i >
307 std::tuple< const DiscreteFunctionSpaces & ... > spaceTuple ( std::index_sequence< i ... > ) const
308 {
309 return std::tuple< const DiscreteFunctionSpaces & ... >( BaseType::template subDiscreteFunctionSpace< i >() ... );
310 }
311
312 template< std::size_t ... i >
313 InterpolationImplType localInterpolation ( const EntityType &entity, std::index_sequence< i ... > ) const
314 {
315 return InterpolationImplType( std::get< i >( spaceTuple() ) ..., entity );
316 }
317 };
318
319 namespace Capabilities
320 {
321 namespace detail
322 {
323 template< template <class> class capability, class ... DiscreteFunctionSpaces >
324 struct LogicAnd
325 {
326 typedef std::tuple< DiscreteFunctionSpaces ... > SpaceTuple;
327 static const int length = std::tuple_size< SpaceTuple >::value;
328
329 template < int i, bool prev >
330 static constexpr bool acc()
331 {
332 if constexpr( i >= length )
333 {
334 return prev;
335 }
336 else
337 {
338 return acc< i+1, prev && capability< typename std::tuple_element< i, SpaceTuple >::type >::v >();
339 }
340 }
341
342 static const bool v = acc<0, true>();
343 };
344
345 template< template <class> class capability, class ... DiscreteFunctionSpaces >
346 struct PolOrder
347 {
348 typedef std::tuple< DiscreteFunctionSpaces ... > SpaceTuple;
349 static const int length = std::tuple_size< SpaceTuple >::value;
350
351 template < int i, int p >
352 static constexpr int acc()
353 {
354 if constexpr( i >= length )
355 {
356 return p;
357 }
358 else
359 {
360 return acc< i+1, (p == capability< typename std::tuple_element< i, SpaceTuple >::type >::order) ? p : -1 >();
361 }
362 }
363
364 static const int order = acc<0, capability< typename std::tuple_element< 0, SpaceTuple >::type >::order>();
365 static const bool v = (order >= 0) ? true : false ;
366 };
367 } // end namespace detail
368
369
370 template< class CombineOp, class ... DiscreteFunctionSpaces >
371 struct hasFixedPolynomialOrder< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
372 {
373 static const bool v = detail::LogicAnd< hasFixedPolynomialOrder, DiscreteFunctionSpaces ... >::v;
374 };
375
376 template< class CombineOp, class ... DiscreteFunctionSpaces >
377 struct hasStaticPolynomialOrder< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
378 {
379 typedef detail::PolOrder< hasStaticPolynomialOrder, DiscreteFunctionSpaces ... > PolOrder;
380 static const bool v = PolOrder :: v;
381 static const int order = PolOrder :: order;
382 };
383
384 template< class CombineOp, class ... DiscreteFunctionSpaces >
385 struct isContinuous< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
386 {
387 static const bool v = detail::LogicAnd< isContinuous, DiscreteFunctionSpaces ... >::v;
388 };
389
390 template< class CombineOp, class ... DiscreteFunctionSpaces >
391 struct isLocalized< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
392 {
393 static const bool v = detail::LogicAnd< isLocalized, DiscreteFunctionSpaces ... >::v;
394 };
395
396 template< class CombineOp, class ... DiscreteFunctionSpaces >
397 struct isAdaptive< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
398 {
399 static const bool v = detail::LogicAnd< isAdaptive, DiscreteFunctionSpaces ... >::v;
400 };
401
402 template< class CombineOp, class ... DiscreteFunctionSpaces >
403 struct isPAdaptiveSpace< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
404 {
405 static const bool v = detail::LogicAnd< isPAdaptiveSpace, DiscreteFunctionSpaces ... >::v;
406 };
407
408 template< class CombineOp, class ... DiscreteFunctionSpaces >
409 struct threadSafe< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
410 {
411 static const bool v = detail::LogicAnd< threadSafe, DiscreteFunctionSpaces ... >::v;
412 };
413 }
414
415
416 // DifferentDiscreteFunctionSpace
417 // ------------------------------
418
420 template< class CombineOp, class ... DiscreteFunctionSpaces, class NewFunctionSpace >
421 struct DifferentDiscreteFunctionSpace< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces... >, NewFunctionSpace >
422 {
423 static_assert( (NewFunctionSpace::dimRange % TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces... >::dimRange == 0),
424 "DifferentDiscreteFunctionSpace can only be applied to TupleFunctionSpace, if new dimRange is a multiple of the original one." );
425
426 private:
427 static const int factor = (NewFunctionSpace::dimRange / TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces... >::dimRange);
428
429 template< class DiscreteFunctionSpace >
431
432 public:
433 typedef TupleDiscreteFunctionSpaceImpl< CombineOp, typename DifferentDiscreteFunctionSpace< DiscreteFunctionSpaces, NewSubFunctionSpace< DiscreteFunctionSpaces > >::Type... > Type;
434 };
435
436
437
438 // DefaultLocalRestrictProlong
439 // ---------------------------
440
441 template< class CombineOp, class ... DiscreteFunctionSpaces >
442 class DefaultLocalRestrictProlong< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
443 : public TupleLocalRestrictProlong< DiscreteFunctionSpaces ... >
444 {
445 typedef DefaultLocalRestrictProlong< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > > ThisType;
446 typedef TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > DiscreteFunctionSpacesType;
447 typedef TupleLocalRestrictProlong< DiscreteFunctionSpaces ... > BaseType;
448
449 public:
450 DefaultLocalRestrictProlong ( const DiscreteFunctionSpacesType &space )
451 : BaseType( space.spaceTuple() )
452 {}
453
454 };
455
456 // Creating a space V = V_1 x V_2 x ...
457 template < class ... DiscreteFunctionSpaces >
458 using TupleDiscreteFunctionSpace = TupleDiscreteFunctionSpaceImpl< TupleSpaceProduct, DiscreteFunctionSpaces ... >;
459
460 // Creating a space V = V_1 + V_2 + ...
461 template < class ... DiscreteFunctionSpaces >
462 using SummationDiscreteFunctionSpace = TupleDiscreteFunctionSpaceImpl< TupleSpaceSummation, DiscreteFunctionSpaces ... >;
463
464 template < class ... DiscreteFunctionSpaces >
465 using EnrichedDiscreteFunctionSpace = SummationDiscreteFunctionSpace< DiscreteFunctionSpaces ... >;
466
467 } // namespace Fem
468
469} // namespace Dune
470
471#endif // #ifndef DUNE_FEM_SPACE_COMBINEDSPACE_TUPLESPACE_HH
IntersectionIteratorType::Intersection IntersectionType
type of intersection
Definition: adaptiveleafgridpart.hh:95
consecutive, persistent index set for the leaf level based on the grid's hierarchy index set
Definition: adaptiveleafindexset.hh:1351
A vector valued function space.
Definition: functionspace.hh:60
Different resources needed by all grid implementations.
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
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:257
constexpr T accumulate(Range &&range, T value, F &&f)
Accumulate values.
Definition: hybridutilities.hh:280
Some useful basic math stuff.
Dune namespace.
Definition: alignedallocator.hh:13
STL namespace.
convert functions space to space with new dim range
Definition: functionspace.hh:250
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Apr 21, 22:33, 2025)