1 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 // vi: set et ts=8 sw=2 sts=2: 3 4 #ifndef DUNE_PDELAB_GRIDFUNCTIONSPACE_TAGS_HH 5 #define DUNE_PDELAB_GRIDFUNCTIONSPACE_TAGS_HH 6 7 #include <dune/grid/common/gridenums.hh> 8 #include <dune/typetree/utility.hh> 9 10 #include <dune/pdelab/common/dofindex.hh> 11 #include <dune/pdelab/common/simpledofindex.hh> 12 13 #include <numeric> 14 15 namespace Dune { 16 namespace PDELab { 17 18 //! \addtogroup GridFunctionSpace 19 //! \ingroup PDELab 20 //! \{ 21 22 struct FunctionSpaceTag {}; 23 24 struct GridFunctionSpaceTag : public FunctionSpaceTag {}; 25 26 struct PowerGridFunctionSpaceTag : public GridFunctionSpaceTag {}; 27 28 struct VectorGridFunctionSpaceTag : public PowerGridFunctionSpaceTag {}; 29 30 struct CompositeGridFunctionSpaceTag : public GridFunctionSpaceTag {}; 31 32 struct LeafGridFunctionSpaceTag : public GridFunctionSpaceTag {}; 33 34 template<typename ProxiedGFSTag> 35 struct GridFunctionSubSpaceTag 36 : public ProxiedGFSTag 37 {}; 38 39 //! Tag for the intermediate base class of the CompositeGridFunctionSpace. 40 struct CompositeGridFunctionSpaceBaseTag {}; 41 42 //! \brief Indicate blocking of the unknowns by grid entity. 43 /** 44 * This class instructs the non-leaf GridFunctionSpaces to block the dofs 45 * of the child-GridFunctionSpaces by grid entity, i.e. first all dofs of 46 * all children that belong to vertex 0, then all dofs associated with vertex 47 * 1 etc. 48 * 49 * The EntityBlockedOrdering correctly handles different block sizes for different 50 * GeometryTypes as well as GridFunctionSpaces with variable sizes, e.g. for 51 * $p$-adaptivity and in a MultiDomain context. 52 */ 53 struct EntityBlockedOrderingTag {}; 54 55 //! \brief Indicate lexicographic ordering of the unknowns of non-leaf 56 //! grid function spaces. 57 /** 58 * This class instructs the non-leaf GridFunctionSpaces to order the dofs 59 * of the child-GridFunctionSpaces in a lexicographic manner in the 60 * combined dof-vector, i.e. first all dofs of child 0, then all dofs of 61 * child 1 and so on. 62 */ 63 struct LexicographicOrderingTag { }; 64 65 //! \brief Indicate interleaved ordering of the unknowns of non-leaf 66 //! grid function spaces according to a given blocking pattern. 67 /** 68 * This class instructs the non-leaf GridFunctionSpaces to order the dofs 69 * of the child-GridFunctionSpaces in an interleaved manner in the 70 * combined dof-vector. The sizes of the individual blocks have to be passed 71 * to the constructor of the tag. 72 * 73 * \note In the vast majority of scenarios, you will want to use the 74 * EntityBlockedOrderingTag instead of this one, as it is much less error-prone 75 * and works in a wider variety of settings. Only use the InterleavedOrderingTag 76 * if you know that the EntityBlockedOrderingTag will not work for you! 77 */ 78 struct InterleavedOrderingTag 79 { 80 81 //! Constructs an InterleavedOrderingTag with a block structure given by the initializer list sizes. 82 /** 83 * If you have a sufficiently recent compiler, this constructor enables a much more readable 84 * syntax when creating a GridFunctionSpace. Assuming that GFS is a PowerGridFunctionSpace and VBE its 85 * associated vector backend, you can shorten the verbose 86 * 87 * \code 88 * std::vector<std::size_t> sizes(3); 89 * sizes[0] = 2; 90 * sizes[1] = 5; 91 * sizes[2] = 3; 92 * GFS gfs(child_gfs,VBE(),InterleavedOrderingTag(sizes)); 93 * \endcode 94 * 95 * to the much shorter and more readable 96 * 97 * \code 98 * GFS gfs(child_gfs,VBE(),{2,5,3}); 99 * \endcode 100 */ InterleavedOrderingTagDune::PDELab::InterleavedOrderingTag101 InterleavedOrderingTag(std::initializer_list<std::size_t> sizes) 102 : _offsets(sizes.size() + 1,0) 103 { 104 std::partial_sum(sizes.begin(),sizes.end(),_offsets.begin() + 1); 105 } 106 107 //! Constructs an InterleavedOrderingTag with a block structure given by the std::vector sizes. InterleavedOrderingTagDune::PDELab::InterleavedOrderingTag108 InterleavedOrderingTag(std::vector<std::size_t> sizes) 109 : _offsets(sizes.size() + 1,0) 110 { 111 std::partial_sum(sizes.begin(),sizes.end(),_offsets.begin() + 1); 112 } 113 114 //! Returns a list of offsets for the child blocks. offsetsDune::PDELab::InterleavedOrderingTag115 const std::vector<std::size_t>& offsets() const 116 { 117 return _offsets; 118 } 119 120 private: 121 122 std::vector<std::size_t> _offsets; 123 }; 124 125 //! Mixin indicating whether a leaf GridFunctionSpace should never assume a const ordering size. 126 template<bool v> 127 struct NoConstOrderingSize 128 { 129 static const bool no_const_ordering_size = v; 130 }; 131 132 namespace { 133 134 // Use this compile-time bridge to shup up GCC warnings 135 136 template<int i> 137 struct shift_if_nonnegative 138 { 139 static const unsigned int value = 1 << i; 140 }; 141 142 template<> 143 struct shift_if_nonnegative<-1> 144 { 145 static const unsigned int value = 0; 146 }; 147 148 } 149 150 //! Helper for building the bitmask describing the grid partitions contained in a GFS. 151 /** 152 * This struct should be used to construct the bitmask for use by the 153 * PartitionInfoProvider. 154 */ 155 template<int p0 = -1, int p1 = -1, int p2 = -1, int p3 = -1, int p4 = -1> 156 struct PartitionSelector 157 { 158 159 static const unsigned int partition_mask = 160 shift_if_nonnegative<p0>::value | 161 shift_if_nonnegative<p1>::value | 162 shift_if_nonnegative<p2>::value | 163 shift_if_nonnegative<p3>::value | 164 shift_if_nonnegative<p4>::value; 165 166 }; 167 168 struct EmptyParams 169 {}; 170 171 //! Tag indicating a standard ordering for a leaf GridfunctionSpace. 172 /** 173 * Any additional policies regarding the ordering should be passed via 174 * the template parameter Params. By itself, this tag indicates that the 175 * user wants to use the standard, MultiIndex-based ordering infrastructure 176 * for this GridFunctionSpace. 177 * 178 * \tparam Params Parameter struct for passing additional static information 179 * to the ordering. This parameter will become the base class 180 * of the tag. 181 */ 182 template<typename Params> 183 struct LeafOrderingTag 184 : public Params 185 {}; 186 187 using DefaultLeafOrderingTag = LeafOrderingTag<EmptyParams>; 188 189 //! Tag indicating a function space with a single unknown attached to every 190 //! entity of a exactly one single codimension. 191 struct SingleCodimMapper {}; 192 193 //! Tag denoting a PowerLocalFunctionSpace 194 struct PowerLocalFunctionSpaceTag {}; 195 196 //! Tag denoting a CompositeLocalFunctionSpace 197 struct CompositeLocalFunctionSpaceTag {}; 198 199 //! Tag denoting a LeafLocalFunctionSpace 200 struct LeafLocalFunctionSpaceTag {}; 201 202 //! Tag for denoting possibly nested containers, requiring a recursive 203 //! allocation algorithm. 204 struct HierarchicContainerAllocationTag {}; 205 206 //! Tag for denoting that a backend / ordering will always spawn flat 207 //! containers. 208 struct FlatContainerAllocationTag {}; 209 210 //! Tag denoting that an ordering will work with the default implementation 211 //! of the LFSIndexCache. 212 struct DefaultLFSCacheTag {}; 213 214 //! Tag denoting that an ordering will work with the simplified version of 215 //! the LFSIndexCache. 216 struct SimpleLFSCacheTag {}; 217 218 namespace Experimental { 219 220 struct DuneFunctionsCacheTag {}; 221 222 } 223 224 template<typename GFS, typename Tag> 225 struct _build_dof_index_type 226 { 227 typedef Dune::PDELab::DOFIndex<std::size_t,TypeTree::TreeInfo<GFS>::depth,2> type; 228 }; 229 230 template<typename GFS> 231 struct _build_dof_index_type<GFS,SingleCodimMapper> 232 { 233 typedef SimpleDOFIndex<typename GFS::Traits::SizeType> type; 234 }; 235 236 237 template<typename GFS> 238 struct build_dof_index_type 239 { 240 typedef typename _build_dof_index_type<GFS,typename GFS::OrderingTag>::type type; 241 }; 242 243 244 #ifndef DOXYGEN 245 246 //! GridFunctionSpace to LocalFunctionSpace transformation. 247 /** 248 * gfs_to_lfs describes the transformation of a GridFunctionSpace tree to its corresponding 249 * LocalFunctionSpace tree and holds any information that may be required for performing 250 * the transformation. 251 * 252 * \warning The exact meaning of the template parameter is an implementation detail 253 * and may change at any time, as the only class that is supposed to instantiate 254 * the transformation is LocalFunctionSpace. Implementors of custom transformation 255 * descriptors should only use information exported by gfs_to_lfs. In particular, 256 * the registration declaration should not make any assumptions on GFS and just 257 * treat it as some kind of opaque parameter type. 258 * 259 * \tparam GFS the root GridFunctionSpace that the resulting LocalFunctionSpace tree 260 * will be based on. 261 */ 262 template<typename GFS> 263 struct gfs_to_lfs { 264 265 //! The MultiIndex type that will be used in the resulting LocalFunctionSpace tree. 266 //typedef Dune::PDELab::MultiIndex<std::size_t,TypeTree::TreeInfo<GFS>::depth> MultiIndex; 267 typedef typename build_dof_index_type<GFS>::type DOFIndex; 268 269 }; 270 271 #endif // DOXYGEN 272 273 //! \} group GridFunctionSpace 274 } // namespace PDELab 275 } // namespace Dune 276 277 #endif // DUNE_PDELAB_GRIDFUNCTIONSPACE_TAGS_HH 278