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>
36 class PowerNodeIndexSet;
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>
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;
auto power(ChildPreBasisFactory &&childPreBasisFactory)
Create a factory builder that can build a PowerPreBasis.
Definition: powerbasis.hh:499
typename std::enable_if< std::is_constructible< T, Args... >::value, int >::type enableIfConstructible
Helper to constrain forwarding constructors.
Definition: type_traits.hh:26
Definition: polynomial.hh:10
Base class for index merging strategies to simplify detection.
Definition: basistags.hh:44
Interleaved merging of direct children without blocking.
Definition: basistags.hh:114
Definition: functionspacebases/concepts.hh:144
Definition: powerbasis.hh:266
std::size_t size_type
Definition: powerbasis.hh:269
IMS IndexMergingStrategy
Definition: powerbasis.hh:276
PowerNodeIndexSet(const PreBasis &preBasis)
Definition: powerbasis.hh:282
PB PreBasis
Definition: powerbasis.hh:270
size_type size() const
Definition: powerbasis.hh:300
void unbind()
Definition: powerbasis.hh:294
typename PreBasis::MultiIndex MultiIndex
Definition: powerbasis.hh:271
typename PreBasis::Node Node
Definition: powerbasis.hh:272
It indices(It it) const
Maps from subtree index set [0..size-1] to a globally unique multi index in global basis.
Definition: powerbasis.hh:307
void bind(const Node &node)
Definition: powerbasis.hh:287
typename PreBasis::SubPreBasis::IndexSet SubIndexSet
Definition: powerbasis.hh:277
A pre-basis for power bases.
Definition: powerbasis.hh:53
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: powerbasis.hh:241
const SubPreBasis & subPreBasis() const
Const access to the stored prebasis of the factor in the power space.
Definition: powerbasis.hh:247
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: powerbasis.hh:122
void initializeIndices()
Initialize the global indices.
Definition: powerbasis.hh:110
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: powerbasis.hh:116
std::size_t size_type
Type used for indices and size information.
Definition: powerbasis.hh:68
typename SubPreBasis::Node SubNode
Definition: powerbasis.hh:73
size_type size() const
Same as size(prefix) with empty prefix.
Definition: powerbasis.hh:150
MI MultiIndex
Type used for global numbering of the basis vectors.
Definition: powerbasis.hh:84
Dune::ReservedVector< size_type, MultiIndex::max_size()> SizePrefix
Type used for prefixes handed to the size() method.
Definition: powerbasis.hh:87
size_type dimension() const
Get the total dimension of the space spanned by this basis.
Definition: powerbasis.hh:235
IMS IndexMergingStrategy
Strategy used to merge the global indices of the child factories.
Definition: powerbasis.hh:71
typename SubPreBasis::IndexSet SubIndexSet
Definition: powerbasis.hh:75
size_type size(const SizePrefix &prefix) const
Return number of possible values for next position in multi index.
Definition: powerbasis.hh:156
typename SPB::GridView GridView
The grid view that the FE basis is defined on.
Definition: powerbasis.hh:65
SubPreBasis & subPreBasis()
Mutable access to the stored prebasis of the factor in the power space.
Definition: powerbasis.hh:253
Node makeNode() const
Create tree node.
Definition: powerbasis.hh:130
SPB SubPreBasis
The child pre-basis.
Definition: powerbasis.hh:62
PowerPreBasis(SFArgs &&... sfArgs)
Constructor for given child pre-basis objects.
Definition: powerbasis.hh:103
IndexSet makeIndexSet() const
Create tree node index set.
Definition: powerbasis.hh:144