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