dune-pdelab  2.7-git
gridviewordering.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_GRIDVIEWORDERING_HH
5 #define DUNE_PDELAB_ORDERING_GRIDVIEWORDERING_HH
6 
7 #include <dune/typetree/typetree.hh>
8 
15 
16 namespace Dune {
17  namespace PDELab {
18 
21 
22  template<typename Codims>
24  : public TypeTree::TreeVisitor
25  , public TypeTree::DynamicTraversal
26  {
27 
28  template<typename Node, typename TreePath>
29  void leaf(Node& node, TreePath tp)
30  {
31  node.collect_used_codims(codims);
32  }
33 
34  collect_used_codims(Codims& codims_)
35  : codims(codims_)
36  {}
37 
38  Codims& codims;
39 
40  };
41 
42 
44  : public TypeTree::TreeVisitor
45  , public TypeTree::DynamicTraversal
46  {
47 
48  template<typename Node, typename TreePath>
49  void leaf(Node& node, TreePath tp)
50  {
51  node.update_a_priori_fixed_size();
52  any = any || node._fixed_size;
53  all = all && node._fixed_size;
54  }
55 
56  template<typename Node, typename TreePath>
57  void pre(Node& node, TreePath tp) const
58  {
59  node._fixed_size = true;
60  }
61 
62  template<typename Node, typename Child, typename TreePath, typename ChildIndex>
63  void afterChild(Node& node, const Child& child, TreePath tp, ChildIndex childIndex) const
64  {
65  node._fixed_size = node._fixed_size && child._fixed_size;
66  }
67 
69  : any(false)
70  , all(true)
71  {}
72 
73  bool any;
74  bool all;
75 
76  };
77 
78 
79  template<typename ES>
81  : public TypeTree::TreeVisitor
82  , public TypeTree::DynamicTraversal
83  {
84 
85  template<typename Node, typename TreePath>
86  void leaf(Node& node, TreePath tp) const
87  {
88  if (node._fixed_size)
89  {
90  typedef typename Node::Traits::SizeType size_type;
91  const size_type dim = ES::dimension;
92  node._codim_used.reset();
93  node._gt_used.assign(GlobalGeometryTypeIndex::size(dim),false);
94  node._gt_dof_offsets.assign(GlobalGeometryTypeIndex::size(dim),0);
95  for (const auto& gt : es.indexSet().types())
96  {
97  size_type size = node.finiteElementMap().size(gt);
98  node._gt_dof_offsets[GlobalGeometryTypeIndex::index(gt)] = size;
99  node._gt_used[GlobalGeometryTypeIndex::index(gt)] = size > 0;
100  node._codim_used[dim - gt.dim()] = node._codim_used[dim - gt.dim()] || (size > 0);
101  }
102  node._max_local_size = node.finiteElementMap().maxLocalSize();
103  }
104  }
105 
106  template<typename Node, typename TreePath>
107  void pre(Node& node, TreePath tp) const
108  {
109  if (node._fixed_size)
110  {
111  typedef typename Node::Traits::SizeType size_type;
112  const size_type dim = ES::dimension;
113  node._codim_used.reset();
114  node._gt_used.assign(Dune::GlobalGeometryTypeIndex::size(dim),false);
115  node._gt_dof_offsets.assign(Dune::GlobalGeometryTypeIndex::size(dim) * TypeTree::degree(node),0);
116  node._max_local_size = 0;
117  }
118  }
119 
120  template<typename Node, typename Child, typename TreePath, typename ChildIndex>
121  void afterChild(Node& node, const Child& child, TreePath tp, ChildIndex childIndex) const
122  {
123  if (node._fixed_size)
124  {
125  node._codim_used |= child._codim_used;
126 
127  std::transform(node._gt_used.begin(),
128  node._gt_used.end(),
129  child._gt_used.begin(),
130  node._gt_used.begin(),
131  std::logical_or<bool>());
132 
133  node._max_local_size += child._max_local_size;
134 
135  typedef typename Node::Traits::SizeType size_type;
136 
137  const size_type per_gt_size = child._child_count > 0 ? child._child_count : 1;
138  const size_type size_offset = child._child_count > 0 ? child._child_count - 1 : 0;
139 
140  for (size_type gt = 0; gt < Dune::GlobalGeometryTypeIndex::size(ES::dimension); ++gt)
141  node._gt_dof_offsets[gt * TypeTree::degree(node) + childIndex] = child._gt_dof_offsets[gt * per_gt_size + size_offset];
142  }
143  }
144 
145  template<typename Node, typename TreePath>
146  void post(Node& node, TreePath tp) const
147  {
148  if (node._fixed_size)
149  {
150  typedef typename std::vector<typename Node::Traits::SizeType>::iterator iterator;
151 
152  iterator next_gt_it = node._gt_dof_offsets.begin() + TypeTree::degree(node);
153  const iterator end_it = node._gt_dof_offsets.end();
154 
155  for (iterator it = node._gt_dof_offsets.begin();
156  it != end_it;
157  it += TypeTree::degree(node), next_gt_it += TypeTree::degree(node))
158  std::partial_sum(it,next_gt_it,it);
159  }
160  }
161 
162  update_fixed_size(const ES es_)
163  : es(es_)
164  {}
165 
166  ES es;
167 
168  };
169 
170 
172  : public TypeTree::TreeVisitor
173  , public TypeTree::DynamicTraversal
174  {
175 
176  template<typename Node, typename TreePath>
177  void leaf(Node& node, TreePath tp) const
178  {
179  if (!node._fixed_size)
180  {
181  node._codim_used.reset();
182  node._gt_used.assign(Dune::GlobalGeometryTypeIndex::size(dim),false);
183  node._gt_dof_offsets.assign(Dune::GlobalGeometryTypeIndex::size(dim) * std::max(node._child_count,static_cast<std::size_t>(1)),Node::GT_UNUSED);
184  node._gt_entity_offsets.assign(Dune::GlobalGeometryTypeIndex::size(dim) + 1,0);
185  }
186  }
187 
188  template<typename Node, typename TreePath>
189  void pre(Node& node, TreePath tp) const
190  {
191  leaf(node,tp);
192  }
193 
194  pre_collect_used_geometry_types(std::size_t dimension)
195  : dim(dimension)
196  {}
197 
198  const std::size_t dim;
199 
200  };
201 
202 
203  template<typename Cell>
205  : public TypeTree::TreeVisitor
206  , public TypeTree::DynamicTraversal
207  {
208 
209  template<typename Node, typename TreePath>
210  void leaf(Node& node, TreePath tp) const
211  {
212  if (!node._fixed_size)
213  node.collect_used_geometry_types_from_cell(cell);
214  }
215 
217  : cell(cell_)
218  , ref_el(Dune::ReferenceElements<typename Cell::Geometry::ctype,Cell::dimension>::general(cell_.type()))
219  {}
220 
221  const Cell& cell;
222  Dune::ReferenceElement<typename Cell::Geometry> ref_el;
223 
224  };
225 
226 
227  template<typename ES>
229  : public TypeTree::TreeVisitor
230  , public TypeTree::DynamicTraversal
231  {
232 
233  template<typename Node, typename TreePath>
234  void leaf(Node& node, TreePath tp) const
235  {
236  if (!node._fixed_size)
237  {
238  typedef typename Node::Traits::SizeType size_type;
239 
240  for (const auto& gt : es.indexSet().types())
241  {
242  if (node._gt_used[Dune::GlobalGeometryTypeIndex::index(gt)])
243  node._gt_entity_offsets[Dune::GlobalGeometryTypeIndex::index(gt) + 1] = es.indexSet().size(gt);
244  }
245 
246  std::partial_sum(node._gt_entity_offsets.begin(),node._gt_entity_offsets.end(),node._gt_entity_offsets.begin());
247  node._entity_dof_offsets.assign(node._gt_entity_offsets.back() * std::max(node._child_count,static_cast<size_type>(1)),0);
248  node.setup_fixed_size_possible();
249  }
250  }
251 
252  template<typename Node, typename Child, typename TreePath, typename ChildIndex>
253  void afterChild(Node& node, const Child& child, TreePath tp, ChildIndex childIndex) const
254  {
255  if (!node._fixed_size)
256  {
257  node._codim_used |= child._codim_used;
258 
259  std::transform(node._gt_used.begin(),
260  node._gt_used.end(),
261  child._gt_used.begin(),
262  node._gt_used.begin(),
263  std::logical_or<bool>());
264  }
265  }
266 
267  template<typename Node, typename TreePath>
268  void post(Node& node, TreePath tp) const
269  {
270  leaf(node,tp);
271  }
272 
274  : es(es_)
275  {}
276 
277  ES es;
278 
279  };
280 
281 
282  template<typename ES>
284  : public TypeTree::TreeVisitor
285  , public TypeTree::DynamicTraversal
286  {
287 
288  static const std::size_t dim = ES::dimension;
289  typedef typename ES::template Codim<0>::Entity Cell;
290  typedef std::size_t size_type;
291 
292  template<typename Node, typename TreePath>
293  void leaf(Node& node, TreePath tp)
294  {
295  if (!node._fixed_size)
296  node.extract_per_entity_sizes_from_cell(*cell,gt_sizes);
297  }
298 
300  : es(es_)
301  , cell(nullptr)
302  , ref_el()
303  , gt_sizes(Dune::GlobalGeometryTypeIndex::size(dim),0)
304  {}
305 
306  void set_cell(const Cell& cell_)
307  {
308  cell = &cell_;
309  ref_el = referenceElement(cell_.geometry());
310  }
311 
312  ES es;
313  const Cell* cell;
314  Dune::ReferenceElement<typename Cell::Geometry> ref_el;
315  std::vector<size_type> gt_sizes;
316 
317  };
318 
319 
320  template<typename ES>
322  : public TypeTree::TreeVisitor
323  , public TypeTree::DynamicTraversal
324  {
325 
326  typedef std::vector<GeometryType> GTVector;
327 
328 
329  template<typename Node, typename TreePath>
330  void leaf(Node& node, TreePath tp) const
331  {
332  if (!node._fixed_size)
333  {
334  // mask out GT_UNUSED for geometry types that really weren't used
335  for (auto& size : node._gt_dof_offsets)
336  if (size == Node::GT_UNUSED)
337  size = 0;
338  if (node._fixed_size_possible)
339  {
340  node._entity_dof_offsets = std::vector<typename Node::Traits::SizeType>();
341  node._fixed_size = true;
342  }
343  }
344  }
345 
346  template<typename Node, typename TreePath>
347  void pre(Node& node, TreePath tp) const
348  {
349  if (!node._fixed_size)
350  {
351  node._fixed_size_possible = true;
352  node._max_local_size = 0;
353  }
354  }
355 
356 
357  template<typename Node, typename Child, typename TreePath, typename ChildIndex>
358  void afterChild(Node& node, const Child& child, TreePath tp, ChildIndex childIndex) const
359  {
360  if (!node._fixed_size)
361  {
362  node._fixed_size_possible = node._fixed_size_possible && child._fixed_size;
363  node._max_local_size += child._max_local_size;
364  }
365  }
366 
367 
368  template<typename Node, typename TreePath>
369  void post(Node& node, TreePath tp) const
370  {
371  if (!node._fixed_size)
372  {
373 
374  typedef typename Node::Traits::SizeType size_type;
375  const size_type dim = ES::dimension;
376 
377  if (node._fixed_size_possible)
378  {
379 
380  for (size_type gt = 0; gt < GlobalGeometryTypeIndex::size(ES::dimension); ++gt)
381  {
382  for (size_type child_index = 0; child_index < TypeTree::degree(node); ++child_index)
383  {
384  const size_type per_gt_size = node.childOrdering(child_index)._child_count > 0 ? node.childOrdering(child_index)._child_count : 1;
385  const size_type size_offset = node.childOrdering(child_index)._child_count > 0 ? node.childOrdering(child_index)._child_count - 1 : 0;
386 
387  node._gt_dof_offsets[gt * TypeTree::degree(node) + child_index] = node.childOrdering(child_index)._gt_dof_offsets[gt * per_gt_size + size_offset];
388  }
389  }
390 
391  typedef typename std::vector<typename Node::Traits::SizeType>::iterator iterator;
392 
393  const iterator end_it = node._gt_dof_offsets.end();
394 
395  for (iterator it = node._gt_dof_offsets.begin();
396  it != end_it;
397  it += TypeTree::degree(node))
398  std::partial_sum(it,it + TypeTree::degree(node),it);
399 
400  node._fixed_size = true;
401  }
402  else
403  {
404  typedef typename Node::Traits::SizeType size_type;
405 
406  size_type index = 0;
407  for (size_type geometry_type_index = 0; geometry_type_index < GlobalGeometryTypeIndex::size(dim); ++geometry_type_index)
408  {
409  if (!node._gt_used[geometry_type_index])
410  continue;
411  const size_type entity_count = node._gt_entity_offsets[geometry_type_index+1] - node._gt_entity_offsets[geometry_type_index];
412  for (size_type entity_index = 0; entity_index < entity_count; ++entity_index)
413  {
414  size_type carry = 0;
415  for (size_type child_index = 0; child_index < TypeTree::degree(node); ++child_index)
416  node._entity_dof_offsets[index++] = (carry += node.childOrdering(child_index).size(geometry_type_index,entity_index));
417  }
418  }
419 
420  }
421  }
422  }
423 
425  : es(es_)
426  {}
427 
428  ES es;
429 
430  };
431 
433  template<typename LocalOrdering>
435  : public TypeTree::CompositeNode<LocalOrdering>
436  , public VirtualOrderingBase<typename LocalOrdering::Traits::DOFIndex,
437  typename LocalOrdering::Traits::ContainerIndex>
438  , public OrderingBase<typename LocalOrdering::Traits::DOFIndex,
439  typename LocalOrdering::Traits::ContainerIndex>
440  {
441  public:
442  typedef typename LocalOrdering::Traits Traits;
443 
444  static const bool has_dynamic_ordering_children = false;
445 
446  static const bool consume_tree_index = false;
447 
448  private:
449 
450  typedef TypeTree::CompositeNode<LocalOrdering> NodeT;
451  typedef OrderingBase<
452  typename LocalOrdering::Traits::DOFIndex,
453  typename LocalOrdering::Traits::ContainerIndex
454  > BaseT;
455 
456  using EntitySet = typename Traits::EntitySet;
457 
458  public:
460 
465  GridViewOrdering(const typename NodeT::NodeStorage &local_ordering,
466  bool container_blocked,
467  typename BaseT::GFSData *gfs_data,
468  const EntitySet &entity_Set)
469  : NodeT(local_ordering),
470  BaseT(*this, container_blocked, gfs_data, this), _es(entity_Set) {
471  // make sure to switch off container blocking handling in the local ordering,
472  // we already handle it in the GridViewOrdering
473  localOrdering().disable_container_blocking();
474  }
475 
476 #ifndef DOXYGEN
477 
478 // we need to override the default copy / move ctor to fix the delegate pointer, but that is
479 // hardly interesting to our users...
480 
482  : NodeT(r.nodeStorage())
483  , BaseT(r)
484  , _es(r._es)
485  , _gt_dof_offsets(r._gt_dof_offsets)
486  , _gt_entity_offsets(r._gt_entity_offsets)
487  , _entity_dof_offsets(r._entity_dof_offsets)
488  {
489  this->setDelegate(this);
490  }
491 
493  : NodeT(r.nodeStorage())
494  , BaseT(std::move(r))
495  , _es(std::move(r._es))
496  , _gt_dof_offsets(std::move(r._gt_dof_offsets))
497  , _gt_entity_offsets(std::move(r._gt_entity_offsets))
498  , _entity_dof_offsets(std::move(r._entity_dof_offsets))
499  {
500  this->setDelegate(this);
501  }
502 
503  virtual ~GridViewOrdering() override = default;
504 
505 #endif // DOXYGEN
506 
507  using BaseT::size;
508 
514  typename Traits::SizeType size(typename Traits::ContainerIndex suffix) const
515  {
516  using size_type = typename Traits::SizeType;
517  if (suffix.size() == Traits::ContainerIndex::max_depth)
518  return 0; // all indices in suffix were consumed, no more sizes to provide
519  if (suffix.size() == 0) // suffix wants the size of this depth
520  return _block_count; // blocked or not, this gives the number of blocks/dofs in next node hierarchy
521 
522  // we first have to figure out the entity index
523  typename Traits::DOFIndex::EntityIndex entity_index;
524 
525  // the next index to find out its size
526  auto back_index = suffix.back();
527  // we just need to make the inverse computation of the mapIndex funtion to find the entity index
528  if (_container_blocked) {
529  suffix.pop_back();
530  auto gt_begin = _fixed_size ? _gt_dof_offsets.begin() : _gt_entity_offsets.begin();
531  auto gt_end = _fixed_size ? _gt_dof_offsets.end() : _gt_entity_offsets.end();
532  auto gt_it = std::prev(std::upper_bound(gt_begin, gt_end, back_index));
533  size_type gt = std::distance(gt_begin, gt_it);
534  assert(back_index >= *gt_it);
535  size_type ei = back_index - *gt_it;
536  Traits::DOFIndexAccessor::GeometryIndex::store(entity_index,gt,ei);
537  } else {
538  auto dof_begin = _fixed_size ? _gt_dof_offsets.begin() : _entity_dof_offsets.begin();
539  auto dof_end = _fixed_size ? _gt_dof_offsets.end() : _entity_dof_offsets.end();
540  auto dof_it = std::prev(std::upper_bound(dof_begin, dof_end, back_index));
541  size_type dof_dist = std::distance(dof_begin, dof_it);
542  if (_fixed_size) {
543  // On fixed size, entity index is not used down the tree. Set max to trigger segfault if this does not hold.
544  Traits::DOFIndexAccessor::GeometryIndex::store(entity_index,dof_dist,~size_type{0});
545  } else {
546  auto gt_begin = _gt_entity_offsets.begin();
547  auto gt_end = _gt_entity_offsets.end();
548  auto gt_it = std::prev(std::upper_bound(gt_begin, gt_end, dof_dist));
549  size_type gt = std::distance(gt_begin, gt_it);
550  assert(dof_dist >= *gt_it);
551  size_type ei = dof_dist - *gt_it;
552  Traits::DOFIndexAccessor::GeometryIndex::store(entity_index,gt,ei);
553  }
554  }
555  // then, the local ordering knows the size for a given entity.
556  return localOrdering().size(suffix, entity_index);
557  }
558 
559  LocalOrdering& localOrdering()
560  {
561  return this->template child<0>();
562  }
563 
564  const LocalOrdering& localOrdering() const
565  {
566  return this->template child<0>();
567  }
568 
569  virtual void map_index_dynamic(typename Traits::DOFIndexView di, typename Traits::ContainerIndex& ci) const override
570  {
571  mapIndex(di,ci);
572  }
573 
574  typename Traits::ContainerIndex mapIndex(const typename Traits::DOFIndex& di) const
575  {
576  typename Traits::ContainerIndex ci;
577  mapIndex(di.view(),ci);
578  return ci;
579  }
580 
581  void mapIndex(typename Traits::DOFIndexView di, typename Traits::ContainerIndex& ci) const
582  {
583  typedef typename Traits::SizeType size_type;
584  const size_type geometry_type_index = Traits::DOFIndexAccessor::geometryType(di);
585  const size_type entity_index = Traits::DOFIndexAccessor::entityIndex(di);
586  localOrdering().map_local_index(geometry_type_index,entity_index,di.treeIndex(),ci);
587  if (_container_blocked)
588  {
589  if (_fixed_size)
590  {
591  ci.push_back(_gt_dof_offsets[geometry_type_index] + entity_index);
592  }
593  else
594  {
595  ci.push_back(_gt_entity_offsets[geometry_type_index] + entity_index);
596  }
597  }
598  else
599  {
600  if (_fixed_size)
601  {
602  ci.back() += _gt_dof_offsets[geometry_type_index] + entity_index * localOrdering().size(geometry_type_index,entity_index);
603  }
604  else
605  {
606  ci.back() += _entity_dof_offsets[_gt_entity_offsets[geometry_type_index] + entity_index];
607  }
608  }
609  }
610 
611  template<typename ItIn, typename ItOut>
612  void map_lfs_indices(const ItIn begin, const ItIn end, ItOut out) const
613  {
614  typedef typename Traits::SizeType size_type;
615  if (_container_blocked)
616  {
617  if (_fixed_size)
618  for (ItIn in = begin; in != end; ++in, ++out)
619  {
620  const size_type geometry_type_index = Traits::DOFIndexAccessor::geometryType(*in);
621  const size_type entity_index = Traits::DOFIndexAccessor::entityIndex(*in);
622  out->push_back(_gt_dof_offsets[geometry_type_index] + entity_index);
623  }
624  else
625  for (ItIn in = begin; in != end; ++in, ++out)
626  {
627  const size_type geometry_type_index = Traits::DOFIndexAccessor::geometryType(*in);
628  const size_type entity_index = Traits::DOFIndexAccessor::entityIndex(*in);
629  out->push_back(_gt_entity_offsets[geometry_type_index] + entity_index);
630  }
631  }
632  else if (_fixed_size)
633  {
634  for (ItIn in = begin; in != end; ++in, ++out)
635  {
636  const size_type geometry_type_index = Traits::DOFIndexAccessor::geometryType(*in);
637  const size_type entity_index = Traits::DOFIndexAccessor::entityIndex(*in);
638  out->back() += _gt_dof_offsets[geometry_type_index] + entity_index * localOrdering().size(geometry_type_index,entity_index);
639  }
640  }
641  else
642  {
643  for (ItIn in = begin; in != end; ++in, ++out)
644  {
645  const size_type geometry_type_index = Traits::DOFIndexAccessor::geometryType(*in);
646  const size_type entity_index = Traits::DOFIndexAccessor::entityIndex(*in);
647  out->back() += _entity_dof_offsets[_gt_entity_offsets[geometry_type_index] + entity_index];
648  }
649  }
650  }
651 
652  template<typename CIOutIterator>
653  typename Traits::SizeType
654  extract_entity_indices(const typename Traits::DOFIndex::EntityIndex& ei,
655  typename Traits::SizeType child_index,
656  CIOutIterator ci_out, const CIOutIterator ci_end) const
657  {
658  typedef typename Traits::SizeType size_type;
659 
660  const size_type geometry_type_index = Traits::DOFIndexAccessor::GeometryIndex::geometryType(ei);
661  const size_type entity_index = Traits::DOFIndexAccessor::GeometryIndex::entityIndex(ei);
662 
663  if (_container_blocked)
664  {
665  if (_fixed_size)
666  for (; ci_out != ci_end; ++ci_out)
667  {
668  ci_out->push_back(_gt_dof_offsets[geometry_type_index] + entity_index);
669  }
670  else
671  for (; ci_out != ci_end; ++ci_out)
672  {
673  ci_out->push_back(_gt_entity_offsets[geometry_type_index] + entity_index);
674  }
675  }
676  else if (_fixed_size)
677  {
678  for (; ci_out != ci_end; ++ci_out)
679  {
680  ci_out->back() += _gt_dof_offsets[geometry_type_index] + entity_index * localOrdering().size(geometry_type_index,entity_index);
681  }
682  }
683  else
684  {
685  for (; ci_out != ci_end; ++ci_out)
686  {
687  ci_out->back() += _entity_dof_offsets[_gt_entity_offsets[geometry_type_index] + entity_index];
688  }
689  }
690 
691  // The return value is not used for non-leaf orderings.
692  return 0;
693  }
694 
695  void update()
696  {
697 
698  typedef typename Traits::SizeType size_type;
699  using ES = typename Traits::EntitySet;
700  const size_type dim = ES::dimension;
701 
702  typename ES::CodimMask codims;
703  codims.set(0); // we always need cells
704 
705  TypeTree::applyToTree(localOrdering(),collect_used_codims<typename ES::CodimMask>(codims));
706 
707  for (typename ES::dim_type codim = 0; codim <= ES::dimension; ++codim)
708  if (codims.test(codim))
709  _es.addCodim(codim);
710 
711  _es.update();
712 
713  // Do we already know that we have fixed per-GeometryType sizes?
714  collect_a_priori_fixed_size fixed_size_collector;
715  TypeTree::applyToTree(localOrdering(),fixed_size_collector);
716  _fixed_size = localOrdering().fixedSize();
717 
718  const size_type gt_index_count = GlobalGeometryTypeIndex::size(ES::dimension);
719 
720  if (fixed_size_collector.any)
721  {
722  // collect used GeometryTypes
723  TypeTree::applyToTree(localOrdering(),update_fixed_size<ES>(_es));
724  }
725 
726  if (!fixed_size_collector.all)
727  {
728  TypeTree::applyToTree(localOrdering(),pre_collect_used_geometry_types(ES::dimension));
729 
730  using Element = typename ES::template Codim<0>::Entity;
731 
732  for (const auto& element : elements(_es))
733  {
735  }
736  TypeTree::applyToTree(localOrdering(),post_collect_used_geometry_types<ES>(_es));
737  // allocate
738 
739  //TypeTree::applyToTree(localOrdering(),pre_extract_per_entity_sizes<GV>(_gv));
741  for (const auto& element : elements(_es))
742  {
743  visitor.set_cell(element);
744  TypeTree::applyToTree(localOrdering(),visitor);
745  }
746  TypeTree::applyToTree(localOrdering(),post_extract_per_entity_sizes<ES>(_es));
747  }
748 
749  _codim_used = localOrdering()._codim_used;
750 
751  if (localOrdering().fixedSize())
752  {
753  _fixed_size = true;
754  _gt_dof_offsets.assign(gt_index_count + 1,0);
755 
756  _block_count = 0;
757 
758  _size = 0;
759 
760  for (const auto& gt : _es.indexSet().types())
761  {
762  const size_type gt_index = GlobalGeometryTypeIndex::index(gt);
763  size_type gt_size = localOrdering().size(gt_index,0);
764  const size_type gt_entity_count = _es.indexSet().size(gt);
765  _size += gt_size * gt_entity_count;
766  if (_container_blocked)
767  gt_size = gt_size > 0;
768  _gt_dof_offsets[gt_index + 1] = gt_size * gt_entity_count;
769  }
770 
771  std::partial_sum(_gt_dof_offsets.begin(),_gt_dof_offsets.end(),_gt_dof_offsets.begin());
772  _block_count = _gt_dof_offsets.back();
773 
774  _codim_fixed_size.set();
775 
776  }
777  else
778  {
779  _gt_entity_offsets.assign(gt_index_count + 1,0);
780 
781  for (const auto& gt : _es.indexSet().types())
782  {
783  if (!localOrdering().contains(gt))
784  continue;
785  const size_type gt_index = GlobalGeometryTypeIndex::index(gt);
786  _gt_entity_offsets[gt_index + 1] = _es.indexSet().size(gt);
787  }
788 
789  std::partial_sum(_gt_entity_offsets.begin(),_gt_entity_offsets.end(),_gt_entity_offsets.begin());
790  _entity_dof_offsets.assign(_gt_entity_offsets.back()+1,0);
791  _block_count = 0;
792 
793  size_type carry = 0;
794  size_type index = 0;
795  for (size_type gt_index = 0; gt_index < GlobalGeometryTypeIndex::size(dim); ++gt_index)
796  {
797  if (!localOrdering().contains_geometry_type(gt_index))
798  continue;
799  const size_type entity_count = _gt_entity_offsets[gt_index + 1] - _gt_entity_offsets[gt_index];
800  for (size_type entity_index = 0; entity_index < entity_count; ++entity_index)
801  {
802  const size_type size = localOrdering().size(gt_index,entity_index);
803  _entity_dof_offsets[++index] = (carry += size);
804  _block_count += (size > 0);
805  }
806  }
807  _size = _entity_dof_offsets.back();
808 
809  if (!_container_blocked)
810  _block_count = _size;
811 
812  _codim_fixed_size.reset();
813  }
814 
815  _max_local_size = localOrdering().maxLocalSize();
816  }
817 
818  using BaseT::fixedSize;
819 
820  private:
821 
823  using BaseT::_fixed_size;
825  using BaseT::_size;
826  using BaseT::_block_count;
827  using BaseT::_codim_used;
829 
830  typename Traits::EntitySet _es;
831  std::vector<typename Traits::SizeType> _gt_dof_offsets;
832  std::vector<typename Traits::SizeType> _gt_entity_offsets;
833  std::vector<typename Traits::SizeType> _entity_dof_offsets;
834 
835  };
836 
837 
839  } // namespace PDELab
840 } // namespace Dune
841 
842 #endif // DUNE_PDELAB_ORDERING_GRIDVIEWORDERING_HH
static const int dim
Definition: adaptivity.hh:84
std::size_t index
Definition: interpolate.hh:97
For backward compatibility – Do not use this!
Definition: adaptivity.hh:28
Definition: gridviewordering.hh:26
void leaf(Node &node, TreePath tp)
Definition: gridviewordering.hh:29
Codims & codims
Definition: gridviewordering.hh:38
collect_used_codims(Codims &codims_)
Definition: gridviewordering.hh:34
Definition: gridviewordering.hh:46
bool any
Definition: gridviewordering.hh:73
void leaf(Node &node, TreePath tp)
Definition: gridviewordering.hh:49
bool all
Definition: gridviewordering.hh:74
void afterChild(Node &node, const Child &child, TreePath tp, ChildIndex childIndex) const
Definition: gridviewordering.hh:63
collect_a_priori_fixed_size()
Definition: gridviewordering.hh:68
void pre(Node &node, TreePath tp) const
Definition: gridviewordering.hh:57
Definition: gridviewordering.hh:83
update_fixed_size(const ES es_)
Definition: gridviewordering.hh:162
void leaf(Node &node, TreePath tp) const
Definition: gridviewordering.hh:86
void post(Node &node, TreePath tp) const
Definition: gridviewordering.hh:146
ES es
Definition: gridviewordering.hh:166
void afterChild(Node &node, const Child &child, TreePath tp, ChildIndex childIndex) const
Definition: gridviewordering.hh:121
void pre(Node &node, TreePath tp) const
Definition: gridviewordering.hh:107
Definition: gridviewordering.hh:174
pre_collect_used_geometry_types(std::size_t dimension)
Definition: gridviewordering.hh:194
void pre(Node &node, TreePath tp) const
Definition: gridviewordering.hh:189
const std::size_t dim
Definition: gridviewordering.hh:198
void leaf(Node &node, TreePath tp) const
Definition: gridviewordering.hh:177
void leaf(Node &node, TreePath tp) const
Definition: gridviewordering.hh:210
collect_used_geometry_types_from_cell_visitor(const Cell &cell_)
Definition: gridviewordering.hh:216
const Cell & cell
Definition: gridviewordering.hh:221
Dune::ReferenceElement< typename Cell::Geometry > ref_el
Definition: gridviewordering.hh:222
Definition: gridviewordering.hh:231
void leaf(Node &node, TreePath tp) const
Definition: gridviewordering.hh:234
post_collect_used_geometry_types(const ES &es_)
Definition: gridviewordering.hh:273
ES es
Definition: gridviewordering.hh:277
void post(Node &node, TreePath tp) const
Definition: gridviewordering.hh:268
void afterChild(Node &node, const Child &child, TreePath tp, ChildIndex childIndex) const
Definition: gridviewordering.hh:253
void set_cell(const Cell &cell_)
Definition: gridviewordering.hh:306
ES es
Definition: gridviewordering.hh:312
static const std::size_t dim
Definition: gridviewordering.hh:288
Dune::ReferenceElement< typename Cell::Geometry > ref_el
Definition: gridviewordering.hh:314
extract_per_entity_sizes_from_cell_visitor(const ES &es_)
Definition: gridviewordering.hh:299
const Cell * cell
Definition: gridviewordering.hh:313
std::vector< size_type > gt_sizes
Definition: gridviewordering.hh:315
std::size_t size_type
Definition: gridviewordering.hh:290
ES::template Codim< 0 >::Entity Cell
Definition: gridviewordering.hh:289
void leaf(Node &node, TreePath tp)
Definition: gridviewordering.hh:293
Definition: gridviewordering.hh:324
void afterChild(Node &node, const Child &child, TreePath tp, ChildIndex childIndex) const
Definition: gridviewordering.hh:358
void post(Node &node, TreePath tp) const
Definition: gridviewordering.hh:369
post_extract_per_entity_sizes(const ES &es_)
Definition: gridviewordering.hh:424
void pre(Node &node, TreePath tp) const
Definition: gridviewordering.hh:347
ES es
Definition: gridviewordering.hh:428
std::vector< GeometryType > GTVector
Definition: gridviewordering.hh:326
void leaf(Node &node, TreePath tp) const
Definition: gridviewordering.hh:330
Transforms a local ordering (entity-wise order) into a global ordering.
Definition: gridviewordering.hh:440
LocalOrdering::Traits Traits
Definition: gridviewordering.hh:442
virtual void map_index_dynamic(typename Traits::DOFIndexView di, typename Traits::ContainerIndex &ci) const override
Definition: gridviewordering.hh:569
void mapIndex(typename Traits::DOFIndexView di, typename Traits::ContainerIndex &ci) const
Definition: gridviewordering.hh:581
bool fixedSize() const
Definition: orderingbase.hh:209
static const bool has_dynamic_ordering_children
Definition: gridviewordering.hh:444
void update()
Definition: gridviewordering.hh:695
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: gridviewordering.hh:654
GridViewOrdering(const typename NodeT::NodeStorage &local_ordering, bool container_blocked, typename BaseT::GFSData *gfs_data, const EntitySet &entity_Set)
Construct ordering object.
Definition: gridviewordering.hh:465
static const bool consume_tree_index
Definition: gridviewordering.hh:446
void map_lfs_indices(const ItIn begin, const ItIn end, ItOut out) const
Definition: gridviewordering.hh:612
LocalOrdering & localOrdering()
Definition: gridviewordering.hh:559
Traits::SizeType size() const
Definition: orderingbase.hh:61
Traits::ContainerIndex mapIndex(const typename Traits::DOFIndex &di) const
Definition: gridviewordering.hh:574
const LocalOrdering & localOrdering() const
Definition: gridviewordering.hh:564
Traits::SizeType size(typename Traits::ContainerIndex suffix) const
Gives the size for a given suffix.
Definition: gridviewordering.hh:514
Definition: orderingbase.hh:21
Dune::PDELab::impl::GridFunctionSpaceOrderingData< typename Traits::SizeType > GFSData
Definition: orderingbase.hh:32
Traits::CodimFlag _codim_fixed_size
Definition: orderingbase.hh:285
bool fixedSize() const
Definition: orderingbase.hh:209
Traits::CodimFlag _codim_used
Definition: orderingbase.hh:284
std::size_t _size
Definition: orderingbase.hh:288
void setDelegate(const VirtualOrderingBase< LocalOrdering::Traits::DOFIndex, LocalOrdering::Traits::ContainerIndex > *delegate)
Set the delegate called in mapIndex().
Definition: orderingbase.hh:227
Traits::SizeType size() const
Definition: orderingbase.hh:61
std::size_t _max_local_size
Definition: orderingbase.hh:287
std::size_t _block_count
Definition: orderingbase.hh:289
bool contains(typename Traits::SizeType codim) const
Definition: orderingbase.hh:204
bool _fixed_size
Definition: orderingbase.hh:274
const bool _container_blocked
Definition: orderingbase.hh:275
Definition: ordering/utility.hh:243