dune-pdelab  2.7-git
leafgridviewordering.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_LEAFGRIDVIEWORDERING_HH
5 #define DUNE_PDELAB_ORDERING_LEAFGRIDVIEWORDERING_HH
6 
9 
10 namespace Dune {
11  namespace PDELab {
12 
15 
17  template<typename LocalOrdering>
19  : public LeafOrderingBase<LocalOrdering>
20  {
21  public:
22  typedef typename LocalOrdering::Traits Traits;
23 
24  private:
25 
26  using ES = typename Traits::EntitySet;
27 
29  typedef typename BaseT::NodeT NodeT;
30 
31  public:
32 
33  LeafGridViewOrdering(const typename NodeT::NodeStorage& local_ordering, bool container_blocked, typename BaseT::GFSData* gfs_data)
34  : BaseT(local_ordering, container_blocked, gfs_data)
35  , _es(this->template child<0>().entitySet())
36  {}
37 
38 #ifndef DOXYGEN
39 
40 // we need to override the default copy / move ctor to fix the delegate pointer, but that is
41 // hardly interesting to our users...
42 
44  : BaseT(r)
45  , _es(r._es)
46  {}
47 
49  : BaseT(std::move(r))
50  , _es(r._es)
51  {}
52 
53 #endif // DOXYGEN
54 
55  virtual ~LeafGridViewOrdering() override = default;
56 
57 
58  using BaseT::size;
59 
65  typename Traits::SizeType size(typename Traits::ContainerIndex suffix) const
66  {
67  // notice that this algorithm is the same as for GridViewOrdering
68  // the only difference is that here we can borrow some offsets from the
69  // local ordering
70 
71  using size_type = typename Traits::SizeType;
72  if (suffix.size() == Traits::ContainerIndex::max_depth)
73  return 0; // all indices in suffix were consumed, no more sizes to provide
74  if (suffix.size() == 0) // suffix wants the size of this depth
75  return _block_count; // blocked or not, this gives the number of blocks/dofs in next node hierarchy
76 
77  // we first have to figure out the entity index
78  typename Traits::DOFIndex::EntityIndex entity_index;
79 
80  // the next index to find out its size
81  auto back_index = suffix.back();
82 
83  // borrow offsets & fixed_size from local ordering
84  auto& _gt_entity_offsets = this->localOrdering()._gt_entity_offsets;
85  auto& _entity_dof_offsets = this->localOrdering()._entity_dof_offsets;
86  bool _fixed_size = this->localOrdering()._fixed_size;
87  // we just need to make the inverse computation of the mapIndex funtion to find the entity index
88  if (_container_blocked) {
89  suffix.pop_back();
90  auto gt_begin = _fixed_size ? _gt_dof_offsets.begin() : _gt_entity_offsets.begin();
91  auto gt_end = _fixed_size ? _gt_dof_offsets.end() : _gt_entity_offsets.end();
92  auto gt_it = std::prev(std::upper_bound(gt_begin, gt_end, back_index));
93  size_type gt = std::distance(gt_begin, gt_it);
94  assert(back_index >= *gt_it);
95  size_type ei = back_index - *gt_it;
96  Traits::DOFIndexAccessor::GeometryIndex::store(entity_index,gt,ei);
97  } else {
98  auto dof_begin = _fixed_size ? _gt_dof_offsets.begin() : _entity_dof_offsets.begin();
99  auto dof_end = _fixed_size ? _gt_dof_offsets.end() : _entity_dof_offsets.end();
100  auto dof_it = std::prev(std::upper_bound(dof_begin, dof_end, back_index));
101  size_type dof_dist = std::distance(dof_begin, dof_it);
102  if (_fixed_size) {
103  // On fixed size, entity index is not used down the tree. Set max to trigger segfault if this does not hold.
104  Traits::DOFIndexAccessor::GeometryIndex::store(entity_index,dof_dist,~size_type{0});
105  } else {
106  auto gt_begin = _gt_entity_offsets.begin();
107  auto gt_end = _gt_entity_offsets.end();
108  auto gt_it = std::prev(std::upper_bound(gt_begin, gt_end, dof_dist));
109  size_type gt = std::distance(gt_begin, gt_it);
110  assert(dof_dist >= *gt_it);
111  size_type ei = dof_dist - *gt_it;
112  Traits::DOFIndexAccessor::GeometryIndex::store(entity_index,gt,ei);
113  }
114  }
115  // then, the local ordering knows the size for a given entity.
116  return this->localOrdering().size(suffix, entity_index);
117  }
118 
119 
120  virtual void update() override
121  {
122  LocalOrdering& lo = this->localOrdering();
123  lo.update_a_priori_fixed_size();
124 
125  const std::size_t dim = ES::dimension;
126 
127  typename ES::CodimMask codims;
128  codims.set(0); // always need cells
129  lo.collect_used_codims(codims);
130 
131  for (typename ES::dim_type codim = 0; codim <= ES::dimension; ++codim)
132  if (codims.test(codim))
133  _es.addCodim(codim);
134 
135  _es.update();
136 
137  typedef typename Traits::SizeType size_type;
138  auto geom_types = _es.indexSet().types();
139 
140  if (lo._fixed_size)
141  {
142  lo.update_fixed_size(geom_types.begin(),geom_types.end());
143  }
144  else
145  {
146  lo.pre_collect_used_geometry_types_from_cell();
147 
148  for (const auto& element : elements(_es))
149  {
150  lo.collect_used_geometry_types_from_cell(element);
151  }
152 
153  lo.allocate_entity_offset_vector(geom_types.begin(),geom_types.end());
154 
155  for (const auto& element : elements(_es))
156  {
157  lo.extract_per_entity_sizes_from_cell(element);
158  }
159 
160  // FIXME: handling of blocked containers!
161  lo.finalize_non_fixed_size_update();
162  }
163 
164  // we need to re-test here, as the local ordering could have detected a fixed size ordering
165  // and switched its implementation
166  if (lo._fixed_size)
167  {
168  _gt_dof_offsets.assign(GlobalGeometryTypeIndex::size(dim) + 1,0);
169  _size = 0;
170 
171  for (auto gt : geom_types)
172  {
173  const size_type gt_index = GlobalGeometryTypeIndex::index(gt);
174  size_type gt_size = lo.size(gt_index,0);
175  size_type entity_count = _es.indexSet().size(gt);
176  _size += gt_size * entity_count;
177  if (_container_blocked)
178  gt_size = gt_size > 0;
179  _gt_dof_offsets[gt_index + 1] = gt_size * entity_count;
180  }
181  std::partial_sum(_gt_dof_offsets.begin(),_gt_dof_offsets.end(),_gt_dof_offsets.begin());
182  _block_count = _gt_dof_offsets.back();
183  _codim_fixed_size.set();
184  }
185  else
186  {
187  _block_count = _size = lo._entity_dof_offsets.back();
188  _codim_fixed_size.reset();
189  }
190 
191  _fixed_size = lo._fixed_size;
192  _max_local_size = lo.maxLocalSize();
193 
194  _codim_used = lo._codim_used;
195  _codim_fixed_size = lo._codim_fixed_size;
196 
197  }
198 
199  using BaseT::fixedSize;
200 
201  private:
202 
204  using BaseT::_size;
205  using BaseT::_block_count;
207  using BaseT::_fixed_size;
208  using BaseT::_codim_used;
211 
212  typename Traits::EntitySet _es;
213  };
214 
215 
216  template<typename GFS, typename Transformation>
218  {
219 
220  static const bool recursive = false;
221 
222  typedef DirectLeafLocalOrdering<typename GFS::Traits::OrderingTag,
223  typename GFS::Traits::FiniteElementMap,
224  typename GFS::Traits::EntitySet,
225  typename Transformation::DOFIndex,
226  typename Transformation::ContainerIndex
228 
230 
232  typedef std::shared_ptr<transformed_type> transformed_storage_type;
233 
234  static transformed_type transform(const GFS& gfs, const Transformation& t)
235  {
236  return transformed_type(make_tuple(std::make_shared<LocalOrdering>(gfs.finiteElementMapStorage(),gfs.entitySet())),gfs.backend().blocked(gfs),const_cast<GFS*>(&gfs));
237  }
238 
239  static transformed_storage_type transform_storage(std::shared_ptr<const GFS> gfs, const Transformation& t)
240  {
241  return std::make_shared<transformed_type>(make_tuple(std::make_shared<LocalOrdering>(gfs->finiteElementMapStorage(),gfs->entitySet())),gfs->backend().blocked(*gfs),const_cast<GFS*>(gfs.get()));
242  }
243 
244  };
245 
246 
247  template<typename GFS, typename Transformation, typename Params>
248  direct_leaf_gfs_to_gridview_ordering_descriptor<GFS,Transformation>
250 
252  } // namespace PDELab
253 } // namespace Dune
254 
255 #endif // DUNE_PDELAB_ORDERING_LEAFGRIDVIEWORDERING_HH
static const int dim
Definition: adaptivity.hh:84
std::size_t index
Definition: interpolate.hh:97
direct_leaf_gfs_to_gridview_ordering_descriptor< GFS, Transformation > register_leaf_gfs_to_ordering_descriptor(GFS *, Transformation *, LeafOrderingTag< Params > *)
For backward compatibility – Do not use this!
Definition: adaptivity.hh:28
Tag indicating a standard ordering for a leaf GridfunctionSpace.
Definition: gridfunctionspace/tags.hh:185
Definition: directleaflocalordering.hh:27
Gridview ordering for leaf spaces.
Definition: leafgridviewordering.hh:20
virtual ~LeafGridViewOrdering() override=default
virtual void update() override
Definition: leafgridviewordering.hh:120
LeafGridViewOrdering(const typename NodeT::NodeStorage &local_ordering, bool container_blocked, typename BaseT::GFSData *gfs_data)
Definition: leafgridviewordering.hh:33
Traits::SizeType size(typename Traits::ContainerIndex suffix) const
Gives the size for a given suffix.
Definition: leafgridviewordering.hh:65
LocalOrdering::Traits Traits
Definition: leafgridviewordering.hh:22
static transformed_type transform(const GFS &gfs, const Transformation &t)
Definition: leafgridviewordering.hh:234
static const bool recursive
Definition: leafgridviewordering.hh:220
static transformed_storage_type transform_storage(std::shared_ptr< const GFS > gfs, const Transformation &t)
Definition: leafgridviewordering.hh:239
GridViewOrdering transformed_type
Definition: leafgridviewordering.hh:231
std::shared_ptr< transformed_type > transformed_storage_type
Definition: leafgridviewordering.hh:232
DirectLeafLocalOrdering< typename GFS::Traits::OrderingTag, typename GFS::Traits::FiniteElementMap, typename GFS::Traits::EntitySet, typename Transformation::DOFIndex, typename Transformation::ContainerIndex > LocalOrdering
Definition: leafgridviewordering.hh:227
LeafGridViewOrdering< LocalOrdering > GridViewOrdering
Definition: leafgridviewordering.hh:229
Generic infrastructure for orderings for leaf spaces.
Definition: leaforderingbase.hh:27
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
std::size_t _max_local_size
Definition: orderingbase.hh:287
std::size_t _block_count
Definition: orderingbase.hh:289
std::vector< typename Traits::SizeType > _gt_dof_offsets
Definition: leaforderingbase.hh:281
TypeTree::CompositeNode< LocalOrdering > NodeT
Definition: leaforderingbase.hh:37
LocalOrdering & localOrdering()
Definition: leaforderingbase.hh:44
bool _fixed_size
Definition: orderingbase.hh:274
const bool _container_blocked
Definition: orderingbase.hh:275
Dune::PDELab::impl::GridFunctionSpaceOrderingData< typename Traits::SizeType > GFSData
Definition: orderingbase.hh:32