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 
12 #include <dune/grid/common/grid.hh>
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 
25 namespace Dune
26 {
27 
28  namespace Fem
29  {
30 
31  // forward declaration
32  template< class CombineOp, class ... DiscreteFunctionSpaces >
33  class TupleDiscreteFunctionSpaceImpl;
34 
35  // TupleDiscreteFunctionSpaceTraits
36  // --------------------------------
37 
38  template< class CombineOp, class ... DiscreteFunctionSpaces >
39  struct TupleDiscreteFunctionSpaceTraits
40  {
41  static_assert( sizeof ... ( DiscreteFunctionSpaces ) > 0,
42  "You should provide at least one space to the TupleDiscreteFunctionSpace" );
43 
44  // we need to store pointer to the spaces in the SpaceTuple, since space can not be copied.
45  typedef std::tuple< std::shared_ptr< DiscreteFunctionSpaces > ... > DiscreteFunctionSpaceTupleType;
46 
47  public:
48  // helper struct to access contained sub spaces
49  template< int i >
50  struct SubDiscreteFunctionSpace
51  {
52  // type of i-th sub space
53  typedef typename std::tuple_element< i, DiscreteFunctionSpaceTupleType >::type::element_type Type;
54 
55  // type of i-th sub BlockMapper
56  typedef typename Type::BlockMapperType BlockMapperType;
57 
58  // we will unblock all mappers
59  typedef NonBlockMapper< BlockMapperType, Type::localBlockSize > NonBlockMapperType;
60 
61  // access to a const ref of the i-th subspace
62  static const Type &subDiscreteFunctionSpace ( const DiscreteFunctionSpaceTupleType &tuple )
63  {
64  assert( std::get< i >( tuple ) );
65  return *( std::get< i >( tuple ) );
66  }
67 
68  static BlockMapperType &subBlockMapper ( const DiscreteFunctionSpaceTupleType &tuple )
69  {
70  return subDiscreteFunctionSpace( tuple ).blockMapper();
71  }
72 
73  static NonBlockMapperType subNonBlockMapper ( const DiscreteFunctionSpaceTupleType &tuple )
74  {
75  return NonBlockMapperType( subDiscreteFunctionSpace( tuple ).blockMapper() );
76  }
77  };
78 
79  public:
80  static_assert( Std::are_all_same< typename DiscreteFunctionSpaces::GridPartType::template Codim< 0 >::EntityType ... >::value,
81  "TupleDiscreteFunctionSpace works only for GridPart's with the same entity type" );
82 
83  static_assert( Std::are_all_same< std::integral_constant< int, DiscreteFunctionSpaces::Traits::codimension > ... >::value,
84  "TupleDiscreteFunctionSpace for spaces with different codimensions is not supported" );
85  static const int codimension = SubDiscreteFunctionSpace< 0 >::Type::Traits::codimension;
86 
87  typedef typename SubDiscreteFunctionSpace< 0 >::Type::GridPartType GridPartType;
88  typedef typename GridPartType::GridType GridType;
89  typedef typename GridPartType::IndexSetType IndexSetType;
90  typedef typename GridPartType::template Codim< 0 >::IteratorType IteratorType;
91  typedef typename IteratorType::Entity EntityType;
92  typedef typename GridPartType::IntersectionType IntersectionType;
93 
94  // type of this space
95  typedef TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > DiscreteFunctionSpaceType;
96 
98  typedef TupleBasisFunctionSet< CombineOp, typename DiscreteFunctionSpaces::BasisFunctionSetType ... > BasisFunctionSetType;
99 
100  // mapper
101  typedef TupleMapper< GridPartType, NonBlockMapper< typename DiscreteFunctionSpaces::BlockMapperType, DiscreteFunctionSpaces::localBlockSize > ... > BlockMapperType;
102 
103  // in the most general case we will unroll all local blockings
104  typedef std::index_sequence< 0 > LocalBlockIndices;
105 
106  // type functionspace
107  typedef typename BasisFunctionSetType::FunctionSpaceType FunctionSpaceType;
108 
109  typedef TupleSpaceInterpolation< CombineOp, DiscreteFunctionSpaces ... > InterpolationImplType;
110 
111  // review to make it work for all kind of combinations
112  template< class DiscreteFunction, class Operation = DFCommunicationOperation::Copy >
113  struct CommDataHandle
114  {
116  typedef DefaultCommunicationHandler< DiscreteFunction, Operation > Type;
118  typedef Operation OperationType;
119  };
120 
121  // construct new instance of blockMapper
122  static BlockMapperType *getBlockMapper ( const DiscreteFunctionSpaceTupleType &spaceTuple )
123  {
124  return getBlockMapper( spaceTuple, std::index_sequence_for< DiscreteFunctionSpaces ... >() );
125  }
126 
127  // create Tuple of contained subspaces
128  static DiscreteFunctionSpaceTupleType createSpaces ( GridPartType &gridPart, InterfaceType commInterface,
129  CommunicationDirection commDirection )
130  {
131  DiscreteFunctionSpaceTupleType tuple;
132  Hybrid::forEach( std::make_index_sequence< sizeof ... ( DiscreteFunctionSpaces ) >{},
133  [ & ]( auto i )
134  {
135  typedef typename SubDiscreteFunctionSpace< i >::Type Element;
136  std::get< i >( tuple ) = std::make_shared< Element >( gridPart, commInterface, commDirection );
137  } );
138  return tuple;
139  }
140 
141  template< class Entity >
142  static BasisFunctionSetType getBasisFunctionSet ( const Entity &entity, const DiscreteFunctionSpaceTupleType &tuple )
143  {
144  return getBasisFunctionSet( entity, tuple, std::index_sequence_for< DiscreteFunctionSpaces ... >() );
145  }
146 
147  template< class T, class F >
148  static T accumulate ( const DiscreteFunctionSpaceTupleType &tuple, T value, F &&f )
149  {
150  Hybrid::forEach( std::index_sequence_for< DiscreteFunctionSpaces... >{}, [ & ] ( auto &&idx ) {
151  const std::size_t i = std::decay_t< decltype( idx ) >::value;
152  value = f( value, SubDiscreteFunctionSpace< i >::subDiscreteFunctionSpace( tuple ) );
153  } );
154  return value;
155  }
156 
157  protected:
158  template< std::size_t ... i >
159  static BlockMapperType *getBlockMapper ( const DiscreteFunctionSpaceTupleType &tuple, std::index_sequence< i ... > )
160  {
161  return new BlockMapperType( SubDiscreteFunctionSpace< 0 >::subDiscreteFunctionSpace( tuple ).gridPart(),
162  SubDiscreteFunctionSpace< i >::subNonBlockMapper( tuple ) ... );
163  }
164 
165  template< class Entity, std::size_t ... i >
166  static BasisFunctionSetType getBasisFunctionSet ( const Entity &entity, const DiscreteFunctionSpaceTupleType &tuple,
167  std::index_sequence< i ... > )
168  {
169  return BasisFunctionSetType( SubDiscreteFunctionSpace< i >::subDiscreteFunctionSpace( tuple ).basisFunctionSet( entity ) ... );
170  }
171  };
172 
173 
174 
189  template< class CombineOp, class ... DiscreteFunctionSpaces >
190  class TupleDiscreteFunctionSpaceImpl
191  : public GenericCombinedDiscreteFunctionSpace< TupleDiscreteFunctionSpaceTraits< CombineOp, DiscreteFunctionSpaces ... > >
192  {
193  typedef TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > ThisType;
194  typedef GenericCombinedDiscreteFunctionSpace< TupleDiscreteFunctionSpaceTraits< CombineOp, DiscreteFunctionSpaces ... > > BaseType;
195 
196  public:
197  typedef decltype ( std::index_sequence_for< DiscreteFunctionSpaces ... >() ) Sequence;
198  typedef typename BaseType::Traits Traits;
199  typedef typename BaseType::GridPartType GridPartType;
200  typedef typename BaseType::EntityType EntityType;
201 
202  typedef typename Traits::InterpolationImplType InterpolationImplType;
203 
204  typedef LocalInterpolationWrapper< ThisType > InterpolationType;
205  typedef typename Traits::DiscreteFunctionSpaceTupleType DiscreteFunctionSpaceTupleType;
206 
214  template <class GP,
215  typename = std::enable_if_t<(... &&
216  std::is_constructible<DiscreteFunctionSpaces, GP&>::value)> >
217  TupleDiscreteFunctionSpaceImpl ( GP &gridPart,
218  const InterfaceType commInterface = InteriorBorder_All_Interface,
219  const CommunicationDirection commDirection = ForwardCommunication )
220  : BaseType( gridPart, commInterface, commDirection )
221  {}
222 
230  TupleDiscreteFunctionSpaceImpl ( DiscreteFunctionSpaces &&... spaces )
231  : BaseType( std::make_tuple( std::make_shared( std::move( spaces ) )... ) )
232  {}
233 
241  TupleDiscreteFunctionSpaceImpl ( const DiscreteFunctionSpaces &... spaces )
242  : BaseType( std::make_tuple( referenceToSharedPtr( spaces )... ) )
243  {}
244 
252  TupleDiscreteFunctionSpaceImpl ( std::shared_ptr< const DiscreteFunctionSpaces >... spaces )
253  : BaseType( std::make_tuple( std::move( spaces )... ) )
254  {}
255 
263  explicit TupleDiscreteFunctionSpaceImpl ( DiscreteFunctionSpaceTupleType spaceTuple )
264  : BaseType( std::move( spaceTuple ) )
265  {}
266 
267  TupleDiscreteFunctionSpaceImpl ( const ThisType & ) = delete;
268  ThisType &operator= ( const ThisType & ) = delete;
269 
271  std::tuple< const DiscreteFunctionSpaces & ... > spaceTuple () const
272  {
273  return spaceTuple( std::index_sequence_for< DiscreteFunctionSpaces ... >() );
274  }
275 
276  InterpolationType interpolation() const
277  {
278  return InterpolationType( *this );
279  }
280 
281  [[deprecated]]
282  InterpolationImplType interpolation ( const EntityType &entity ) const
283  {
284  return localInterpolation( entity );
285  }
286 
287  InterpolationImplType localInterpolation ( const EntityType &entity ) const
288  {
289  return localInterpolation( entity, std::index_sequence_for< DiscreteFunctionSpaces ... >() );
290  }
291 
292  protected:
293  template< std::size_t ... i >
294  std::tuple< const DiscreteFunctionSpaces & ... > spaceTuple ( std::index_sequence< i ... > ) const
295  {
296  return std::tuple< const DiscreteFunctionSpaces & ... >( BaseType::template subDiscreteFunctionSpace< i >() ... );
297  }
298 
299  template< std::size_t ... i >
300  InterpolationImplType localInterpolation ( const EntityType &entity, std::index_sequence< i ... > ) const
301  {
302  return InterpolationImplType( std::get< i >( spaceTuple() ) ..., entity );
303  }
304  };
305 
306 
307 
308  // DifferentDiscreteFunctionSpace
309  // ------------------------------
310 
312  template< class CombineOp, class ... DiscreteFunctionSpaces, class NewFunctionSpace >
313  struct DifferentDiscreteFunctionSpace< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces... >, NewFunctionSpace >
314  {
315  static_assert( (NewFunctionSpace::dimRange % TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces... >::dimRange == 0),
316  "DifferentDiscreteFunctionSpace can only be applied to TupleFunctionSpace, if new dimRange is a multiple of the original one." );
317 
318  private:
319  static const int factor = (NewFunctionSpace::dimRange / TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces... >::dimRange);
320 
321  template< class DiscreteFunctionSpace >
323 
324  public:
325  typedef TupleDiscreteFunctionSpaceImpl< CombineOp, typename DifferentDiscreteFunctionSpace< DiscreteFunctionSpaces, NewSubFunctionSpace< DiscreteFunctionSpaces > >::Type... > Type;
326  };
327 
328 
329 
330  // DefaultLocalRestrictProlong
331  // ---------------------------
332 
333  template< class CombineOp, class ... DiscreteFunctionSpaces >
334  class DefaultLocalRestrictProlong< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
335  : public TupleLocalRestrictProlong< DiscreteFunctionSpaces ... >
336  {
337  typedef DefaultLocalRestrictProlong< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > > ThisType;
338  typedef TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > DiscreteFunctionSpacesType;
339  typedef TupleLocalRestrictProlong< DiscreteFunctionSpaces ... > BaseType;
340 
341  public:
342  DefaultLocalRestrictProlong ( const DiscreteFunctionSpacesType &space )
343  : BaseType( space.spaceTuple() )
344  {}
345 
346  };
347 
348  // Creating a space V = V_1 x V_2 x ...
349  template < class ... DiscreteFunctionSpaces >
350  using TupleDiscreteFunctionSpace = TupleDiscreteFunctionSpaceImpl< TupleSpaceProduct, DiscreteFunctionSpaces ... >;
351 
352  // Creating a space V = V_1 + V_2 + ...
353  template < class ... DiscreteFunctionSpaces >
354  using SummationDiscreteFunctionSpace = TupleDiscreteFunctionSpaceImpl< TupleSpaceSummation, DiscreteFunctionSpaces ... >;
355 
356  template < class ... DiscreteFunctionSpaces >
357  using EnrichedDiscreteFunctionSpace = SummationDiscreteFunctionSpace< DiscreteFunctionSpaces ... >;
358 
359  } // namespace Fem
360 
361 } // namespace Dune
362 
363 #endif // #ifndef DUNE_FEM_SPACE_COMBINEDSPACE_TUPLESPACE_HH
A vector valued function space.
Definition: functionspace.hh:60
IntersectionIteratorType::Intersection IntersectionType
type of Intersection
Definition: gridpart.hh:116
Traits::IndexSetType IndexSetType
Index set implementation.
Definition: gridpart.hh:92
Different resources needed by all grid implementations.
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
concept Entity
Model of a grid entity.
Definition: entity.hh:107
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
constexpr T accumulate(Range &&range, T value, F &&f)
Accumulate values.
Definition: hybridutilities.hh:279
Some useful basic math stuff.
Dune namespace.
Definition: alignedallocator.hh:13
convert functions space to space with new dim range
Definition: functionspace.hh:250
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 8, 22:30, 2024)