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