FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
standard_attrib_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/shape.hpp>
10#include <kernel/geometry/attribute_set.hpp>
11#include <kernel/geometry/intern/standard_refinement_traits.hpp>
12
13namespace FEAT
14{
15 namespace Geometry
16 {
18 namespace Intern
19 {
20 template<
21 typename Shape_,
22 typename AttribSet_>
23 struct StandardAttribRefiner;
24
30 template<typename AttribSet_>
31 struct StandardAttribRefiner<Shape::Vertex, AttribSet_>
32 {
33 typedef AttribSet_ AttribSetType;
34
35 static Index refine(
36 const Index offset,
37 AttribSetType& attrib_set_out,
38 const AttribSetType& attrib_set_in)
39 {
40 XASSERT(attrib_set_out.get_dimension() == attrib_set_in.get_dimension());
41
42 // get the number of coarse mesh attributes
43 const Index num_values = attrib_set_in.get_num_values();
44 const int dim_attrib = attrib_set_in.get_dimension();
45
46 XASSERT(attrib_set_out.get_num_values() >= offset + num_values);
47
48 // loop over all attributes
49 FEAT_PRAGMA_OMP(parallel for)
50 for(Index i = 0; i < num_values; ++i)
51 {
52 for(int j(0); j < dim_attrib; ++j)
53 {
54 attrib_set_out(offset+i, j) = attrib_set_in(i, j);
55 }
56 }
57
58 // return number of created vertices
59 return num_values;
60 }
61 }; // class StandardAttribRefiner<Vertex,...>
62
68 template<int cell_dim_, typename AttribSet_>
69 struct StandardAttribRefiner<Shape::Hypercube<cell_dim_>, AttribSet_>
70 {
71 typedef Shape::Hypercube<cell_dim_> ShapeType;
72 typedef IndexSet<Shape::FaceTraits<ShapeType, 0>::count> IndexSetType;
73 typedef AttribSet_ AttribSetType;
74
75 static Index refine(
76 Index offset,
77 AttribSetType& attrib_set_out,
78 const AttribSetType& attrib_set_in,
79 const IndexSetType& index_set_in)
80 {
81 // dimensional assert
82 XASSERT(attrib_set_out.get_dimension() == attrib_set_in.get_dimension());
83
84 typedef typename AttribSetType::DataType DataType;
85
86 // scaling factor
87 static const DataType scale = DataType(1) / DataType(IndexSetType::num_indices);
88
89 // get number of cells
90 const Index num_cells = index_set_in.get_num_entities();
91 const int dim_attrib = attrib_set_in.get_dimension();
92
93 XASSERT(attrib_set_out.get_num_values() >= offset + num_cells);
94
95 // loop over all cells
96 FEAT_PRAGMA_OMP(parallel for)
97 for(Index i = 0; i < num_cells; ++i)
98 {
99 // get input index tuple
100 const auto& idx_in = index_set_in[i];
101
102 // clear output attributes
103 for(int j(0); j < dim_attrib; ++j)
104 attrib_set_out(offset+i, j) = DataType(0);
105
106 // sum up the input attributes
107 for(int k(0); k < IndexSetType::num_indices; ++k)
108 {
109 for(int j(0); j < dim_attrib; ++j)
110 attrib_set_out(offset+i, j) += attrib_set_in(idx_in[k], j);
111 }
112
113 // scale attribute
114 for(int j(0); j < dim_attrib; ++j)
115 attrib_set_out(offset+i, j) *= scale;
116 }
117
118 // return number of created vertices
119 return num_cells;
120 }
121 }; // struct StandardAttribRefiner<Hypercube<...>,...>
122
128 template<int cell_dim_, typename AttribSet_>
129 struct StandardAttribRefiner<Shape::Simplex<cell_dim_>, AttribSet_>
130 {
131 typedef Shape::Simplex<cell_dim_> ShapeType;
132 typedef IndexSet<Shape::FaceTraits<ShapeType, 0>::count> IndexSetType;
133 typedef AttribSet_ AttribSetType;
134
135 static Index refine(
136 Index offset,
137 AttribSetType& attrib_set_out,
138 const AttribSetType& attrib_set_in,
139 const IndexSetType& index_set_in)
140 {
141 // dimensional assert
142 XASSERT(attrib_set_out.get_dimension() == attrib_set_in.get_dimension());
143
144 typedef typename AttribSetType::DataType DataType;
145
146 // scaling factor
147 static const DataType scale = DataType(1) / DataType(IndexSetType::num_indices);
148
149 // get number of cells
150 const Index num_cells = index_set_in.get_num_entities();
151 const int dim_attrib = attrib_set_in.get_dimension();
152
153 XASSERT(attrib_set_out.get_num_values() >= offset + num_cells);
154
155 // loop over all cells
156 FEAT_PRAGMA_OMP(parallel for)
157 for(Index i = 0; i < num_cells; ++i)
158 {
159 // get input index tuple
160 const auto& idx_in = index_set_in[i];
161
162 // clear output attributes
163 for(int j(0); j < dim_attrib; ++j)
164 attrib_set_out(offset+i, j) = DataType(0);
165
166 // sum up the input attributes
167 for(int k(0); k < IndexSetType::num_indices; ++k)
168 {
169 for(int j(0); j < dim_attrib; ++j)
170 attrib_set_out(offset+i, j) += attrib_set_in(idx_in[k], j);
171 }
172
173 // scale attribute
174 for(int j(0); j < dim_attrib; ++j)
175 attrib_set_out(offset+i, j) *= scale;
176 }
177
178 // return number of created vertices
179 return num_cells;
180 }
181 }; // struct AttribRefiner<Simplex<...>,...>
182
188 template<typename AttribSet_>
189 struct StandardAttribRefiner<Shape::Simplex<2>, AttribSet_>
190 {
191 typedef Shape::Simplex<2> ShapeType;
192 typedef IndexSet<Shape::FaceTraits<ShapeType, 0>::count> IndexSetType;
193 typedef AttribSet_ AttribSetType;
194
195 static Index refine(
196 Index /*offset*/,
197 AttribSetType& /*attrib_set_out*/,
198 const AttribSetType& /*attrib_set_in*/,
199 const IndexSetType& /*index_set_in*/)
200 {
201 // return number of created attributes
202 return 0;
203 }
204 }; // struct StandardAttribRefiner<Simplex<2>,...>
205
211 template<
212 typename Shape_,
213 typename AttribSet_>
214 struct StandardAttribRefineWrapper
215 {
216 typedef AttribSet_ AttribSetType;
217 typedef IndexSetHolder<Shape_> IndexSetHolderType;
218 typedef IndexSet<Shape::FaceTraits<Shape_, 0>::count> IndexSetType;
219
220 static Index refine(
221 AttribSetType& attrib_set_out,
222 const AttribSetType& attrib_set_in,
223 const IndexSetHolderType& index_set_holder_in)
224 {
225 typedef typename Shape::FaceTraits<Shape_, Shape_::dimension-1>::ShapeType FacetType;
226
227 // recursive call of AttribRefineWrapper
228 Index offset = StandardAttribRefineWrapper<FacetType, AttribSet_>
229 ::refine(attrib_set_out, attrib_set_in, index_set_holder_in);
230
231 // get index set of current shape
232 const IndexSetType& index_set_in = index_set_holder_in.
233 template get_index_set_wrapper<Shape_::dimension>().template get_index_set<0>();
234
235 // call AttribRefiner
236 Index num_values = StandardAttribRefiner<Shape_, AttribSet_>
237 ::refine(offset, attrib_set_out, attrib_set_in, index_set_in);
238
239 // validate number of created vertices
240 XASSERTM(num_values == (StandardRefinementTraits<Shape_, 0>::count * index_set_in.get_num_entities()),
241 "AttribRefiner output does not match StdRefTraits prediction");
242
243 // return new offset
244 return offset + num_values;
245 }
246 }; // struct StandardAttribRefineWrapper<...>
247
248 template<typename AttribSet_>
249 struct StandardAttribRefineWrapper<Shape::Vertex, AttribSet_>
250 {
251 typedef AttribSet_ AttribSetType;
252 typedef IndexSetHolder<Shape::Vertex> IndexSetHolderType;
253
254 static Index refine(
255 AttribSetType& attrib_set_out,
256 const AttribSetType& attrib_set_in,
257 const IndexSetHolderType& /*index_set_holder_in*/)
258 {
259 // call AttribRefiner
260 Index num_values = StandardAttribRefiner<Shape::Vertex,AttribSet_>
261 ::refine(0, attrib_set_out, attrib_set_in);
262
263 // validate number of created values
264 XASSERTM(num_values == (StandardRefinementTraits<Shape::Vertex, 0>::count * attrib_set_in.get_num_values()),
265 "AttribRefiner output does not match StdRefTraits prediction");
266
267 // return new offset
268 return num_values;
269 }
270 }; // struct StandardAttribRefineWrapper<Vertex,...>
271 } // namespace Intern
273 } // namespace Geometry
274} // namespace FEAT
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.