FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
refinement_types.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#include <kernel/geometry/intern/adaptive_refinement_utils.hpp>
9#include <kernel/geometry/intern/congruency_mapping.hpp>
10#include <kernel/geometry/intern/face_index_mapping.hpp>
11#include <kernel/geometry/intern/refinement_field.hpp>
12#include <kernel/geometry/subdivision_levels.hpp>
13#include <kernel/shape.hpp>
14
15#include <bitset>
16
17namespace FEAT::Geometry
18{
19 namespace Intern
20 {
21 template<typename Shape_>
22 static std::bitset<Shape::FaceTraits<Shape_, 0>::count>
23 orient_bitset(const std::bitset<Shape::FaceTraits<Shape_, 0>::count>& bits, int orientation)
24 {
25 using CongruencyMapping = CongruencyMapping<Shape_, 0>;
26 static constexpr const int num_bits = Shape::FaceTraits<Shape_, 0>::count;
27
28 std::bitset<num_bits> result = 0;
29
30 for(int current_bit = 0; current_bit < num_bits; current_bit++)
31 {
32 if(bits[std::size_t(current_bit)])
33 {
34 std::size_t mapped_bit = std::size_t(CongruencyMapping::map(orientation, current_bit));
35 result[mapped_bit] = true;
36 }
37 }
38 return result;
39 }
40 } // namespace Intern
41
42 template<typename Shape_>
44 {
45 static constexpr int num_vertices = Shape::FaceTraits<Shape_, 0>::count;
46
47 std::bitset<num_vertices> bits;
48
49 template<typename S_>
50 friend bool operator==(const VertexMarking<S_>&, const VertexMarking<S_>&);
51
52 template<typename S_>
53 friend std::ostream& operator<<(std::ostream&, const VertexMarking<S_>&);
54
55 explicit VertexMarking(std::uint64_t markings) : bits(markings)
56 {
57 }
58
59 explicit VertexMarking(std::bitset<num_vertices> markings) : bits(markings)
60 {
61 }
62
63 explicit VertexMarking(const SubdivisionLevelTuple<num_vertices>& tuple) : bits(0)
64 {
65 for(int i = 0; i < num_vertices; i++)
66 {
67 bits[i] = (tuple[i] > 0);
68 }
69 }
70
71 static VertexMarking all_marked()
72 {
73 return VertexMarking((1ULL << (std::size_t)num_vertices) - 1ULL);
74 }
75
76 bool covers(const VertexMarking& other) const
77 {
78 // We cover other, if no bits in other are set, that are not already set for us
79 return (bits | other.bits) == bits;
80 }
81
82 bool is_vertex_marked(int vertex) const
83 {
84 ASSERT(vertex < num_vertices);
85 return bits[std::size_t(vertex)];
86 }
87
88 std::size_t distance(const VertexMarking& other) const
89 {
90 return (bits ^ other.bits).count();
91 }
92 };
93
94 template<typename Shape_>
95 bool operator==(const VertexMarking<Shape_>& lhs, const VertexMarking<Shape_>& rhs)
96 {
97 return lhs._markings == rhs._markings;
98 }
99
100 template<typename Shape_>
101 bool operator!=(const VertexMarking<Shape_>& lhs, const VertexMarking<Shape_>& rhs)
102 {
103 return !(lhs == rhs);
104 }
105
106 template<typename Shape_>
107 std::ostream& operator<<(std::ostream& stream, const VertexMarking<Shape_>& type)
108 {
109 stream << "VertexMarkings<" << Shape_::name() << "> { markings: " << type.bits << " }";
110 return stream;
111 }
112
113 template<typename Shape_>
115 {
116 static constexpr int num_vertices = Shape::FaceTraits<Shape_, 0>::count;
117
118 std::bitset<num_vertices> _type;
119
120 template<typename S_>
121 friend bool operator==(const StandardRefinementType<S_>&, const StandardRefinementType<S_>&);
122
123 template<typename S_>
124 friend std::ostream& operator<<(std::ostream&, const StandardRefinementType<S_>&);
125
126 template<typename T_>
127 friend struct std::hash;
128
129 public:
130 explicit StandardRefinementType(std::uint64_t type) : _type(type)
131 {
132 }
133
134 explicit StandardRefinementType(std::bitset<num_vertices> bits) : _type(bits)
135 {
136 }
137
138 explicit StandardRefinementType(VertexMarking<Shape_> markings) : _type(markings.bits)
139 {
140 }
141
142 explicit StandardRefinementType(
143 const Intern::template RefinementFieldTuple<std::uint64_t, num_vertices>& markings) :
144 _type(0)
145 {
146 for(int i = 0; i < num_vertices; i++)
147 {
148 _type[std::size_t(i)] = (markings[i] > 0);
149 }
150 }
151
152 bool is_full_refinement() const
153 {
154 return _type.all();
155 }
156
157 bool is_zero_refinement() const
158 {
159 return _type.none();
160 }
161
162 template<int dim_>
164 {
165 using FaceShape = typename Shape::FaceTraits<Shape_, dim_>::ShapeType;
166 using Mapping = Intern::FaceIndexMapping<Shape_, dim_, 0>;
167
168 static constexpr const int num_verts = Shape::FaceTraits<FaceShape, 0>::count;
169
170 std::bitset<num_verts> result;
171 for(int i(0); i < num_verts; i++)
172 {
173 auto vertex = static_cast<Index>(Mapping::map(face, i));
174 result[std::size_t(i)] = _type[vertex];
175 }
176
178 }
179
180 StandardRefinementType rotate_2d() const
181 {
182 return StandardRefinementType(Intern::rotate_arraylike_2d(_type));
183 }
184
185 StandardRefinementType rotate_xaxis() const
186 {
187 return StandardRefinementType(Intern::rotate_arraylike_xaxis(_type));
188 }
189
190 StandardRefinementType rotate_yaxis() const
191 {
192 return StandardRefinementType(Intern::rotate_arraylike_yaxis(_type));
193 }
194
195 StandardRefinementType rotate_zaxis() const
196 {
197 return StandardRefinementType(Intern::rotate_arraylike_zaxis(_type));
198 }
199
200 StandardRefinementType orient(int orientation) const
201 {
202 return StandardRefinementType(Intern::orient_bitset<Shape_>(_type, orientation));
203 }
204
205 VertexMarking<Shape_> to_vertex_marking() const
206 {
207 return VertexMarking<Shape_>(_type);
208 }
209
210 Index to_number() const
211 {
212 return _type.to_ulong();
213 }
214
215 Index num_marked() const
216 {
217 return _type.count();
218 }
219 };
220
221 template<typename Shape_>
222 bool operator==(const StandardRefinementType<Shape_>& lhs, const StandardRefinementType<Shape_>& rhs)
223 {
224 return lhs._type == rhs._type;
225 }
226
227 template<typename Shape_>
228 bool operator!=(const StandardRefinementType<Shape_>& lhs, const StandardRefinementType<Shape_>& rhs)
229 {
230 return !(lhs == rhs);
231 }
232
233 template<typename Shape_>
234 std::ostream& operator<<(std::ostream& stream, const StandardRefinementType<Shape_>& type)
235 {
236 stream << "StandardRefinementType<" << Shape_::name() << "> { type: " << type._type << " }";
237 return stream;
238 }
239
241 {
242 std::uint64_t level = 0;
243 bool is_isolated = false;
244
245 IsolatedPointVertexMarking() = default;
246
247 IsolatedPointVertexMarking(std::uint64_t l, bool i) : level(l), is_isolated(i)
248 {
249 }
250 };
251
252 inline bool operator==(const IsolatedPointVertexMarking& a, const IsolatedPointVertexMarking& b)
253 {
254 return a.level == b.level && a.is_isolated == b.is_isolated;
255 }
256
257 inline bool operator!=(const IsolatedPointVertexMarking& a, const IsolatedPointVertexMarking& b)
258 {
259 return !(a == b);
260 }
261
262 inline std::ostream& operator<<(std::ostream& stream, const IsolatedPointVertexMarking& marking)
263 {
264 stream << "IsolatedPointVertexMarking{ level: " << unsigned(marking.level) << ", is_isolated: " << marking.is_isolated << " }";
265 return stream;
266 }
267
268 template<typename Shape_>
270 {
271 static constexpr int num_vertices = Shape::FaceTraits<Shape_, 0>::count;
272
273 std::bitset<num_vertices> _type;
274 bool _isolated;
275
276 template<typename S_>
277 friend bool operator==(const IsolatedPointRefinementType<S_>&, const IsolatedPointRefinementType<S_>&);
278
279 template<typename S_>
280 friend std::ostream& operator<<(std::ostream&, const IsolatedPointRefinementType<S_>&);
281
282 template<typename T_>
283 friend struct std::hash;
284
285 public:
286 explicit IsolatedPointRefinementType(std::uint64_t type, bool isolated) : _type(type), _isolated(isolated)
287 {
288 }
289
290 explicit IsolatedPointRefinementType(std::bitset<num_vertices> bits, bool isolated) :
291 _type(bits),
292 _isolated(isolated)
293 {
294 }
295
296 explicit IsolatedPointRefinementType(VertexMarking<Shape_> markings, bool isolated) :
297 _type(markings.bits),
298 _isolated(isolated)
299 {
300 }
301
303 const Intern::template RefinementFieldTuple<IsolatedPointVertexMarking, num_vertices>& markings) :
304 _type(0),
305 _isolated(false)
306 {
307 for(int i = 0; i < num_vertices; i++)
308 {
309 _type[std::size_t(i)] = (markings[i].level > 0);
310 _isolated = _isolated || markings[i].is_isolated;
311 }
312 }
313
314 bool is_full_refinement() const
315 {
316 return _type.all();
317 }
318
319 bool is_zero_refinement() const
320 {
321 return _type.none();
322 }
323
324 template<int dim_>
326 {
327 using FaceShape = typename Shape::FaceTraits<Shape_, dim_>::ShapeType;
328 using Mapping = Intern::FaceIndexMapping<Shape_, dim_, 0>;
329
330 static constexpr const int num_verts = Shape::FaceTraits<FaceShape, 0>::count;
331
332 std::bitset<num_verts> result_bits;
333
334 for(int i(0); i < num_verts; i++)
335 {
336 auto vertex = static_cast<Index>(Mapping::map(face, i));
337 result_bits[std::size_t(i)] = _type[vertex];
338 }
339
340 // Result type has same isolation as us, as long as we picked any marked vertices
341 return IsolatedPointRefinementType<FaceShape>(result_bits, _isolated && result_bits.any());
342 }
343
344 IsolatedPointRefinementType rotate_2d() const
345 {
346 return IsolatedPointRefinementType(Intern::rotate_arraylike_2d(_type), _isolated);
347 }
348
349 IsolatedPointRefinementType rotate_xaxis() const
350 {
351 return IsolatedPointRefinementType(Intern::rotate_arraylike_xaxis(_type), _isolated);
352 }
353
354 IsolatedPointRefinementType rotate_yaxis() const
355 {
356 return IsolatedPointRefinementType(Intern::rotate_arraylike_yaxis(_type), _isolated);
357 }
358
359 IsolatedPointRefinementType rotate_zaxis() const
360 {
361 return IsolatedPointRefinementType(Intern::rotate_arraylike_zaxis(_type), _isolated);
362 }
363
364 IsolatedPointRefinementType orient(int orientation) const
365 {
366 return IsolatedPointRefinementType(Intern::orient_bitset<Shape_>(_type, orientation), _isolated);
367 }
368
369 VertexMarking<Shape_> to_vertex_marking() const
370 {
371 return VertexMarking<Shape_>(_type);
372 }
373
374 Index to_number() const
375 {
376 return _type.to_ulong();
377 }
378
379 Index num_marked() const
380 {
381 return _type.count();
382 }
383 };
384
385 template<typename Shape_>
387 {
388 return lhs._type == rhs._type && lhs._isolated == rhs._isolated;
389 }
390
391 template<typename Shape_>
392 bool operator!=(const IsolatedPointRefinementType<Shape_>& lhs, const IsolatedPointRefinementType<Shape_>& rhs)
393 {
394 return !(lhs == rhs);
395 }
396
397 template<typename Shape_>
398 std::ostream& operator<<(std::ostream& stream, const IsolatedPointRefinementType<Shape_>& type)
399 {
400 stream << "IsolatedPointRefinementType<" << Shape_::name() << "> { type: " << type._type
401 << ", isolated: " << stringify(type._isolated) << " }";
402 return stream;
403 }
404
405} // namespace FEAT::Geometry
406
407namespace std
408{
409 template<typename Shape_>
410 struct hash<FEAT::Geometry::StandardRefinementType<Shape_>>
411 {
412 static constexpr int num_vertices = FEAT::Shape::template FaceTraits<Shape_, 0>::count;
413
414 std::size_t operator()(const FEAT::Geometry::StandardRefinementType<Shape_>& type) const
415 {
416 return std::hash<std::bitset<num_vertices>>{}(type._type);
417 }
418 };
419
420 template<typename Shape_>
421 struct hash<FEAT::Geometry::IsolatedPointRefinementType<Shape_>>
422 {
423 static constexpr int num_vertices = FEAT::Shape::template FaceTraits<Shape_, 0>::count;
424
425 std::size_t operator()(const FEAT::Geometry::IsolatedPointRefinementType<Shape_>& type) const
426 {
427 auto h1 = std::hash<std::bitset<num_vertices>>{}(type._type);
428 auto h2 = std::hash<bool>{}(type._isolated);
429 return h1 ^ (h2 << 1UL);
430 }
431 };
432} // namespace std
#define ASSERT(expr)
Debug-Assertion macro definition.
Definition: assertion.hpp:229
Geometry namespace.
@ other
generic/other permutation strategy
FEAT namespace.
Definition: adjactor.hpp:12
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:993
std::uint64_t Index
Index data type.
Tuple-type for SubdivisionLevels.
Face traits tag struct template.
Definition: shape.hpp:106