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>
8#include <dune/common/indices.hh>
10#include <dune/functions/common/utility.hh>
11#include <dune/functions/common/type_traits.hh>
12#include <dune/functions/functionspacebases/basistags.hh>
13#include <dune/functions/functionspacebases/nodes.hh>
14#include <dune/functions/functionspacebases/concepts.hh>
15#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
44template<
class MI,
class IMS,
class SPB, std::
size_t C>
47 static const std::size_t children = C;
63 using SubNode =
typename SubPreBasis::Node;
66 using Node = PowerBasisNode<SubNode, children>;
69 using IndexSet = Impl::DefaultNodeIndexSet<PowerPreBasis>;
79 using SubMultiIndex = MI;
88 template<
class... SFArgs,
92 subPreBasis_(std::forward<SFArgs>(sfArgs)...)
94 static_assert(models<Concept::PreBasis<GridView>,
SubPreBasis>(),
"Subprebasis passed to PowerPreBasis does not model the PreBasis concept.");
100 subPreBasis_.initializeIndices();
106 return subPreBasis_.gridView();
112 subPreBasis_.update(gv);
121 for (std::size_t i=0; i<children; ++i)
122 node.setChild(i, subPreBasis_.makeNode());
133 [[deprecated(
"Warning: The IndexSet typedef and the makeIndexSet method are deprecated. "\
134 "As a replacement use the indices() method of the PreBasis directly.")]]
159 if (prefix.size() == 0)
160 return children*subPreBasis_.size({});
167 typename SubPreBasis::SizePrefix subPrefix;
168 subPrefix.push_back(prefix[0] / children);
169 for(std::size_t i=1; i<prefix.size(); ++i)
170 subPrefix.push_back(prefix[i]);
171 return subPreBasis_.size(subPrefix);
179 if (prefix.size() == 0)
180 return children*subPreBasis_.size({});
187 typename SubPreBasis::SizePrefix subPrefix;
188 subPrefix.push_back(prefix[0] % children);
189 for(std::size_t i=1; i<prefix.size(); ++i)
190 subPrefix.push_back(prefix[i]);
191 return subPreBasis_.size(subPrefix);
196 if (prefix.size() == 0)
198 typename SubPreBasis::SizePrefix subPrefix;
199 for(std::size_t i=1; i<prefix.size(); ++i)
200 subPrefix.push_back(prefix[i]);
201 return subPreBasis_.size(subPrefix);
206 if (prefix.size() == 0)
207 return subPreBasis_.size();
209 typename SubPreBasis::SizePrefix subPrefix;
210 for(std::size_t i=0; i<prefix.size()-1; ++i)
211 subPrefix.push_back(prefix[i]);
213 size_type r = subPreBasis_.size(subPrefix);
216 subPrefix.push_back(prefix.back());
217 r = subPreBasis_.size(subPrefix);
228 return subPreBasis_.dimension() * children;
234 return subPreBasis_.maxNodeSize() * children;
250 template<
typename It>
258 template<
typename It>
261 using namespace Dune::Indices;
262 size_type subTreeSize = node.child(_0).size();
264 auto next = Impl::preBasisIndices(
subPreBasis(), node.child(_0), multiIndices);
267 for (std::size_t i = 0; i<subTreeSize; ++i)
268 multiIndices[i][0] *= children;
269 for (std::size_t child = 1; child<children; ++child)
271 for (std::size_t i = 0; i<subTreeSize; ++i)
277 (*next) = multiIndices[i];
278 (*next)[0] = multiIndices[i][0]+child;
285 template<
typename It>
286 It
indices(
const Node& node, It multiIndices, BasisFactory::FlatLexicographic)
const
288 using namespace Dune::Indices;
289 size_type subTreeSize = node.child(_0).size();
292 auto next = Impl::preBasisIndices(
subPreBasis(), node.child(_0), multiIndices);
293 for (std::size_t child = 1; child<children; ++child)
295 for (std::size_t i = 0; i<subTreeSize; ++i)
301 (*next) = multiIndices[i];
302 (*next)[0] += child*firstIndexEntrySize;
311 M.resize(M.size()+1);
312 for(std::size_t i=M.size()-1; i>0; --i)
317 template<
typename It>
318 It
indices(
const Node& node, It multiIndices, BasisFactory::BlockedLexicographic)
const
320 using namespace Dune::Indices;
321 size_type subTreeSize = node.child(_0).size();
323 auto next = Impl::preBasisIndices(
subPreBasis(), node.child(_0), multiIndices);
325 for (std::size_t i = 0; i<subTreeSize; ++i)
326 multiIndexPushFront(multiIndices[i], 0);
327 for (std::size_t child = 1; child<children; ++child)
329 for (std::size_t i = 0; i<subTreeSize; ++i)
335 (*next) = multiIndices[i];
343 template<
typename It>
344 It
indices(
const Node& node, It multiIndices, BasisFactory::BlockedInterleaved)
const
346 using namespace Dune::Indices;
347 size_type subTreeSize = node.child(_0).size();
349 auto next = Impl::preBasisIndices(
subPreBasis(), node.child(_0), multiIndices);
351 for (std::size_t i = 0; i<subTreeSize; ++i)
352 multiIndices[i].push_back(0);
353 for (std::size_t child = 1; child<children; ++child)
355 for (std::size_t i = 0; i<subTreeSize; ++i)
359 (*next) = multiIndices[i];
360 (*next).back() = child;
372namespace BasisFactory {
376template<std::
size_t k,
class IndexMergingStrategy,
class ChildPreBasisFactory>
377class PowerPreBasisFactory
379 static const bool isBlocked = std::is_same<IndexMergingStrategy,BlockedLexicographic>::value or std::is_same<IndexMergingStrategy,BlockedInterleaved>::value;
381 static const std::size_t maxChildIndexSize = ChildPreBasisFactory::requiredMultiIndexSize;
385 static const std::size_t requiredMultiIndexSize = isBlocked ? (maxChildIndexSize+1) : maxChildIndexSize;
387 PowerPreBasisFactory(
const ChildPreBasisFactory& childPreBasisFactory) :
388 childPreBasisFactory_(childPreBasisFactory)
391 PowerPreBasisFactory(ChildPreBasisFactory&& childPreBasisFactory) :
392 childPreBasisFactory_(std::move(childPreBasisFactory))
395 template<
class MultiIndex,
class Gr
idView>
396 auto makePreBasis(
const GridView& gridView)
const
398 auto childPreBasis = childPreBasisFactory_.template makePreBasis<MultiIndex>(gridView);
399 using ChildPreBasis =
decltype(childPreBasis);
401 return PowerPreBasis<MultiIndex, IndexMergingStrategy, ChildPreBasis, k>(std::move(childPreBasis));
405 ChildPreBasisFactory childPreBasisFactory_;
424template<std::
size_t k,
class ChildPreBasisFactory,
class IndexMergingStrategy>
427 return Imp::PowerPreBasisFactory<k, IndexMergingStrategy, ChildPreBasisFactory>(std::forward<ChildPreBasisFactory>(childPreBasisFactory));
440template<std::
size_t k,
class ChildPreBasisFactory>
441auto power(ChildPreBasisFactory&& childPreBasisFactory)
443 return Imp::PowerPreBasisFactory<k, BlockedInterleaved, ChildPreBasisFactory>(std::forward<ChildPreBasisFactory>(childPreBasisFactory));
449namespace BasisBuilder {
451 using namespace BasisFactory;
A pre-basis for power bases.
Definition: powerbasis.hh:46
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: powerbasis.hh:232
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: powerbasis.hh:110
void initializeIndices()
Initialize the global indices.
Definition: powerbasis.hh:98
std::size_t size_type
Type used for indices and size information.
Definition: powerbasis.hh:58
size_type size() const
Same as size(prefix) with empty prefix.
Definition: powerbasis.hh:141
MI MultiIndex
Type used for global numbering of the basis vectors.
Definition: powerbasis.hh:72
Dune::ReservedVector< size_type, MultiIndex::max_size()> SizePrefix
Type used for prefixes handed to the size() method.
Definition: powerbasis.hh:75
SubPreBasis & subPreBasis()
Mutable access to the stored prebasis of the factor in the power space.
Definition: powerbasis.hh:244
size_type dimension() const
Get the total dimension of the space spanned by this basis.
Definition: powerbasis.hh:226
IMS IndexMergingStrategy
Strategy used to merge the global indices of the child factories.
Definition: powerbasis.hh:61
size_type size(const SizePrefix &prefix) const
Return number of possible values for next position in multi index.
Definition: powerbasis.hh:147
typename SPB::GridView GridView
The grid view that the FE basis is defined on.
Definition: powerbasis.hh:55
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: powerbasis.hh:104
Node makeNode() const
Create tree node.
Definition: powerbasis.hh:118
SPB SubPreBasis
The child pre-basis.
Definition: powerbasis.hh:52
PowerPreBasis(SFArgs &&... sfArgs)
Constructor for given child pre-basis objects.
Definition: powerbasis.hh:91
IndexSet makeIndexSet() const
Create tree node index set.
Definition: powerbasis.hh:135
const SubPreBasis & subPreBasis() const
Const access to the stored prebasis of the factor in the power space.
Definition: powerbasis.hh:238
It indices(const Node &node, It it) const
Maps from subtree index set [0..size-1] to a globally unique multi index in global basis.
Definition: powerbasis.hh:251
PowerBasisNode< SubNode, children > Node
Template mapping root tree path to type of created tree node.
Definition: powerbasis.hh:66
Impl::DefaultNodeIndexSet< PowerPreBasis > IndexSet
Type of created tree node index set.
Definition: powerbasis.hh:69
auto power(ChildPreBasisFactory &&childPreBasisFactory)
Create a factory builder that can build a PowerPreBasis.
Definition: powerbasis.hh:441
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
Interleaved merging of direct children without blocking.
Definition: basistags.hh:114
Base class for index merging strategies to simplify detection.
Definition: basistags.hh:44