dune-pdelab  2.0.0
orderingbase.hh
Go to the documentation of this file.
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_ORDERINGBASE_HH
5 #define DUNE_PDELAB_ORDERING_ORDERINGBASE_HH
6 
7 #include <dune/common/shared_ptr.hh>
12 
13 #include <vector>
14 
15 namespace Dune {
16  namespace PDELab {
17 
20 
21  template<typename DI, typename CI>
23  : public PartitionInfoProvider
24  {
25 
26  template<typename size_type>
27  friend struct ::Dune::PDELab::impl::update_ordering_data;
28 
29  public:
30 
32 
33  protected:
34 
35  typedef Dune::PDELab::impl::GridFunctionSpaceOrderingData<typename Traits::SizeType> GFSData;
36 
37  public:
38 
40 
42 
43  static const bool has_dynamic_ordering_children = true;
44 
45  static const bool consume_tree_index = true;
46 
47  typename Traits::ContainerIndex mapIndex(const typename Traits::DOFIndex& di) const
48  {
49  typename Traits::ContainerIndex ci;
50  mapIndex(di.view(),ci);
51  return ci;
52  }
53 
54  void mapIndex(typename Traits::DOFIndexView di, typename Traits::ContainerIndex& ci) const
55  {
56  if (_delegate)
57  _delegate->map_index_dynamic(di,ci);
58  else
59  {
60  _mapIndex(di,ci);
61  }
62  }
63 
64  typename Traits::SizeType size() const
65  {
66  return _size;
67  }
68 
69  typename Traits::SizeType blockCount() const
70  {
71  return _block_count;
72  }
73 
74  typename Traits::SizeType size(const typename Traits::SizeType child_index) const
75  {
76  return _child_size_offsets[child_index + 1] - _child_size_offsets[child_index];
77  }
78 
79  typename Traits::SizeType sizeOffset(const typename Traits::SizeType child_index) const
80  {
81  return _child_size_offsets[child_index];
82  }
83 
84  typename Traits::SizeType blockOffset(const typename Traits::SizeType child_index) const
85  {
87  return _child_block_offsets[child_index];
88  }
89 
90  typename Traits::SizeType maxLocalSize() const
91  {
92  return _max_local_size;
93  }
94 
96  {
97  return _merge_mode;
98  }
99 
100  void update()
101  {
102  std::fill(_child_size_offsets.begin(),_child_size_offsets.end(),0);
103  std::fill(_child_block_offsets.begin(),_child_block_offsets.end(),0);
104  _codim_used.reset();
105  _codim_fixed_size.set();
106  _max_local_size = 0;
107  _block_count = 0;
108  typename Traits::SizeType block_carry = 0;
109  typename Traits::SizeType size_carry = 0;
110  for (typename Traits::SizeType i = 0; i < _child_count; ++i)
111  {
112  _child_block_offsets[i+1] = (block_carry += _children[i]->blockCount());
113  _child_size_offsets[i+1] = (size_carry += _children[i]->size());
114  _codim_used |= _children[i]->_codim_used;
115  _codim_fixed_size &= _children[i]->_codim_fixed_size;
116  _block_count += _children[i]->blockCount();
117  _max_local_size += _children[i]->maxLocalSize();
118  }
119  if (_container_blocked)
121  {
123  }
124  else
125  {
126  if (_child_block_offsets.back() % _child_block_merge_offsets.back() != 0)
127  DUNE_THROW(OrderingStructureError,
128  "Invalid ordering structure: "
129  << "total number of blocks ("
130  << _child_block_offsets.back()
131  << ") is not a multiple of the interleaved block size ("
133  << ")."
134  );
136  }
137  else
139  _size = _child_size_offsets.back();
140  }
141 
142  template<typename Node>
143  OrderingBase(Node& node,
144  bool container_blocked,
145  GFSData* gfs_data,
146  VirtualOrderingBase<DI,CI>* delegate = nullptr)
147  : _container_blocked(container_blocked)
148  , _merge_mode(MergeMode::lexicographic)
149  , _child_count(Node::has_dynamic_ordering_children ? Node::CHILDREN : 0)
150  , _children(_child_count,nullptr)
151  , _child_size_offsets((_child_count > 0 ? _child_count + 1 : 0),0)
152  , _child_block_offsets((_child_count > 0 ? _child_count + 1 : 0),0)
153  , _max_local_size(0)
154  , _size(0)
155  , _block_count(0)
156  , _delegate(delegate)
157  , _gfs_data(gfs_data)
158  {
159  TypeTree::applyToTree(node,extract_child_bases<OrderingBase>(_children));
160  // We contain all grid PartitionTypes that any of our children contain.
161  mergePartitionSets(_children.begin(),_children.end());
162  }
163 
164  template<typename Node>
165  OrderingBase(Node& node,
166  bool container_blocked,
167  const std::vector<std::size_t>& merge_offsets,
168  GFSData* gfs_data,
169  VirtualOrderingBase<DI,CI>* delegate = nullptr)
170  : _container_blocked(container_blocked)
171  , _merge_mode(MergeMode::interleaved)
172  , _child_count(Node::has_dynamic_ordering_children ? Node::CHILDREN : 0)
173  , _children(_child_count,nullptr)
174  , _child_size_offsets((_child_count > 0 ? _child_count + 1 : 0),0)
175  , _child_block_offsets((_child_count > 0 ? _child_count + 1 : 0),0)
176  , _child_block_merge_offsets(merge_offsets)
177  , _max_local_size(0)
178  , _size(0)
179  , _block_count(0)
180  , _delegate(delegate)
181  , _gfs_data(gfs_data)
182  {
183  TypeTree::applyToTree(node,extract_child_bases<OrderingBase>(_children));
184  // We contain all grid PartitionTypes that any of our children contain.
185  mergePartitionSets(_children.begin(),_children.end());
186  }
187 
188 
189  bool containerBlocked() const
190  {
191  return _container_blocked;
192  }
193 
194  std::size_t childOrderingCount() const
195  {
196  return _child_count;
197  }
198 
200  {
201  return *_children[i];
202  }
203 
204  const OrderingBase& childOrdering(typename Traits::SizeType i) const
205  {
206  return *_children[i];
207  }
208 
209  bool contains(typename Traits::SizeType codim) const
210  {
211  return _codim_used.test(codim);
212  }
213 
214  bool fixedSize(typename Traits::SizeType codim) const
215  {
216  return _codim_fixed_size.test(codim);
217  }
218 
219  protected:
220 
222 
228  {
229  _delegate = delegate;
230  }
231 
232  void _mapIndex(typename Traits::DOFIndexView di, typename Traits::ContainerIndex& ci) const
233  {
234  typedef typename Traits::SizeType size_type;
235  size_type child_index = di.treeIndex().back();
236  _children[child_index]->mapIndex(di.back_popped(),ci);
238  {
239  if (_container_blocked)
240  ci.push_back(child_index);
241  else
242  ci.back() += blockOffset(child_index);
243  }
244  else
245  {
246  size_type child_block_offset = _child_block_merge_offsets[child_index];
247  size_type child_block_size = _child_block_merge_offsets[child_index + 1] - child_block_offset;
248  size_type block_index = ci.back() / child_block_size;
249  size_type offset = ci.back() % child_block_size;
250  if (_container_blocked)
251  {
252  ci.back() = child_block_offset + offset;
253  ci.push_back(block_index);
254  }
255  else
256  {
257  size_type block_size = _child_block_merge_offsets.back();
258  ci.back() = block_index * block_size + child_block_offset + offset;
259  }
260  }
261  }
262 
263  private:
264 
265  bool update_gfs_data_size(typename Traits::SizeType& size, typename Traits::SizeType& block_count) const
266  {
267  size = _size;
268  block_count = _block_count;
269  return true;
270  }
271 
272  public:
273 
275  const bool _container_blocked;
277 
278  const std::size_t _child_count;
279  std::vector<OrderingBase*> _children;
280 
281  std::vector<typename Traits::SizeType> _child_size_offsets;
282  std::vector<typename Traits::SizeType> _child_block_offsets;
283  std::vector<typename Traits::SizeType> _child_block_merge_offsets;
286 
287  std::size_t _max_local_size;
288  std::size_t _size;
289  std::size_t _block_count;
290 
293 
294  };
295 
297 
298  } // namespace PDELab
299 } // namespace Dune
300 
301 #endif // DUNE_PDELAB_ORDERING_ORDERINGBASE_HH
OrderingBase & childOrdering(typename Traits::SizeType i)
Definition: orderingbase.hh:199
Mixin class for providing information about contained grid partitions.
Definition: partitioninfoprovider.hh:22
bool fixedSize(typename Traits::SizeType codim) const
Definition: orderingbase.hh:214
Definition: gridfunctionspace/tags.hh:280
MergeMode::type mergeMode() const
Definition: orderingbase.hh:95
OrderingBase(Node &node, bool container_blocked, const std::vector< std::size_t > &merge_offsets, GFSData *gfs_data, VirtualOrderingBase< DI, CI > *delegate=nullptr)
Definition: orderingbase.hh:165
Traits::CodimFlag _codim_fixed_size
Definition: orderingbase.hh:285
std::size_t _max_local_size
Definition: orderingbase.hh:287
DI::size_type SizeType
Definition: ordering/utility.hh:201
Traits::ContainerIndex mapIndex(const typename Traits::DOFIndex &di) const
Definition: orderingbase.hh:47
std::vector< typename Traits::SizeType > _child_block_offsets
Definition: orderingbase.hh:282
bool _fixed_size
Definition: orderingbase.hh:274
std::vector< OrderingBase * > _children
Definition: orderingbase.hh:279
std::vector< typename Traits::SizeType > _child_size_offsets
Definition: orderingbase.hh:281
void _mapIndex(typename Traits::DOFIndexView di, typename Traits::ContainerIndex &ci) const
Definition: orderingbase.hh:232
PDELab-specific exceptions.
HierarchicContainerAllocationTag ContainerAllocationTag
Definition: orderingbase.hh:39
CI ContainerIndex
Definition: ordering/utility.hh:160
Traits::SizeType sizeOffset(const typename Traits::SizeType child_index) const
Definition: orderingbase.hh:79
Traits::SizeType blockCount() const
Definition: orderingbase.hh:69
Definition: orderingbase.hh:22
Traits::SizeType blockOffset(const typename Traits::SizeType child_index) const
Definition: orderingbase.hh:84
OrderingTraits< DI, CI > Traits
Definition: orderingbase.hh:31
Definition: ordering/utility.hh:230
static const bool has_dynamic_ordering_children
Definition: orderingbase.hh:43
type
Definition: ordering/utility.hh:24
Definition: ordering/utility.hh:186
const std::size_t offset
Definition: localfunctionspace.hh:74
const OrderingBase & childOrdering(typename Traits::SizeType i) const
Definition: orderingbase.hh:204
bool containerBlocked() const
Definition: orderingbase.hh:189
Definition: gridfunctionspace/tags.hh:288
OrderingBase(Node &node, bool container_blocked, GFSData *gfs_data, VirtualOrderingBase< DI, CI > *delegate=nullptr)
Definition: orderingbase.hh:143
bool contains(typename Traits::SizeType codim) const
Definition: orderingbase.hh:209
std::vector< typename Traits::SizeType > _child_block_merge_offsets
Definition: orderingbase.hh:283
Traits::SizeType size(const typename Traits::SizeType child_index) const
Definition: orderingbase.hh:74
Traits::SizeType size() const
Definition: orderingbase.hh:64
DefaultLFSCacheTag CacheTag
Definition: orderingbase.hh:41
const VirtualOrderingBase< DI, CI > * _delegate
Definition: orderingbase.hh:291
std::size_t childOrderingCount() const
Definition: orderingbase.hh:194
GFSData * _gfs_data
Definition: orderingbase.hh:292
const MergeMode::type _merge_mode
Definition: orderingbase.hh:276
void mapIndex(typename Traits::DOFIndexView di, typename Traits::ContainerIndex &ci) const
Definition: orderingbase.hh:54
Error related to the logical structure of an Ordering.
Definition: exceptions.hh:44
void update()
Definition: orderingbase.hh:100
DI DOFIndex
Definition: ordering/utility.hh:158
Traits::CodimFlag _codim_used
Definition: orderingbase.hh:284
Definition: ordering/utility.hh:243
Traits::SizeType maxLocalSize() const
Definition: orderingbase.hh:90
std::size_t _block_count
Definition: orderingbase.hh:289
Index merging algorithm for global orderings.
Definition: ordering/utility.hh:21
static const bool consume_tree_index
Definition: orderingbase.hh:45
std::size_t _size
Definition: orderingbase.hh:288
const std::size_t _child_count
Definition: orderingbase.hh:278
const bool _container_blocked
Definition: orderingbase.hh:275
DI::View DOFIndexView
Definition: ordering/utility.hh:198
Lexicographically ordered ([i1,i2],[j1,j2] -> [i1,i2,j1,j2]).
Definition: ordering/utility.hh:25
std::bitset< max_dim > CodimFlag
Definition: ordering/utility.hh:194
Dune::PDELab::impl::GridFunctionSpaceOrderingData< typename Traits::SizeType > GFSData
Definition: orderingbase.hh:35
void mergePartitionSets(It begin, It end)
Adds the partitions from all PartitionInfoProviders in the range [begin,end).
Definition: partitioninfoprovider.hh:77
void setDelegate(const VirtualOrderingBase< DI, CI > *delegate)
Set the delegate called in mapIndex().
Definition: orderingbase.hh:227