dune-pdelab  2.5-dev
interleavedordering.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_PDELAB_ORDERING_INTERLEAVEDORDERING_HH
4 #define DUNE_PDELAB_ORDERING_INTERLEAVEDORDERING_HH
5 
6 #include <string>
7 
8 #include <dune/typetree/compositenode.hh>
9 #include <dune/typetree/powernode.hh>
10 
12 
16 
17 namespace Dune {
18  namespace PDELab {
19 
22 
23  namespace interleaved_ordering {
24 
26  template<typename DI, typename CI, typename Node>
27  class Base
28  : public OrderingBase<DI,CI>
29  {
30 
31  typedef OrderingBase<DI,CI> BaseT;
32 
33  public:
34 
36 
38 
39  static const bool consume_tree_index = true;
40 
42 
47  Base(Node& node, bool container_blocked, const OrderingTag& ordering_tag, typename BaseT::GFSData* gfs_data)
48  : BaseT(node,container_blocked,ordering_tag.offsets(),gfs_data,nullptr)
49  {
50  // This check looks a little weird, but there is always one offset more than
51  // there are blocks (the first offsets is 0, and the last one is the "offset
52  // beyond the end" to encode the size of the final child).
53  if (node.CHILDREN != ordering_tag.offsets().size() - 1)
54  DUNE_THROW(OrderingStructureError,
55  "Invalid block structure for InterleavedOrdering: "
56  << node.CHILDREN << " children, but "
57  << (ordering_tag.offsets().size() - 1) << " block sizes.");
58  }
59 
60  template<typename ItIn, typename ItOut>
61  void map_lfs_indices(const ItIn begin, const ItIn end, ItOut out) const
62  {
63  typedef typename Traits::SizeType size_type;
64  if (this->_container_blocked)
65  {
66  for (ItIn in = begin; in != end; ++in, ++out)
67  {
68  size_type child_index = in->treeIndex().back();
69  size_type child_block_offset = this->_child_block_merge_offsets[child_index];
70  size_type child_block_size = this->_child_block_merge_offsets[child_index + 1] - child_block_offset;
71  size_type index = out->back();
72  size_type block_index = index / child_block_size;
73  size_type offset = index % child_block_size;
74  out->back() = child_block_offset + offset;
75  out->push_back(block_index);
76  }
77  }
78  else
79  {
80  for (ItIn in = begin; in != end; ++in, ++out)
81  {
82  size_type child_index = in->treeIndex().back();
83  size_type child_block_offset = this->_child_block_merge_offsets[child_index];
84  size_type child_block_size = this->_child_block_merge_offsets[child_index + 1] - child_block_offset;
85  size_type block_size = this->_child_block_merge_offsets.back();
86  size_type index = out->back();
87  size_type block_index = index / child_block_size;
88  size_type offset = index % child_block_size;
89  out->back() = block_index * block_size + child_block_offset + offset;
90  }
91  }
92  }
93 
94  template<typename CIOutIterator, typename DIOutIterator = DummyDOFIndexIterator>
95  typename Traits::SizeType
96  extract_entity_indices(const typename Traits::DOFIndex::EntityIndex& ei,
97  typename Traits::SizeType child_index,
98  CIOutIterator ci_out, const CIOutIterator ci_end) const
99  {
100  typedef typename Traits::SizeType size_type;
101  if (this->_container_blocked)
102  {
103  for (; ci_out != ci_end; ++ci_out)
104  {
105  size_type child_block_offset = this->_child_block_merge_offsets[child_index];
106  size_type child_block_size = this->_child_block_merge_offsets[child_index + 1] - child_block_offset;
107  size_type index = ci_out->back();
108  size_type block_index = index / child_block_size;
109  size_type offset =index % child_block_size;
110  ci_out->back() = child_block_offset + offset;
111  ci_out->push_back(block_index);
112  }
113  }
114  else
115  {
116  for (; ci_out != ci_end; ++ci_out)
117  {
118  size_type child_block_offset = this->_child_block_merge_offsets[child_index];
119  size_type child_block_size = this->_child_block_merge_offsets[child_index + 1] - child_block_offset;
120  size_type block_size = this->_child_block_merge_offsets.back();
121  size_type index = ci_out->back();
122  size_type block_index = index / child_block_size;
123  size_type offset =index % child_block_size;
124  ci_out->back() = block_index * block_size + child_block_offset + offset;
125  }
126  }
127 
128  // The return value is not used for non-leaf orderings.
129  return 0;
130  }
131 
132  };
133 
134  } // namespace interleaved_ordering
135 
136 
137  template<typename DI, typename CI, typename Child, std::size_t k>
139  : public TypeTree::PowerNode<Child, k>
140  , public interleaved_ordering::Base<DI,
141  CI,
142  PowerInterleavedOrdering<DI,CI,Child,k>
143  >
144  {
145  typedef TypeTree::PowerNode<Child, k> Node;
146 
147  typedef interleaved_ordering::Base<DI,
148  CI,
150  > Base;
151 
152  public:
153 
155 
163  PowerInterleavedOrdering(bool container_blocked, const InterleavedOrderingTag& ordering_tag, const typename Node::NodeStorage& children, typename Base::GFSData* gfs_data)
164  : Node(children)
165  , Base(*this,container_blocked,ordering_tag,gfs_data)
166  {}
167 
168  void update()
169  {
170  for (std::size_t i = 0; i < k; ++i)
171  {
172  this->child(i).update();
173  }
174  Base::update();
175  }
176 
177  std::string name() const { return "PowerInterleavedOrdering"; }
178  };
179 
180 
181  template<typename GFS, typename Transformation>
183  {
184 
185  static const bool recursive = true;
186 
187  template<typename TC>
188  struct result
189  {
190 
191  typedef PowerInterleavedOrdering<
192  typename Transformation::DOFIndex,
193  typename Transformation::ContainerIndex,
194  TC,
196  > type;
197 
198  typedef std::shared_ptr<type> storage_type;
199 
200  };
201 
202  template<typename TC>
203  static typename result<TC>::type transform(const GFS& gfs, const Transformation& t, const array<std::shared_ptr<TC>,TypeTree::StaticDegree<GFS>::value>& children)
204  {
205  return typename result<TC>::type(gfs.backend().blocked(gfs),gfs.orderingTag(),children,const_cast<GFS*>(&gfs));
206  }
207 
208  template<typename TC>
209  static typename result<TC>::storage_type transform_storage(std::shared_ptr<const GFS> gfs, const Transformation& t, const array<std::shared_ptr<TC>,TypeTree::StaticDegree<GFS>::value>& children)
210  {
211  return std::make_shared<typename result<TC>::type>(gfs->backend().blocked(*gfs),gfs->orderingTag(),children,const_cast<GFS*>(gfs.get()));
212  }
213 
214  };
215 
216  template<typename GFS, typename Transformation>
219 
220 
221 
222  template<typename DI, typename CI, typename... Children>
224  public TypeTree::CompositeNode<Children...>,
225  public interleaved_ordering::Base<DI,
226  CI,
227  CompositeInterleavedOrdering<
228  DI,
229  CI,
230  Children...
231  >
232  >
233  {
234  typedef TypeTree::CompositeNode<Children...> Node;
235 
237  DI,
238  CI,
240  DI,
241  CI,
242  Children...
243  >
244  > Base;
245 
246  public:
248 
256  CompositeInterleavedOrdering(bool backend_blocked, const InterleavedOrderingTag& ordering_tag, typename Base::GFSData* gfs_data, std::shared_ptr<Children>... children)
257  : Node(children...)
258  , Base(*this,backend_blocked,ordering_tag,gfs_data)
259  { }
260 
261  std::string name() const { return "CompositeInterleavedOrdering"; }
262 
263  void update()
264  {
265  TypeTree::applyToTree(*this,ordering::update_direct_children());
266  Base::update();
267  }
268  };
269 
270  template<typename GFS, typename Transformation>
272  {
273 
274  static const bool recursive = true;
275 
276  template<typename... TC>
277  struct result
278  {
279 
281  typename Transformation::DOFIndex,
282  typename Transformation::ContainerIndex,
283  TC...
284  > type;
285 
286  typedef std::shared_ptr<type> storage_type;
287 
288  };
289 
290  template<typename... TC>
291  static typename result<TC...>::type transform(const GFS& gfs, const Transformation& t, std::shared_ptr<TC>... children)
292  {
293  return typename result<TC...>::type(gfs.backend().blocked(gfs),gfs.orderingTag(),const_cast<GFS*>(&gfs),children...);
294  }
295 
296  template<typename... TC>
297  static typename result<TC...>::storage_type transform_storage(std::shared_ptr<const GFS> gfs, const Transformation& t, std::shared_ptr<TC>... children)
298  {
299  return std::make_shared<typename result<TC...>::type>(gfs->backend().blocked(*gfs),gfs.orderingTag(),const_cast<GFS*>(gfs.get()),children...);
300  }
301 
302  };
303 
304  template<typename GFS, typename Transformation>
307 
309  } // namespace PDELab
310 } // namespace Dune
311 
312 #endif // DUNE_PDELAB_ORDERING_INTERLEAVEDORDERING_HH
PowerInterleavedOrdering(bool container_blocked, const InterleavedOrderingTag &ordering_tag, const typename Node::NodeStorage &children, typename Base::GFSData *gfs_data)
Construct ordering object.
Definition: interleavedordering.hh:163
const std::vector< std::size_t > & offsets() const
Returns a list of offsets for the child blocks.
Definition: gridfunctionspace/tags.hh:115
static const bool consume_tree_index
Definition: interleavedordering.hh:39
Definition: orderingbase.hh:20
void update()
Definition: orderingbase.hh:97
Base(Node &node, bool container_blocked, const OrderingTag &ordering_tag, typename BaseT::GFSData *gfs_data)
Construct ordering object.
Definition: interleavedordering.hh:47
static result< TC... >::type transform(const GFS &gfs, const Transformation &t, std::shared_ptr< TC >... children)
Definition: interleavedordering.hh:291
Interface for merging index spaces.
Definition: interleavedordering.hh:27
InterleavedOrderingTag OrderingTag
Definition: interleavedordering.hh:37
For backward compatibility – Do not use this!
Definition: adaptivity.hh:27
std::vector< typename Traits::SizeType > _child_block_merge_offsets
Definition: orderingbase.hh:278
Definition: ordering/utility.hh:186
std::shared_ptr< type > storage_type
Definition: interleavedordering.hh:198
std::string name() const
Definition: interleavedordering.hh:261
Definition: interleavedordering.hh:223
Error related to the logical structure of an Ordering.
Definition: exceptions.hh:44
static result< TC >::type transform(const GFS &gfs, const Transformation &t, const array< std::shared_ptr< TC >, TypeTree::StaticDegree< GFS >::value > &children)
Definition: interleavedordering.hh:203
static const unsigned int value
Definition: gridfunctionspace/tags.hh:139
static result< TC... >::storage_type transform_storage(std::shared_ptr< const GFS > gfs, const Transformation &t, std::shared_ptr< TC >... children)
Definition: interleavedordering.hh:297
std::shared_ptr< type > storage_type
Definition: interleavedordering.hh:286
std::string name() const
Definition: interleavedordering.hh:177
const bool _container_blocked
Definition: orderingbase.hh:270
DI::size_type SizeType
Definition: ordering/utility.hh:201
composite_gfs_to_entityblocked_ordering_descriptor< GFS, Transformation > register_composite_gfs_to_ordering_descriptor(GFS *, Transformation *, EntityBlockedOrderingTag *)
void map_lfs_indices(const ItIn begin, const ItIn end, ItOut out) const
Definition: interleavedordering.hh:61
CompositeInterleavedOrdering< typename Transformation::DOFIndex, typename Transformation::ContainerIndex, TC... > type
Definition: interleavedordering.hh:284
PowerInterleavedOrdering< typename Transformation::DOFIndex, typename Transformation::ContainerIndex, TC, TypeTree::StaticDegree< GFS >::value > type
Definition: interleavedordering.hh:196
power_gfs_to_entityblocked_ordering_descriptor< GFS, Transformation > register_power_gfs_to_ordering_descriptor(GFS *, Transformation *, EntityBlockedOrderingTag *)
PDELab-specific exceptions.
CompositeInterleavedOrdering(bool backend_blocked, const InterleavedOrderingTag &ordering_tag, typename Base::GFSData *gfs_data, std::shared_ptr< Children >... children)
Construct ordering object.
Definition: interleavedordering.hh:256
OrderingBase< DI, CI >::Traits Traits
Definition: interleavedordering.hh:35
void update()
Definition: interleavedordering.hh:168
const std::size_t offset
Definition: localfunctionspace.hh:74
void update()
Definition: interleavedordering.hh:263
Dune::PDELab::impl::GridFunctionSpaceOrderingData< typename Traits::SizeType > GFSData
Definition: orderingbase.hh:32
Traits::SizeType extract_entity_indices(const typename Traits::DOFIndex::EntityIndex &ei, typename Traits::SizeType child_index, CIOutIterator ci_out, const CIOutIterator ci_end) const
Definition: interleavedordering.hh:96
Indicate interleaved ordering of the unknowns of non-leaf grid function spaces according to a given b...
Definition: gridfunctionspace/tags.hh:78
Definition: interleavedordering.hh:138
static result< TC >::storage_type transform_storage(std::shared_ptr< const GFS > gfs, const Transformation &t, const array< std::shared_ptr< TC >, TypeTree::StaticDegree< GFS >::value > &children)
Definition: interleavedordering.hh:209