DUNE PDELab (2.7)

interleavedordering.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_ORDERING_INTERLEAVEDORDERING_HH
4#define DUNE_PDELAB_ORDERING_INTERLEAVEDORDERING_HH
5
6#include <array>
7#include <string>
8
9#include <dune/typetree/compositenode.hh>
10#include <dune/typetree/powernode.hh>
11
13
14#include <dune/pdelab/gridfunctionspace/tags.hh>
15#include <dune/pdelab/ordering/utility.hh>
16#include <dune/pdelab/ordering/orderingbase.hh>
17
18namespace Dune {
19 namespace PDELab {
20
23
24 namespace interleaved_ordering {
25
27 template<typename DI, typename CI, typename Node>
28 class Base
29 : public OrderingBase<DI,CI>
30 {
31
32 typedef OrderingBase<DI,CI> BaseT;
33
34 public:
35
36 typedef typename OrderingBase<DI,CI>::Traits Traits;
37
39
40 static const bool consume_tree_index = true;
41
43
48 Base(Node& node, bool container_blocked, const OrderingTag& ordering_tag, typename BaseT::GFSData* gfs_data)
49 : BaseT(node,container_blocked,ordering_tag.offsets(),gfs_data,nullptr)
50 {
51 // This check looks a little weird, but there is always one offset more than
52 // there are blocks (the first offsets is 0, and the last one is the "offset
53 // beyond the end" to encode the size of the final child).
54 if (node.CHILDREN != ordering_tag.offsets().size() - 1)
56 "Invalid block structure for InterleavedOrdering: "
57 << node.CHILDREN << " children, but "
58 << (ordering_tag.offsets().size() - 1) << " block sizes.");
59 }
60
61 template<typename ItIn, typename ItOut>
62 void map_lfs_indices(const ItIn begin, const ItIn end, ItOut out) const
63 {
64 typedef typename Traits::SizeType size_type;
65 if (this->_container_blocked)
66 {
67 for (ItIn in = begin; in != end; ++in, ++out)
68 {
69 size_type child_index = in->treeIndex().back();
70 size_type child_block_offset = this->_child_block_merge_offsets[child_index];
71 size_type child_block_size = this->_child_block_merge_offsets[child_index + 1] - child_block_offset;
72 size_type index = out->back();
73 size_type block_index = index / child_block_size;
74 size_type offset = index % child_block_size;
75 out->back() = child_block_offset + offset;
76 out->push_back(block_index);
77 }
78 }
79 else
80 {
81 for (ItIn in = begin; in != end; ++in, ++out)
82 {
83 size_type child_index = in->treeIndex().back();
84 size_type child_block_offset = this->_child_block_merge_offsets[child_index];
85 size_type child_block_size = this->_child_block_merge_offsets[child_index + 1] - child_block_offset;
86 size_type block_size = this->_child_block_merge_offsets.back();
87 size_type index = out->back();
88 size_type block_index = index / child_block_size;
89 size_type offset = index % child_block_size;
90 out->back() = block_index * block_size + child_block_offset + offset;
91 }
92 }
93 }
94
95 template<typename CIOutIterator, typename DIOutIterator = DummyDOFIndexIterator>
96 typename Traits::SizeType
97 extract_entity_indices(const typename Traits::DOFIndex::EntityIndex& ei,
98 typename Traits::SizeType child_index,
99 CIOutIterator ci_out, const CIOutIterator ci_end) const
100 {
101 typedef typename Traits::SizeType size_type;
102 if (this->_container_blocked)
103 {
104 for (; ci_out != ci_end; ++ci_out)
105 {
106 size_type child_block_offset = this->_child_block_merge_offsets[child_index];
107 size_type child_block_size = this->_child_block_merge_offsets[child_index + 1] - child_block_offset;
108 size_type index = ci_out->back();
109 size_type block_index = index / child_block_size;
110 size_type offset =index % child_block_size;
111 ci_out->back() = child_block_offset + offset;
112 ci_out->push_back(block_index);
113 }
114 }
115 else
116 {
117 for (; ci_out != ci_end; ++ci_out)
118 {
119 size_type child_block_offset = this->_child_block_merge_offsets[child_index];
120 size_type child_block_size = this->_child_block_merge_offsets[child_index + 1] - child_block_offset;
121 size_type block_size = this->_child_block_merge_offsets.back();
122 size_type index = ci_out->back();
123 size_type block_index = index / child_block_size;
124 size_type offset =index % child_block_size;
125 ci_out->back() = block_index * block_size + child_block_offset + offset;
126 }
127 }
128
129 // The return value is not used for non-leaf orderings.
130 return 0;
131 }
132
133 };
134
135 } // namespace interleaved_ordering
136
137
138 template<typename DI, typename CI, typename Child, std::size_t k>
139 class PowerInterleavedOrdering
140 : public TypeTree::PowerNode<Child, k>
141 , public interleaved_ordering::Base<DI,
142 CI,
143 PowerInterleavedOrdering<DI,CI,Child,k>
144 >
145 {
146 typedef TypeTree::PowerNode<Child, k> Node;
147
148 typedef interleaved_ordering::Base<DI,
149 CI,
150 PowerInterleavedOrdering<DI,CI,Child,k>
151 > Base;
152
153 public:
154
156
164 PowerInterleavedOrdering(bool container_blocked, const InterleavedOrderingTag& ordering_tag, const typename Node::NodeStorage& children, typename Base::GFSData* gfs_data)
165 : Node(children)
166 , Base(*this,container_blocked,ordering_tag,gfs_data)
167 {}
168
169 void update()
170 {
171 for (std::size_t i = 0; i < k; ++i)
172 {
173 this->child(i).update();
174 }
175 Base::update();
176 }
177
178 std::string name() const { return "PowerInterleavedOrdering"; }
179 };
180
181
182 template<typename GFS, typename Transformation>
183 struct power_gfs_to_interleaved_ordering_descriptor
184 {
185
186 static const bool recursive = true;
187
188 template<typename TC>
189 struct result
190 {
191
192 typedef PowerInterleavedOrdering<
193 typename Transformation::DOFIndex,
194 typename Transformation::ContainerIndex,
195 TC,
196 TypeTree::StaticDegree<GFS>::value
197 > type;
198
199 typedef std::shared_ptr<type> storage_type;
200
201 };
202
203 template<typename TC>
204 static typename result<TC>::type transform(const GFS& gfs, const Transformation& t, const std::array<std::shared_ptr<TC>,TypeTree::StaticDegree<GFS>::value>& children)
205 {
206 return typename result<TC>::type(gfs.backend().blocked(gfs),gfs.orderingTag(),children,const_cast<GFS*>(&gfs));
207 }
208
209 template<typename TC>
210 static typename result<TC>::storage_type transform_storage(std::shared_ptr<const GFS> gfs, const Transformation& t, const std::array<std::shared_ptr<TC>,TypeTree::StaticDegree<GFS>::value>& children)
211 {
212 return std::make_shared<typename result<TC>::type>(gfs->backend().blocked(*gfs),gfs->orderingTag(),children,const_cast<GFS*>(gfs.get()));
213 }
214
215 };
216
217 template<typename GFS, typename Transformation>
218 power_gfs_to_interleaved_ordering_descriptor<GFS,Transformation>
219 register_power_gfs_to_ordering_descriptor(GFS*,Transformation*,InterleavedOrderingTag*);
220
221
222
223 template<typename DI, typename CI, typename... Children>
224 class CompositeInterleavedOrdering :
225 public TypeTree::CompositeNode<Children...>,
226 public interleaved_ordering::Base<DI,
227 CI,
228 CompositeInterleavedOrdering<
229 DI,
230 CI,
231 Children...
232 >
233 >
234 {
235 typedef TypeTree::CompositeNode<Children...> Node;
236
237 typedef interleaved_ordering::Base<
238 DI,
239 CI,
240 CompositeInterleavedOrdering<
241 DI,
242 CI,
243 Children...
244 >
245 > Base;
246
247 public:
249
257 CompositeInterleavedOrdering(bool backend_blocked, const InterleavedOrderingTag& ordering_tag, typename Base::GFSData* gfs_data, std::shared_ptr<Children>... children)
258 : Node(children...)
259 , Base(*this,backend_blocked,ordering_tag,gfs_data)
260 { }
261
262 std::string name() const { return "CompositeInterleavedOrdering"; }
263
264 void update()
265 {
266 TypeTree::applyToTree(*this,ordering::update_direct_children());
267 Base::update();
268 }
269 };
270
271 template<typename GFS, typename Transformation>
272 struct composite_gfs_to_interleaved_ordering_descriptor
273 {
274
275 static const bool recursive = true;
276
277 template<typename... TC>
278 struct result
279 {
280
281 typedef CompositeInterleavedOrdering<
282 typename Transformation::DOFIndex,
283 typename Transformation::ContainerIndex,
284 TC...
285 > type;
286
287 typedef std::shared_ptr<type> storage_type;
288
289 };
290
291 template<typename... TC>
292 static typename result<TC...>::type transform(const GFS& gfs, const Transformation& t, std::shared_ptr<TC>... children)
293 {
294 return typename result<TC...>::type(gfs.backend().blocked(gfs),gfs.orderingTag(),const_cast<GFS*>(&gfs),children...);
295 }
296
297 template<typename... TC>
298 static typename result<TC...>::storage_type transform_storage(std::shared_ptr<const GFS> gfs, const Transformation& t, std::shared_ptr<TC>... children)
299 {
300 return std::make_shared<typename result<TC...>::type>(gfs->backend().blocked(*gfs),gfs.orderingTag(),const_cast<GFS*>(gfs.get()),children...);
301 }
302
303 };
304
305 template<typename GFS, typename Transformation>
306 composite_gfs_to_interleaved_ordering_descriptor<GFS,Transformation>
307 register_composite_gfs_to_ordering_descriptor(GFS*,Transformation*,InterleavedOrderingTag*);
308
310 } // namespace PDELab
311} // namespace Dune
312
313#endif // DUNE_PDELAB_ORDERING_INTERLEAVEDORDERING_HH
Error related to the logical structure of an Ordering.
Definition: exceptions.hh:46
Interface for merging index spaces.
Definition: interleavedordering.hh:30
Base(Node &node, bool container_blocked, const OrderingTag &ordering_tag, typename BaseT::GFSData *gfs_data)
Construct ordering object.
Definition: interleavedordering.hh:48
std::array< ChildStorageType, k > NodeStorage
The type used for storing the children.
Definition: powernode.hh:84
PDELab-specific exceptions.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition: traversal.hh:213
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:179
Dune namespace.
Definition: alignedallocator.hh:14
Indicate interleaved ordering of the unknowns of non-leaf grid function spaces according to a given b...
Definition: tags.hh:79
const std::vector< std::size_t > & offsets() const
Returns a list of offsets for the child blocks.
Definition: tags.hh:115
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)