3 #ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_COMPOSITEBASIS_HH
4 #define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_COMPOSITEBASIS_HH
9 #include <dune/common/std/utility.hh>
10 #include <dune/common/std/apply.hh>
11 #include <dune/common/hybridutilities.hh>
12 #include <dune/common/reservedvector.hh>
13 #include <dune/common/typeutilities.hh>
14 #include <dune/common/hybridutilities.hh>
15 #include <dune/common/tupleutility.hh>
16 #include <dune/common/tuplevector.hh>
18 #include <dune/typetree/compositenode.hh>
19 #include <dune/typetree/utility.hh>
44 template<
class PB,
class IMS>
45 class CompositeNodeIndexSet;
59 template<
class MI,
class IMS,
class... SPB>
68 template<std::
size_t i>
72 using GridView =
typename std::tuple_element_t<0, SubPreBases>::GridView;
81 static const std::size_t
children =
sizeof...(SPB);
83 template<
class,
class>
88 template<
class Indices>
91 template<std::size_t... indices>
94 template<std::
size_t i>
95 using SubNode =
typename std::tuple_element_t<i, SubPreBases>::Node;
97 template<std::
size_t i>
98 using SubIndexSet =
typename std::tuple_element_t<i, SubPreBases>::IndexSet;
126 template<
class... SFArgs,
130 subPreBases_(std::forward<SFArgs>(sfArgs)...)
132 Hybrid::forEach(subPreBases_, [&](
const auto&
subPreBasis){
148 return std::get<0>(subPreBases_).gridView();
180 unpackIntegerSequence([&](
auto... i) {
201 if (prefix.size() == 0)
204 return Hybrid::switchCases(
ChildIndices(), prefix[0], [&] (
auto i) {
205 typename SubPreBasis<i>::SizePrefix subPrefix;
206 for(std::size_t i=1; i<prefix.size(); ++i)
207 subPrefix.push_back(prefix[i]);
208 return this->subPreBasis(i).size(subPrefix);
217 if (prefix.size() == 0)
223 staticFindInRange<0, children>([&](
auto i) {
225 if (shiftedFirstDigit < firstDigitSize)
227 typename SubPreBasis<i>::SizePrefix subPrefix;
228 subPrefix.push_back(shiftedFirstDigit);
229 for(std::size_t i=1; i<prefix.size(); ++i)
230 subPrefix.push_back(prefix[i]);
234 shiftedFirstDigit -= firstDigitSize;
266 template<std::
size_t i>
269 return std::get<i>(subPreBases_);
273 template<std::
size_t i>
276 return std::get<i>(subPreBases_);
280 std::tuple<SPB...> subPreBases_;
285 template<
class PB,
class IMS>
293 using Node =
typename PreBasis::Node;
304 preBasis_(&preBasis),
305 subNodeIndexSetTuple_(std::move(subNodeIndexSets)),
313 Hybrid::elementAt(subNodeIndexSetTuple_, i).bind(node.child(i));
321 Hybrid::elementAt(subNodeIndexSetTuple_, i).unbind();
327 return node_->size();
331 template<
typename It>
337 template<
typename It>
343 const auto& subNodeIndexSet = Hybrid::elementAt(subNodeIndexSetTuple_, child);
344 const auto& subPreBasis = preBasis_->subPreBasis(child);
345 size_type subTreeSize = subNodeIndexSet.size();
349 subNodeIndexSet.indices(multiIndices);
350 for (std::size_t i = 0; i<subTreeSize; ++i)
351 multiIndices[i][0] += firstComponentOffset;
353 firstComponentOffset += subPreBasis.size({});
355 multiIndices += subTreeSize;
362 M.resize(M.size()+1);
363 for(std::size_t i=M.size()-1; i>0; --i)
368 template<
typename It>
373 const auto& subNodeIndexSet = Hybrid::elementAt(subNodeIndexSetTuple_, child);
374 size_type subTreeSize = subNodeIndexSet.size();
376 subNodeIndexSet.indices(multiIndices);
378 for (std::size_t i = 0; i<subTreeSize; ++i)
379 this->multiIndexPushFront(multiIndices[i], child);
381 multiIndices += subTreeSize;
387 const PreBasis* preBasis_;
388 SubIndexSets subNodeIndexSetTuple_;
394 namespace BasisFactory {
399 constexpr std::size_t maxHelper(ST0&& i0)
404 template<
class ST0,
class... ST>
405 constexpr std::size_t maxHelper(ST0&& i0, ST&&... i)
407 return (i0 > maxHelper(i...)) ? i0 : maxHelper(i...);
410 template<
class IndexMergingStrategy,
class... ChildPreBasisFactory>
411 class CompositePreBasisFactory
413 static const bool isBlocked = std::is_same<IndexMergingStrategy,BlockedLexicographic>::value or std::is_same<IndexMergingStrategy,BlockedInterleaved>::value;
415 static const std::size_t maxChildIndexSize = maxHelper(ChildPreBasisFactory::requiredMultiIndexSize...);
417 template<
class MultiIndex,
class GridView,
class... ChildPreBasis>
418 auto makePreBasisFromChildPreBases(
const GridView&, ChildPreBasis&&... childPreBasis)
const
420 return CompositePreBasis<MultiIndex, IndexMergingStrategy, std::decay_t<ChildPreBasis>...>(std::forward<ChildPreBasis>(childPreBasis)...);
425 static const std::size_t requiredMultiIndexSize = isBlocked ? (maxChildIndexSize+1) : maxChildIndexSize;
427 CompositePreBasisFactory(
const ChildPreBasisFactory&... childPreBasisFactory) :
428 childPreBasisFactories_(childPreBasisFactory...)
431 CompositePreBasisFactory(ChildPreBasisFactory&&... childPreBasisFactory) :
432 childPreBasisFactories_(std::move(childPreBasisFactory)...)
435 template<
class MultiIndex,
class Gr
idView>
436 auto makePreBasis(
const GridView& gridView)
const
439 return Std::apply([&](
const auto&... childPreBasisFactory) {
440 return this->makePreBasisFromChildPreBases<MultiIndex>(gridView, childPreBasisFactory.template makePreBasis<MultiIndex>(gridView)...);
441 }, childPreBasisFactories_);
445 std::tuple<ChildPreBasisFactory...> childPreBasisFactories_;
470 using ArgTuple = std::tuple<std::decay_t<Args>...>;
473 constexpr std::size_t children = Dune::SizeOf<Args...>::value-1;
479 auto childIndices = std::make_index_sequence<children>{};
482 return applyPartial([](
auto&&... childPreBasisFactory){
483 return Imp::CompositePreBasisFactory<
IndexMergingStrategy, std::decay_t<decltype(childPreBasisFactory)>...>(std::forward<decltype(childPreBasisFactory)>(childPreBasisFactory)...);
485 std::forward_as_tuple(std::forward<Args>(args)...),
505 return Imp::CompositePreBasisFactory<BasisFactory::BlockedLexicographic, std::decay_t<Args>...>(std::forward<Args>(args)...);
511 namespace BasisBuilder {
513 using namespace BasisFactory;
auto composite(Args &&... args)
Create a factory builder that can build a CompositePreBasis.
Definition: compositebasis.hh:465
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
static constexpr bool isIndexMergingStrategy()
Definition: basistags.hh:23
Get last entry of type list.
Definition: utility.hh:222
Base class for index merging strategies to simplify detection.
Definition: basistags.hh:44
Lexicographic merging of direct children without blocking.
Definition: basistags.hh:80
Lexicographic merging of direct children with blocking (i.e. creating one block per direct child).
Definition: basistags.hh:148
Definition: compositebasis.hh:287
typename PreBasis::SubIndexSets SubIndexSets
Definition: compositebasis.hh:298
static void multiIndexPushFront(MultiIndex &M, size_type M0)
Definition: compositebasis.hh:360
It indices(It multiIndices, BasisFactory::BlockedLexicographic) const
Definition: compositebasis.hh:369
size_type size() const
Definition: compositebasis.hh:325
void bind(const Node &node)
Definition: compositebasis.hh:309
PB PreBasis
Definition: compositebasis.hh:291
void unbind()
Definition: compositebasis.hh:317
std::size_t size_type
Definition: compositebasis.hh:290
It indices(It it) const
Maps from subtree index set [0..size-1] to a globally unique multi index in global basis.
Definition: compositebasis.hh:332
typename PreBasis::ChildIndices ChildIndices
Definition: compositebasis.hh:299
typename PreBasis::MultiIndex MultiIndex
Definition: compositebasis.hh:292
typename PreBasis::Node Node
Definition: compositebasis.hh:293
It indices(It multiIndices, BasisFactory::FlatLexicographic) const
Definition: compositebasis.hh:338
CompositeNodeIndexSet(const PreBasis &preBasis, SubIndexSets &&subNodeIndexSets)
Definition: compositebasis.hh:303
IMS IndexMergingStrategy
Definition: compositebasis.hh:297
A pre-basis for composite bases.
Definition: compositebasis.hh:61
SubPreBasis< i > & subPreBasis(Dune::index_constant< i >={})
Mutable access to the stored prebasis of the factor in the power space.
Definition: compositebasis.hh:274
typename Types< ChildIndices >::SubIndexSets SubIndexSets
Definition: compositebasis.hh:105
typename std::tuple_element_t< 0, SubPreBases >::GridView GridView
The grid view that the FE basis is defined on.
Definition: compositebasis.hh:72
Node makeNode() const
Create tree node.
Definition: compositebasis.hh:162
size_type size() const
Same as size(prefix) with empty prefix.
Definition: compositebasis.hh:186
static const std::size_t children
Definition: compositebasis.hh:81
typename Types< ChildIndices >::Node Node
Template mapping root tree path to type of created tree node.
Definition: compositebasis.hh:110
Dune::ReservedVector< size_type, MultiIndex::max_size()> SizePrefix
Type used for prefixes handed to the size() method.
Definition: compositebasis.hh:119
size_type dimension() const
Get the total dimension of the space spanned by this basis.
Definition: compositebasis.hh:244
std::size_t size_type
Type used for indices and size information.
Definition: compositebasis.hh:75
size_type size(const SizePrefix &prefix) const
Return number of possible values for next position in multi index.
Definition: compositebasis.hh:192
IndexSet makeIndexSet() const
Create tree node index set.
Definition: compositebasis.hh:177
std::make_index_sequence< children > ChildIndices
Definition: compositebasis.hh:86
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: compositebasis.hh:152
CompositePreBasis(SFArgs &&... sfArgs)
Constructor for given child pre-basis objects.
Definition: compositebasis.hh:129
IMS IndexMergingStrategy
Strategy used to merge the global indices of the child pre-bases.
Definition: compositebasis.hh:78
std::tuple_element_t< i, SubPreBases > SubPreBasis
Export individual child pre-bases by index.
Definition: compositebasis.hh:69
MI MultiIndex
Type used for global numbering of the basis vectors.
Definition: compositebasis.hh:116
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: compositebasis.hh:255
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: compositebasis.hh:146
std::tuple< SPB... > SubPreBases
Tuple of child pre-bases.
Definition: compositebasis.hh:65
const SubPreBasis< i > & subPreBasis(Dune::index_constant< i >={}) const
Const access to the stored prebasis of the factor in the power space.
Definition: compositebasis.hh:267
void initializeIndices()
Initialize the global indices.
Definition: compositebasis.hh:138
Definition: compositebasis.hh:89
typename std::tuple_element_t< i, SubPreBases >::IndexSet SubIndexSet
Definition: compositebasis.hh:98
std::tuple< SubIndexSet< indices >... > SubIndexSets
Definition: compositebasis.hh:100
typename std::tuple_element_t< i, SubPreBases >::Node SubNode
Definition: compositebasis.hh:95
Definition: functionspacebases/concepts.hh:144