FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
structured_target_refiner.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// includes, FEAT
9#include <kernel/geometry/target_set.hpp>
10#include <kernel/geometry/intern/entity_counter.hpp>
11#include <kernel/geometry/intern/standard_refinement_traits.hpp>
12#include <kernel/geometry/intern/struct_index_coding.hpp>
13
14namespace FEAT
15{
16 namespace Geometry
17 {
19 namespace Intern
20 {
22 template<int shape_dim_, int cell_dim_, int child_dim_>
23 struct StructuredTargetRefiner;
24 /*{
25 static Index refine_simple(TargetSet&,const TargetSet&,const Index,const Index[],const Index[])
26 {
27 std::cout << "SPECIALISE ME: StructuredTargetRefiner<" << shape_dim_
28 << "," << cell_dim_ << "," << child_dim_ << ">\n";
29 return Index(0);
30 }
31 };*/
32
33 // vertex -> vertex
34 template<int shape_dim_>
35 struct StructuredTargetRefiner<shape_dim_, 0, 0>
36 {
37 static Index refine_simple(
38 TargetSet& target_set_out,
39 const TargetSet& target_set_in,
40 const Index offset,
41 const Index num_slices_c[],
42 const Index num_slices_f[])
43 {
44 const Index num_verts = target_set_in.get_num_entities();
45 Index v[shape_dim_];
46
47 for(Index i(0); i < num_verts; ++i)
48 {
49 // decode coarse vertex index
50 StructIndexCoding<shape_dim_, 0>::decode(v, target_set_in[i], num_slices_c);
51
52 // transform vertex index-coords
53 for(int j(0); j < shape_dim_; ++j)
54 v[j] *= 2;
55
56 // encode fine vertex index
57 target_set_out[offset+i] = StructIndexCoding<shape_dim_, 0>::encode(v, num_slices_f);
58 }
59
60 return num_verts;
61 }
62 };
63
64 // edge -> vertex
65 template<int shape_dim_>
66 struct StructuredTargetRefiner<shape_dim_, 1, 0>
67 {
68 static Index refine_simple(
69 TargetSet& target_set_out,
70 const TargetSet& target_set_in,
71 const Index offset,
72 const Index num_slices_c[],
73 const Index num_slices_f[])
74 {
75 const Index num_edges = target_set_in.get_num_entities();
76 Index v[shape_dim_+1];
77
78 for(Index i(0); i < num_edges; ++i)
79 {
80 // decode coarse edge index
81 StructIndexCoding<shape_dim_, 1>::decode(v, target_set_in[i], num_slices_c);
82
83 // transform edge index-coords
84 for(int j(0); j < shape_dim_; ++j)
85 v[j] *= 2;
86
87 // funny trick :)
88 ++v[v[shape_dim_]];
89
90 // encode fine vertex index
91 target_set_out[offset+i] = StructIndexCoding<shape_dim_, 0>::encode(v, num_slices_f);
92 }
93
94 return num_edges;
95 }
96 };
97
98 // edge -> edge
99 template<int shape_dim_>
100 struct StructuredTargetRefiner<shape_dim_, 1, 1>
101 {
102 static Index refine_simple(
103 TargetSet& target_set_out,
104 const TargetSet& target_set_in,
105 const Index offset,
106 const Index num_slices_c[],
107 const Index num_slices_f[])
108 {
109 const Index num_edges = target_set_in.get_num_entities();
110 Index v[shape_dim_+1];
111
112 for(Index i(0); i < num_edges; ++i)
113 {
114 // decode coarse edge index
115 StructIndexCoding<shape_dim_, 1>::decode(v, target_set_in[i], num_slices_c);
116
117 // transform edge index-coords
118 for(int j(0); j < shape_dim_; ++j)
119 v[j] *= 2;
120
121 // add first child edge
122 target_set_out[offset+2*i+0] = StructIndexCoding<shape_dim_, 1>::encode(v, num_slices_f);
123
124 // funny trick :)
125 ++v[v[shape_dim_]];
126
127 // encode fine vertex index
128 target_set_out[offset+2*i+1] = StructIndexCoding<shape_dim_, 1>::encode(v, num_slices_f);
129 }
130
131 return 2*num_edges;
132 }
133 };
134
135 // 2D quad -> vertex
136 template<int shape_dim_>
137 struct StructuredTargetRefiner<shape_dim_, 2, 0>
138 {
139 static Index refine_simple(
140 TargetSet& target_set_out,
141 const TargetSet& target_set_in,
142 const Index offset,
143 const Index num_slices_c[],
144 const Index num_slices_f[])
145 {
146 const Index num_quads = target_set_in.get_num_entities();
147 Index v[shape_dim_+1];
148
149 for(Index i(0); i < num_quads; ++i)
150 {
151 // decode coarse quad index
152 StructIndexCoding<shape_dim_, 2>::decode(v, target_set_in[i], num_slices_c);
153
154 // transform quad index-coords
155 for(int j(0); j < shape_dim_; ++j)
156 (v[j] *= 2) += 1;
157
158 // encode fine vertex index
159 target_set_out[offset+i] = StructIndexCoding<shape_dim_, 0>::encode(v, num_slices_f);
160 }
161
162 return num_quads;
163 }
164 };
165
166 // 2D quad -> edge
167 template</*int shape_dim_*/>
168 struct StructuredTargetRefiner</*shape_dim_*/2, 2, 1>
169 {
170 static constexpr int shape_dim_ = 2;
171
172 static Index refine_simple(
173 TargetSet& target_set_out,
174 const TargetSet& target_set_in,
175 const Index offset,
176 const Index num_slices_c[],
177 const Index num_slices_f[])
178 {
179 const Index num_quads = target_set_in.get_num_entities();
180 Index v[shape_dim_+1];
181
182 for(Index i(0); i < num_quads; ++i)
183 {
184 // decode coarse quad index
185 StructIndexCoding<shape_dim_, 2>::decode(v, target_set_in[i], num_slices_c);
186
187 // transform quad index-coords
188 for(int j(0); j < shape_dim_; ++j)
189 v[j] *= 2;
190
191 // add horizontal edges
192 v[2] = 0;
193 // left edge
194 ++v[1];
195 target_set_out[offset+4*i+0] = StructIndexCoding<shape_dim_, 1>::encode(v, num_slices_f);
196 // right edge
197 ++v[0];
198 target_set_out[offset+4*i+1] = StructIndexCoding<shape_dim_, 1>::encode(v, num_slices_f);
199
200 // add vertical edges
201 v[2] = 1;
202 // bottom edge
203 --v[1];
204 target_set_out[offset+4*i+2] = StructIndexCoding<shape_dim_, 1>::encode(v, num_slices_f);
205 // top edge
206 ++v[1];
207 target_set_out[offset+4*i+3] = StructIndexCoding<shape_dim_, 1>::encode(v, num_slices_f);
208 }
209
210 return Index(4)*num_quads;
211 }
212 };
213
214 // 2D quad -> quad
215 template</*int shape_dim_*/>
216 struct StructuredTargetRefiner</*shape_dim_*/ 2, 2, 2>
217 {
218 static constexpr int shape_dim_ = 2;
219
220 static Index refine_simple(
221 TargetSet& target_set_out,
222 const TargetSet& target_set_in,
223 const Index offset,
224 const Index num_slices_c[],
225 const Index num_slices_f[])
226 {
227 const Index num_quads = target_set_in.get_num_entities();
228 Index v[shape_dim_+1];
229
230 for(Index i(0); i < num_quads; ++i)
231 {
232 // decode coarse quad index
233 StructIndexCoding<shape_dim_, 2>::decode(v, target_set_in[i], num_slices_c);
234
235 // transform quad index-coords
236 for(int j(0); j < shape_dim_; ++j)
237 v[j] *= 2;
238
239 // encode fine quad indices:
240 // lower left child
241 target_set_out[offset+4*i+0] = StructIndexCoding<shape_dim_, 2>::encode(v, num_slices_f);
242
243 // lower right child
244 ++v[0];
245 target_set_out[offset+4*i+1] = StructIndexCoding<shape_dim_, 2>::encode(v, num_slices_f);
246
247 // upper left child
248 --v[0];
249 ++v[1];
250 target_set_out[offset+4*i+2] = StructIndexCoding<shape_dim_, 2>::encode(v, num_slices_f);
251
252 // upper right child
253 ++v[0];
254 target_set_out[offset+4*i+3] = StructIndexCoding<shape_dim_, 2>::encode(v, num_slices_f);
255 }
256
257 return Index(4) * num_quads;
258 }
259 };
260
261 template<int shape_dim_, int child_dim_, int cell_dim_ = shape_dim_>
262 struct StructuredTargetRefineShapeWrapper
263 {
264 typedef Shape::Hypercube<shape_dim_> ShapeType;
265 typedef typename Shape::FaceTraits<ShapeType, cell_dim_>::ShapeType CellType;
266
267 static Index refine_simple(
268 TargetSet& target_set_out,
269 const TargetSetHolder<CellType>& target_set_holder_in,
270 const Index num_slices_c[], const Index num_slices_f[])
271 {
272 // recursive call of SubSetRefineShapeWrapper
273 Index offset = StructuredTargetRefineShapeWrapper<shape_dim_, child_dim_, cell_dim_-1>::refine_simple(
274 target_set_out, target_set_holder_in, num_slices_c, num_slices_f);
275
276 // call target refiner
277 Index count = StructuredTargetRefiner<shape_dim_, cell_dim_, child_dim_>::refine_simple(
278 target_set_out, target_set_holder_in.template get_target_set<cell_dim_>(),
279 offset, num_slices_c, num_slices_f);
280
281 // return new offset
282 return offset + count;
283 }
284 };
285
286 template<int shape_dim_, int cell_dim_>
287 struct StructuredTargetRefineShapeWrapper<shape_dim_, cell_dim_, cell_dim_>
288 {
289 typedef Shape::Hypercube<shape_dim_> ShapeType;
290 typedef typename Shape::FaceTraits<ShapeType, cell_dim_>::ShapeType CellType;
291
292 static Index refine_simple(
293 TargetSet& target_set_out,
294 const TargetSetHolder<CellType>& target_set_holder_in,
295 const Index num_slices_c[], const Index num_slices_f[])
296 {
297 // call target refiner
298 Index count = StructuredTargetRefiner<shape_dim_, cell_dim_, cell_dim_>::refine_simple(
299 target_set_out, target_set_holder_in.template get_target_set<cell_dim_>(),
300 Index(0), num_slices_c, num_slices_f);
301
302 // return offset
303 return count;
304 }
305 };
306
307 template<int shape_dim_, int cell_dim_ = shape_dim_>
308 struct StructuredTargetRefineWrapper
309 {
310 typedef Shape::Hypercube<shape_dim_> ShapeType;
311 typedef Shape::Hypercube<cell_dim_> CellType;
312
313 static void refine_simple(
314 TargetSetHolder<CellType>& target_set_holder_out,
315 const TargetSetHolder<ShapeType>& target_set_holder_in,
316 const Index num_slices_c[], const Index num_slices_f[])
317 {
318 // recursive call
319 StructuredTargetRefineWrapper<shape_dim_, cell_dim_-1>::refine_simple(
320 target_set_holder_out, target_set_holder_in, num_slices_c, num_slices_f);
321
322 // call shape wrapper
323 StructuredTargetRefineShapeWrapper<shape_dim_, cell_dim_>::refine_simple(
324 target_set_holder_out.template get_target_set<cell_dim_>(),
325 target_set_holder_in, num_slices_c, num_slices_f);
326 }
327 };
328
329 template<int shape_dim_>
330 struct StructuredTargetRefineWrapper<shape_dim_, 0>
331 {
332 typedef Shape::Hypercube<shape_dim_> ShapeType;
333 //typedef typename Shape::FaceTraits<ShapeType, cell_dim_>::ShapeType CellType;
334
335 static void refine_simple(
336 TargetSetHolder<Shape::Vertex>& target_set_holder_out,
337 const TargetSetHolder<ShapeType>& target_set_holder_in,
338 const Index num_slices_c[], const Index num_slices_f[])
339 {
340 // call shape wrapper
341 StructuredTargetRefineShapeWrapper<shape_dim_, 0>::refine_simple(
342 target_set_holder_out.template get_target_set<0>(),
343 target_set_holder_in, num_slices_c, num_slices_f);
344 }
345 };
346 } // namespace Intern
348 } // namespace Geometry
349} // namespace FEAT
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.