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