DUNE PDELab (git)

datahandleprovider.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_PDELAB_GRIDFUNCTIONSPACE_DATAHANDLEPROVIDER_HH
4#define DUNE_PDELAB_GRIDFUNCTIONSPACE_DATAHANDLEPROVIDER_HH
5
6#include <vector>
7#include <stack>
8
11#include <dune/typetree/visitor.hh>
12
13#include <dune/pdelab/ordering/utility.hh>
14
15namespace Dune {
16 namespace PDELab {
17
18 namespace {
19
20 template<typename EntityIndex>
21 struct get_size_for_entity
22 : public TypeTree::TreeVisitor
23 , public TypeTree::DynamicTraversal
24 {
25
26 template<typename Ordering, typename TreePath>
27 void leaf(const Ordering& ordering, TreePath tp)
28 {
29 _size += ordering.size(_entity_index);
30 }
31
32 get_size_for_entity(const EntityIndex& entity_index)
33 : _size(0)
34 , _entity_index(entity_index)
35 {}
36
37 std::size_t size() const
38 {
39 return _size;
40 }
41
42 private:
43
44 std::size_t _size;
45 const EntityIndex& _entity_index;
46
47 };
48
49
50 template<typename EntityIndex, typename OffsetIterator>
51 struct get_leaf_offsets_for_entity
52 : public TypeTree::TreeVisitor
53 , public TypeTree::DynamicTraversal
54 {
55
56 template<typename Ordering, typename TreePath>
57 void leaf(const Ordering& ordering, TreePath tp)
58 {
59 *(++_oit) = ordering.size(_entity_index);
60 }
61
62 get_leaf_offsets_for_entity(const EntityIndex& entity_index, OffsetIterator oit)
63 : _oit(oit)
64 , _entity_index(entity_index)
65 {}
66
68 OffsetIterator offsetIterator() const
69 {
70 return _oit;
71 }
72
73 private:
74
75 OffsetIterator _oit;
76 const EntityIndex& _entity_index;
77
78 };
79
80
81 template<typename DOFIndex, typename ContainerIndex, std::size_t tree_depth, bool map_dof_indices = false>
82 struct indices_for_entity
83 : public TypeTree::TreeVisitor
84 , public TypeTree::DynamicTraversal
85 {
86
87 typedef std::size_t size_type;
88 typedef typename DOFIndex::EntityIndex EntityIndex;
89 typedef typename std::vector<ContainerIndex>::iterator CIIterator;
90 typedef typename std::conditional<
91 map_dof_indices,
92 typename std::vector<DOFIndex>::iterator,
93 DummyDOFIndexIterator
94 >::type DIIterator;
95
96
97 template<typename Ordering, typename Child, typename TreePath, typename ChildIndex>
98 void beforeChild(const Ordering& ordering, const Child& child, TreePath tp, ChildIndex childIndex)
99 {
100 _stack.push(std::make_pair(_ci_it,_di_it));
101 }
102
103 template<typename Ordering, typename TreePath>
104 void leaf(const Ordering& ordering, TreePath tp)
105 {
106 static_assert(tp.size()>=1, "Cannot call method 'indices_for_entity::leaf' for empty tree path");
107 size_type size = ordering.extract_entity_indices(_entity_index,
108 tp.back(),
109 _ci_it,
110 _ci_end,
111 _di_it);
112
113 _ci_end += size;
114 _ci_it = _ci_end;
115 _di_end += size;
116 _di_it = _di_end;
117 }
118
119 template<typename Ordering, typename Child, typename TreePath, typename ChildIndex>
120 void afterChild(const Ordering& ordering, const Child& child, TreePath tp, ChildIndex childIndex)
121 {
122 // pop
123 ordering.extract_entity_indices(_entity_index,
124 childIndex,
125 _stack.top().first,
126 _ci_end);
127
128 if (Ordering::consume_tree_index)
129 for (DIIterator it = _stack.top().second;
130 it != _di_end;
131 ++it)
132 it->treeIndex().push_back(childIndex);
133
134 _stack.pop();
135 }
136
137
138 indices_for_entity(const EntityIndex& entity_index,
139 CIIterator ci_begin,
140 DIIterator di_begin = DIIterator())
141 : _entity_index(entity_index)
142 , _ci_it(ci_begin)
143 , _ci_end(ci_begin)
144 , _di_it(di_begin)
145 , _di_end(di_begin)
146 {}
147
148
149 // Exposed for multidomain support
150 CIIterator ci_end() const
151 {
152 return _ci_end;
153 }
154
155 // Exposed for multidomain support
156 DIIterator di_end() const
157 {
158 return _di_end;
159 }
160
161 private:
162
163 const EntityIndex& _entity_index;
164 CIIterator _ci_it;
165 CIIterator _ci_end;
166 DIIterator _di_it;
167 DIIterator _di_end;
168
169 std::stack<
170 std::pair<
171 CIIterator,
172 DIIterator
173 >,
174 ReservedVector<
175 std::pair<
176 CIIterator,
177 DIIterator
178 >,
179 tree_depth
180 >
181 > _stack;
182 };
183
184 } // anonymous namespace
185
186
187 template<typename GFS>
188 class DataHandleProvider
189 {
190
191 public:
192
193 typedef std::size_t size_type;
194
195 //------------------------------
196 // generic data handle interface
197 //------------------------------
198
200 bool dataHandleContains (int codim) const
201 {
202 return gfs().ordering().contains(codim);
203 }
204
206 bool dataHandleFixedSize (int codim) const
207 {
208 return gfs().ordering().fixedSize(codim);
209 }
210
212
226 constexpr bool sendLeafSizes() const
227 {
228 return false;
229 }
230
235 template<typename Entity>
236 size_type dataHandleSize (const Entity& e) const
237 {
238 typedef typename GFS::Ordering Ordering;
239
240 typedef typename Ordering::Traits::DOFIndex::EntityIndex EntityIndex;
241 EntityIndex ei;
242
243 Ordering::Traits::DOFIndexAccessor::GeometryIndex::store(
244 ei,
245 e.type(),
246 gfs().gridView().indexSet().index(e)
247 );
248
249 get_size_for_entity<EntityIndex> get_size(ei);
250 TypeTree::applyToTree(gfs().ordering(),get_size);
251
252 return get_size.size();
253 }
254
255 template<typename V, typename EntityIndex>
256 void setup_dof_indices(V& v, size_type n, const EntityIndex& ei, std::integral_constant<bool,true>) const
257 {
258 v.resize(n);
259 for (typename V::iterator it = v.begin(),
260 endit = v.end();
261 it != endit;
262 ++it)
263 {
264 it->treeIndex().clear();
265 it->entityIndex() = ei;
266 }
267 }
268
269 template<typename V, typename EntityIndex>
270 void setup_dof_indices(V& v, size_type n, const EntityIndex& ei, std::integral_constant<bool,false>) const
271 {}
272
273 template<typename V>
274 typename V::iterator dof_indices_begin(V& v, std::integral_constant<bool,true>) const
275 {
276 return v.begin();
277 }
278
279 template<typename V>
280 DummyDOFIndexIterator dof_indices_begin(V& v, std::integral_constant<bool,false>) const
281 {
282 return DummyDOFIndexIterator();
283 }
284
286 template<typename Entity, typename ContainerIndex, typename DOFIndex, typename OffsetIterator, bool map_dof_indices>
287 void dataHandleIndices (const Entity& e,
288 std::vector<ContainerIndex>& container_indices,
289 std::vector<DOFIndex>& dof_indices,
290 OffsetIterator oit,
291 std::integral_constant<bool,map_dof_indices> map_dof_indices_value
292 ) const
293 {
294 typedef typename GFS::Ordering Ordering;
295
296 static_assert((std::is_same<ContainerIndex,typename Ordering::Traits::ContainerIndex>::value),
297 "dataHandleContainerIndices() called with invalid ContainerIndex type.");
298
299 typedef typename Ordering::Traits::DOFIndex::EntityIndex EntityIndex;
300 EntityIndex ei;
301
302 Ordering::Traits::DOFIndexAccessor::GeometryIndex::store(
303 ei,
304 e.type(),
305 gfs().entitySet().indexSet().index(e)
306 );
307
308 get_leaf_offsets_for_entity<EntityIndex,OffsetIterator> get_offsets(ei,oit);
309 TypeTree::applyToTree(gfs().ordering(),get_offsets);
310 OffsetIterator end_oit = oit + (TypeTree::TreeInfo<Ordering>::leafCount + 1);
311
312 // convert sizes to offsets - last entry contains total size
313 std::partial_sum(oit,end_oit,oit);
315
316 container_indices.resize(size);
317 // Clear index state
318 for (typename std::vector<ContainerIndex>::iterator it = container_indices.begin(),
319 endit = container_indices.end();
320 it != endit;
321 ++it)
322 it->clear();
323
324 setup_dof_indices(dof_indices,size,ei,map_dof_indices_value);
325
326#ifndef NDEBUG
327 // this checks that gfs has common entity set on leaf nodes (throw if that's not the case)
328 // in case of multidomain gfs, indices_for_entity will fail
329 // because DOFIndex will have wrong entity indices
330 auto es_visitor = impl::common_entity_set<typename GFS::Traits::EntitySet>{};
331 TypeTree::applyToTree(gfs(), es_visitor);
332#endif
333
334 indices_for_entity<
335 DOFIndex,
336 ContainerIndex,
338 map_dof_indices
339 > extract_indices(ei,container_indices.begin(),dof_indices_begin(dof_indices,map_dof_indices_value));
340 TypeTree::applyToTree(gfs().ordering(),extract_indices);
341
342 }
343
344 protected:
345
346 const GFS& gfs() const
347 {
348 return static_cast<const GFS&>(*this);
349 }
350
351 };
352
353 } // namespace PDELab
354} // namespace Dune
355
356#endif // DUNE_PDELAB_GRIDFUNCTIONSPACE_DATAHANDLEPROVIDER_HH
Traits for type conversions and type information.
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition: traversal.hh:239
typename impl::_Child< Node, indices... >::type Child
Template alias for the type of a child node given by a list of child indices.
Definition: childextraction.hh:225
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
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
An stl-compliant random-access container which stores everything on the stack.
static const std::size_t leafCount
The number of leaf nodes in the TypeTree.
Definition: utility.hh:136
static const std::size_t depth
The depth of the TypeTree.
Definition: utility.hh:130
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 23, 23:29, 2024)