3#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_POWERBASIS_HH
4#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_POWERBASIS_HH
9#include <dune/typetree/powernode.hh>
10#include <dune/typetree/utility.hh>
12#include <dune/functions/common/utility.hh>
13#include <dune/functions/common/type_traits.hh>
14#include <dune/functions/functionspacebases/basistags.hh>
15#include <dune/functions/functionspacebases/nodes.hh>
16#include <dune/functions/functionspacebases/concepts.hh>
35template<
class PB,
class IMS>
36class PowerNodeIndexSet;
51template<
class MI,
class IMS,
class SPB, std::
size_t C>
54 static const std::size_t children = C;
56 template<
class,
class>
57 friend class PowerNodeIndexSet;
73 using SubNode =
typename SubPreBasis::Node;
75 using SubIndexSet =
typename SubPreBasis::IndexSet;
78 using Node = PowerBasisNode<SubNode, children>;
81 using IndexSet = PowerNodeIndexSet<PowerPreBasis, IMS>;
91 using SubMultiIndex = MI;
100 template<
class... SFArgs,
104 subPreBasis_(
std::forward<SFArgs>(sfArgs)...)
106 static_assert(models<Concept::PreBasis<GridView>,
SubPreBasis>(),
"Subprebasis passed to PowerPreBasis does not model the PreBasis concept.");
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;
264template<
class PB,
class IMS>
265class PowerNodeIndexSet
269 using size_type = std::size_t;
271 using MultiIndex =
typename PreBasis::MultiIndex;
272 using Node =
typename PreBasis::Node;
276 using IndexMergingStrategy = IMS;
277 using SubIndexSet =
typename PreBasis::SubPreBasis::IndexSet;
278 static const std::size_t children = PreBasis::children;
282 PowerNodeIndexSet(
const PreBasis & preBasis) :
283 preBasis_(&preBasis),
284 subNodeIndexSet_(preBasis_->subPreBasis().makeIndexSet())
287 void bind(
const Node& node)
289 using namespace TypeTree::Indices;
291 subNodeIndexSet_.bind(node.child(
_0));
297 subNodeIndexSet_.unbind();
300 size_type size()
const
302 return node_->size();
306 template<
typename It>
307 It indices(It it)
const
309 return indices(it, IndexMergingStrategy{});
314 template<
typename It>
315 It indices(It multiIndices, BasisFactory::FlatInterleaved)
const
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;
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);
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);
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)
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_;
430namespace BasisFactory {
434template<std::
size_t k,
class IndexMergingStrategy,
class ChildPreBasisFactory>
435class 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_;
482template<std::
size_t k,
class ChildPreBasisFactory,
class IndexMergingStrategy>
485 return Imp::PowerPreBasisFactory<k, IndexMergingStrategy, ChildPreBasisFactory>(std::forward<ChildPreBasisFactory>(childPreBasisFactory));
498template<std::
size_t k,
class ChildPreBasisFactory>
499auto power(ChildPreBasisFactory&& childPreBasisFactory)
501 return Imp::PowerPreBasisFactory<k, BlockedInterleaved, ChildPreBasisFactory>(std::forward<ChildPreBasisFactory>(childPreBasisFactory));
507namespace BasisBuilder {
509 using namespace BasisFactory;
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
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
std::size_t size_type
Type used for indices and size information.
Definition: powerbasis.hh:68
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
SubPreBasis & subPreBasis()
Mutable access to the stored prebasis of the factor in the power space.
Definition: powerbasis.hh:253
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
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
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: powerbasis.hh:116
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
const SubPreBasis & subPreBasis() const
Const access to the stored prebasis of the factor in the power space.
Definition: powerbasis.hh:247
PowerNodeIndexSet< PowerPreBasis, IMS > IndexSet
Template mapping root tree path to type of created tree node index set.
Definition: powerbasis.hh:81
PowerBasisNode< SubNode, children > Node
Template mapping root tree path to type of created tree node.
Definition: powerbasis.hh:78
A Vector class with statically reserved memory.
Definition: reservedvector.hh:43
size_type size() const
Returns number of elements in the vector.
Definition: reservedvector.hh:184
constexpr index_constant< 0 > _0
Compile time index with value 0.
Definition: indices.hh:51
constexpr HybridTreePath< T..., std::size_t > push_back(const HybridTreePath< T... > &tp, std::size_t i)
Appends a run time index to a HybridTreePath.
Definition: treepath.hh:278
std::enable_if_t< not Impl::disableCopyMoveHelper< This, T... >::value, int > disableCopyMove
Helper to disable constructor as copy and move constructor.
Definition: typeutilities.hh:43
typename std::enable_if< std::is_constructible< T, Args... >::value, int >::type enableIfConstructible
Helper to constrain forwarding constructors.
Definition: type_traits.hh:26
Dune namespace.
Definition: alignedallocator.hh:14
constexpr Mantissa power(Mantissa m, Exponent p)
Power method for integer exponents.
Definition: math.hh:73
An stl-compliant random-access container which stores everything on the stack.
Interleaved merging of direct children without blocking.
Definition: basistags.hh:114
Base class for index merging strategies to simplify detection.
Definition: basistags.hh:44
Utilities for type computations, constraining overloads, ...