DUNE PDELab (git)

lexicographicordering.hh
1 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=8 sw=2 sts=2:
3 
4 #ifndef DUNE_PDELAB_ORDERING_LEXICOGRAPHICORDERING_HH
5 #define DUNE_PDELAB_ORDERING_LEXICOGRAPHICORDERING_HH
6 
7 #include <cstddef>
8 #include <ostream>
9 #include <string>
10 
11 #include <dune/common/classname.hh>
14 #include <dune/common/hybridutilities.hh>
15 
16 #include <dune/typetree/compositenode.hh>
17 #include <dune/typetree/powernode.hh>
18 #include <dune/typetree/traversal.hh>
19 #include <dune/typetree/visitor.hh>
20 
21 #include <dune/pdelab/gridfunctionspace/tags.hh>
22 #include <dune/pdelab/ordering/utility.hh>
23 #include <dune/pdelab/ordering/orderingbase.hh>
24 
25 namespace Dune {
26  namespace PDELab {
27 
30 
31  namespace lexicographic_ordering {
32 
33  template<typename DI, typename CI, typename Node>
34  class Base
35  : public OrderingBase<DI,CI>
36  {
37 
38  typedef OrderingBase<DI,CI> BaseT;
39 
40  public:
41 
42  typedef typename OrderingBase<DI,CI>::Traits Traits;
43 
44  typedef LexicographicOrderingTag OrderingTag;
45 
46  static const bool consume_tree_index = true;
47 
49 
54  Base(Node& node, bool container_blocked, typename BaseT::GFSData* gfs_data)
55  : BaseT(node,container_blocked,gfs_data,nullptr)
56  {
57  }
58 
59  template<typename ItIn, typename ItOut>
60  void map_lfs_indices(const ItIn begin, const ItIn end, ItOut out) const
61  {
62  if (this->_container_blocked)
63  {
64  for (ItIn in = begin; in != end; ++in, ++out)
65  out->push_back(in->treeIndex().back());
66  }
67  else
68  {
69  for (ItIn in = begin; in != end; ++in, ++out)
70  out->back() += (this->blockOffset(in->treeIndex().back()));
71  }
72  }
73 
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
79  {
80  if (this->_container_blocked)
81  {
82  for (; ci_out != ci_end; ++ci_out)
83  {
84  ci_out->push_back(child_index);
85  }
86  }
87  else
88  {
89  for (; ci_out != ci_end; ++ci_out)
90  {
91  ci_out->back() += (this->blockOffset(child_index));
92  }
93  }
94 
95  // The return value is not used for non-leaf orderings.
96  return 0;
97  }
98 
99  };
100  }
101 
102 
103 
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,
108  CI,
109  PowerLexicographicOrdering<DI,CI,Child,k>
110  >
111  {
112  typedef TypeTree::PowerNode<Child, k> Node;
113 
114  typedef lexicographic_ordering::Base<DI,
115  CI,
116  PowerLexicographicOrdering<DI,CI,Child,k>
117  > Base;
118 
119  public:
120 
121  using Traits = typename Base::Traits;
122 
124 
132  PowerLexicographicOrdering(bool container_blocked, const typename Node::NodeStorage& children, typename Base::GFSData* gfs_data)
133  : Node(children)
134  , Base(*this,container_blocked,gfs_data)
135  { }
136 
137  void update()
138  {
139  for (std::size_t i = 0; i < k; ++i)
140  {
141  this->child(i).update();
142  }
143  Base::update();
144  }
145 
146  std::string name() const { return "PowerLexicographicOrdering"; }
147 
148  using Base::size;
149 
155  typename Traits::SizeType size(typename Traits::ContainerIndex suffix) const {
156  if (suffix.size() == Traits::ContainerIndex::max_depth)
157  return 0; // all indices in suffix were consumed, no more sizes to provide
158 
159  if (suffix.size() == 0)
160  return this->blockCount();
161 
162  if (this->containerBlocked()) {
163  auto child = suffix.back();
164  assert(this->degree() > child);
165  suffix.pop_back();
166  return this->child(child).size(suffix);
167  } else {
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);
171  }
172  }
173 
174  };
175 
176 
177  template<typename GFS, typename Transformation>
178  struct power_gfs_to_lexicographic_ordering_descriptor
179  {
180 
181  static const bool recursive = true;
182 
183  template<typename TC>
184  struct result
185  {
186 
187  typedef PowerLexicographicOrdering<
188  typename Transformation::DOFIndex,
189  typename Transformation::ContainerIndex,
190  TC,
191  TypeTree::StaticDegree<GFS>::value
192  > type;
193 
194  typedef std::shared_ptr<type> storage_type;
195 
196  };
197 
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)
200  {
201  return typename result<TC>::type(gfs.backend().blocked(gfs),children,const_cast<GFS*>(&gfs));
202  }
203 
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)
206  {
207  return std::make_shared<typename result<TC>::type>(gfs->backend().blocked(*gfs),children,const_cast<GFS*>(gfs.get()));
208  }
209 
210  };
211 
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*);
215 
216  // the generic registration for PowerGridFunctionSpace happens in transformations.hh
217 
218 
220  template<typename DI, typename CI, typename... Children>
222  public TypeTree::CompositeNode<Children...>,
223  public lexicographic_ordering::Base<DI,
224  CI,
225  CompositeLexicographicOrdering<
226  DI,
227  CI,
228  Children...
229  >
230  >
231  {
232  typedef TypeTree::CompositeNode<Children...> Node;
233 
234  typedef lexicographic_ordering::Base<
235  DI,
236  CI,
238  DI,
239  CI,
240  Children...
241  >
242  > Base;
243 
244  public:
245  using Traits = typename Base::Traits;
246 
248 
256  CompositeLexicographicOrdering(bool backend_blocked, typename Base::GFSData* gfs_data, std::shared_ptr<Children>... children)
257  : Node(children...)
258  , Base(*this,backend_blocked,gfs_data)
259  { }
260 
261  std::string name() const { return "CompositeLexicographicOrdering"; }
262 
263  void update()
264  {
265  TypeTree::applyToTree(*this,ordering::update_direct_children());
266  Base::update();
267  }
268 
269  using Base::size;
270 
276  typename Traits::SizeType size(typename Traits::ContainerIndex suffix) const {
277  if (suffix.size() == Traits::ContainerIndex::max_depth)
278  return 0; // all indices in suffix were consumed, no more sizes to provide
279 
280  if (suffix.size() == 0)
281  return this->blockCount();
282 
283  auto indices = std::make_index_sequence<Node::degree()>{};
285  std::size_t _child;
286 
287  if (this->containerBlocked()) {
288  _child = suffix.back();
289  assert(this->degree() > _child);
290  suffix.pop_back();
291  } else {
292  auto it = std::upper_bound(this->_child_block_offsets.begin(), this->_child_block_offsets.end(), suffix.back());
293  _child = *std::prev(it);
294  }
295 
296  Hybrid::forEach(indices, [&](auto i){
297  if (i == _child)
298  _size = this->template child<i>().size(suffix);
299  });
300  return _size;
301  }
302  };
303 
304  template<typename GFS, typename Transformation>
305  struct composite_gfs_to_lexicographic_ordering_descriptor
306  {
307 
308  static const bool recursive = true;
309 
310  template<typename... TC>
311  struct result
312  {
313 
314  typedef CompositeLexicographicOrdering<
315  typename Transformation::DOFIndex,
316  typename Transformation::ContainerIndex,
317  TC...
318  > type;
319 
320  typedef std::shared_ptr<type> storage_type;
321 
322  };
323 
324  template<typename... TC>
325  static typename result<TC...>::type transform(const GFS& gfs, const Transformation& t, std::shared_ptr<TC>... children)
326  {
327  return typename result<TC...>::type(gfs.backend().blocked(gfs),const_cast<GFS*>(&gfs),children...);
328  }
329 
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)
332  {
333  return std::make_shared<typename result<TC...>::type>(gfs->backend().blocked(*gfs),const_cast<GFS*>(gfs.get()),children...);
334  }
335 
336  };
337 
338 
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*);
342 
344  } // namespace PDELab
345 } // namespace Dune
346 
347 #endif // DUNE_PDELAB_ORDERING_LEXICOGRAPHICORDERING_HH
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:28
std::array< std::shared_ptr< Child >, k > NodeStorage
The type used for storing the children.
Definition: powernode.hh:77
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:256
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:79
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition: traversal.hh:239
ImplementationDefined child(Node &&node, Indices... indices)
Extracts the child of a node given by a sequence of compile-time and run-time indices.
Definition: childextraction.hh:128
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
Standard Dune debug streams.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)