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>
43template<
class IMS,
class SPB, std::
size_t C>
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;
354namespace BasisFactory {
368template<std::
size_t k,
class ChildPreBasisFactory,
class IndexMergingStrategy>
371 return [childPreBasisFactory](
const auto& gridView) {
372 auto childPreBasis = childPreBasisFactory(gridView);
387template<std::
size_t k,
class ChildPreBasisFactory>
388auto power(ChildPreBasisFactory&& childPreBasisFactory)
390 return [childPreBasisFactory](
const auto& gridView) {
391 auto childPreBasis = childPreBasisFactory(gridView);
399namespace BasisBuilder {
401 using namespace BasisFactory;
auto power(ChildPreBasisFactory &&childPreBasisFactory)
Create a factory builder that can build a PowerPreBasis.
Definition: powerbasis.hh:388
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
A pre-basis for power bases.
Definition: powerbasis.hh:45
size_type dimension() const
Get the total dimension of the space spanned by this basis.
Definition: powerbasis.hh:207
std::size_t size_type
Type used for indices and size information.
Definition: powerbasis.hh:58
IMS IndexMergingStrategy
Strategy used to merge the global indices of the child factories.
Definition: powerbasis.hh:61
PowerBasisNode< SubNode, children > Node
Template mapping root tree path to type of created tree node.
Definition: powerbasis.hh:66
typename SPB::GridView GridView
The grid view that the FE basis is defined on.
Definition: powerbasis.hh:55
static constexpr size_type multiIndexBufferSize
Definition: powerbasis.hh:70
SPB SubPreBasis
The child pre-basis.
Definition: powerbasis.hh:52
typename SubPreBasis::Node SubNode
Definition: powerbasis.hh:63
void initializeIndices()
Initialize the global indices.
Definition: powerbasis.hh:87
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: powerbasis.hh:99
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:232
PowerPreBasis(SFArgs &&... sfArgs)
Constructor for given child pre-basis objects.
Definition: powerbasis.hh:80
size_type size() const
Same as size(prefix) with empty prefix.
Definition: powerbasis.hh:116
SubPreBasis & subPreBasis()
Mutable access to the stored prebasis of the factor in the power space.
Definition: powerbasis.hh:225
Node makeNode() const
Create tree node.
Definition: powerbasis.hh:107
static constexpr size_type maxMultiIndexSize
Definition: powerbasis.hh:68
static constexpr size_type minMultiIndexSize
Definition: powerbasis.hh:69
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: powerbasis.hh:213
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: powerbasis.hh:93
size_type size(const SizePrefix &prefix) const
Return number of possible values for next position in multi index.
Definition: powerbasis.hh:124
const SubPreBasis & subPreBasis() const
Const access to the stored prebasis of the factor in the power space.
Definition: powerbasis.hh:219