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>
18 template<
typename ES,
typename DI,
typename CI>
19 class LocalOrderingBase
22 friend struct collect_a_priori_fixed_size;
25 friend struct update_fixed_size;
28 friend struct post_collect_used_geometry_types;
31 friend struct post_extract_per_entity_sizes;
33 friend struct pre_collect_used_geometry_types;
36 friend struct collect_used_geometry_types_from_cell;
39 friend struct extract_per_entity_sizes_from_cell;
42 friend class GridViewOrdering;
44 template<
typename size_type>
45 friend struct ::Dune::PDELab::impl::update_ordering_data;
47 typedef std::vector<LocalOrderingBase*> ChildVector;
48 typedef typename ChildVector::iterator ChildIterator;
49 typedef typename ChildVector::const_iterator ConstChildIterator;
53 static const bool has_dynamic_ordering_children =
true;
55 static const bool consume_tree_index =
true;
57 typedef LocalOrderingTraits<ES,DI,CI> Traits;
59 static constexpr auto GT_UNUSED =
~std::size_t(0);
63 typedef impl::GridFunctionSpaceOrderingData<typename Traits::SizeType> GFSData;
67 void map_local_index(
const typename Traits::SizeType geometry_type_index,
68 const typename Traits::SizeType entity_index,
69 typename Traits::TreeIndexView mi,
70 typename Traits::ContainerIndex& ci)
const
72 if (_child_count == 0)
74 assert(mi.size() == 1 &&
"MultiIndex length must match GridFunctionSpace tree depth");
75 ci.push_back(mi.back());
79 const typename Traits::SizeType child_index = mi.back();
81 _children[child_index]->map_local_index(geometry_type_index,entity_index,mi.back_popped(),ci);
82 if (_container_blocked)
84 ci.push_back(child_index);
86 else if (child_index > 0)
90 const typename Traits::SizeType index = geometry_type_index * _child_count + child_index - 1;
91 ci.back() += _gt_dof_offsets[index];
95 assert(_gt_used[geometry_type_index]);
96 const typename Traits::SizeType index = (_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index - 1;
97 ci.back() += _entity_dof_offsets[index];
104 template<
typename ItIn,
typename ItOut>
105 void map_lfs_indices(
const ItIn begin,
const ItIn end, ItOut out)
const
107 if (_child_count == 0)
109 for (ItIn in = begin; in != end; ++in, ++out)
111 assert(in->size() == 1 &&
"MultiIndex length must match GridFunctionSpace tree depth");
112 out->push_back(in->treeIndex().back());
115 else if (_container_blocked)
117 for (ItIn in = begin; in != end; ++in, ++out)
118 out->push_back(in->treeIndex().back());
120 else if (_fixed_size)
122 for (ItIn in = begin; in != end; ++in, ++out)
124 const typename Traits::SizeType child_index = in->treeIndex().back();
125 const typename Traits::SizeType gt_index = Traits::DOFIndexAccessor::geometryType(*in);
128 const typename Traits::SizeType index = gt_index * _child_count + child_index - 1;
129 out->back() += _gt_dof_offsets[index];
135 for (ItIn in = begin; in != end; ++in, ++out)
137 const typename Traits::SizeType child_index = in->treeIndex().back();
140 const typename Traits::SizeType gt_index = Traits::DOFIndexAccessor::geometryType(*in);
141 const typename Traits::SizeType entity_index = Traits::DOFIndexAccessor::entityIndex(*in);
143 assert(_gt_used[gt_index]);
145 const typename Traits::SizeType index = (_gt_entity_offsets[gt_index] + entity_index) * _child_count + child_index - 1;
146 out->back() += _entity_dof_offsets[index];
152 template<
typename CIOutIterator,
typename DIOutIterator = DummyDOFIndexIterator>
153 typename Traits::SizeType
154 extract_entity_indices(
const typename Traits::DOFIndex::EntityIndex& ei,
155 typename Traits::SizeType child_index,
156 CIOutIterator ci_out,
const CIOutIterator ci_end,
157 DIOutIterator di_out = DIOutIterator())
const
159 typedef typename Traits::SizeType size_type;
161 const size_type geometry_type_index = Traits::DOFIndexAccessor::GeometryIndex::geometryType(ei);
162 const size_type entity_index = Traits::DOFIndexAccessor::GeometryIndex::entityIndex(ei);
164 if (!_gt_used[geometry_type_index])
167 if (_child_count == 0)
169 const size_type size = _fixed_size
170 ? _gt_dof_offsets[geometry_type_index]
171 : _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index)];
173 for (size_type i = 0; i < size; ++i, ++ci_out, ++di_out)
175 ci_out->push_back(i);
176 di_out->treeIndex().push_back(i);
182 if (_container_blocked)
184 for (; ci_out != ci_end; ++ci_out)
186 ci_out->push_back(child_index);
189 else if (child_index > 0)
192 for (; ci_out != ci_end; ++ci_out)
194 const typename Traits::SizeType index = geometry_type_index * _child_count + child_index - 1;
195 ci_out->back() += _gt_dof_offsets[index];
198 for (; ci_out != ci_end; ++ci_out)
200 const typename Traits::SizeType index = (_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index - 1;
201 ci_out->back() += _entity_dof_offsets[index];
210 typename Traits::SizeType size(
const typename Traits::DOFIndex::EntityIndex& index)
const
213 Traits::DOFIndexAccessor::GeometryIndex::geometryType(index),
214 Traits::DOFIndexAccessor::GeometryIndex::entityIndex(index)
218 typename Traits::SizeType size(
const typename Traits::SizeType geometry_type_index,
const typename Traits::SizeType entity_index)
const
221 return _child_count > 0
222 ? _gt_dof_offsets[geometry_type_index * _child_count + _child_count - 1]
223 : _gt_dof_offsets[geometry_type_index];
225 if (!_gt_used[geometry_type_index])
228 return _child_count > 0
229 ? _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + _child_count - 1]
230 : _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index)];
233 typename Traits::SizeType size(
const typename Traits::SizeType geometry_type_index,
const typename Traits::SizeType entity_index,
const typename Traits::SizeType child_index)
const
235 assert(child_index < _child_count);
238 const typename Traits::SizeType index = geometry_type_index * _child_count + child_index;
239 return child_index > 0 ? _gt_dof_offsets[index] - _gt_dof_offsets[index-1] : _gt_dof_offsets[index];
243 if (_gt_used[geometry_type_index])
245 const typename Traits::SizeType index = (_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index;
246 return child_index > 0 ? _entity_dof_offsets[index] - _entity_dof_offsets[index-1] : _entity_dof_offsets[index];
255 typename Traits::SizeType offset(
const typename Traits::SizeType geometry_type_index,
const typename Traits::SizeType entity_index,
const typename Traits::SizeType child_index)
const
257 assert(child_index < _child_count);
258 assert(_gt_used[geometry_type_index]);
260 return child_index > 0 ? _gt_dof_offsets[geometry_type_index * _child_count + child_index - 1] : 0;
262 return child_index > 0 ? _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index - 1] : 0;
265 template<
typename Node>
266 LocalOrderingBase(Node& node,
bool container_blocked, GFSData* gfs_data)
268 , _fixed_size_possible(false)
269 , _container_blocked(container_blocked)
271 , _child_count(TypeTree::
degree(node))
272 , _children(TypeTree::
degree(node),nullptr)
273 , _gfs_data(gfs_data)
283 bool contains(
const GeometryType&
gt)
const
288 bool contains_geometry_type(
typename Traits::SizeType gt_index)
const
290 return _gt_used[gt_index];
293 bool contains(
typename Traits::SizeType codim)
const
295 return _codim_used.test(codim);
298 typename Traits::SizeType maxLocalSize()
const
300 return _max_local_size;
305 bool update_gfs_data_size(
typename Traits::SizeType& size,
typename Traits::SizeType& block_count)
const
312 LocalOrderingBase& childOrdering(
typename Traits::SizeType i)
314 return *_children[i];
317 const LocalOrderingBase& childOrdering(
typename Traits::SizeType i)
const
319 return *_children[i];
322 void disable_container_blocking()
324 _container_blocked =
false;
337 void setup_fixed_size_possible()
339 _fixed_size_possible =
true;
340 for (ConstChildIterator it = _children.begin(),
341 end_it = _children.end();
344 _fixed_size_possible = _fixed_size_possible && (*it)->_fixed_size_possible;
350 bool _fixed_size_possible;
351 bool _container_blocked;
352 std::size_t _max_local_size;
354 const std::size_t _child_count;
355 std::vector<LocalOrderingBase*> _children;
357 typename Traits::CodimFlag _codim_used;
358 std::vector<bool> _gt_used;
360 std::vector<typename Traits::SizeType> _gt_entity_offsets;
361 std::vector<typename Traits::SizeType> _gt_dof_offsets;
362 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:133
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition: float_cmp.cc:156
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:71
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition: traversal.hh:213
Dune namespace.
Definition: alignedallocator.hh:14
std::size_t fixedSize
The number of data items per index if it is fixed, 0 otherwise.
Definition: variablesizecommunicator.hh:245