1 #ifndef DUNE_FEM_DOFSTORAGE_HH
2 #define DUNE_FEM_DOFSTORAGE_HH
3 
4 #include <cassert>
5 
6 namespace Dune
7 {
8 
9   namespace Fem
10   {
11 
12     //! Indicates how the dofs shall be stored in the discrete functions
13     //! Point based means that all dofs belonging to one local degree in a
14     //! contained spaced are stored consecutively, whereas in the variable based
15     //! approach all dofs belonging to one subspace are stored consecutively
16     enum DofStoragePolicy { PointBased, VariableBased };
17 
18     //! Utility class that helps in the transformation between dofs in the
19     //! combined space and its enclosed spaces
20     template <DofStoragePolicy p>
21     class DofConversionUtility;
22 
23     //! Specialisation for PointBased approach
24     template <>
25     class DofConversionUtility<PointBased> {
26     public:
27       //! Constructor
28       //! \param numComponents Number of components in range vector (==dimRange).
DofConversionUtility(int numComponents)29       DofConversionUtility(int numComponents) :
30         numComponents_(numComponents)
31       {}
32 
33       //! Find out what type of policy this is.
policy()34       static DofStoragePolicy policy() { return PointBased; }
35 
36       //! The size of the range vector cannot change, hence this method does
37       //! nothing. (In fact, this method is only here so that you can treat
38       //! all DofStorageUtility objects identically without knowing whether they
39       //! are PointBased or VariableBased.)
newSize(int size)40       void newSize(int size) {} // just do nothing
41 
42       //! Component which the actual base function index gives a contribution
43       //! \return is in range {0, dimRange-1}
component(int combinedIndex) const44       int component(int combinedIndex) const {
45         return combinedIndex%numComponents_;
46       }
47       //! Number of the (scalar) base function belonging to base function index
containedDof(int combinedIndex) const48       int containedDof(int combinedIndex) const {
49         return combinedIndex/numComponents_;
50       }
51 
52       //! Reverse operation of containedDof, component
53       //! i == combinedDof(containedDof(i), component(i))
combinedDof(int containedIndex,int component) const54       int combinedDof(int containedIndex, int component) const {
55         return containedIndex*numComponents_ + component;
56       }
57 
58     private:
59       const int numComponents_;
60     };
61 
62     //! Specialisation for VariableBased approach
63     template <>
64     class DofConversionUtility<VariableBased> {
65     public:
66       //! Constructor
67       //! \param size Number of global dofs per component.
DofConversionUtility(int size)68       DofConversionUtility(int size) :
69         size_(size)
70       {}
71 
72       //! Find out what type of policy this is.
policy()73       static DofStoragePolicy policy() { return VariableBased; }
74 
75       //! Set new size after adaptation.
newSize(int size)76       void newSize(int size) { size_ = size; }
77 
78       //! Component which the actual base function index gives a contribution
79       //! \return is in range {0, dimRange-1}
component(int combinedIndex) const80       int component(int combinedIndex) const {
81         return combinedIndex/size_;
82       }
83 
84       //! Number of the (scalar) base function belonging to base function index
containedDof(int combinedIndex) const85       int containedDof(int combinedIndex) const {
86         return combinedIndex%size_;
87       }
88 
89       //! Reverse operation of containedDof, component
90       //! i == combinedDof(containedDof(i), component(i))
combinedDof(int containedIndex,int component) const91       int combinedDof(int containedIndex, int component) const {
92         return containedIndex + component*size_;
93       }
94 
95     private:
96       int size_;
97     };
98 
99     //! Specialisation for PointBased approach
100     template <unsigned int dimRange>
101     class PointBasedDofConversionUtility {
102     public:
103       //! Constructor
104       //! \param numComponents Number of components in range vector (==dimRange).
PointBasedDofConversionUtility(int numComponents)105       PointBasedDofConversionUtility(int numComponents)
106       {
107         // make sure that we use the correct number of components
108         assert( numComponents == int(dimRange) );
109       }
110 
111       //! Find out what type of policy this is.
policy()112       static DofStoragePolicy policy() { return PointBased; }
113 
114       //! The size of the range vector cannot change, hence this method does
115       //! nothing. (In fact, this method is only here so that you can treat
116       //! all DofStorageUtility objects identically without knowing whether they
117       //! are PointBased or VariableBased.)
newSize(const int size)118       void newSize(const int size) {} // just do nothing
119 
120       //! Component which the actual base function index gives a contribution
121       //! \return is in range {0, dimRange-1}
component(const int combinedIndex) const122       int component(const int combinedIndex) const
123       {
124         return combinedIndex % dimRange;
125       }
126       //! Number of the (scalar) base function belonging to base function index
containedDof(const int combinedIndex) const127       int containedDof(const int combinedIndex) const
128       {
129         return combinedIndex / dimRange;
130       }
131 
132       //! Reverse operation of containedDof, component
133       //! i == combinedDof(containedDof(i), component(i))
combinedDof(const int containedIndex,const int component) const134       int combinedDof(const int containedIndex,
135                       const int component) const
136       {
137         return containedIndex * dimRange + component;
138       }
139     };
140 
141   } // namespace Fem
142 
143 } // namespace Dune
144 
145 #endif // #ifndef DUNE_FEM_DOFSTORAGE_HH
146