4#ifndef DUNE_PDELAB_ORDERING_LOCALORDERINGBASE_HH
5#define DUNE_PDELAB_ORDERING_LOCALORDERINGBASE_HH
7#include <dune/pdelab/ordering/utility.hh>
8#include <dune/pdelab/gridfunctionspace/gridfunctionspacebase.hh>
28 template<
typename ES,
typename DI,
typename CI>
32 friend struct collect_a_priori_fixed_size;
35 friend struct update_fixed_size;
38 friend struct post_collect_used_geometry_types;
41 friend struct post_extract_per_entity_sizes;
43 friend struct pre_collect_used_geometry_types;
46 friend struct collect_used_geometry_types_from_cell;
49 friend struct extract_per_entity_sizes_from_cell;
54 template<
typename size_type>
55 friend struct ::Dune::PDELab::impl::update_ordering_data;
59 static const bool has_dynamic_ordering_children =
true;
61 static const bool consume_tree_index =
true;
63 typedef LocalOrderingTraits<ES,DI,CI,MultiIndexOrder::Inner2Outer> Traits;
65 static constexpr auto GT_UNUSED =
~std::size_t(0);
69 typedef impl::GridFunctionSpaceOrderingData<typename Traits::SizeType> GFSData;
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
78 if (_child_count == 0)
80 assert(mi.size() == 1 &&
"MultiIndex length must match GridFunctionSpace tree depth");
81 ci.push_back(mi.back());
85 const typename Traits::SizeType child_index = mi.back();
87 _children[child_index]->map_local_index(geometry_type_index,entity_index,mi.back_popped(),ci);
88 if (_container_blocked)
90 ci.push_back(child_index);
92 else if (child_index > 0)
96 const typename Traits::SizeType index = geometry_type_index * _child_count + child_index - 1;
97 ci.back() += _gt_dof_offsets[index];
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];
121 template<
typename ItIn,
typename ItOut>
124 if (_child_count == 0)
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());
131 }
else if (_container_blocked)
133 for (ItIn in = begin; in != end; ++in, ++out)
134 out->push_back(in->treeIndex().back());
135 }
else if (_fixed_size)
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];
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);
159 assert(_gt_used[gt_index]);
161 const typename Traits::SizeType index =
162 (_gt_entity_offsets[gt_index] + entity_index) *
165 out->back() += _entity_dof_offsets[index];
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
178 typedef typename Traits::SizeType size_type;
180 const size_type geometry_type_index = Traits::DOFIndexAccessor::GeometryIndex::geometryType(ei);
181 const size_type entity_index = Traits::DOFIndexAccessor::GeometryIndex::entityIndex(ei);
183 if (!_gt_used[geometry_type_index])
186 if (_child_count == 0)
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)];
192 for (size_type i = 0; i < size; ++i, ++ci_out, ++di_out)
194 ci_out->push_back(i);
195 di_out->treeIndex().push_back(i);
201 if (_container_blocked)
203 for (; ci_out != ci_end; ++ci_out)
205 ci_out->push_back(child_index);
208 else if (child_index > 0)
211 for (; ci_out != ci_end; ++ci_out)
213 const typename Traits::SizeType index = geometry_type_index * _child_count + child_index - 1;
214 ci_out->back() += _gt_dof_offsets[index];
217 for (; ci_out != ci_end; ++ci_out)
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];
229 typename Traits::SizeType size(
const typename Traits::DOFIndex::EntityIndex& index)
const
232 Traits::DOFIndexAccessor::GeometryIndex::geometryType(index),
233 Traits::DOFIndexAccessor::GeometryIndex::entityIndex(index)
237 typename Traits::SizeType size(
const typename Traits::SizeType geometry_type_index,
const typename Traits::SizeType entity_index)
const
240 return _child_count > 0
241 ? _gt_dof_offsets[geometry_type_index * _child_count + _child_count - 1]
242 : _gt_dof_offsets[geometry_type_index];
244 if (!_gt_used[geometry_type_index])
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)];
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
254 assert(child_index < _child_count);
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];
262 if (_gt_used[geometry_type_index])
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];
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;
292 if (suffix.size() == 0)
293 return node.size(index);
295 if constexpr (Node::isLeaf) {
299 auto back_index = suffix.back();
303 if (node.containerBlocked()) {
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;
318 _child = dof_dist - (node._gt_entity_offsets[gt_index] + entity_index) * node._child_count + 1;
321 assert(node.degree() > _child);
322 if constexpr (Node::isPower) {
323 return node.child(_child).size(suffix, index);
325 typename Traits::SizeType _size;
327 auto indices = Dune::range(node.degree());
331 _size = node.child(i).size(suffix, index);
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
342 assert(child_index < _child_count);
343 assert(_gt_used[geometry_type_index]);
345 return child_index > 0 ? _gt_dof_offsets[geometry_type_index * _child_count + child_index - 1] : 0;
347 return child_index > 0 ? _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index - 1] : 0;
350 template<
typename Node>
351 LocalOrderingBase(Node& node,
bool container_blocked, GFSData* gfs_data)
353 , _fixed_size_possible(false)
354 , _container_blocked(container_blocked)
356 , _child_count(TypeTree::
degree(node))
357 , _children(TypeTree::
degree(node),nullptr)
358 , _gfs_data(gfs_data)
368 bool contains(
const GeometryType&
gt)
const
373 bool contains_geometry_type(
typename Traits::SizeType gt_index)
const
375 return _gt_used[gt_index];
378 bool contains(
typename Traits::SizeType codim)
const
380 return _codim_used.test(codim);
383 typename Traits::SizeType maxLocalSize()
const
385 return _max_local_size;
390 bool update_gfs_data_size(
typename Traits::SizeType& size,
typename Traits::SizeType& block_count)
const
397 bool containerBlocked()
const
399 return _container_blocked;
402 std::size_t childOrderingCount()
const
407 LocalOrderingBase& childOrdering(
typename Traits::SizeType i)
409 return *_children[i];
412 const LocalOrderingBase& childOrdering(
typename Traits::SizeType i)
const
414 return *_children[i];
417 void disable_container_blocking()
419 _container_blocked =
false;
434 _fixed_size_possible =
true;
435 for (
const auto&
child : _children)
436 _fixed_size_possible &=
child->_fixed_size_possible;
442 bool _fixed_size_possible;
443 bool _container_blocked;
444 std::size_t _max_local_size;
446 const std::size_t _child_count;
447 std::vector<LocalOrderingBase*> _children;
449 typename Traits::CodimFlag _codim_used;
450 std::vector<bool> _gt_used;
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;
static constexpr std::size_t index(const GeometryType >)
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
Dune namespace.
Definition: alignedallocator.hh:13
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