46 static const std::size_t children = C;
47 static const bool isBlocked = std::is_same_v<IMS,BasisFactory::BlockedLexicographic> or std::is_same_v<IMS,BasisFactory::BlockedInterleaved>;
63 using SubNode =
typename SubPreBasis::Node;
77 template<
class... SFArgs,
81 subPreBasis_(std::forward<SFArgs>(sfArgs)...)
83 static_assert(models<Concept::PreBasis<GridView>,
SubPreBasis>(),
"Subprebasis passed to PowerPreBasis does not model the PreBasis concept.");
89 subPreBasis_.initializeIndices();
95 return subPreBasis_.gridView();
101 subPreBasis_.update(gv);
110 for (std::size_t i=0; i<children; ++i)
111 node.setChild(i, subPreBasis_.makeNode());
118 return size(Dune::ReservedVector<size_type, multiIndexBufferSize>{});
123 template<
class SizePrefix>
131 template<
class SizePrefix>
137 if (prefix.size() == 0)
138 return children*subPreBasis_.size();
145 SizePrefix subPrefix;
146 subPrefix.push_back(prefix[0] / children);
147 for(std::size_t i=1; i<prefix.size(); ++i)
148 subPrefix.push_back(prefix[i]);
149 return subPreBasis_.size(subPrefix);
152 template<
class SizePrefix>
153 size_type size(
const SizePrefix& prefix, BasisFactory::FlatLexicographic)
const
158 if (prefix.size() == 0)
159 return children*subPreBasis_.size();
166 SizePrefix subPrefix;
167 subPrefix.push_back(prefix[0] % children);
168 for(std::size_t i=1; i<prefix.size(); ++i)
169 subPrefix.push_back(prefix[i]);
170 return subPreBasis_.size(subPrefix);
173 template<
class SizePrefix>
174 size_type size(
const SizePrefix& prefix, BasisFactory::BlockedLexicographic)
const
176 if (prefix.size() == 0)
178 SizePrefix subPrefix;
179 for(std::size_t i=1; i<prefix.size(); ++i)
180 subPrefix.push_back(prefix[i]);
181 return subPreBasis_.size(subPrefix);
184 template<
class SizePrefix>
185 size_type size(
const SizePrefix& prefix, BasisFactory::BlockedInterleaved)
const
187 if (prefix.size() == 0)
188 return subPreBasis_.size();
190 SizePrefix subPrefix;
191 for(std::size_t i=0; i<prefix.size()-1; ++i)
192 subPrefix.push_back(prefix[i]);
194 size_type r = subPreBasis_.size(subPrefix);
197 subPrefix.push_back(prefix.back());
198 r = subPreBasis_.size(subPrefix);
209 return subPreBasis_.dimension() * children;
215 return subPreBasis_.maxNodeSize() * children;
231 template<
typename It>
239 template<
typename It>
242 using namespace Dune::Indices;
243 size_type subTreeSize = node.child(_0).size();
245 auto next =
subPreBasis().indices(node.child(_0), multiIndices);
248 for (std::size_t i = 0; i<subTreeSize; ++i)
249 multiIndices[i][0] *= children;
250 for (std::size_t child = 1; child<children; ++child)
252 for (std::size_t i = 0; i<subTreeSize; ++i)
258 (*next) = multiIndices[i];
259 (*next)[0] = multiIndices[i][0]+child;
266 template<
typename It>
267 It
indices(
const Node& node, It multiIndices, BasisFactory::FlatLexicographic)
const
269 using namespace Dune::Indices;
270 size_type subTreeSize = node.child(_0).size();
273 auto next =
subPreBasis().indices(node.child(_0), multiIndices);
274 for (std::size_t child = 1; child<children; ++child)
276 for (std::size_t i = 0; i<subTreeSize; ++i)
282 (*next) = multiIndices[i];
283 (*next)[0] += child*firstIndexEntrySize;
290 template<
class MultiIndex>
291 static void multiIndexPushFront(MultiIndex& M,
size_type M0)
293 M.resize(M.size()+1);
294 for(std::size_t i=M.size()-1; i>0; --i)
299 template<
typename It>
300 It
indices(
const Node& node, It multiIndices, BasisFactory::BlockedLexicographic)
const
302 using namespace Dune::Indices;
303 size_type subTreeSize = node.child(_0).size();
305 auto next =
subPreBasis().indices(node.child(_0), multiIndices);
307 for (std::size_t i = 0; i<subTreeSize; ++i)
308 multiIndexPushFront(multiIndices[i], 0);
309 for (std::size_t child = 1; child<children; ++child)
311 for (std::size_t i = 0; i<subTreeSize; ++i)
317 (*next) = multiIndices[i];
325 template<
typename It>
326 It
indices(
const Node& node, It multiIndices, BasisFactory::BlockedInterleaved)
const
328 using namespace Dune::Indices;
329 size_type subTreeSize = node.child(_0).size();
331 auto next =
subPreBasis().indices(node.child(_0), multiIndices);
333 for (std::size_t i = 0; i<subTreeSize; ++i)
334 multiIndices[i].push_back(0);
335 for (std::size_t child = 1; child<children; ++child)
337 for (std::size_t i = 0; i<subTreeSize; ++i)
341 (*next) = multiIndices[i];
342 (*next).back() = child;