1#ifndef DUNE_FEM_SPACE_COMBINEDSPACE_TUPLESPACE_HH
2#define DUNE_FEM_SPACE_COMBINEDSPACE_TUPLESPACE_HH
9#include <dune/common/hybridutilities.hh>
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>
33 template<
class CombineOp,
class ... DiscreteFunctionSpaces >
34 class TupleDiscreteFunctionSpaceImpl;
39 template<
class CombineOp,
class ... DiscreteFunctionSpaces >
40 struct TupleDiscreteFunctionSpaceTraits
42 static_assert(
sizeof ... ( DiscreteFunctionSpaces ) > 0,
43 "You should provide at least one space to the TupleDiscreteFunctionSpace" );
46 typedef std::tuple< std::shared_ptr< DiscreteFunctionSpaces > ... > DiscreteFunctionSpaceTupleType;
51 struct SubDiscreteFunctionSpace
54 typedef typename std::tuple_element< i, DiscreteFunctionSpaceTupleType >::type::element_type Type;
57 typedef typename Type::BlockMapperType BlockMapperType;
60 typedef NonBlockMapper< BlockMapperType, Type::localBlockSize > NonBlockMapperType;
63 static const Type &subDiscreteFunctionSpace (
const DiscreteFunctionSpaceTupleType &tuple )
65 assert( std::get< i >( tuple ) );
66 return *( std::get< i >( tuple ) );
69 static BlockMapperType &subBlockMapper (
const DiscreteFunctionSpaceTupleType &tuple )
71 return subDiscreteFunctionSpace( tuple ).blockMapper();
74 static NonBlockMapperType subNonBlockMapper (
const DiscreteFunctionSpaceTupleType &tuple )
76 return NonBlockMapperType( subDiscreteFunctionSpace( tuple ).blockMapper() );
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" );
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;
88 typedef typename SubDiscreteFunctionSpace< 0 >::Type::GridPartType GridPartType;
89 typedef typename GridPartType::GridType GridType;
91 typedef typename GridPartType::template Codim< 0 >::IteratorType IteratorType;
92 typedef typename IteratorType::Entity EntityType;
96 typedef TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > DiscreteFunctionSpaceType;
99 typedef TupleBasisFunctionSet< CombineOp,
typename DiscreteFunctionSpaces::BasisFunctionSetType ... > BasisFunctionSetType;
102 typedef TupleMapper< GridPartType, NonBlockMapper< typename DiscreteFunctionSpaces::BlockMapperType, DiscreteFunctionSpaces::localBlockSize > ... > BlockMapperType;
105 typedef std::index_sequence< 0 > LocalBlockIndices;
110 typedef TupleSpaceInterpolation< CombineOp, DiscreteFunctionSpaces ... > InterpolationImplType;
113 template<
class DiscreteFunction,
class Operation = DFCommunicationOperation::Copy >
114 struct CommDataHandle
117 typedef DefaultCommunicationHandler< DiscreteFunction, Operation > Type;
119 typedef Operation OperationType;
123 static BlockMapperType *getBlockMapper (
const DiscreteFunctionSpaceTupleType &spaceTuple )
125 return getBlockMapper( spaceTuple, std::index_sequence_for< DiscreteFunctionSpaces ... >() );
129 static DiscreteFunctionSpaceTupleType createSpaces ( GridPartType &gridPart,
InterfaceType commInterface,
132 DiscreteFunctionSpaceTupleType tuple;
133 Hybrid::forEach( std::make_index_sequence<
sizeof ... ( DiscreteFunctionSpaces ) >{},
136 typedef typename SubDiscreteFunctionSpace< i >::Type Element;
137 std::get< i >( tuple ) = std::make_shared< Element >( gridPart, commInterface, commDirection );
142 template<
class Entity >
143 static BasisFunctionSetType getBasisFunctionSet (
const Entity &entity,
const DiscreteFunctionSpaceTupleType &tuple )
145 return getBasisFunctionSet( entity, tuple, std::index_sequence_for< DiscreteFunctionSpaces ... >() );
148 template<
class T,
class F >
149 static T
accumulate (
const DiscreteFunctionSpaceTupleType &tuple, T value, F &&f )
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 ) );
159 template< std::size_t ... i >
160 static BlockMapperType *getBlockMapper (
const DiscreteFunctionSpaceTupleType &tuple, std::index_sequence< i ... > )
162 return new BlockMapperType( SubDiscreteFunctionSpace< 0 >::subDiscreteFunctionSpace( tuple ).gridPart(),
163 SubDiscreteFunctionSpace< i >::subNonBlockMapper( tuple ) ... );
166 template<
class Entity, std::size_t ... i >
167 static BasisFunctionSetType getBasisFunctionSet (
const Entity &entity,
const DiscreteFunctionSpaceTupleType &tuple,
168 std::index_sequence< i ... > )
170 return BasisFunctionSetType( SubDiscreteFunctionSpace< i >::subDiscreteFunctionSpace( tuple ).basisFunctionSet( entity ) ... );
190 template<
class CombineOp,
class ... DiscreteFunctionSpaces >
191 class TupleDiscreteFunctionSpaceImpl
192 :
public GenericCombinedDiscreteFunctionSpace< TupleDiscreteFunctionSpaceTraits< CombineOp, DiscreteFunctionSpaces ... > >
194 typedef TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > ThisType;
195 typedef GenericCombinedDiscreteFunctionSpace< TupleDiscreteFunctionSpaceTraits< CombineOp, DiscreteFunctionSpaces ... > > BaseType;
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;
203 typedef typename Traits::InterpolationImplType InterpolationImplType;
205 typedef LocalInterpolationWrapper< ThisType > InterpolationType;
206 typedef typename Traits::DiscreteFunctionSpaceTupleType DiscreteFunctionSpaceTupleType;
216 typename = std::enable_if_t<(... &&
217 std::is_constructible<DiscreteFunctionSpaces, GP&>::value)> >
218 TupleDiscreteFunctionSpaceImpl ( GP &gridPart,
221 : BaseType( gridPart, commInterface, commDirection )
231 TupleDiscreteFunctionSpaceImpl ( DiscreteFunctionSpaces &&... spaces )
232 : BaseType(
std::make_tuple(
std::make_shared(
std::move( spaces ) )... ) )
242 TupleDiscreteFunctionSpaceImpl (
const DiscreteFunctionSpaces &... spaces )
243 : BaseType(
std::make_tuple( referenceToSharedPtr( spaces )... ) )
253 TupleDiscreteFunctionSpaceImpl ( std::shared_ptr< const DiscreteFunctionSpaces >... spaces )
254 : BaseType(
std::make_tuple(
std::move( spaces )... ) )
264 explicit TupleDiscreteFunctionSpaceImpl ( DiscreteFunctionSpaceTupleType spaceTuple )
265 : BaseType(
std::move( spaceTuple ) )
268 TupleDiscreteFunctionSpaceImpl (
const ThisType & ) =
delete;
269 ThisType &operator= (
const ThisType & ) =
delete;
272 std::tuple<
const DiscreteFunctionSpaces & ... > spaceTuple ()
const
274 return spaceTuple( std::index_sequence_for< DiscreteFunctionSpaces ... >() );
277 InterpolationType interpolation()
const
279 return InterpolationType( *
this );
283 InterpolationImplType interpolation (
const EntityType &entity )
const
285 return localInterpolation( entity );
288 InterpolationImplType localInterpolation (
const EntityType &entity )
const
290 return localInterpolation( entity, std::index_sequence_for< DiscreteFunctionSpaces ... >() );
294 KeyType getMark(
const EntityType &entity )
const
296 DUNE_THROW(NotImplemented,
"TupleDiscreteFunctionSpaceImpl::getMark: This method has to be called on the subspaces!");
300 void mark(
const KeyType& key,
const EntityType &entity )
const
302 DUNE_THROW(NotImplemented,
"TupleDiscreteFunctionSpaceImpl::mark: This method has to be called on the subspaces!");
306 template< std::size_t ... i >
307 std::tuple<
const DiscreteFunctionSpaces & ... > spaceTuple ( std::index_sequence< i ... > )
const
309 return std::tuple<
const DiscreteFunctionSpaces & ... >( BaseType::template subDiscreteFunctionSpace< i >() ... );
312 template< std::size_t ... i >
313 InterpolationImplType localInterpolation (
const EntityType &entity, std::index_sequence< i ... > )
const
315 return InterpolationImplType( std::get< i >( spaceTuple() ) ..., entity );
319 namespace Capabilities
323 template<
template <
class>
class capability,
class ... DiscreteFunctionSpaces >
326 typedef std::tuple< DiscreteFunctionSpaces ... > SpaceTuple;
327 static const int length = std::tuple_size< SpaceTuple >::value;
329 template <
int i,
bool prev >
330 static constexpr bool acc()
332 if constexpr( i >= length )
338 return acc< i+1, prev && capability< typename std::tuple_element< i, SpaceTuple >::type >::v >();
342 static const bool v = acc<0, true>();
345 template<
template <
class>
class capability,
class ... DiscreteFunctionSpaces >
348 typedef std::tuple< DiscreteFunctionSpaces ... > SpaceTuple;
349 static const int length = std::tuple_size< SpaceTuple >::value;
351 template <
int i,
int p >
352 static constexpr int acc()
354 if constexpr( i >= length )
360 return acc< i+1, (p == capability< typename std::tuple_element< i, SpaceTuple >::type >::order) ? p : -1 >();
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 ;
370 template<
class CombineOp,
class ... DiscreteFunctionSpaces >
371 struct hasFixedPolynomialOrder< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
373 static const bool v = detail::LogicAnd< hasFixedPolynomialOrder, DiscreteFunctionSpaces ... >::v;
376 template<
class CombineOp,
class ... DiscreteFunctionSpaces >
377 struct hasStaticPolynomialOrder< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
379 typedef detail::PolOrder< hasStaticPolynomialOrder, DiscreteFunctionSpaces ... > PolOrder;
380 static const bool v = PolOrder :: v;
381 static const int order = PolOrder :: order;
384 template<
class CombineOp,
class ... DiscreteFunctionSpaces >
385 struct isContinuous< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
387 static const bool v = detail::LogicAnd< isContinuous, DiscreteFunctionSpaces ... >::v;
390 template<
class CombineOp,
class ... DiscreteFunctionSpaces >
391 struct isLocalized< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
393 static const bool v = detail::LogicAnd< isLocalized, DiscreteFunctionSpaces ... >::v;
396 template<
class CombineOp,
class ... DiscreteFunctionSpaces >
397 struct isAdaptive< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
399 static const bool v = detail::LogicAnd< isAdaptive, DiscreteFunctionSpaces ... >::v;
402 template<
class CombineOp,
class ... DiscreteFunctionSpaces >
403 struct isPAdaptiveSpace< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
405 static const bool v = detail::LogicAnd< isPAdaptiveSpace, DiscreteFunctionSpaces ... >::v;
408 template<
class CombineOp,
class ... DiscreteFunctionSpaces >
409 struct threadSafe< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
411 static const bool v = detail::LogicAnd< threadSafe, DiscreteFunctionSpaces ... >::v;
420 template<
class CombineOp,
class ... DiscreteFunctionSpaces,
class NewFunctionSpace >
421 struct DifferentDiscreteFunctionSpace< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces... >, NewFunctionSpace >
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." );
427 static const int factor = (NewFunctionSpace::dimRange / TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces... >::dimRange);
429 template<
class DiscreteFunctionSpace >
433 typedef TupleDiscreteFunctionSpaceImpl< CombineOp, typename DifferentDiscreteFunctionSpace< DiscreteFunctionSpaces, NewSubFunctionSpace< DiscreteFunctionSpaces > >::Type... > Type;
441 template<
class CombineOp,
class ... DiscreteFunctionSpaces >
442 class DefaultLocalRestrictProlong< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > >
443 :
public TupleLocalRestrictProlong< DiscreteFunctionSpaces ... >
445 typedef DefaultLocalRestrictProlong< TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > > ThisType;
446 typedef TupleDiscreteFunctionSpaceImpl< CombineOp, DiscreteFunctionSpaces ... > DiscreteFunctionSpacesType;
447 typedef TupleLocalRestrictProlong< DiscreteFunctionSpaces ... > BaseType;
450 DefaultLocalRestrictProlong (
const DiscreteFunctionSpacesType &space )
451 : BaseType( space.spaceTuple() )
457 template <
class ... DiscreteFunctionSpaces >
458 using TupleDiscreteFunctionSpace = TupleDiscreteFunctionSpaceImpl< TupleSpaceProduct, DiscreteFunctionSpaces ... >;
461 template <
class ... DiscreteFunctionSpaces >
462 using SummationDiscreteFunctionSpace = TupleDiscreteFunctionSpaceImpl< TupleSpaceSummation, DiscreteFunctionSpaces ... >;
464 template <
class ... DiscreteFunctionSpaces >
465 using EnrichedDiscreteFunctionSpace = SummationDiscreteFunctionSpace< DiscreteFunctionSpaces ... >;
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
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
convert functions space to space with new dim range
Definition: functionspace.hh:250