1 #ifndef DUNE_FEM_SPACE_COMBINEDSPACE_GENERIC_HH
2 #define DUNE_FEM_SPACE_COMBINEDSPACE_GENERIC_HH
3 
4 #include <algorithm>
5 #include <memory>
6 
7 #include <dune/common/hybridutilities.hh>
8 
9 #include <dune/fem/space/common/discretefunctionspace.hh>
10 #include <dune/fem/space/common/dofmanager.hh>
11 
12 namespace Dune
13 {
14 
15   namespace Fem
16   {
17     // GenericCombinedDiscreteFunctionSpace
18     // ------------------------------------
19 
20     template< class Traits >
21     class GenericCombinedDiscreteFunctionSpace
22       : public DiscreteFunctionSpaceDefault< Traits >
23     {
24       typedef GenericCombinedDiscreteFunctionSpace< Traits > ThisType;
25       typedef DiscreteFunctionSpaceDefault< Traits > BaseType;
26 
27       typedef typename Traits::DiscreteFunctionSpaceTupleType DiscreteFunctionSpaceTupleType;
28 
29     public:
30       // type of i-th contained sub space
31       template< int i >
32       using SubDiscreteFunctionSpace = typename Traits::template SubDiscreteFunctionSpace< i >;
33 
34       //! extract grid informations, it is assumed the both spaces are living on the
35       //! same gridPart
36       typedef typename Traits::GridPartType GridPartType;
37       typedef typename Traits::GridType GridType;
38       typedef typename GridPartType::IntersectionType IntersectionType;
39       //! extract informations about IndexSet and Iterators
40       typedef typename Traits::IndexSetType IndexSetType;
41       typedef typename Traits::IteratorType IteratorType;
42       //! dimension of the grid (not the world)
43       enum { dimension = GridType::dimension };
44 
45       //! the underlaying analytical function space
46       typedef typename Traits::FunctionSpaceType FunctionSpaceType;
47 
48       //! type of the base function set(s)
49       typedef typename Traits::BasisFunctionSetType BasisFunctionSetType;
50 
51       //! mapper used to for block vector function
52       typedef typename Traits::BlockMapperType BlockMapperType;
53 
54       //! type of identifier for this discrete function space
55       typedef int IdentifierType;
56       //! identifier of this discrete function space
57       static const IdentifierType id = 669;
58 
59       //! type of DofManager
60       typedef DofManager< GridType > DofManagerType;
61 
62       //! default communication interface
63       static const InterfaceType defaultInterface = InteriorBorder_All_Interface;
64 
65       //! default communication direction
66       static const CommunicationDirection defaultDirection = ForwardCommunication;
67 
68       /** \brief constructor
69        *
70        *  \param[in]  gridPart       reference to the grid part
71        *  \param[in]  commInterface  communication interface to use (optional)
72        *  \param[in]  commDirection  communication direction to use (optional)
73        *
74        */
GenericCombinedDiscreteFunctionSpace(GridPartType & gridPart,const InterfaceType commInterface=defaultInterface,const CommunicationDirection commDirection=defaultDirection)75       GenericCombinedDiscreteFunctionSpace ( GridPartType &gridPart,
76                                              const InterfaceType commInterface = defaultInterface,
77                                              const CommunicationDirection commDirection = defaultDirection )
78         : BaseType( gridPart, commInterface, commDirection ),
79           spaceTuple_( Traits::createSpaces( gridPart, commInterface, commDirection ) ),
80           blockMapper_( Traits::getBlockMapper( spaceTuple_ ) )
81       {}
82 
83     protected:
84 
GenericCombinedDiscreteFunctionSpace(DiscreteFunctionSpaceTupleType && spaceTuple)85       GenericCombinedDiscreteFunctionSpace ( DiscreteFunctionSpaceTupleType &&spaceTuple )
86         : BaseType(
87             Traits::template SubDiscreteFunctionSpace< 0 >::subDiscreteFunctionSpace( spaceTuple ).gridPart(),
88             Traits::template SubDiscreteFunctionSpace< 0 >::subDiscreteFunctionSpace( spaceTuple ).communicationInterface(),
89             Traits::template SubDiscreteFunctionSpace< 0 >::subDiscreteFunctionSpace( spaceTuple ).communicationDirection() ),
90           spaceTuple_( std::move( spaceTuple ) ),
91           blockMapper_( Traits::getBlockMapper( spaceTuple_ ) )
92       {}
93 
94     public:
95 
96       GenericCombinedDiscreteFunctionSpace ( const ThisType & ) = delete;
97       ThisType &operator= ( const ThisType & ) = delete;
98 
99       using BaseType::gridPart;
100 
101       /** \copydoc Dune::Fem::DiscreteFunctionSpaceInterface::contains */
contains(const int codim) const102       bool contains ( const int codim ) const
103       {
104         // forward to mapper since this information is held there
105         return blockMapper().contains( codim );
106       }
107 
108       /** \copydoc Dune::Fem::DiscreteFunctionSpaceInterface::continuous */
continuous() const109       bool continuous () const
110       {
111         return Traits::accumulate( spaceTuple_, true, [] ( bool c, const auto &s ) { return c && s.continuous(); } );
112       }
113 
114       /** \copydoc Dune::Fem::DiscreteFunctionSpaceInterface::continuous */
continuous(const IntersectionType & intersection) const115       bool continuous ( const IntersectionType &intersection ) const
116       {
117         return Traits::accumulate( spaceTuple_, true, [ &intersection ] ( bool c, const auto &s ) { return c && s.continuous( intersection ); } );
118       }
119 
120       /** \brief get the type of this discrete function space
121           \return DFSpaceIdentifier
122        **/
type() const123       DFSpaceIdentifier type () const
124       {
125         return DFSpaceIdentifier( -1 );
126       }
127 
128       /** \copydoc Dune::Fem::DiscreteFunctionSpaceInterface::order */
order() const129       int order () const
130       {
131         return Traits::accumulate( spaceTuple_, int( 0 ), [] ( int o, const auto &s ) { return std::max( o, s.order() ); } );
132       }
133 
134       /** \copydoc Dune::Fem::DiscreteFunctionSpaceInterface::order */
135       template< class Entity >
order(const Entity & entity) const136       int order ( const Entity &entity ) const
137       {
138         return Traits::accumulate( spaceTuple_, int( 0 ), [ &entity ] ( int o, const auto &s ) { return std::max( o, s.order( entity ) ); } );
139       }
140 
141       /** \copydoc Dune::Fem::DiscreteFunctionSpaceInterface::basisFunctionSet(const EntityType &entity) const */
142       template< class EntityType >
basisFunctionSet(const EntityType & entity) const143       BasisFunctionSetType basisFunctionSet ( const EntityType &entity ) const
144       {
145         return Traits::getBasisFunctionSet( entity, spaceTuple_ );
146       }
147 
148       /** \brief obtain the DoF block mapper of this space
149           \return BlockMapperType
150        **/
blockMapper() const151       BlockMapperType &blockMapper () const
152       {
153         return *blockMapper_;
154       }
155 
156       //! obtain the i-th subspace
157       template< int i >
subDiscreteFunctionSpace() const158       const typename SubDiscreteFunctionSpace< i >::Type& subDiscreteFunctionSpace() const
159       {
160         return SubDiscreteFunctionSpace< i >::subDiscreteFunctionSpace( spaceTuple_ );
161       }
162 
163     private:
164       //! tuple of spaces
165       DiscreteFunctionSpaceTupleType spaceTuple_;
166 
167       //! BlockMapper
168       std::unique_ptr< BlockMapperType > blockMapper_;
169     };
170 
171   } // namespace Fem
172 
173 } // namespace Dune
174 
175 #endif // #ifndef DUNE_FEM_SPACE_COMBINEDSPACE_GENERIC_HH
176