7#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_DYNAMICPOWERBASIS_HH
8#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_DYNAMICPOWERBASIS_HH
10#include <dune/common/reservedvector.hh>
11#include <dune/common/typeutilities.hh>
12#include <dune/common/indices.hh>
14#include <dune/common/typetree/nodeconcepts.hh>
48template<
class IMS,
class SPB>
51 static const bool isBlocked = std::is_same_v<IMS,BasisFactory::BlockedLexicographic> or std::is_same_v<IMS,BasisFactory::BlockedInterleaved>;
79 template<
class... SFArgs,
86 static_assert(models<Concept::PreBasis<GridView>,
SubPreBasis>(),
"Subprebasis passed to DynamicPowerPreBasis does not model the PreBasis concept.");
126 return size(Dune::ReservedVector<size_type, multiIndexBufferSize>{});
130 template<
class SizePrefix>
138 template<
class SizePrefix,
class Children>
144 if (prefix.size() == 0)
154 template<
class SizePrefix,
class Children>
160 if (prefix.size() == 0)
176 template<
class MultiIndex>
179 for(std::size_t i=0; i<M.size()-1; ++i)
181 M.resize(M.size()-1);
184 template<
class SizePrefix,
class Children>
187 if (prefix.size() == 0)
193 template<
class SizePrefix,
class Children>
196 if (prefix.size() == 0)
204 auto tail = prefix.back();
208 prefix.push_back(tail);
248 template<
class NodeType,
typename It>
249 requires Dune::TypeTree::Concept::UniformInnerTreeNode<NodeType>
263 template<
class NodeType,
typename It,
class Children>
266 using namespace Dune::Indices;
267 size_type subTreeSize = node.child(_0).size();
269 auto next =
subPreBasis().indices(node.child(_0), multiIndices);
272 for (std::size_t i = 0; i<subTreeSize; ++i)
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] = multiIndices[i][0]+child;
290 template<
class NodeType,
typename It,
class Children>
293 using namespace Dune::Indices;
294 size_type subTreeSize = node.child(_0).size();
297 auto next =
subPreBasis().indices(node.child(_0), multiIndices);
298 for (std::size_t child = 1; child<
children_; ++child)
300 for (std::size_t i = 0; i<subTreeSize; ++i)
306 (*next) = multiIndices[i];
307 (*next)[0] += child*firstIndexEntrySize;
314 template<
class MultiIndex>
317 M.resize(M.size()+1);
318 for(std::size_t i=M.size()-1; i>0; --i)
323 template<
class NodeType,
typename It,
class Children>
326 using namespace Dune::Indices;
327 size_type subTreeSize = node.child(_0).size();
329 auto next =
subPreBasis().indices(node.child(_0), multiIndices);
331 for (std::size_t i = 0; i<subTreeSize; ++i)
333 for (std::size_t child = 1; child<
children_; ++child)
335 for (std::size_t i = 0; i<subTreeSize; ++i)
341 (*next) = multiIndices[i];
349 template<
class NodeType,
typename It,
class Children>
352 using namespace Dune::Indices;
353 size_type subTreeSize = node.child(_0).size();
355 auto next =
subPreBasis().indices(node.child(_0), multiIndices);
357 for (std::size_t i = 0; i<subTreeSize; ++i)
358 multiIndices[i].push_back(0);
359 for (std::size_t child = 1; child<
children_; ++child)
361 for (std::size_t i = 0; i<subTreeSize; ++i)
365 (*next) = multiIndices[i];
366 (*next).back() = child;
373 template<
class Children>
377 if constexpr(std::is_same_v<IMS, BasisFactory::FlatInterleaved>)
378 return ContainerDescriptors::Impl::flatInterleavedN(
children,std::move(subTree));
379 else if constexpr(std::is_same_v<IMS, BasisFactory::FlatLexicographic>)
380 return ContainerDescriptors::Impl::flatLexicographicN(
children,std::move(subTree));
381 else if constexpr(std::is_same_v<IMS, BasisFactory::BlockedLexicographic>)
383 else if constexpr(std::is_same_v<IMS, BasisFactory::BlockedInterleaved>)
384 return ContainerDescriptors::Impl::appendToTree(
children,std::move(subTree));
409template<
class ChildPreBasisFactory,
class IndexMergingStrategy>
412 return [childPreBasisFactory,k](
const auto& gridView) {
413 auto childPreBasis = childPreBasisFactory(gridView);
428template<
class ChildPreBasisFactory>
429[[deprecated(
"Using the method `power` without an explicit index merging strategy"
430 " will change its meaning after the release of dune-functions 2.11."
431 " Previously, the default merging strategy was `BlockedInterleaved`,"
432 " but this will change to `FlatInterleaved`."
433 " Change the call to `power(..., blockedInterleaved())` to retain the old behavior.")]]
434auto power(ChildPreBasisFactory&& childPreBasisFactory, std::size_t k)
436 return [childPreBasisFactory,k](
const auto& gridView) {
437 auto childPreBasis = childPreBasisFactory(gridView);
Lightweight representation of (hierarchical) size and block structure extracted from a basis to descr...
auto power(ChildPreBasisFactory &&childPreBasisFactory, std::size_t k, const IndexMergingStrategy &)
Create a pre-basis factory that can build a PowerPreBasis.
Definition dynamicpowerbasis.hh:410
std::enable_if_t< std::is_constructible_v< T, Args... >, int > enableIfConstructible
Helper to constrain forwarding constructors.
Definition type_traits.hh:30
Definition monomialset.hh:19
Definition monomialset.hh:19
auto containerDescriptor(const PreBasis &preBasis)
Return the container descriptor of the pre-basis, if defined, otherwise ContainerDescriptor::Unknown.
Definition containerdescriptors.hh:58
auto makeUniformDescriptor(std::integral_constant< std::size_t, n >, Child child)
Generate a uniform descriptor in case the size is a static constant.
Definition containerdescriptors.hh:147
Definition argyrisbasis.hh:926
Base class for index merging strategies to simplify detection.
Definition basistags.hh:48
Lexicographic merging of direct children without blocking.
Definition basistags.hh:84
Interleaved merging of direct children without blocking.
Definition basistags.hh:118
Lexicographic merging of direct children with blocking (i.e. creating one block per direct child).
Definition basistags.hh:152
Interleaved merging of direct children with blocking (i.e. creating blocks at the leaves containing o...
Definition basistags.hh:184
Fallback container descriptor if nothing else fits.
Definition containerdescriptors.hh:52
A pre-basis for dynamic power bases.
Definition dynamicpowerbasis.hh:50
std::size_t size_type
Type used for indices and size information.
Definition dynamicpowerbasis.hh:62
IMS IndexMergingStrategy
Strategy used to merge the global indices of the child factories.
Definition dynamicpowerbasis.hh:65
DynamicPowerPreBasis(std::size_t c, SFArgs &&... sfArgs)
Constructor for given child pre-basis objects.
Definition dynamicpowerbasis.hh:82
static void multiIndexPopFront(MultiIndex &M)
Definition dynamicpowerbasis.hh:177
size_type dimension() const
Get the total dimension of the space spanned by this basis.
Definition dynamicpowerbasis.hh:224
auto containerDescriptorImpl(Children children) const
Definition dynamicpowerbasis.hh:374
void initializeIndices()
Initialize the global indices.
Definition dynamicpowerbasis.hh:90
size_type sizeImpl(SizePrefix prefix, Children children, BasisFactory::FlatInterleaved) const
Definition dynamicpowerbasis.hh:139
static constexpr size_type maxMultiIndexSize
Definition dynamicpowerbasis.hh:70
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition dynamicpowerbasis.hh:102
auto containerDescriptor() const
Return the associated container descriptor.
Definition dynamicpowerbasis.hh:256
size_type size() const
Same as size(prefix) with empty prefix.
Definition dynamicpowerbasis.hh:124
It indicesImpl(const NodeType &node, It multiIndices, Children children, BasisFactory::BlockedInterleaved) const
Definition dynamicpowerbasis.hh:350
SubPreBasis & subPreBasis()
Mutable access to the stored prebasis of the factor in the power space.
Definition dynamicpowerbasis.hh:242
size_type sizeImpl(SizePrefix prefix, Children children, BasisFactory::FlatLexicographic) const
Definition dynamicpowerbasis.hh:155
static void multiIndexPushFront(MultiIndex &M, size_type M0)
Definition dynamicpowerbasis.hh:315
SubPreBasis subPreBasis_
Definition dynamicpowerbasis.hh:391
It indices(const NodeType &node, It it) const
Maps from subtree index set [0..size-1] to a globally unique multi index in global basis.
Definition dynamicpowerbasis.hh:250
size_type sizeImpl(SizePrefix prefix, Children children, BasisFactory::BlockedLexicographic) const
Definition dynamicpowerbasis.hh:185
size_type sizeImpl(SizePrefix prefix, Children children, BasisFactory::BlockedInterleaved) const
Definition dynamicpowerbasis.hh:194
It indicesImpl(const NodeType &node, It multiIndices, Children children, BasisFactory::BlockedLexicographic) const
Definition dynamicpowerbasis.hh:324
static constexpr size_type multiIndexBufferSize
Definition dynamicpowerbasis.hh:72
SPB SubPreBasis
The child pre-basis.
Definition dynamicpowerbasis.hh:56
Node makeNode() const
Create tree node.
Definition dynamicpowerbasis.hh:110
const SubPreBasis & subPreBasis() const
Const access to the stored prebasis of the factor in the power space.
Definition dynamicpowerbasis.hh:236
It indicesImpl(const NodeType &node, It multiIndices, Children children, BasisFactory::FlatInterleaved) const
Definition dynamicpowerbasis.hh:264
std::size_t children() const
Definition dynamicpowerbasis.hh:118
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition dynamicpowerbasis.hh:230
It indicesImpl(const NodeType &node, It multiIndices, Children children, BasisFactory::FlatLexicographic) const
Definition dynamicpowerbasis.hh:291
size_type size(const SizePrefix &prefix) const
Return number of possible values for next position in multi index.
Definition dynamicpowerbasis.hh:131
DynamicPowerBasisNode< typename SubPreBasis::Node > Node
Template mapping root tree path to type of created tree node.
Definition dynamicpowerbasis.hh:68
typename SPB::GridView GridView
The grid view that the FE basis is defined on.
Definition dynamicpowerbasis.hh:59
std::size_t children_
Definition dynamicpowerbasis.hh:390
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition dynamicpowerbasis.hh:96
static constexpr size_type minMultiIndexSize
Definition dynamicpowerbasis.hh:71