1 #ifndef DUNE_FEM_COMBINEDDOFSTORAGE_HH
2 #define DUNE_FEM_COMBINEDDOFSTORAGE_HH
3 
4 //- local includes
5 #include <dune/fem/space/common/dofstorage.hh>
6 #include <dune/fem/storage/subvector.hh>
7 
8 namespace Dune
9 {
10 
11   namespace Fem
12   {
13 
14     //! Utility class that helps in the transformation between dofs in the
15     //! combined space and its enclosed spaces
16     template< class ContainedMapper, int N, DofStoragePolicy policy >
17     class CombinedDofConversionUtility;
18 
19 
20     //! does the same as DofConversionUtility<PointBased>, just other
21     //! construtor
22     template< class ContainedMapper , int N >
23     class CombinedDofConversionUtility< ContainedMapper, N, PointBased >
24     : public PointBasedDofConversionUtility< N >
25     {
26       typedef PointBasedDofConversionUtility< N >  BaseType;
27 
28     public:
29       typedef ContainedMapper ContainedMapperType;
30 
CombinedDofConversionUtility(const ContainedMapperType & mapper,const int numComponents)31       CombinedDofConversionUtility ( const ContainedMapperType & mapper, const int numComponents )
32       : BaseType( numComponents )
33       {}
34     };
35 
36     //! Specialisation for VariableBased approach
37     template< class ContainedMapper, int N >
38     class CombinedDofConversionUtility< ContainedMapper, N, VariableBased >
39     {
40     public:
41       typedef ContainedMapper ContainedMapperType;
42 
43       /** \brief constructor
44        *
45        *  \param[in]  mapper  mapper of the contained space
46        *  \param[in]  size    number of global DoFs per component
47        */
CombinedDofConversionUtility(const ContainedMapperType & mapper,int size)48       CombinedDofConversionUtility ( const ContainedMapperType &mapper, int size )
49       : mapper_( mapper )
50       {}
51 
52       //! Find out what type of policy this is.
policy()53       static DofStoragePolicy policy ()
54       {
55         return VariableBased;
56       }
57 
58       //! Set new size after adaptation.
newSize(int size)59       void newSize ( int size )
60       {}
61 
62       //! Component which the actual base function index gives a contribution
63       //! \return is in range {0, dimRange-1}
component(int combinedIndex) const64       int component ( int combinedIndex ) const
65       {
66         return combinedIndex / containedSize();
67       }
68 
69       //! Number of the (scalar) base function belonging to base function index
containedDof(int combinedIndex) const70       int containedDof ( int combinedIndex ) const
71       {
72         return combinedIndex % containedSize();
73       }
74 
75       //! Reverse operation of containedDof, component
76       //! i == combinedDof(containedDof(i), component(i))
combinedDof(int containedIndex,int component) const77       int combinedDof ( int containedIndex, int component ) const
78       {
79         return containedIndex + (component * containedSize());
80       }
81 
82     protected:
83       const ContainedMapperType &mapper_;
84 
containedSize() const85       int containedSize () const
86       {
87         return mapper_.size();
88       }
89     };
90 
91 
92 
93     template< class MapperImp, int N, DofStoragePolicy policy  >
94     class CombinedSubMapper
95     : public Fem :: IndexMapperInterface< CombinedSubMapper< MapperImp, N, policy > >
96     {
97       typedef CombinedSubMapper< MapperImp, N , policy > ThisType;
98 
99     public:
100       // original mapper
101       typedef MapperImp ContainedMapperType;
102       typedef CombinedDofConversionUtility< ContainedMapperType, N, policy > DofConversionType;
103 
CombinedSubMapper(const ContainedMapperType & mapper,unsigned int component)104       CombinedSubMapper ( const ContainedMapperType& mapper, unsigned int component )
105       : mapper_( mapper ),
106         component_( component ),
107         utilGlobal_(mapper_, policy  == PointBased ? N : mapper.size() )
108       {
109         assert(component_ < N);
110       }
111 
112       CombinedSubMapper(const ThisType& ) = default;
113       CombinedSubMapper(ThisType&& ) = default;
114       ThisType& operator=(const ThisType& ) = delete;
115       ThisType& operator=(ThisType&& ) = delete;
116 
117       //! Total number of degrees of freedom
size() const118       unsigned int size () const
119       {
120         return mapper_.size();
121       }
122 
range() const123       unsigned int range () const
124       {
125         return size() * N;
126       }
127 
operator [](unsigned int index) const128       unsigned int operator[] ( unsigned int index ) const
129       {
130         utilGlobal_.newSize( mapper_.size() );
131         return utilGlobal_.combinedDof(index, component_);
132       }
133 
134     private:
135       const ContainedMapperType& mapper_;
136       const unsigned int component_;
137       mutable DofConversionType utilGlobal_;
138     };
139 
140   } // namespace Fem
141 
142 } // namespace Dune
143 
144 #endif // #ifndef DUNE_FEM_COMBINEDDOFSTORAGE_HH
145