AutoPas  3.0.0
Loading...
Searching...
No Matches
OctreeDirection.h
Go to the documentation of this file.
1
8#pragma once
9
10namespace autopas::octree {
11
15using Any = int unsigned;
16
20enum Face : Any {
21 O = 0, // omega/unknown
22 L = 1,
23 R = 2,
24 D = 3,
25 U = 4,
26 B = 5,
27 F = 6,
28};
29
37template <Face f1, Face f2>
38static constexpr Any buildEdge() {
39 static_assert(f1 != f2, "Faces must be different");
40 return (f1 << 3) | f2;
41}
42
51template <Face f1, Face f2, Face f3>
52static constexpr Any buildVertex() {
53 static_assert((f1 != f2) and (f2 != f3), "Faces must be different");
54 return (f1 << 6) | (f2 << 3) | f3;
55}
56
60enum Edge : Any {
61 OO = 0, // omega/unknown
62 LD = buildEdge<L, D>(),
63 LU = buildEdge<L, U>(),
64 LB = buildEdge<L, B>(),
65 LF = buildEdge<L, F>(),
66 RD = buildEdge<R, D>(),
67 RU = buildEdge<R, U>(),
68 RB = buildEdge<R, B>(),
69 RF = buildEdge<R, F>(),
70 DB = buildEdge<D, B>(),
71 DF = buildEdge<D, F>(),
72 UB = buildEdge<U, B>(),
73 UF = buildEdge<U, F>(),
74};
75
79enum Vertex : Any {
80 OOO = 0, // omega/unknown
81 LDB = buildVertex<L, D, B>(),
82 LDF = buildVertex<L, D, F>(),
83 LUB = buildVertex<L, U, B>(),
84 LUF = buildVertex<L, U, F>(),
85 RDB = buildVertex<R, D, B>(),
86 RDF = buildVertex<R, D, F>(),
87 RUB = buildVertex<R, U, B>(),
88 RUF = buildVertex<R, U, F>(),
89};
90
94namespace Tables {
98constexpr static std::array<Face, 6> faces = {L, R, D, U, B, F};
99
103constexpr static std::array<Edge, 12> edges = {LD, LU, LB, LF, RD, RU, RB, RF, DB, DF, UB, UF};
104
108constexpr static std::array<Vertex, 8> vertices = {LDB, LDF, LUB, LUF, RDB, RDF, RUB, RUF};
109} // namespace Tables
110
117inline int vertexToIndex(Vertex vertex) {
118 // @todo This is very slow and could be sped up.
119 // Mentioned in https://github.com/AutoPas/AutoPas/issues/623
120 int result = -1;
121 for (int i = 0; i < 8; ++i) {
122 if (vertex == Tables::vertices[i]) {
123 result = i;
124 break;
125 }
126 }
127 return result;
128}
129
134
141template <typename T>
142inline bool isFace(T f) {
143 return std::find(Tables::faces.begin(), Tables::faces.end(), f) != Tables::faces.end();
144}
145
153template <typename T>
154inline bool isEdge(T e) {
155 return std::find(Tables::edges.begin(), Tables::edges.end(), e) != Tables::edges.end();
156}
157
165template <typename T>
166inline bool isVertex(T v) {
167 return std::find(Tables::vertices.begin(), Tables::vertices.end(), v) != Tables::vertices.end();
168}
169
174namespace {
180constexpr std::array<std::array<bool, 8>, 1 << 9> createADJTable() {
181 std::array<std::array<bool, 8>, 1 << 9> table{};
182 table[L] = {true, true, true, true, false, false, false, false};
183 table[R] = {false, false, false, false, true, true, true, true};
184 table[D] = {true, true, false, false, true, true, false, false};
185 table[U] = {false, false, true, true, false, false, true, true};
186 table[B] = {true, false, true, false, true, false, true, false};
187 table[F] = {false, true, false, true, false, true, false, true};
188 table[LD] = {true, true, false, false, false, false, false, false};
189 table[LU] = {false, false, true, true, false, false, false, false};
190 table[LB] = {true, false, true, false, false, false, false, false};
191 table[LF] = {false, true, false, true, false, false, false, false};
192 table[RD] = {false, false, false, false, true, true, false, false};
193 table[RU] = {false, false, false, false, false, false, true, true};
194 table[RB] = {false, false, false, false, true, false, true, false};
195 table[RF] = {false, false, false, false, false, true, false, true};
196 table[DB] = {true, false, false, false, true, false, false, false};
197 table[DF] = {false, true, false, false, false, true, false, false};
198 table[UB] = {false, false, true, false, false, false, true, false};
199 table[UF] = {false, false, false, true, false, false, false, true};
200 table[LDB] = {true, false, false, false, false, false, false, false};
201 table[LDF] = {false, true, false, false, false, false, false, false};
202 table[LUB] = {false, false, true, false, false, false, false, false};
203 table[LUF] = {false, false, false, true, false, false, false, false};
204 table[RDB] = {false, false, false, false, true, false, false, false};
205 table[RDF] = {false, false, false, false, false, true, false, false};
206 table[RUB] = {false, false, false, false, false, false, true, false};
207 table[RUF] = {false, false, false, false, false, false, false, true};
208 return table;
209}
210
216constexpr std::array<std::array<Octant, 8>, 1 << 9> createREFLECTTable() {
217 std::array<std::array<Octant, 8>, 1 << 9> table{};
218 table[L] = {RDB, RDF, RUB, RUF, LDB, LDF, LUB, LUF};
219 table[R] = {RDB, RDF, RUB, RUF, LDB, LDF, LUB, LUF};
220 table[D] = {LUB, LUF, LDB, LDF, RUB, RUF, RDB, RDF};
221 table[U] = {LUB, LUF, LDB, LDF, RUB, RUF, RDB, RDF};
222 table[B] = {LDF, LDB, LUF, LUB, RDF, RDB, RUF, RUB};
223 table[F] = {LDF, LDB, LUF, LUB, RDF, RDB, RUF, RUB};
224 table[LD] = {RUB, RUF, RDB, RDF, LUB, LUF, LDB, LDF};
225 table[LU] = {RUB, RUF, RDB, RDF, LUB, LUF, LDB, LDF};
226 table[LB] = {RDF, RDB, RUF, RUB, LDF, LDB, LUF, LUB};
227 table[LF] = {RDF, RDB, RUF, RUB, LDF, LDB, LUF, LUB};
228 table[RD] = {RUB, RUF, RDB, RDF, LUB, LUF, LDB, LDF};
229 table[RU] = {RUB, RUF, RDB, RDF, LUB, LUF, LDB, LDF};
230 table[RB] = {RDF, RDB, RUF, RUB, LDF, LDB, LUF, LUB};
231 table[RF] = {RDF, RDB, RUF, RUB, LDF, LDB, LUF, LUB};
232 table[DB] = {LUF, LUB, LDF, LDB, RUF, RUB, RDF, RDB};
233 table[DF] = {LUF, LUB, LDF, LDB, RUF, RUB, RDF, RDB};
234 table[UB] = {LUF, LUB, LDF, LDB, RUF, RUB, RDF, RDB};
235 table[UF] = {LUF, LUB, LDF, LDB, RUF, RUB, RDF, RDB};
236 table[LDB] = {RUF, RUB, RDF, RDB, LUF, LUB, LDF, LDB};
237 table[LDF] = {RUF, RUB, RDF, RDB, LUF, LUB, LDF, LDB};
238 table[LUB] = {RUF, RUB, RDF, RDB, LUF, LUB, LDF, LDB};
239 table[LUF] = {RUF, RUB, RDF, RDB, LUF, LUB, LDF, LDB};
240 table[RDB] = {RUF, RUB, RDF, RDB, LUF, LUB, LDF, LDB};
241 table[RDF] = {RUF, RUB, RDF, RDB, LUF, LUB, LDF, LDB};
242 table[RUB] = {RUF, RUB, RDF, RDB, LUF, LUB, LDF, LDB};
243 table[RUF] = {RUF, RUB, RDF, RDB, LUF, LUB, LDF, LDB};
244 return table;
245}
246
252constexpr std::array<std::array<Face, 8>, 1 << 9> createCOMMONFACETable() {
253 std::array<std::array<Face, 8>, 1 << 9> table{};
254 table[LD] = {O, O, L, L, D, D, O, O};
255 table[LU] = {L, L, O, O, O, O, U, U};
256 table[LB] = {O, L, O, L, B, O, B, O};
257 table[LF] = {L, O, L, O, O, F, O, F};
258 table[RD] = {D, D, O, O, O, O, R, R};
259 table[RU] = {O, O, U, U, R, R, O, O};
260 table[RB] = {B, O, B, O, O, R, O, R};
261 table[RF] = {O, F, O, F, R, O, R, O};
262 table[DB] = {O, D, B, O, O, D, B, O};
263 table[DF] = {D, O, O, F, D, O, O, F};
264 table[UB] = {B, O, O, U, B, O, O, U};
265 table[UF] = {O, F, U, O, O, F, U, O};
266 table[LDB] = {O, O, O, L, O, D, B, O};
267 table[LDF] = {O, O, L, O, D, O, O, F};
268 table[LUB] = {O, L, O, O, B, O, O, U};
269 table[LUF] = {L, O, O, O, O, F, U, O};
270 table[RDB] = {O, D, B, O, O, O, O, R};
271 table[RDF] = {D, O, O, F, O, O, R, O};
272 table[RUB] = {B, O, O, U, O, R, O, O};
273 table[RUF] = {O, F, U, O, R, O, O, O};
274 return table;
275}
276
282constexpr std::array<std::array<Edge, 8>, 1 << 9> createCOMMONEDGETable() {
283 std::array<std::array<Edge, 8>, 1 << 9> table{};
284 table[LDB] = {OO, LD, LB, OO, DB, OO, OO, OO};
285 table[LDF] = {LD, OO, OO, LF, OO, DF, OO, OO};
286 table[LUB] = {LB, OO, OO, LU, OO, OO, UB, OO};
287 table[LUF] = {OO, LF, LU, OO, OO, OO, OO, UF};
288 table[RDB] = {DB, OO, OO, OO, OO, RD, RB, OO};
289 table[RDF] = {OO, DF, OO, OO, RD, OO, OO, RF};
290 table[RUB] = {OO, OO, UB, OO, RB, OO, OO, RU};
291 table[RUF] = {OO, OO, OO, UF, OO, RF, RU, OO};
292 return table;
293}
294
300constexpr std::array<Any, 1 << 9> createOppositeDirectionTable() {
301 std::array<Any, 1 << 9> table{};
302 table[L] = R;
303 table[R] = L;
304 table[D] = U;
305 table[U] = D;
306 table[B] = F;
307 table[F] = B;
308 table[LD] = RU;
309 table[LU] = RD;
310 table[LB] = RF;
311 table[LF] = RB;
312 table[RD] = LU;
313 table[RU] = LD;
314 table[RB] = LF;
315 table[RF] = LB;
316 table[DB] = UF;
317 table[DF] = UB;
318 table[UB] = DF;
319 table[UF] = DB;
320 table[LDB] = RUF;
321 table[LDF] = RUB;
322 table[LUB] = RDF;
323 table[LUF] = RDB;
324 table[RDB] = LUF;
325 table[RDF] = LUB;
326 table[RUB] = LDF;
327 table[RUF] = LDB;
328 return table;
329}
330
336constexpr std::array<std::array<Octant, 5>, 1 << 9> createAllowedDirectionsTable() {
337 std::array<std::array<Octant, 5>, 1 << 9> table{};
338 table[L] = {LDB, LDF, LUB, LUF, OOO};
339 table[R] = {RDB, RDF, RUB, RUF, OOO};
340 table[D] = {LDB, LDF, RDB, RDF, OOO};
341 table[U] = {LUB, LUF, RUB, RUF, OOO};
342 table[B] = {LDB, LUB, RDB, RUB, OOO};
343 table[F] = {LDF, LUF, RDF, RUF, OOO};
344 table[LD] = {LDB, LDF, OOO, OOO, OOO};
345 table[LU] = {LUB, LUF, OOO, OOO, OOO};
346 table[LB] = {LDB, LUB, OOO, OOO, OOO};
347 table[LF] = {LDF, LUF, OOO, OOO, OOO};
348 table[RD] = {RDB, RDF, OOO, OOO, OOO};
349 table[RU] = {RUB, RUF, OOO, OOO, OOO};
350 table[RB] = {RDB, RUB, OOO, OOO, OOO};
351 table[RF] = {RDF, RUF, OOO, OOO, OOO};
352 table[DB] = {LDB, RDB, OOO, OOO, OOO};
353 table[DF] = {LDF, RDF, OOO, OOO, OOO};
354 table[UB] = {LUB, RUB, OOO, OOO, OOO};
355 table[UF] = {LUF, RUF, OOO, OOO, OOO};
356 table[LDB] = {LDB, OOO, OOO, OOO, OOO};
357 table[LDF] = {LDF, OOO, OOO, OOO, OOO};
358 table[LUB] = {LUB, OOO, OOO, OOO, OOO};
359 table[LUF] = {LUF, OOO, OOO, OOO, OOO};
360 table[RDB] = {RDB, OOO, OOO, OOO, OOO};
361 table[RDF] = {RDF, OOO, OOO, OOO, OOO};
362 table[RUB] = {RUB, OOO, OOO, OOO, OOO};
363 table[RUF] = {RUF, OOO, OOO, OOO, OOO};
364 return table;
365}
366
370constexpr std::array<std::array<bool, 8>, 1 << 9> adjTable = createADJTable();
371
375constexpr std::array<std::array<Octant, 8>, 1 << 9> reflectTable = createREFLECTTable();
376
380constexpr std::array<std::array<Face, 8>, 1 << 9> commonFaceTable = createCOMMONFACETable();
381
385constexpr std::array<std::array<Edge, 8>, 1 << 9> commonEdgeTable = createCOMMONEDGETable();
386
390constexpr std::array<Any, 1 << 9> oppositeDirectionTable = createOppositeDirectionTable();
391
395constexpr std::array<std::array<Octant, 5>, 1 << 9> allowedDirectionsTable = createAllowedDirectionsTable();
396} // namespace
397
406inline bool ADJ(Any direction, Vertex octant) {
407 // Check the argument preconditions
408 if ((not isFace(direction)) and (not isEdge(direction)) and (not isVertex(direction))) {
409 throw std::runtime_error("[OctreeDirection.h] Received invalid direction");
410 }
411
412 if (not isVertex(octant)) {
413 throw std::runtime_error("[OctreeDirection.h] Received invalid octant");
414 }
415
416 int flatOctant = vertexToIndex(octant);
417 bool result = adjTable[direction][flatOctant];
418 return result;
419}
420
430inline Octant REFLECT(Any direction, Octant octant) {
431 // Check the argument preconditions
432 if ((not isFace(direction)) and (not isEdge(direction)) and (not isVertex(direction))) {
433 throw std::runtime_error("[OctreeDirection.h] Received invalid direction");
434 }
435
436 if (not isVertex(octant)) {
437 throw std::runtime_error("[OctreeDirection.h] Received invalid octant");
438 }
439
440 int flatOctant = vertexToIndex(octant);
441 Octant result = reflectTable[direction][flatOctant];
442 return result;
443}
444
454inline Face COMMON_FACE(Any direction, Vertex octant) {
455 // Check the argument preconditions
456 if ((not isEdge(direction)) and (not isVertex(direction))) {
457 throw std::runtime_error("[OctreeDirection.h] Received invalid direction");
458 }
459
460 if (not isVertex(octant)) {
461 throw std::runtime_error("[OctreeDirection.h] Received invalid octant");
462 }
463
464 int flatOctant = vertexToIndex(octant);
465 Face result = commonFaceTable[direction][flatOctant];
466 return result;
467}
468
478inline Edge COMMON_EDGE(Any direction, Vertex octant) {
479 // Check the argument preconditions
480 if (not isVertex(direction)) {
481 throw std::runtime_error("[OctreeDirection.h] Received invalid direction");
482 }
483
484 if (not isVertex(octant)) {
485 throw std::runtime_error("[OctreeDirection.h] Received invalid octant");
486 }
487
488 int flatOctant = vertexToIndex(octant);
489 Edge result = commonEdgeTable[direction][flatOctant];
490
491 if (not(isEdge(result) or result == OO)) {
492 throw std::runtime_error("[OctreeDirection.h] Invalid output");
493 }
494
495 return result;
496}
497
504inline Any getOppositeDirection(Any direction) {
505 using namespace autopas;
506
507 if ((not isFace(direction)) and (not isEdge(direction)) and (not isVertex(direction))) {
508 throw std::runtime_error("[OctreeDirection.h] Received invalid direction");
509 }
510
511 Any result = oppositeDirectionTable[direction];
512
513 if (not(isFace(result) or isEdge(result) or isVertex(result))) {
514 throw std::runtime_error("[OctreeDirection.h] Invalid output");
515 }
516
517 return result;
518}
519
526inline std::vector<Octant> getAllowedDirections(Any along) {
527 using namespace autopas;
528
529 if ((not isFace(along)) and (not isEdge(along)) and (not isVertex(along))) {
530 throw std::runtime_error("[OctreeDirection.h] Received invalid direction");
531 }
532
533 auto resultWithOOO = allowedDirectionsTable[along];
534 std::vector<Octant> result;
535 // At most, there should be 4 elements in the result vector.
536 result.reserve(4);
537 for (auto v : resultWithOOO) {
538 if (v == OOO) break;
539 result.push_back(v);
540 }
541
542 // Check post-conditions
543 for (auto v : result) {
544 if (not isVertex(v)) {
545 throw std::runtime_error("[OctreeDirection.h] Result contains an illegal vertex.");
546 }
547 }
548
549 return result;
550}
551
552} // namespace autopas::octree
static constexpr std::array< Face, 6 > faces
All available faces for a cube.
Definition: OctreeDirection.h:98
static constexpr std::array< Edge, 12 > edges
All available edges for a cube.
Definition: OctreeDirection.h:103
static constexpr std::array< Vertex, 8 > vertices
All available vertices for a cube.
Definition: OctreeDirection.h:108
constexpr std::array< std::array< bool, 8 >, 1<< 9 > adjTable
A LUT containing the entries for ADJ().
Definition: OctreeDirection.h:370
constexpr std::array< std::array< Octant, 8 >, 1<< 9 > reflectTable
A LUT containing the entries for REFLECT().
Definition: OctreeDirection.h:375
constexpr std::array< std::array< Face, 8 >, 1<< 9 > commonFaceTable
A LUT containing the entries for COMMON_FACE().
Definition: OctreeDirection.h:380
constexpr std::array< std::array< Octant, 5 >, 1<< 9 > allowedDirectionsTable
A LUT containing the entries for getAllowedDirections().
Definition: OctreeDirection.h:395
constexpr std::array< Any, 1<< 9 > createOppositeDirectionTable()
A constexpr for creating the table for getOppositeDirection().
Definition: OctreeDirection.h:300
constexpr std::array< Any, 1<< 9 > oppositeDirectionTable
A LUT containing the entries for getOppositeDirection().
Definition: OctreeDirection.h:390
constexpr std::array< std::array< Edge, 8 >, 1<< 9 > createCOMMONEDGETable()
A constexpr for creating the table for COMMON_EDGE().
Definition: OctreeDirection.h:282
constexpr std::array< std::array< Edge, 8 >, 1<< 9 > commonEdgeTable
A LUT containing the entries for COMMON_EDGE().
Definition: OctreeDirection.h:385
constexpr std::array< std::array< bool, 8 >, 1<< 9 > createADJTable()
A constexpr for creating the table for ADJ().
Definition: OctreeDirection.h:180
constexpr std::array< std::array< Octant, 8 >, 1<< 9 > createREFLECTTable()
A constexpr for creating the table for REFLECT().
Definition: OctreeDirection.h:216
constexpr std::array< std::array< Octant, 5 >, 1<< 9 > createAllowedDirectionsTable()
A constexpr for creating the table for getAllowedDirections().
Definition: OctreeDirection.h:336
constexpr std::array< std::array< Face, 8 >, 1<< 9 > createCOMMONFACETable()
A constexpr for creating the table for COMMON_FACE().
Definition: OctreeDirection.h:252
Namespace that contains code that is used by the octree internally.
Definition: OctreeDirection.h:10
Octant REFLECT(Any direction, Octant octant)
This function implements a LUT obtained from the Samet paper: "REFLECT(I,O) yields the SONTYPE value ...
Definition: OctreeDirection.h:430
bool isFace(T f)
Check if f is a face.
Definition: OctreeDirection.h:142
int unsigned Any
A datatype that is wide enough to hold faces, edges or vertices.
Definition: OctreeDirection.h:15
Edge COMMON_EDGE(Any direction, Vertex octant)
This function implements a LUT obtained from the Samet paper: "COMMON_EDGE(I,O) yields the type of th...
Definition: OctreeDirection.h:478
std::vector< Octant > getAllowedDirections(Any along)
Get a list of octants that are along the given direction.
Definition: OctreeDirection.h:526
bool ADJ(Any direction, Vertex octant)
This function implements a LUT obtained from the Samet paper: "ADJ(I,O) is true if and only if octant...
Definition: OctreeDirection.h:406
Vertex
This enum can be used to index all vertices of a cube including an "invalid" vertex.
Definition: OctreeDirection.h:79
Edge
This enum can be used to index all edges of a cube including an "invalid" edge.
Definition: OctreeDirection.h:60
int vertexToIndex(Vertex vertex)
Map an arbitrary vertex to a flat index.
Definition: OctreeDirection.h:117
Any getOppositeDirection(Any direction)
Convert any direction to a direction that is directly opposing the given direction.
Definition: OctreeDirection.h:504
Face
This enum can be used to index the faces of a cube including an "invalid" face.
Definition: OctreeDirection.h:20
static constexpr Any buildVertex()
Create a bitfield for a vertex given by the template parameters.
Definition: OctreeDirection.h:52
Face COMMON_FACE(Any direction, Vertex octant)
This function implements a LUT obtained from the Samet paper: "COMMON_FACE(I,O) yields the type on th...
Definition: OctreeDirection.h:454
bool isEdge(T e)
Check if e is an edge.
Definition: OctreeDirection.h:154
bool isVertex(T v)
Check if v is a vertex.
Definition: OctreeDirection.h:166
static constexpr Any buildEdge()
Create a bitfield for an edge given by the template parameters.
Definition: OctreeDirection.h:38
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:32