3 #ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_POWERBASIS_HH
4 #define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_POWERBASIS_HH
6 #include <dune/common/reservedvector.hh>
7 #include <dune/common/typeutilities.hh>
9 #include <dune/typetree/powernode.hh>
10 #include <dune/typetree/utility.hh>
35 template<
class PB,
class IMS>
51 template<
class MI,
class IMS,
class SPB, std::
size_t C>
54 static const std::size_t children = C;
56 template<
class,
class>
73 using SubNode =
typename SubPreBasis::Node;
91 using SubMultiIndex = MI;
100 template<
class... SFArgs,
104 subPreBasis_(std::forward<SFArgs>(sfArgs)...)
112 subPreBasis_.initializeIndices();
118 return subPreBasis_.gridView();
124 subPreBasis_.update(gv);
133 for (std::size_t i=0; i<children; ++i)
134 node.setChild(i, subPreBasis_.makeNode());
168 if (prefix.size() == 0)
169 return children*subPreBasis_.size({});
176 typename SubPreBasis::SizePrefix subPrefix;
177 subPrefix.push_back(prefix[0] / children);
178 for(std::size_t i=1; i<prefix.size(); ++i)
179 subPrefix.push_back(prefix[i]);
180 return subPreBasis_.size(subPrefix);
188 if (prefix.size() == 0)
189 return children*subPreBasis_.size({});
196 typename SubPreBasis::SizePrefix subPrefix;
197 subPrefix.push_back(prefix[0] % children);
198 for(std::size_t i=1; i<prefix.size(); ++i)
199 subPrefix.push_back(prefix[i]);
200 return subPreBasis_.size(subPrefix);
205 if (prefix.size() == 0)
207 typename SubPreBasis::SizePrefix subPrefix;
208 for(std::size_t i=1; i<prefix.size(); ++i)
209 subPrefix.push_back(prefix[i]);
210 return subPreBasis_.size(subPrefix);
215 if (prefix.size() == 0)
216 return subPreBasis_.size();
218 typename SubPreBasis::SizePrefix subPrefix;
219 for(std::size_t i=0; i<prefix.size()-1; ++i)
220 subPrefix.push_back(prefix[i]);
222 size_type r = subPreBasis_.size(subPrefix);
225 subPrefix.push_back(prefix.back());
226 r = subPreBasis_.size(subPrefix);
237 return subPreBasis_.dimension() * children;
243 return subPreBasis_.maxNodeSize() * children;
264 template<
class PB,
class IMS>
265 class PowerNodeIndexSet
272 using Node =
typename PreBasis::Node;
278 static const std::size_t children = PreBasis::children;
283 preBasis_(&preBasis),
284 subNodeIndexSet_(preBasis_->subPreBasis().makeIndexSet())
289 using namespace TypeTree::Indices;
291 subNodeIndexSet_.bind(node.child(_0));
297 subNodeIndexSet_.unbind();
302 return node_->size();
306 template<
typename It>
314 template<
typename It>
317 using namespace Dune::TypeTree::Indices;
318 size_type subTreeSize = node_->child(_0).size();
320 auto next = subNodeIndexSet_.indices(multiIndices);
323 for (std::size_t i = 0; i<subTreeSize; ++i)
324 multiIndices[i][0] *= children;
325 for (std::size_t child = 1; child<children; ++child)
327 for (std::size_t i = 0; i<subTreeSize; ++i)
333 (*next) = multiIndices[i];
334 (*next)[0] = multiIndices[i][0]+child;
341 template<
typename It>
342 It indices(It multiIndices, BasisFactory::FlatLexicographic)
const
344 using namespace Dune::TypeTree::Indices;
345 size_type subTreeSize = node_->child(_0).size();
346 size_type firstIndexEntrySize = preBasis_->subPreBasis().size({});
348 auto next = subNodeIndexSet_.indices(multiIndices);
349 for (std::size_t child = 1; child<children; ++child)
351 for (std::size_t i = 0; i<subTreeSize; ++i)
357 (*next) = multiIndices[i];
358 (*next)[0] += child*firstIndexEntrySize;
365 static void multiIndexPushFront(MultiIndex& M, size_type M0)
367 M.resize(M.size()+1);
368 for(std::size_t i=M.size()-1; i>0; --i)
373 template<
typename It>
374 It indices(It multiIndices, BasisFactory::BlockedLexicographic)
const
376 using namespace Dune::TypeTree::Indices;
377 size_type subTreeSize = node_->child(_0).size();
379 auto next = subNodeIndexSet_.indices(multiIndices);
381 for (std::size_t i = 0; i<subTreeSize; ++i)
382 multiIndexPushFront(multiIndices[i], 0);
383 for (std::size_t child = 1; child<children; ++child)
385 for (std::size_t i = 0; i<subTreeSize; ++i)
391 (*next) = multiIndices[i];
399 template<
typename It>
400 It indices(It multiIndices, BasisFactory::BlockedInterleaved)
const
402 using namespace Dune::TypeTree::Indices;
403 size_type subTreeSize = node_->child(_0).size();
405 auto next = subNodeIndexSet_.indices(multiIndices);
407 for (std::size_t i = 0; i<subTreeSize; ++i)
408 multiIndices[i].push_back(0);
409 for (std::size_t child = 1; child<children; ++child)
411 for (std::size_t i = 0; i<subTreeSize; ++i)
415 (*next) = multiIndices[i];
416 (*next).back() = child;
423 const PreBasis* preBasis_;
424 SubIndexSet subNodeIndexSet_;
430 namespace BasisFactory {
434 template<std::
size_t k,
class IndexMergingStrategy,
class ChildPreBasisFactory>
435 class PowerPreBasisFactory
437 static const bool isBlocked = std::is_same<IndexMergingStrategy,BlockedLexicographic>::value or std::is_same<IndexMergingStrategy,BlockedInterleaved>::value;
439 static const std::size_t maxChildIndexSize = ChildPreBasisFactory::requiredMultiIndexSize;
443 static const std::size_t requiredMultiIndexSize = isBlocked ? (maxChildIndexSize+1) : maxChildIndexSize;
445 PowerPreBasisFactory(
const ChildPreBasisFactory& childPreBasisFactory) :
446 childPreBasisFactory_(childPreBasisFactory)
449 PowerPreBasisFactory(ChildPreBasisFactory&& childPreBasisFactory) :
450 childPreBasisFactory_(std::move(childPreBasisFactory))
453 template<
class MultiIndex,
class Gr
idView>
454 auto makePreBasis(
const GridView& gridView)
const
456 auto childPreBasis = childPreBasisFactory_.template makePreBasis<MultiIndex>(gridView);
457 using ChildPreBasis = decltype(childPreBasis);
459 return PowerPreBasis<MultiIndex, IndexMergingStrategy, ChildPreBasis, k>(std::move(childPreBasis));
463 ChildPreBasisFactory childPreBasisFactory_;
482 template<std::
size_t k,
class ChildPreBasisFactory,
class IndexMergingStrategy>
485 return Imp::PowerPreBasisFactory<k, IndexMergingStrategy, ChildPreBasisFactory>(std::forward<ChildPreBasisFactory>(childPreBasisFactory));
498 template<std::
size_t k,
class ChildPreBasisFactory>
499 auto power(ChildPreBasisFactory&& childPreBasisFactory)
501 return Imp::PowerPreBasisFactory<k, BlockedInterleaved, ChildPreBasisFactory>(std::forward<ChildPreBasisFactory>(childPreBasisFactory));
507 namespace BasisBuilder {
509 using namespace BasisFactory;
518 #endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_POWERBASIS_HH