FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
structured_vertex_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/vertex_set.hpp>
10
11namespace FEAT
12{
13 namespace Geometry
14 {
16 namespace Intern
17 {
18 template<
19 typename Shape_,
20 typename VertexSet_>
21 class StructuredVertexRefiner;
22
28 template<typename VertexSet_>
29 class StructuredVertexRefiner<Shape::Hypercube<1>, VertexSet_>
30 {
31 public:
32 typedef VertexSet_ VertexSetType;
33
34 static void refine(
35 VertexSetType& vertex_set_out,
36 const VertexSetType& vertex_set_in,
37 const Index num_slices_coarse[])
38 {
39 typedef typename VertexSetType::CoordType CoordType;
40
41 // get number of X-slices
42 const Index n = num_slices_coarse[0];
43
44 // copy first vertex
45 vertex_set_out[0] = vertex_set_in[0];
46
47 // loop over all slices
48 for(Index i(0); i < n; ++i)
49 {
50 // calculate edge midpoint
51 vertex_set_out[2*i + 1] = CoordType(0.5) *(vertex_set_in[i] + vertex_set_in[i + 1]);
52
53 // copy right vertex
54 vertex_set_out[2*i + 2] = vertex_set_in[i + 1];
55 }
56 }
57 }; // class StructuredVertexRefiner<Hypercube<1>,...>
58
59
65 template<typename VertexSet_>
66 class StructuredVertexRefiner<Shape::Hypercube<2>, VertexSet_>
67 {
68 public:
69 typedef VertexSet_ VertexSetType;
70
71 static void refine(
72 VertexSetType& vertex_set_out,
73 const VertexSetType& vertex_set_in,
74 const Index num_slices_coarse[])
75 {
76 typedef typename VertexSetType::CoordType CoordType;
77
78 // get number of X- and Y-slices
79 const Index m = num_slices_coarse[0];
80 const Index n = num_slices_coarse[1];
81
82 // copy lower left vertex
83 vertex_set_out[0] = vertex_set_in[0];
84
85 // loop over all edges in bottom row
86 for(Index i(0); i < m; ++i)
87 {
88 // calculate edge midpoint
89 vertex_set_out[2*i + 1] = CoordType(0.5) * (vertex_set_in[i] + vertex_set_in[i + 1]);
90
91 // copy right vertex
92 vertex_set_out[2*i + 2] = vertex_set_in[i + 1];
93 }
94
95 // loop over all rows
96 FEAT_PRAGMA_OMP(parallel for)
97 for(Index j = 0; j < n; ++j)
98 {
99 // calculate offsets
100 Index k0 = j *(m + 1); // lower-left coarse mesh vertex
101 Index k1 = (1 + j)*(m + 1); // upper-left coarse mesh vertex
102 Index l0 = (2*j + 1)*(2*m + 1); // left fine mesh vertex; generated from coarse mesh edge midpoint
103 Index l1 = 2*(j + 1)*(2*m + 1); // upper-left fine mesh vertex
104
105 // calculate left edge midpoint
106 vertex_set_out[l0] = CoordType(0.5) * (vertex_set_in[k0] + vertex_set_in[k1]);
107
108 // copy upper left vertex
109 vertex_set_out[l1] = vertex_set_in[k1];
110
111 // loop over all cells in current row
112 for(Index i(0); i < m; ++i)
113 {
114 // calculate quad midpoint
115 vertex_set_out[l0 + 2*i + 1] = CoordType(0.25) * (
116 vertex_set_in[k0 + i] + vertex_set_in[k0 + i + 1] +
117 vertex_set_in[k1 + i] + vertex_set_in[k1 + i + 1]);
118
119 // calculate right edge midpoint
120 vertex_set_out[l0 + 2*i + 2] = CoordType(0.5) * (
121 vertex_set_in[k0 + i + 1] + vertex_set_in[k1 + i + 1]);
122
123 // calculate upper edge midpoint
124 vertex_set_out[l1 + 2*i + 1] = CoordType(0.5) * (
125 vertex_set_in[k1 + i] + vertex_set_in[k1 + i + 1]);
126
127 // copy upper right vertex
128 vertex_set_out[l1 + 2*i + 2] = vertex_set_in[k1 + i + 1];
129 }
130 }
131 }
132 }; // class StructuredVertexRefiner<Hypercube<2>,...>
133
137 template<typename VertexSet_>
138 class StructuredVertexRefiner<Shape::Hypercube<3>, VertexSet_>
139 {
140 public:
141 typedef VertexSet_ VertexSetType;
142
143 static void refine(
144 VertexSetType& vertex_set_out,
145 const VertexSetType& vertex_set_in,
146 const Index num_slices_coarse[])
147 {
148 typedef typename VertexSetType::CoordType CoordType;
149
150 // get number of X-, Y- and Z-slices
151 const Index m = num_slices_coarse[0];
152 const Index n = num_slices_coarse[1];
153 const Index l = num_slices_coarse[2];
154
155 // copy lower left front vertex
156 vertex_set_out[0] = vertex_set_in[0];
157
158 // indices of the bottom layer (low,up -> Y-axis, left,right -> X-axis)
159
160 // indices of the lower edge
161 for(Index i(0); i < m; ++i)
162 {
163 // calculate edge midpoint
164 vertex_set_out[2*i + 1] = CoordType(0.5) * (vertex_set_in[i] + vertex_set_in[i + 1]);
165
166 // copy right vertex
167 vertex_set_out[2*i + 2] = vertex_set_in[i + 1];
168 }
169
170 // loop over all Y-slices
171 FEAT_PRAGMA_OMP(parallel for)
172 for(Index j = 0; j < n; ++j)
173 {
174 // calculate offsets
175 const Index k0 = j *(m + 1); // lower-left coarse mesh vertex
176 const Index k1 = (1 + j)*(m + 1); // upper-left coarse mesh vertex
177 const Index l0 = (2*j + 1)*(2*m + 1); // left fine mesh vertex; generated from coarse mesh edge midpoint
178 const Index l1 = 2*(j + 1)*(2*m + 1); // upper-left fine mesh vertex
179
180 // calculate left edge midpoint
181 vertex_set_out[l0] = CoordType(0.5) * (vertex_set_in[k0] + vertex_set_in[k1]);
182
183 // copy upper left vertex
184 vertex_set_out[l1] = vertex_set_in[k1];
185
186 // loop over all cells in the current Y-slice
187 for(Index i(0); i < m; ++i)
188 {
189 // calculate quad midpoint
190 vertex_set_out[l0 + 2*i + 1] = CoordType(0.25) * (
191 vertex_set_in[k0 + i] + vertex_set_in[k0 + i + 1] +
192 vertex_set_in[k1 + i] + vertex_set_in[k1 + i + 1]);
193
194 // calculate right edge midpoint
195 vertex_set_out[l0 + 2*i + 2] = CoordType(0.5) * (
196 vertex_set_in[k0 + i + 1] + vertex_set_in[k1 + i + 1]);
197
198 // calculate upper edge midpoint
199 vertex_set_out[l1 + 2*i + 1] = CoordType(0.5) * (
200 vertex_set_in[k1 + i] + vertex_set_in[k1 + i + 1]);
201
202 // copy upper right vertex
203 vertex_set_out[l1 + 2*i + 2] = vertex_set_in[k1 + i + 1];
204 }
205 }
206 // indices of the bottom face done
207
208 // loop over all Z-slices of the coarse mesh
209 FEAT_PRAGMA_OMP(parallel for)
210 for(Index k = 0; k < l; ++k)
211 {
212 // coarse and fine mesh index of the left front vertex of the current slice (= offsets)
213 const Index oc = (k+1)*(m+1)*(n+1);
214 const Index of = 2*(k+1)*(2*m+1)*(2*n+1);
215
216 // copy lower left front vertex
217 vertex_set_out[of] = vertex_set_in[oc];
218
219 // indices of the front edge
220 for(Index i(0); i < m; ++i)
221 {
222 // calculate edge midpoint
223 vertex_set_out[of + 2*i + 1] = CoordType(0.5) * (vertex_set_in[oc + i] + vertex_set_in[oc + i + 1]);
224
225 // copy right vertex
226 vertex_set_out[of + 2*i + 2] = vertex_set_in[oc + i + 1];
227 }
228
229 // loop over all Y-slices
230 for(Index j(0); j < n; ++j)
231 {
232 // calculate (local) offsets
233 const Index k0 = j *(m + 1); // lower-left coarse mesh vertex
234 const Index k1 = (1 + j)*(m + 1); // upper-left coarse mesh vertex
235 const Index l0 = (2*j + 1)*(2*m + 1); // left fine mesh vertex; generated from coarse mesh edge midpoint
236 const Index l1 = 2*(j + 1)*(2*m + 1); // upper-left fine mesh vertex
237
238 // calculate left edge midpoint
239 vertex_set_out[l0 + of] = CoordType(0.5) * (vertex_set_in[k0 + oc] + vertex_set_in[k1 + oc]);
240
241 // copy upper left vertex
242 vertex_set_out[l1 + of] = vertex_set_in[k1+ oc];
243
244 // loop over all cells in the current Y-slice
245 for(Index i(0); i < m; ++i)
246 {
247 // calculate quad midpoint
248 vertex_set_out[l0 + 2*i + 1 + of] = CoordType(0.25) * (
249 vertex_set_in[k0 + i + oc] + vertex_set_in[k0 + i + 1 + oc] +
250 vertex_set_in[k1 + i + oc] + vertex_set_in[k1 + i + 1 + oc]);
251
252 // calculate right edge midpoint
253 vertex_set_out[l0 + 2*i + 2 + of] = CoordType(0.5) * (
254 vertex_set_in[k0 + i + 1 + oc] + vertex_set_in[k1 + i + 1 + oc]);
255
256 // calculate upper edge midpoint
257 vertex_set_out[l1 + 2*i + 1 + of] = CoordType(0.5) * (
258 vertex_set_in[k1 + i + oc] + vertex_set_in[k1 + i + 1 + oc]);
259
260 // copy upper right vertex
261 vertex_set_out[l1 + 2*i + 2 + of] = vertex_set_in[k1 + i + 1 + oc];
262 } // i-loop (cells)
263 } // j-loop (Y-slices)
264 } // k-loop
265
266 // calculate indices of the layer between the original coarse mesh layers
267 // this must be a separate loop to avoid race conditions in the OpenMP parallel case
268
269 // loop over all Z-slices of the coarse mesh
270 FEAT_PRAGMA_OMP(parallel for)
271 for(Index k = 0; k < l; ++k)
272 {
273 // fine mesh index of the left front vertex of the current slice (= offsets)
274 const Index of = 2*(k+1)*(2*m+1)*(2*n+1);
275
276 // loop over all Y-slices
277 for(Index j(0); j < 2*n+1; ++j)
278 {
279 // loop over all cells
280 for(Index i(0); i < 2*m+1; ++i)
281 {
282 vertex_set_out[i + j*(2*m+1) + of - (2*m+1)*(2*n+1)] = CoordType(0.5) *
283 (vertex_set_out[i + j*(2*m+1) + of] + vertex_set_out[i + j*(2*m+1) + of - 2*(2*m+1)*(2*n+1)]);
284 } // i-loop
285 } // j-loop
286 } // k-loop
287 }
288 }; // class StructuredVertexRefiner<Hypercube<3>,...>
289 } // namespace Intern
291 } // namespace Geometry
292} // namespace FEAT
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.