DUNE PDELab (git)

localorderingbase.hh
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_LOCALORDERINGBASE_HH
5#define DUNE_PDELAB_ORDERING_LOCALORDERINGBASE_HH
6
7#include <dune/pdelab/ordering/utility.hh>
8#include <dune/pdelab/gridfunctionspace/gridfunctionspacebase.hh>
9
11
12#include <vector>
13
14namespace Dune {
15 namespace PDELab {
16
19
28 template<typename ES, typename DI, typename CI>
30 {
31
32 friend struct collect_a_priori_fixed_size;
33
34 template<typename>
35 friend struct update_fixed_size;
36
37 template<typename>
38 friend struct post_collect_used_geometry_types;
39
40 template<typename>
41 friend struct post_extract_per_entity_sizes;
42
43 friend struct pre_collect_used_geometry_types;
44
45 template<typename>
46 friend struct collect_used_geometry_types_from_cell;
47
48 template<typename>
49 friend struct extract_per_entity_sizes_from_cell;
50
51 template<typename>
52 friend class GridViewOrdering;
53
54 template<typename size_type>
55 friend struct ::Dune::PDELab::impl::update_ordering_data;
56
57 public:
58
59 static const bool has_dynamic_ordering_children = true;
60
61 static const bool consume_tree_index = true;
62
63 typedef LocalOrderingTraits<ES,DI,CI,MultiIndexOrder::Inner2Outer> Traits;
64
65 static constexpr auto GT_UNUSED = ~std::size_t(0);
66
67 protected:
68
69 typedef impl::GridFunctionSpaceOrderingData<typename Traits::SizeType> GFSData;
70
71 public:
72
73 void map_local_index(const typename Traits::SizeType geometry_type_index,
74 const typename Traits::SizeType entity_index,
75 typename Traits::TreeIndexView mi,
76 typename Traits::ContainerIndex& ci) const
77 {
78 if (_child_count == 0) // leaf nodes
79 {
80 assert(mi.size() == 1 && "MultiIndex length must match GridFunctionSpace tree depth");
81 ci.push_back(mi.back());
82 }
83 else // inner nodes
84 {
85 const typename Traits::SizeType child_index = mi.back();
86 if (!mi.empty())
87 _children[child_index]->map_local_index(geometry_type_index,entity_index,mi.back_popped(),ci);
88 if (_container_blocked)
89 {
90 ci.push_back(child_index);
91 }
92 else if (child_index > 0)
93 {
94 if (_fixed_size)
95 {
96 const typename Traits::SizeType index = geometry_type_index * _child_count + child_index - 1;
97 ci.back() += _gt_dof_offsets[index];
98 }
99 else
100 {
101 assert(_gt_used[geometry_type_index]);
102 const typename Traits::SizeType index = (_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index - 1;
103 ci.back() += _entity_dof_offsets[index];
104 }
105 }
106 }
107 }
108
109
121 template<typename ItIn, typename ItOut>
122 void map_lfs_indices(const ItIn begin, const ItIn end, ItOut out) const
123 {
124 if (_child_count == 0) // leaf nodes
125 {
126 for (ItIn in = begin; in != end; ++in, ++out) {
127 assert(in->size() == 1 &&
128 "MultiIndex length must match GridFunctionSpace tree depth");
129 out->push_back(in->treeIndex().back());
130 }
131 } else if (_container_blocked) // blocked inner nodes
132 {
133 for (ItIn in = begin; in != end; ++in, ++out)
134 out->push_back(in->treeIndex().back());
135 } else if (_fixed_size) // non-blocked inner nodes with fixed sizes
136 {
137 for (ItIn in = begin; in != end; ++in, ++out) {
138 const typename Traits::SizeType child_index =
139 in->treeIndex().back();
140 const typename Traits::SizeType gt_index =
141 Traits::DOFIndexAccessor::geometryType(*in);
142 if (child_index > 0) {
143 const typename Traits::SizeType index =
144 gt_index * _child_count + child_index - 1;
145 out->back() += _gt_dof_offsets[index];
146 }
147 }
148 } else // non-blocked inner nodes with variable sizes
149 {
150 for (ItIn in = begin; in != end; ++in, ++out) {
151 const typename Traits::SizeType child_index =
152 in->treeIndex().back();
153 if (child_index > 0) {
154 const typename Traits::SizeType gt_index =
155 Traits::DOFIndexAccessor::geometryType(*in);
156 const typename Traits::SizeType entity_index =
157 Traits::DOFIndexAccessor::entityIndex(*in);
158
159 assert(_gt_used[gt_index]);
160
161 const typename Traits::SizeType index =
162 (_gt_entity_offsets[gt_index] + entity_index) *
163 _child_count +
164 child_index - 1;
165 out->back() += _entity_dof_offsets[index];
166 }
167 }
168 }
169 }
170
171 template<typename CIOutIterator, typename DIOutIterator = DummyDOFIndexIterator>
172 typename Traits::SizeType
173 extract_entity_indices(const typename Traits::DOFIndex::EntityIndex& ei,
174 typename Traits::SizeType child_index,
175 CIOutIterator ci_out, const CIOutIterator ci_end,
176 DIOutIterator di_out = DIOutIterator()) const
177 {
178 typedef typename Traits::SizeType size_type;
179
180 const size_type geometry_type_index = Traits::DOFIndexAccessor::GeometryIndex::geometryType(ei);
181 const size_type entity_index = Traits::DOFIndexAccessor::GeometryIndex::entityIndex(ei);
182
183 if (!_gt_used[geometry_type_index])
184 return 0;
185
186 if (_child_count == 0)
187 {
188 const size_type size = _fixed_size
189 ? _gt_dof_offsets[geometry_type_index]
190 : _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index)];
191
192 for (size_type i = 0; i < size; ++i, ++ci_out, ++di_out)
193 {
194 ci_out->push_back(i);
195 di_out->treeIndex().push_back(i);
196 }
197 return size;
198 }
199 else
200 {
201 if (_container_blocked)
202 {
203 for (; ci_out != ci_end; ++ci_out)
204 {
205 ci_out->push_back(child_index);
206 }
207 }
208 else if (child_index > 0)
209 {
210 if (_fixed_size)
211 for (; ci_out != ci_end; ++ci_out)
212 {
213 const typename Traits::SizeType index = geometry_type_index * _child_count + child_index - 1;
214 ci_out->back() += _gt_dof_offsets[index];
215 }
216 else
217 for (; ci_out != ci_end; ++ci_out)
218 {
219 const typename Traits::SizeType index = (_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index - 1;
220 ci_out->back() += _entity_dof_offsets[index];
221 }
222 }
223
224 // The return value is not used for non-leaf orderings.
225 return 0;
226 }
227 }
228
229 typename Traits::SizeType size(const typename Traits::DOFIndex::EntityIndex& index) const
230 {
231 return size(
232 Traits::DOFIndexAccessor::GeometryIndex::geometryType(index),
233 Traits::DOFIndexAccessor::GeometryIndex::entityIndex(index)
234 );
235 }
236
237 typename Traits::SizeType size(const typename Traits::SizeType geometry_type_index, const typename Traits::SizeType entity_index) const
238 {
239 if (_fixed_size)
240 return _child_count > 0
241 ? _gt_dof_offsets[geometry_type_index * _child_count + _child_count - 1]
242 : _gt_dof_offsets[geometry_type_index];
243
244 if (!_gt_used[geometry_type_index])
245 return 0;
246
247 return _child_count > 0
248 ? _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + _child_count - 1]
249 : _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index)];
250 }
251
252 typename Traits::SizeType size(const typename Traits::SizeType geometry_type_index, const typename Traits::SizeType entity_index, const typename Traits::SizeType child_index) const
253 {
254 assert(child_index < _child_count);
255 if (_fixed_size)
256 {
257 const typename Traits::SizeType index = geometry_type_index * _child_count + child_index;
258 return child_index > 0 ? _gt_dof_offsets[index] - _gt_dof_offsets[index-1] : _gt_dof_offsets[index];
259 }
260 else
261 {
262 if (_gt_used[geometry_type_index])
263 {
264 const typename Traits::SizeType index = (_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index;
265 return child_index > 0 ? _entity_dof_offsets[index] - _entity_dof_offsets[index-1] : _entity_dof_offsets[index];
266 }
267 else
268 {
269 return 0;
270 }
271 }
272 }
273
274 protected:
275
285 template<class Node>
286 typename Traits::SizeType
287 node_size(const Node& node, typename Traits::ContainerIndex suffix,
288 const typename Traits::DOFIndex::EntityIndex &index) const {
289 using size_type = typename Traits::size_type;
290
291 // suffix wants the size for this node
292 if (suffix.size() == 0)
293 return node.size(index);
294
295 if constexpr (Node::isLeaf) {
296 return 0; // Assume leaf local orderings are always field vectors
297 } else {
298 // the next index to find out its size
299 auto back_index = suffix.back();
300 // task: find child local ordering because it should know its own size
301 std::size_t _child;
302
303 if (node.containerBlocked()) {
304 // in this case back index is the child ordering itself
305 _child = back_index;
306 suffix.pop_back();
307 } else {
308 // here we need to find the child that describes the back_index (solve child in map_lfs_indices)
309 const size_type gt_index = Traits::DOFIndexAccessor::GeometryIndex::geometryType(index);
310 const size_type entity_index = Traits::DOFIndexAccessor::GeometryIndex::entityIndex(index);
311 auto dof_begin = node._fixed_size ? node._gt_dof_offsets.begin() : node._entity_dof_offsets.begin();
312 auto dof_end = node._fixed_size ? node._gt_dof_offsets.end() : node._entity_dof_offsets.end();
313 auto dof_it = std::prev(std::upper_bound(dof_begin, dof_end, back_index));
314 size_type dof_dist = std::distance(dof_begin, dof_it);
315 if (node._fixed_size)
316 _child = dof_dist - gt_index * node._child_count + 1;
317 else
318 _child = dof_dist - (node._gt_entity_offsets[gt_index] + entity_index) * node._child_count + 1;
319 }
320
321 assert(node.degree() > _child);
322 if constexpr (Node::isPower) {
323 return node.child(_child).size(suffix, index);
324 } else {
325 typename Traits::SizeType _size;
326 // create a dynamic or static index range
327 auto indices = Dune::range(node.degree());
328 // get size for required child
329 Hybrid::forEach(indices, [&](auto i){
330 if (i == _child)
331 _size = node.child(i).size(suffix, index);
332 });
333
334 return _size;
335 }
336 }
337 }
338
339 public:
340 typename Traits::SizeType offset(const typename Traits::SizeType geometry_type_index, const typename Traits::SizeType entity_index, const typename Traits::SizeType child_index) const
341 {
342 assert(child_index < _child_count);
343 assert(_gt_used[geometry_type_index]);
344 if (_fixed_size)
345 return child_index > 0 ? _gt_dof_offsets[geometry_type_index * _child_count + child_index - 1] : 0;
346 else
347 return child_index > 0 ? _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index - 1] : 0;
348 }
349
350 template<typename Node>
351 LocalOrderingBase(Node& node, bool container_blocked, GFSData* gfs_data)
352 : _fixed_size(false)
353 , _fixed_size_possible(false)
354 , _container_blocked(container_blocked)
355 , _max_local_size(0)
356 , _child_count(TypeTree::degree(node))
357 , _children(TypeTree::degree(node),nullptr)
358 , _gfs_data(gfs_data)
359 {
360 TypeTree::applyToTree(node,extract_child_bases<LocalOrderingBase>(_children));
361 }
362
363 bool fixedSize() const
364 {
365 return _fixed_size;
366 }
367
368 bool contains(const GeometryType& gt) const
369 {
370 return _gt_used[GlobalGeometryTypeIndex::index(gt)];
371 }
372
373 bool contains_geometry_type(typename Traits::SizeType gt_index) const
374 {
375 return _gt_used[gt_index];
376 }
377
378 bool contains(typename Traits::SizeType codim) const
379 {
380 return _codim_used.test(codim);
381 }
382
383 typename Traits::SizeType maxLocalSize() const
384 {
385 return _max_local_size;
386 }
387
388 private:
389
390 bool update_gfs_data_size(typename Traits::SizeType& size, typename Traits::SizeType& block_count) const
391 {
392 return false;
393 }
394
395 protected:
396
397 bool containerBlocked() const
398 {
399 return _container_blocked;
400 }
401
402 std::size_t childOrderingCount() const
403 {
404 return _child_count;
405 }
406
407 LocalOrderingBase& childOrdering(typename Traits::SizeType i)
408 {
409 return *_children[i];
410 }
411
412 const LocalOrderingBase& childOrdering(typename Traits::SizeType i) const
413 {
414 return *_children[i];
415 }
416
417 void disable_container_blocking()
418 {
419 _container_blocked = false;
420 }
421
423
433 {
434 _fixed_size_possible = true;
435 for (const auto& child : _children)
436 _fixed_size_possible &= child->_fixed_size_possible;
437 }
438
439
440
441 bool _fixed_size;
442 bool _fixed_size_possible;
443 bool _container_blocked;
444 std::size_t _max_local_size;
445
446 const std::size_t _child_count;
447 std::vector<LocalOrderingBase*> _children;
448
449 typename Traits::CodimFlag _codim_used;
450 std::vector<bool> _gt_used;
451
452 std::vector<typename Traits::SizeType> _gt_entity_offsets;
453 std::vector<typename Traits::SizeType> _gt_dof_offsets;
454 std::vector<typename Traits::SizeType> _entity_dof_offsets;
455
456 GFSData* _gfs_data;
457
458 };
459
461
462 } // namespace PDELab
463} // namespace Dune
464
465#endif // DUNE_PDELAB_ORDERING_LOCALORDERINGBASE_HH
static constexpr std::size_t index(const GeometryType &gt)
Compute the index for the given geometry type over all dimensions.
Definition: typeindex.hh:138
Transforms a local ordering (entity-wise order) into a global ordering.
Definition: gridviewordering.hh:440
Entity-wise orderings.
Definition: localorderingbase.hh:30
void map_lfs_indices(const ItIn begin, const ItIn end, ItOut out) const
Set last index of container indices.
Definition: localorderingbase.hh:122
void setup_fixed_size_possible()
Initial setup of the flag indicating whether a fixed size ordering is possible.
Definition: localorderingbase.hh:432
Traits::SizeType node_size(const Node &node, typename Traits::ContainerIndex suffix, const typename Traits::DOFIndex::EntityIndex &index) const
Gives the size for a given entity and suffix.
Definition: localorderingbase.hh:287
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition: float_cmp.cc:158
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:79
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition: traversal.hh:239
ImplementationDefined child(Node &&node, Indices... indices)
Extracts the child of a node given by a sequence of compile-time and run-time indices.
Definition: childextraction.hh:128
Dune namespace.
Definition: alignedallocator.hh:13
STL namespace.
Utilities for reduction like operations on ranges.
std::size_t fixedSize
The number of data items per index if it is fixed, 0 otherwise.
Definition: variablesizecommunicator.hh:264
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 23, 23:29, 2024)