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[current_bit])
33 {
34 int mapped_bit = 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[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[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[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
216 template<typename Shape_>
217 bool operator==(const StandardRefinementType<Shape_>& lhs, const StandardRefinementType<Shape_>& rhs)
218 {
219 return lhs._type == rhs._type;
220 }
221
222 template<typename Shape_>
223 bool operator!=(const StandardRefinementType<Shape_>& lhs, const StandardRefinementType<Shape_>& rhs)
224 {
225 return !(lhs == rhs);
226 }
227
228 template<typename Shape_>
229 std::ostream& operator<<(std::ostream& stream, const StandardRefinementType<Shape_>& type)
230 {
231 stream << "StandardRefinementType<" << Shape_::name() << "> { type: " << type._type << " }";
232 return stream;
233 }
234
236 {
237 std::uint64_t level = 0;
238 bool is_isolated = false;
239
240 IsolatedPointVertexMarking() = default;
241
242 IsolatedPointVertexMarking(std::uint64_t l, bool i) : level(l), is_isolated(i)
243 {
244 }
245 };
246
247 inline bool operator==(const IsolatedPointVertexMarking& a, const IsolatedPointVertexMarking& b)
248 {
249 return a.level == b.level && a.is_isolated == b.is_isolated;
250 }
251
252 inline bool operator!=(const IsolatedPointVertexMarking& a, const IsolatedPointVertexMarking& b)
253 {
254 return !(a == b);
255 }
256
257 inline std::ostream& operator<<(std::ostream& stream, const IsolatedPointVertexMarking& marking)
258 {
259 stream << "IsolatedPointVertexMarking{ level: " << unsigned(marking.level) << ", is_isolated: " << marking.is_isolated << " }";
260 return stream;
261 }
262
263 template<typename Shape_>
265 {
266 static constexpr int num_vertices = Shape::FaceTraits<Shape_, 0>::count;
267
268 std::bitset<num_vertices> _type;
269 bool _isolated;
270
271 template<typename S_>
272 friend bool operator==(const IsolatedPointRefinementType<S_>&, const IsolatedPointRefinementType<S_>&);
273
274 template<typename S_>
275 friend std::ostream& operator<<(std::ostream&, const IsolatedPointRefinementType<S_>&);
276
277 template<typename T_>
278 friend struct std::hash;
279
280 public:
281 explicit IsolatedPointRefinementType(std::uint64_t type, bool isolated) : _type(type), _isolated(isolated)
282 {
283 }
284
285 explicit IsolatedPointRefinementType(std::bitset<num_vertices> bits, bool isolated) :
286 _type(bits),
287 _isolated(isolated)
288 {
289 }
290
291 explicit IsolatedPointRefinementType(VertexMarking<Shape_> markings, bool isolated) :
292 _type(markings.bits),
293 _isolated(isolated)
294 {
295 }
296
298 const Intern::template RefinementFieldTuple<IsolatedPointVertexMarking, num_vertices>& markings) :
299 _type(0),
300 _isolated(false)
301 {
302 for(Index i = 0; i < num_vertices; i++)
303 {
304 _type[i] = (markings[i].level > 0);
305 _isolated = _isolated || markings[i].is_isolated;
306 }
307 }
308
309 bool is_full_refinement() const
310 {
311 return _type.all();
312 }
313
314 bool is_zero_refinement() const
315 {
316 return _type.none();
317 }
318
319 template<int dim_>
321 {
322 using FaceShape = typename Shape::FaceTraits<Shape_, dim_>::ShapeType;
323 using Mapping = Intern::FaceIndexMapping<Shape_, dim_, 0>;
324
325 static constexpr const int num_verts = Shape::FaceTraits<FaceShape, 0>::count;
326
327 std::bitset<num_verts> result_bits;
328
329 for(int i(0); i < num_verts; i++)
330 {
331 auto vertex = static_cast<Index>(Mapping::map(face, i));
332 result_bits[i] = _type[vertex];
333 }
334
335 // Result type has same isolation as us, as long as we picked any marked vertices
336 return IsolatedPointRefinementType<FaceShape>(result_bits, _isolated && result_bits.any());
337 }
338
339 IsolatedPointRefinementType rotate_2d() const
340 {
341 return IsolatedPointRefinementType(Intern::rotate_arraylike_2d(_type), _isolated);
342 }
343
344 IsolatedPointRefinementType rotate_xaxis() const
345 {
346 return IsolatedPointRefinementType(Intern::rotate_arraylike_xaxis(_type), _isolated);
347 }
348
349 IsolatedPointRefinementType rotate_yaxis() const
350 {
351 return IsolatedPointRefinementType(Intern::rotate_arraylike_yaxis(_type), _isolated);
352 }
353
354 IsolatedPointRefinementType rotate_zaxis() const
355 {
356 return IsolatedPointRefinementType(Intern::rotate_arraylike_zaxis(_type), _isolated);
357 }
358
359 IsolatedPointRefinementType orient(int orientation) const
360 {
361 return IsolatedPointRefinementType(Intern::orient_bitset<Shape_>(_type, orientation), _isolated);
362 }
363
364 VertexMarking<Shape_> to_vertex_marking() const
365 {
366 return VertexMarking<Shape_>(_type);
367 }
368
369 Index to_number() const
370 {
371 return _type.to_ulong();
372 }
373 };
374
375 template<typename Shape_>
377 {
378 return lhs._type == rhs._type && lhs._isolated == rhs._isolated;
379 }
380
381 template<typename Shape_>
382 bool operator!=(const IsolatedPointRefinementType<Shape_>& lhs, const IsolatedPointRefinementType<Shape_>& rhs)
383 {
384 return !(lhs == rhs);
385 }
386
387 template<typename Shape_>
388 std::ostream& operator<<(std::ostream& stream, const IsolatedPointRefinementType<Shape_>& type)
389 {
390 stream << "IsolatedPointRefinementType<" << Shape_::name() << "> { type: " << type._type
391 << ", isolated: " << stringify(type._isolated) << " }";
392 return stream;
393 }
394
395} // namespace FEAT::Geometry
396
397namespace std
398{
399 template<typename Shape_>
400 struct hash<FEAT::Geometry::StandardRefinementType<Shape_>>
401 {
402 static constexpr int num_vertices = FEAT::Shape::template FaceTraits<Shape_, 0>::count;
403
404 std::size_t operator()(const FEAT::Geometry::StandardRefinementType<Shape_>& type) const
405 {
406 return std::hash<std::bitset<num_vertices>>{}(type._type);
407 }
408 };
409
410 template<typename Shape_>
411 struct hash<FEAT::Geometry::IsolatedPointRefinementType<Shape_>>
412 {
413 static constexpr int num_vertices = FEAT::Shape::template FaceTraits<Shape_, 0>::count;
414
415 std::size_t operator()(const FEAT::Geometry::IsolatedPointRefinementType<Shape_>& type) const
416 {
417 auto h1 = std::hash<std::bitset<num_vertices>>{}(type._type);
418 auto h2 = std::hash<bool>{}(type._isolated);
419 return h1 ^ (h2 << 1UL);
420 }
421 };
422} // 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:944
std::uint64_t Index
Index data type.
Tuple-type for SubdivisionLevels.
Face traits tag struct template.
Definition: shape.hpp:106