Go to the documentation of this file.
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>
16 #include <dune/typetree/compositenode.hh>
17 #include <dune/typetree/utility.hh>
32 template<
typename... T>
34 :
public std::integral_constant<std::size_t,sizeof...(T)>
37 template<
typename... T>
38 using index_sequence_for = std::make_index_sequence<SizeOf<T...>{}>;
53 template<
class MI,
class TP,
class IT,
class... SPB>
68 template<
class MI,
class IMS,
class... SPB>
77 using GridView =
typename std::tuple_element<0, SubPreBases>::type::GridView;
86 static const std::size_t
children =
sizeof...(SPB);
88 template<
class,
class,
class,
class...>
102 template<
class F,
class SubTP>
107 template<
class F,
class SubTP>
122 template<std::
size_t k>
123 using SubPreBasis =
typename std::tuple_element<k, std::tuple<SPB...>>::type;
144 template<
class... SFArgs,
150 using namespace Dune::Hybrid;
152 static_assert(models<
Concept::PreBasis<GridView>, std::decay_t<decltype(subPreBasis)>>(),
"Subprebases passed to CompositePreBasis does not model the PreBasis concept.");
159 using namespace Dune::Hybrid;
160 forEach(Dune::Std::make_index_sequence<children>(), [&](
auto i) {
174 using namespace Dune::Hybrid;
175 forEach(Dune::Std::make_index_sequence<children>(), [&](
auto i) {
194 using namespace Dune::Hybrid;
195 forEach(Dune::Std::make_index_sequence<children>(), [&](
auto i) {
232 if (prefix.size() == 0)
235 return Hybrid::switchCases(std::make_index_sequence<children>(), prefix[0], [&] (
auto i) {
236 const auto& subPreBasis = std::get<i.value>(
subPreBases_);
237 typename std::decay<decltype(subPreBasis)>::type::SizePrefix subPrefix;
238 for(std::size_t i=1; i<prefix.size(); ++i)
239 subPrefix.push_back(prefix[i]);
240 return subPreBasis.size(subPrefix);
246 struct Lambda_size_flat_sizeInSubtree
248 template<
class I,
class PB>
251 using SubPreBasis =
typename std::tuple_element<I::value, PB>::type;
252 const SubPreBasis& subPreBasis = std::get<I::value>(subPreBases);
253 if (shiftedFirst < subPreBasis.size())
255 typename SubPreBasis::SizePrefix subPrefix;
256 subPrefix.push_back(shiftedFirst);
257 for(std::size_t i=1; i<prefix.size(); ++i)
258 subPrefix.push_back(prefix[i]);
259 r = subPreBasis.size(subPrefix);
262 shiftedFirst -= subPreBasis.size();
270 using namespace Dune::Hybrid;
271 if (prefix.size() == 0)
272 forEach(Dune::Std::make_index_sequence<children>(), [&](
auto i) {
289 using namespace Dune::Hybrid;
290 forEach(Dune::Std::make_index_sequence<children>(), [&](
auto i) {
301 using namespace Dune::Hybrid;
302 forEach(Dune::Std::make_index_sequence<children>(), [&](
auto i) {
314 template<
class MI,
class TP,
class IMS,
class... SPB>
317 static const std::size_t
children =
sizeof...(SPB);
321 template<std::
size_t k>
322 using SubPreBasis =
typename std::tuple_element<k, std::tuple<SPB...>>::type;
342 template<
class SubPreBasis,
class SubTP>
344 ->decltype(preBasis.template indexSet<SubTP>())
346 return preBasis.template indexSet<SubTP>();
351 preBasis_(&preBasis),
358 using namespace Dune::Hybrid;
359 forEach(Dune::Std::make_index_sequence<children>(), [&](
auto i) {
360 elementAt(subNodeIndexSetTuple_, i).bind(
node.child(i));
367 using namespace Dune::Hybrid;
368 forEach(Dune::Std::make_index_sequence<children>(), [&](
auto i) {
369 elementAt(subNodeIndexSetTuple_, i).unbind();
375 return node_->size();
379 template<
typename It>
385 template<
typename It>
388 using namespace Dune::Hybrid;
391 forEach(Dune::Std::make_index_sequence<children>(), [&](
auto child){
392 const auto& subNodeIndexSet = elementAt(subNodeIndexSetTuple_, child);
393 const auto& subPreBasis = elementAt(preBasis_->subPreBases_, child);
394 size_type subTreeSize = subNodeIndexSet.size();
398 subNodeIndexSet.indices(multiIndices);
399 for (std::size_t i = 0; i<subTreeSize; ++i)
400 multiIndices[i][0] += firstComponentOffset;
402 firstComponentOffset += subPreBasis.size({});
404 multiIndices += subTreeSize;
411 M.resize(M.size()+1);
412 for(std::size_t i=M.size()-1; i>0; --i)
417 template<
typename It>
420 using namespace Dune::Hybrid;
422 forEach(Dune::Std::make_index_sequence<children>(), [&](
auto child){
423 const auto& subNodeIndexSet = elementAt(subNodeIndexSetTuple_, child);
424 size_type subTreeSize = subNodeIndexSet.size();
426 subNodeIndexSet.indices(multiIndices);
428 for (std::size_t i = 0; i<subTreeSize; ++i)
429 this->multiIndexPushFront(multiIndices[i], child);
431 multiIndices += subTreeSize;
438 const PreBasis* preBasis_;
439 SubIndexSets subNodeIndexSetTuple_;
445 namespace BasisBuilder {
450 constexpr std::size_t maxHelper(ST0&& i0)
455 template<
class ST0,
class... ST>
456 constexpr std::size_t maxHelper(ST0&& i0, ST&&... i)
458 return (i0 > maxHelper(i...)) ? i0 : maxHelper(i...);
462 class CompositePreBasisFactory
464 static const bool isBlocked = std::is_same<IndexMergingStrategy,BlockedLexicographic>::value or std::is_same<IndexMergingStrategy,LeafBlockedInterleaved>::value;
466 static const std::size_t maxChildIndexSize = maxHelper(ChildPreBasisFactory::requiredMultiIndexSize...);
469 auto makePreBasisFromChildPreBases(
const GridView&, ChildPreBasis&&... childPreBasis)
const
471 return CompositePreBasis<MultiIndex, IndexMergingStrategy, std::decay_t<ChildPreBasis>...>(std::forward<ChildPreBasis>(childPreBasis)...);
476 static const std::size_t requiredMultiIndexSize = isBlocked ? (maxChildIndexSize+1) : maxChildIndexSize;
478 CompositePreBasisFactory(
const ChildPreBasisFactory&... childPreBasisFactory) :
479 childPreBasisFactories_(childPreBasisFactory...)
482 CompositePreBasisFactory(ChildPreBasisFactory&&... childPreBasisFactory) :
483 childPreBasisFactories_(std::move(childPreBasisFactory)...)
486 template<
class MultiIndex,
class Gr
idView>
490 return Std::apply([&](
const auto&... childPreBasisFactory) {
491 return this->makePreBasisFromChildPreBases<MultiIndex>(
gridView, childPreBasisFactory.template makePreBasis<MultiIndex>(
gridView)...);
492 }, childPreBasisFactories_);
496 std::tuple<ChildPreBasisFactory...> childPreBasisFactories_;
521 using ArgTuple = std::tuple<std::decay_t<Args>...>;
524 constexpr std::size_t
children = Dune::SizeOf<Args...>::value-1;
530 auto childIndices = std::make_index_sequence<children>{};
533 return applyPartial([&](
auto&&... childPreBasisFactory){
534 return Imp::CompositePreBasisFactory<
IndexMergingStrategy, std::decay_t<decltype(childPreBasisFactory)>...>(std::forward<decltype(childPreBasisFactory)>(childPreBasisFactory)...);
536 std::forward_as_tuple(std::forward<Args>(args)...),
556 return Imp::CompositePreBasisFactory<BasisBuilder::BlockedLexicographic, std::decay_t<Args>...>(std::forward<Args>(args)...);
567 #endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_COMPOSITEBASIS_HH
Base class for index merging strategies to simplify detection.
Definition: basistags.hh:44
ExpandTuple< SubNodesToNode, SubNodes > Node
Definition: compositebasis.hh:115
IndexSet< TP > indexSet() const
Create tree node index set with given root tree path.
Definition: compositebasis.hh:211
Definition: polynomial.hh:7
auto composite(Args &&... args)
Create a factory builder that can build a CompositePreBasis.
Definition: compositebasis.hh:516
static const void multiIndexPushFront(MultiIndex &M, size_type M0)
Definition: compositebasis.hh:409
CompositeNodeIndexSet(const PreBasis &preBasis)
Definition: compositebasis.hh:350
typename F::template IndexSet< SubTP > PreBasisToSubIndexSet
Definition: compositebasis.hh:108
auto transformTuple(F &&f, const std::tuple< T... > &tuple) -> decltype(Imp::transformTupleHelper(std::forward< F >(f), tuple, std::index_sequence_for< T... >
Transform tuple value using a functor.
Definition: utility.hh:162
size_type size(const SizePrefix &prefix) const
Return number of possible values for next position in multi index.
Definition: compositebasis.hh:223
typename Imp::ExpandTupleHelper< T, ArgTuple >::Type ExpandTuple
Expand tuple arguments as template arguments.
Definition: utility.hh:91
MI MultiIndex
Type used for global numbering of the basis vectors.
Definition: compositebasis.hh:329
typename FixedTP< TP >::Node Node
Template mapping root tree path to type of created tree node.
Definition: compositebasis.hh:127
void initializeIndices()
Initialize the global indices.
Definition: compositebasis.hh:157
typename PreBasis::template FixedTP< TP >::SubIndexSets SubIndexSets
Definition: compositebasis.hh:336
typename std::tuple_element< k, std::tuple< SPB... > >::type SubPreBasis
Template mapping index of child to its pre-basis type.
Definition: compositebasis.hh:123
IMS IndexMergingStrategy
Definition: compositebasis.hh:326
typename std::tuple_element< k, std::tuple< SPB... > >::type SubPreBasis
Definition: compositebasis.hh:322
auto operator()(const SubPreBasis &preBasis, const SubTP &subTP) -> decltype(preBasis.template indexSet< SubTP >())
Definition: compositebasis.hh:343
size_type maxNodeSize() const
Get the maximal number of DOFs associated to node for any element.
Definition: compositebasis.hh:297
Definition: compositebasis.hh:339
static const std::size_t children
Definition: compositebasis.hh:86
typename Imp::IntegerSequenceTupleHelper< IntegerSequence >::Type IntegerSequenceTuple
Transform integer_sequence<I,k...> to tuple<integral_constant<I,k>...>
Definition: utility.hh:208
MI MultiIndex
Type used for global numbering of the basis vectors.
Definition: compositebasis.hh:134
size_type size() const
Definition: compositebasis.hh:373
typename PreBasis::template Node< TP > Node
Definition: compositebasis.hh:333
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: compositebasis.hh:166
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:380
std::tuple< SPB... > subPreBases_
Definition: compositebasis.hh:309
decltype(TypeTree::push_back(TP(), I())) IndexToSubTreePath
Definition: compositebasis.hh:98
Get last entry of type list.
Definition: utility.hh:218
TransformTuple< PreBasisToSubNode, SubPreBases, SubTreePaths > SubNodes
Definition: compositebasis.hh:105
typename std::tuple_element< 0, SubPreBases >::type::GridView GridView
The grid view that the FE basis is defined on.
Definition: compositebasis.hh:77
It indices(It multiIndices, BasisBuilder::BlockedLexicographic) const
Definition: compositebasis.hh:418
Node< TP > node(const TP &tp) const
Create tree node with given root tree path.
Definition: compositebasis.hh:191
CompositePreBasis(SFArgs &&... sfArgs)
Constructor for given child pre-basis objects.
Definition: compositebasis.hh:147
void bind(const Node &node)
Definition: compositebasis.hh:355
A pre-basis for composite bases.
Definition: compositebasis.hh:69
Dune::ReservedVector< size_type, MultiIndex::max_size()+1 > SizePrefix
Type used for prefixes handed to the size() method.
Definition: compositebasis.hh:137
typename F::template Node< SubTP > PreBasisToSubNode
Definition: compositebasis.hh:103
Lexicographic merging of direct children without blocking.
Definition: basistags.hh:78
IMS IndexMergingStrategy
Strategy used to merge the global indices of the child pre-bases.
Definition: compositebasis.hh:83
std::tuple< SPB... > SubPreBases
Tuple of child pre-bases.
Definition: compositebasis.hh:74
decltype(auto) applyPartial(F &&f, ArgTuple &&args, std::integer_sequence< I, i... > indices)
Apply function with arguments from a given tuple.
Definition: utility.hh:267
std::size_t size_type
Definition: compositebasis.hh:325
void staticFindInRange(F &&f, Args &&... args)
Static find loop.
Definition: staticforloop.hh:56
void update(const GridView &gv)
Update the stored grid view, to be called if the grid has changed.
Definition: compositebasis.hh:172
typename SubPreBasis< 0 >::GridView GridView
Definition: compositebasis.hh:324
TransformTuple< PreBasisToSubIndexSet, SubPreBases, SubTreePaths > SubIndexSets
Definition: compositebasis.hh:110
friend class CompositeNodeIndexSet
Definition: compositebasis.hh:89
Lexicographic merging of direct children with blocking (i.e. creating one block per direct child).
Definition: basistags.hh:146
size_type size() const
Same as size(prefix) with empty prefix.
Definition: compositebasis.hh:217
void unbind()
Definition: compositebasis.hh:364
It indices(It multiIndices, BasisBuilder::FlatLexicographic) const
Definition: compositebasis.hh:386
Definition: compositebasis.hh:54
std::size_t size_type
Type used for indices and size information.
Definition: compositebasis.hh:80
size_type dimension() const
Get the total dimension of the space spanned by this basis.
Definition: compositebasis.hh:285
Definition: concepts.hh:153
typename std::enable_if< std::is_constructible< T, Args... >::value, int >::type enableIfConstructible
Helper to constrain forwarding constructors.
Definition: type_traits.hh:26
typename PreBasis::template FixedTP< TP >::SubTreePaths SubTreePaths
Definition: compositebasis.hh:335
typename Imp::TransformTupleHelper< F, Tuples... >::Type TransformTuple
Transform tuple types argument using type-functor.
Definition: utility.hh:128
IntegerSequenceTuple< Imp::index_sequence_for< SPB... > > ChildIndexTuple
Definition: compositebasis.hh:91
TransformTuple< IndexToSubTreePath, ChildIndexTuple > SubTreePaths
Definition: compositebasis.hh:100
Definition: compositebasis.hh:94
static constexpr bool isIndexMergingStrategy()
Definition: basistags.hh:23