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>
44 template<
class MI,
class IMS,
class SPB, std::
size_t C>
47 static const std::size_t children = C;
63 using SubNode =
typename SubPreBasis::Node;
69 using IndexSet = Impl::DefaultNodeIndexSet<PowerPreBasis>;
79 using SubMultiIndex = MI;
88 template<
class... SFArgs,
92 subPreBasis_(std::forward<SFArgs>(sfArgs)...)
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;
372 namespace BasisFactory {
376 template<std::
size_t k,
class IndexMergingStrategy,
class ChildPreBasisFactory>
377 class 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>
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_;
424 template<std::
size_t k,
class ChildPreBasisFactory,
class IndexMergingStrategy>
427 return Imp::PowerPreBasisFactory<k, IndexMergingStrategy, ChildPreBasisFactory>(std::forward<ChildPreBasisFactory>(childPreBasisFactory));
440 template<std::
size_t k,
class ChildPreBasisFactory>
441 auto power(ChildPreBasisFactory&& childPreBasisFactory)
443 return Imp::PowerPreBasisFactory<k, BlockedInterleaved, ChildPreBasisFactory>(std::forward<ChildPreBasisFactory>(childPreBasisFactory));
449 namespace BasisBuilder {
451 using namespace BasisFactory;
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
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:182
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
const SubPreBasis & subPreBasis() const
Const access to the stored prebasis of the factor in the power space.
Definition: powerbasis.hh:238
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
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: powerbasis.hh:104
std::size_t size_type
Type used for indices and size information.
Definition: powerbasis.hh:58
typename SubPreBasis::Node SubNode
Definition: powerbasis.hh:63
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
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
SubPreBasis & subPreBasis()
Mutable access to the stored prebasis of the factor in the power space.
Definition: powerbasis.hh:244
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
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