DUNE PDELab (2.7)

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
10#include <vector>
11
12namespace Dune {
13 namespace PDELab {
14
17
18 template<typename ES, typename DI, typename CI>
19 class LocalOrderingBase
20 {
21
22 friend struct collect_a_priori_fixed_size;
23
24 template<typename>
25 friend struct update_fixed_size;
26
27 template<typename>
28 friend struct post_collect_used_geometry_types;
29
30 template<typename>
31 friend struct post_extract_per_entity_sizes;
32
33 friend struct pre_collect_used_geometry_types;
34
35 template<typename>
36 friend struct collect_used_geometry_types_from_cell;
37
38 template<typename>
39 friend struct extract_per_entity_sizes_from_cell;
40
41 template<typename>
42 friend class GridViewOrdering;
43
44 template<typename size_type>
45 friend struct ::Dune::PDELab::impl::update_ordering_data;
46
47 typedef std::vector<LocalOrderingBase*> ChildVector;
48 typedef typename ChildVector::iterator ChildIterator;
49 typedef typename ChildVector::const_iterator ConstChildIterator;
50
51 public:
52
53 static const bool has_dynamic_ordering_children = true;
54
55 static const bool consume_tree_index = true;
56
57 typedef LocalOrderingTraits<ES,DI,CI> Traits;
58
59 static constexpr auto GT_UNUSED = ~std::size_t(0);
60
61 protected:
62
63 typedef impl::GridFunctionSpaceOrderingData<typename Traits::SizeType> GFSData;
64
65 public:
66
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
71 {
72 if (_child_count == 0)
73 {
74 assert(mi.size() == 1 && "MultiIndex length must match GridFunctionSpace tree depth");
75 ci.push_back(mi.back());
76 }
77 else
78 {
79 const typename Traits::SizeType child_index = mi.back();
80 if (!mi.empty())
81 _children[child_index]->map_local_index(geometry_type_index,entity_index,mi.back_popped(),ci);
82 if (_container_blocked)
83 {
84 ci.push_back(child_index);
85 }
86 else if (child_index > 0)
87 {
88 if (_fixed_size)
89 {
90 const typename Traits::SizeType index = geometry_type_index * _child_count + child_index - 1;
91 ci.back() += _gt_dof_offsets[index];
92 }
93 else
94 {
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];
98 }
99 }
100 }
101 }
102
103
104 template<typename ItIn, typename ItOut>
105 void map_lfs_indices(const ItIn begin, const ItIn end, ItOut out) const
106 {
107 if (_child_count == 0)
108 {
109 for (ItIn in = begin; in != end; ++in, ++out)
110 {
111 assert(in->size() == 1 && "MultiIndex length must match GridFunctionSpace tree depth");
112 out->push_back(in->treeIndex().back());
113 }
114 }
115 else if (_container_blocked)
116 {
117 for (ItIn in = begin; in != end; ++in, ++out)
118 out->push_back(in->treeIndex().back());
119 }
120 else if (_fixed_size)
121 {
122 for (ItIn in = begin; in != end; ++in, ++out)
123 {
124 const typename Traits::SizeType child_index = in->treeIndex().back();
125 const typename Traits::SizeType gt_index = Traits::DOFIndexAccessor::geometryType(*in);
126 if (child_index > 0)
127 {
128 const typename Traits::SizeType index = gt_index * _child_count + child_index - 1;
129 out->back() += _gt_dof_offsets[index];
130 }
131 }
132 }
133 else
134 {
135 for (ItIn in = begin; in != end; ++in, ++out)
136 {
137 const typename Traits::SizeType child_index = in->treeIndex().back();
138 if (child_index > 0)
139 {
140 const typename Traits::SizeType gt_index = Traits::DOFIndexAccessor::geometryType(*in);
141 const typename Traits::SizeType entity_index = Traits::DOFIndexAccessor::entityIndex(*in);
142
143 assert(_gt_used[gt_index]);
144
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];
147 }
148 }
149 }
150 }
151
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
158 {
159 typedef typename Traits::SizeType size_type;
160
161 const size_type geometry_type_index = Traits::DOFIndexAccessor::GeometryIndex::geometryType(ei);
162 const size_type entity_index = Traits::DOFIndexAccessor::GeometryIndex::entityIndex(ei);
163
164 if (!_gt_used[geometry_type_index])
165 return 0;
166
167 if (_child_count == 0)
168 {
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)];
172
173 for (size_type i = 0; i < size; ++i, ++ci_out, ++di_out)
174 {
175 ci_out->push_back(i);
176 di_out->treeIndex().push_back(i);
177 }
178 return size;
179 }
180 else
181 {
182 if (_container_blocked)
183 {
184 for (; ci_out != ci_end; ++ci_out)
185 {
186 ci_out->push_back(child_index);
187 }
188 }
189 else if (child_index > 0)
190 {
191 if (_fixed_size)
192 for (; ci_out != ci_end; ++ci_out)
193 {
194 const typename Traits::SizeType index = geometry_type_index * _child_count + child_index - 1;
195 ci_out->back() += _gt_dof_offsets[index];
196 }
197 else
198 for (; ci_out != ci_end; ++ci_out)
199 {
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];
202 }
203 }
204
205 // The return value is not used for non-leaf orderings.
206 return 0;
207 }
208 }
209
210 typename Traits::SizeType size(const typename Traits::DOFIndex::EntityIndex& index) const
211 {
212 return size(
213 Traits::DOFIndexAccessor::GeometryIndex::geometryType(index),
214 Traits::DOFIndexAccessor::GeometryIndex::entityIndex(index)
215 );
216 }
217
218 typename Traits::SizeType size(const typename Traits::SizeType geometry_type_index, const typename Traits::SizeType entity_index) const
219 {
220 if (_fixed_size)
221 return _child_count > 0
222 ? _gt_dof_offsets[geometry_type_index * _child_count + _child_count - 1]
223 : _gt_dof_offsets[geometry_type_index];
224
225 if (!_gt_used[geometry_type_index])
226 return 0;
227
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)];
231 }
232
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
234 {
235 assert(child_index < _child_count);
236 if (_fixed_size)
237 {
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];
240 }
241 else
242 {
243 if (_gt_used[geometry_type_index])
244 {
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];
247 }
248 else
249 {
250 return 0;
251 }
252 }
253 }
254
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
256 {
257 assert(child_index < _child_count);
258 assert(_gt_used[geometry_type_index]);
259 if (_fixed_size)
260 return child_index > 0 ? _gt_dof_offsets[geometry_type_index * _child_count + child_index - 1] : 0;
261 else
262 return child_index > 0 ? _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index - 1] : 0;
263 }
264
265 template<typename Node>
266 LocalOrderingBase(Node& node, bool container_blocked, GFSData* gfs_data)
267 : _fixed_size(false)
268 , _fixed_size_possible(false)
269 , _container_blocked(container_blocked)
270 , _max_local_size(0)
271 , _child_count(TypeTree::degree(node))
272 , _children(TypeTree::degree(node),nullptr)
273 , _gfs_data(gfs_data)
274 {
275 TypeTree::applyToTree(node,extract_child_bases<LocalOrderingBase>(_children));
276 }
277
278 bool fixedSize() const
279 {
280 return _fixed_size;
281 }
282
283 bool contains(const GeometryType& gt) const
284 {
285 return _gt_used[GlobalGeometryTypeIndex::index(gt)];
286 }
287
288 bool contains_geometry_type(typename Traits::SizeType gt_index) const
289 {
290 return _gt_used[gt_index];
291 }
292
293 bool contains(typename Traits::SizeType codim) const
294 {
295 return _codim_used.test(codim);
296 }
297
298 typename Traits::SizeType maxLocalSize() const
299 {
300 return _max_local_size;
301 }
302
303 private:
304
305 bool update_gfs_data_size(typename Traits::SizeType& size, typename Traits::SizeType& block_count) const
306 {
307 return false;
308 }
309
310 protected:
311
312 LocalOrderingBase& childOrdering(typename Traits::SizeType i)
313 {
314 return *_children[i];
315 }
316
317 const LocalOrderingBase& childOrdering(typename Traits::SizeType i) const
318 {
319 return *_children[i];
320 }
321
322 void disable_container_blocking()
323 {
324 _container_blocked = false;
325 }
326
328
337 void setup_fixed_size_possible()
338 {
339 _fixed_size_possible = true;
340 for (ConstChildIterator it = _children.begin(),
341 end_it = _children.end();
342 it != end_it;
343 ++it)
344 _fixed_size_possible = _fixed_size_possible && (*it)->_fixed_size_possible;
345 }
346
347
348
349 bool _fixed_size;
350 bool _fixed_size_possible;
351 bool _container_blocked;
352 std::size_t _max_local_size;
353
354 const std::size_t _child_count;
355 std::vector<LocalOrderingBase*> _children;
356
357 typename Traits::CodimFlag _codim_used;
358 std::vector<bool> _gt_used;
359
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;
363
364 GFSData* _gfs_data;
365
366 };
367
369
370 } // namespace PDELab
371} // namespace Dune
372
373#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: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
STL namespace.
std::size_t fixedSize
The number of data items per index if it is fixed, 0 otherwise.
Definition: variablesizecommunicator.hh:245
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)