4#ifndef DUNE_PDELAB_ORDERING_LEXICOGRAPHICORDERING_HH
5#define DUNE_PDELAB_ORDERING_LEXICOGRAPHICORDERING_HH
14#include <dune/common/hybridutilities.hh>
16#include <dune/typetree/compositenode.hh>
17#include <dune/typetree/powernode.hh>
18#include <dune/typetree/traversal.hh>
19#include <dune/typetree/visitor.hh>
21#include <dune/pdelab/gridfunctionspace/tags.hh>
22#include <dune/pdelab/ordering/utility.hh>
23#include <dune/pdelab/ordering/orderingbase.hh>
31 namespace lexicographic_ordering {
33 template<
typename DI,
typename CI,
typename Node>
35 :
public OrderingBase<DI,CI>
38 typedef OrderingBase<DI,CI> BaseT;
42 typedef typename OrderingBase<DI,CI>::Traits Traits;
44 typedef LexicographicOrderingTag OrderingTag;
46 static const bool consume_tree_index =
true;
54 Base(Node& node,
bool container_blocked,
typename BaseT::GFSData* gfs_data)
55 : BaseT(node,container_blocked,gfs_data,nullptr)
59 template<
typename ItIn,
typename ItOut>
60 void map_lfs_indices(
const ItIn begin,
const ItIn end, ItOut out)
const
62 if (this->_container_blocked)
64 for (ItIn in = begin; in != end; ++in, ++out)
65 out->push_back(in->treeIndex().back());
69 for (ItIn in = begin; in != end; ++in, ++out)
70 out->back() += (this->blockOffset(in->treeIndex().back()));
74 template<
typename CIOutIterator,
typename DIOutIterator = DummyDOFIndexIterator>
75 typename Traits::SizeType
76 extract_entity_indices(
const typename Traits::DOFIndex::EntityIndex& ei,
77 typename Traits::SizeType child_index,
78 CIOutIterator ci_out,
const CIOutIterator ci_end)
const
80 if (this->_container_blocked)
82 for (; ci_out != ci_end; ++ci_out)
84 ci_out->push_back(child_index);
89 for (; ci_out != ci_end; ++ci_out)
91 ci_out->back() += (this->blockOffset(child_index));
104 template<
typename DI,
typename CI,
typename Child, std::
size_t k>
105 class PowerLexicographicOrdering
106 :
public TypeTree::PowerNode<Child, k>
107 ,
public lexicographic_ordering::Base<DI,
109 PowerLexicographicOrdering<DI,CI,Child,k>
112 typedef TypeTree::PowerNode<Child, k> Node;
114 typedef lexicographic_ordering::Base<DI,
116 PowerLexicographicOrdering<DI,CI,Child,k>
121 using Traits =
typename Base::Traits;
132 PowerLexicographicOrdering(
bool container_blocked,
const typename Node::NodeStorage& children,
typename Base::GFSData* gfs_data)
134 , Base(*this,container_blocked,gfs_data)
139 for (std::size_t i = 0; i < k; ++i)
141 this->
child(i).update();
146 std::string name()
const {
return "PowerLexicographicOrdering"; }
155 typename Traits::SizeType size(
typename Traits::ContainerIndex suffix)
const {
156 if (suffix.size() == Traits::ContainerIndex::max_depth)
159 if (suffix.size() == 0)
160 return this->blockCount();
162 if (this->containerBlocked()) {
163 auto child = suffix.back();
168 auto it = std::upper_bound(this->_child_block_offsets.begin(), this->_child_block_offsets.end(), suffix.back());
169 std::size_t
child = *std::prev(it);
170 return this->
child(child).size(suffix);
177 template<
typename GFS,
typename Transformation>
178 struct power_gfs_to_lexicographic_ordering_descriptor
181 static const bool recursive =
true;
183 template<
typename TC>
187 typedef PowerLexicographicOrdering<
188 typename Transformation::DOFIndex,
189 typename Transformation::ContainerIndex,
191 TypeTree::StaticDegree<GFS>::value
194 typedef std::shared_ptr<type> storage_type;
198 template<
typename TC>
199 static typename result<TC>::type transform(
const GFS& gfs,
const Transformation& t,
const std::array<std::shared_ptr<TC>,TypeTree::StaticDegree<GFS>::value>& children)
201 return typename result<TC>::type(gfs.backend().blocked(gfs),children,
const_cast<GFS*
>(&gfs));
204 template<
typename TC>
205 static typename result<TC>::storage_type transform_storage(std::shared_ptr<const GFS> gfs,
const Transformation& t,
const std::array<std::shared_ptr<TC>,TypeTree::StaticDegree<GFS>::value>& children)
207 return std::make_shared<typename result<TC>::type>(gfs->backend().blocked(*gfs),children,
const_cast<GFS*
>(gfs.get()));
212 template<
typename GFS,
typename Transformation>
213 power_gfs_to_lexicographic_ordering_descriptor<GFS,Transformation>
214 register_power_gfs_to_ordering_descriptor(GFS*,Transformation*,LexicographicOrderingTag*);
220 template<
typename DI,
typename CI,
typename... Children>
223 public lexicographic_ordering::Base<DI,
225 CompositeLexicographicOrdering<
234 typedef lexicographic_ordering::Base<
245 using Traits =
typename Base::Traits;
258 , Base(*this,backend_blocked,gfs_data)
261 std::string name()
const {
return "CompositeLexicographicOrdering"; }
276 typename Traits::SizeType
size(
typename Traits::ContainerIndex suffix)
const {
277 if (suffix.size() == Traits::ContainerIndex::max_depth)
280 if (suffix.size() == 0)
281 return this->blockCount();
283 auto indices = std::make_index_sequence<Node::degree()>{};
284 typename Traits::SizeType _size;
287 if (this->containerBlocked()) {
288 _child = suffix.back();
289 assert(this->degree() > _child);
292 auto it = std::upper_bound(this->_child_block_offsets.begin(), this->_child_block_offsets.end(), suffix.back());
293 _child = *std::prev(it);
298 _size = this->
template child<i>().
size(suffix);
304 template<
typename GFS,
typename Transformation>
305 struct composite_gfs_to_lexicographic_ordering_descriptor
308 static const bool recursive =
true;
310 template<
typename... TC>
314 typedef CompositeLexicographicOrdering<
315 typename Transformation::DOFIndex,
316 typename Transformation::ContainerIndex,
320 typedef std::shared_ptr<type> storage_type;
324 template<
typename... TC>
325 static typename result<TC...>::type transform(
const GFS& gfs,
const Transformation& t, std::shared_ptr<TC>... children)
327 return typename result<TC...>::type(gfs.backend().blocked(gfs),
const_cast<GFS*
>(&gfs),children...);
330 template<
typename... TC>
331 static typename result<TC...>::storage_type transform_storage(std::shared_ptr<const GFS> gfs,
const Transformation& t, std::shared_ptr<TC>... children)
333 return std::make_shared<
typename result<TC...>::type>(gfs->backend().blocked(*gfs),
const_cast<GFS*
>(gfs.get()),children...);
339 template<
typename GFS,
typename Transformation>
340 composite_gfs_to_lexicographic_ordering_descriptor<GFS,Transformation>
341 register_composite_gfs_to_ordering_descriptor(GFS*,Transformation*,LexicographicOrderingTag*);
Interface for merging index spaces.
Definition: lexicographicordering.hh:231
CompositeLexicographicOrdering(bool backend_blocked, typename Base::GFSData *gfs_data, std::shared_ptr< Children >... children)
Construct ordering object.
Definition: lexicographicordering.hh:256
Traits::SizeType size(typename Traits::ContainerIndex suffix) const
Gives the size for a given suffix.
Definition: lexicographicordering.hh:276
Base class for composite nodes based on variadic templates.
Definition: compositenode.hh:26
std::array< std::shared_ptr< Child >, k > NodeStorage
The type used for storing the children.
Definition: powernode.hh:78
A free function to provide the demangled class name of a given object or type as a string.
A few common exception classes.
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:266
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:76
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition: traversal.hh:237
Dune namespace.
Definition: alignedallocator.hh:11
Standard Dune debug streams.