TTK
Loading...
Searching...
No Matches
PeriodicImplicitTriangulation.cpp
Go to the documentation of this file.
2using namespace std;
3using namespace ttk;
4
11
13
15 const float &yOrigin,
16 const float &zOrigin,
17 const float &xSpacing,
18 const float &ySpacing,
19 const float &zSpacing,
20 const SimplexId &xDim,
21 const SimplexId &yDim,
22 const SimplexId &zDim) {
23
24 // Dimensionality //
25 if(xDim < 1 or yDim < 1 or zDim < 1)
26 dimensionality_ = -1;
27 else if(xDim > 1 and yDim > 1 and zDim > 1)
29 else if((xDim > 1 and yDim > 1) or (yDim > 1 and zDim > 1)
30 or (xDim > 1 and zDim > 1))
32 else if(xDim > 1 or yDim > 1 or zDim > 1)
34 else
36
37 // Essentials //
38 origin_[0] = xOrigin;
39 origin_[1] = yOrigin;
40 origin_[2] = zOrigin;
41 spacing_[0] = xSpacing;
42 spacing_[1] = ySpacing;
43 spacing_[2] = zSpacing;
44 dimensions_[0] = xDim;
45 dimensions_[1] = yDim;
46 dimensions_[2] = zDim;
47 nbvoxels_[0] = xDim - 1;
48 nbvoxels_[1] = yDim - 1;
49 nbvoxels_[2] = zDim - 1;
50
51 if(dimensionality_ == 3) {
52 // VertexShift
53 vshift_[0] = xDim;
54 vshift_[1] = xDim * yDim;
55 // EdgeSetDimensions
56 esetdims_[0] = xDim * yDim * zDim;
57 esetdims_[1] = xDim * yDim * zDim;
58 esetdims_[2] = xDim * yDim * zDim;
59 esetdims_[3] = xDim * yDim * zDim;
60 esetdims_[4] = xDim * yDim * zDim;
61 esetdims_[5] = xDim * yDim * zDim;
62 esetdims_[6] = xDim * yDim * zDim;
63 // EdgeSetShift
64 esetshift_[0] = esetdims_[0];
65 for(int k = 1; k < 7; ++k)
66 esetshift_[k] = esetshift_[k - 1] + esetdims_[k];
67 // EdgeShift
68 eshift_[0] = xDim;
69 eshift_[1] = xDim * yDim;
70 eshift_[2] = xDim;
71 eshift_[3] = xDim * yDim;
72 eshift_[4] = xDim;
73 eshift_[5] = xDim * yDim;
74 eshift_[6] = xDim;
75 eshift_[7] = xDim * yDim;
76 eshift_[8] = xDim;
77 eshift_[9] = xDim * yDim;
78 eshift_[10] = xDim;
79 eshift_[11] = xDim * yDim;
80 eshift_[12] = xDim;
81 eshift_[13] = xDim * yDim;
82 // TriangleSetDimensions
83 tsetdims_[0] = xDim * yDim * zDim * 2;
84 tsetdims_[1] = xDim * yDim * zDim * 2;
85 tsetdims_[2] = xDim * yDim * zDim * 2;
86 tsetdims_[3] = xDim * yDim * zDim * 2;
87 tsetdims_[4] = xDim * yDim * zDim * 2;
88 tsetdims_[5] = xDim * yDim * zDim * 2;
89 // TriangleSetShift
90 tsetshift_[0] = tsetdims_[0];
91 for(int k = 1; k < 6; ++k)
92 tsetshift_[k] = tsetshift_[k - 1] + tsetdims_[k];
93 // TriangleShift
94 tshift_[0] = xDim * 2;
95 tshift_[1] = xDim * yDim * 2;
96 tshift_[2] = xDim * 2;
97 tshift_[3] = xDim * yDim * 2;
98 tshift_[4] = xDim * 2;
99 tshift_[5] = xDim * yDim * 2;
100 tshift_[6] = xDim * 2;
101 tshift_[7] = xDim * yDim * 2;
102 tshift_[8] = xDim * 2;
103 tshift_[9] = xDim * yDim * 2;
104 tshift_[10] = xDim * 2;
105 tshift_[11] = xDim * yDim * 2;
106 // TetrahedronShift
107 tetshift_[0] = xDim * 6;
108 tetshift_[1] = xDim * yDim * 6;
109
110 wrap_[0] = xDim;
111 wrap_[1] = xDim * yDim;
112 wrap_[2] = xDim * yDim * zDim;
113
114 // Numbers
115 vertexNumber_ = xDim * yDim * zDim;
116 edgeNumber_ = 0;
117 for(int k = 0; k < 7; ++k)
119 triangleNumber_ = 0;
120 for(int k = 0; k < 6; ++k)
122 tetrahedronNumber_ = xDim * yDim * zDim * 6;
124
126 } else if(dimensionality_ == 2) {
127 // dimensions selectors
128 if(xDim == 1) {
129 Di_ = 1;
130 Dj_ = 2;
131 } else if(yDim == 1) {
132 Di_ = 0;
133 Dj_ = 2;
134 } else {
135 Di_ = 0;
136 Dj_ = 1;
137 }
138 // VertexShift
139 vshift_[0] = dimensions_[Di_];
140 // EdgeSetDimensions
144 // EdgeSetShift
145 esetshift_[0] = esetdims_[0];
146 for(int k = 1; k < 3; ++k)
147 esetshift_[k] = esetshift_[k - 1] + esetdims_[k];
148 // EdgeShift
149 eshift_[0] = dimensions_[Di_];
150 eshift_[2] = dimensions_[Di_];
151 eshift_[4] = dimensions_[Di_];
152 // TriangleShift
153 tshift_[0] = dimensions_[Di_] * 2;
154
155 wrap_[0] = dimensions_[Di_];
157
158 // Numbers
160 edgeNumber_ = 0;
161 for(int k = 0; k < 3; ++k)
165
167 } else if(dimensionality_ == 1) {
168 // dimensions selectors
169 for(int k = 0; k < 3; ++k) {
170 if(dimensions_[k] > 1) {
171 Di_ = k;
172 break;
173 }
174 }
175
176 // Numbers
180 }
181
182 return 0;
183}
184
186 isAccelerated_ = false;
187
188 unsigned long long int msb[3];
189 if(dimensionality_ == 3) {
190 bool allDimensionsArePowerOfTwo = true;
191 for(int k = 0; k < 3; ++k)
192 if(!isPowerOfTwo(dimensions_[k], msb[k]))
193 allDimensionsArePowerOfTwo = false;
194
195 if(allDimensionsArePowerOfTwo) {
196 mod_[0] = dimensions_[0] - 1;
197 mod_[1] = dimensions_[0] * dimensions_[1] - 1;
198 div_[0] = msb[0];
199 div_[1] = msb[0] + msb[1];
200 isAccelerated_ = true;
201 }
202 } else if(dimensionality_ == 2) {
203 bool const isDi = isPowerOfTwo(dimensions_[Di_], msb[Di_]);
204 bool const isDj = isPowerOfTwo(dimensions_[Dj_], msb[Dj_]);
205 bool const allDimensionsArePowerOfTwo = (isDi and isDj);
206
207 if(allDimensionsArePowerOfTwo) {
208 mod_[0] = dimensions_[Di_] - 1;
209 div_[0] = msb[Di_];
210 isAccelerated_ = true;
211 }
212 }
213
214 if(isAccelerated_) {
215 printMsg("Accelerated getVertex*() requests.", debug::Priority::INFO);
216 }
217
218 return 0;
219}
220
222 unsigned long long int &r) {
223 if(v && !(v & (v - 1))) {
224 r = 0;
225 while(v >>= 1)
226 r++;
227 return true;
228 }
229 return false;
230}
231
232bool PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
233 isVertexOnBoundary)(const SimplexId &vertexId) const {
234#ifndef TTK_ENABLE_KAMIKAZE
235 if(vertexId < 0 or vertexId >= vertexNumber_)
236 return -1;
237#else
238 TTK_FORCE_USE(vertexId);
239#endif
240
241 return false;
242}
243
244bool PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
245 isEdgeOnBoundary)(const SimplexId &edgeId) const {
246#ifndef TTK_ENABLE_KAMIKAZE
247 if(edgeId < 0 or edgeId >= edgeNumber_)
248 return -1;
249#else
250 TTK_FORCE_USE(edgeId);
251#endif
252
253 return false;
254}
255
256bool PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
257 isTriangleOnBoundary)(const SimplexId &triangleId) const {
258#ifndef TTK_ENABLE_KAMIKAZE
259 if(triangleId < 0 or triangleId >= triangleNumber_)
260 return -1;
261#else
262 TTK_FORCE_USE(triangleId);
263#endif
264
265 return false;
266}
267
268SimplexId PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
269 getVertexNeighborNumber)(const SimplexId &vertexId) const {
270#ifndef TTK_ENABLE_KAMIKAZE
271 if(vertexId < 0 or vertexId >= vertexNumber_)
272 return -1;
273#else
274 TTK_FORCE_USE(vertexId);
275#endif
276
277 if(dimensionality_ == 3) {
278 return 14; // abcdefgh
279 } else if(dimensionality_ == 2) {
280 return 6; // abcd
281 } else if(dimensionality_ == 1) {
282 return 2; // ab
283 }
284
285 return -1;
286}
287
288template <typename Derived>
290 getVertexNeighbor)(const SimplexId &vertexId,
291 const int &localNeighborId,
292 SimplexId &neighborId) const {
293#ifndef TTK_ENABLE_KAMIKAZE
294 if(localNeighborId < 0
295 or localNeighborId >= getVertexNeighborNumber(vertexId))
296 return -1;
297#endif
298
299 neighborId = -1;
300 const auto &p = this->underlying().getVertexCoords(vertexId);
301
302 if(dimensionality_ == 3) {
303 neighborId = getVertexNeighbor3d(p.data(), vertexId, localNeighborId);
304 } else if(dimensionality_ == 2) {
305 neighborId = getVertexNeighbor2d(p.data(), vertexId, localNeighborId);
306 } else if(dimensionality_ == 1) {
307 // ab
308 if(vertexId > 0 and vertexId < nbvoxels_[Di_]) {
309 if(localNeighborId == 0)
310 neighborId = vertexId + 1;
311 else
312 neighborId = vertexId - 1;
313 } else if(vertexId == 0) {
314 if(localNeighborId == 0)
315 neighborId = vertexId + 1; // a
316 else
317 neighborId = nbvoxels_[Di_];
318 } else {
319 if(localNeighborId == 0)
320 neighborId = 0; // a
321 else
322 neighborId = vertexId - 1; // b
323 }
324 }
325
326 return 0;
327}
328
329const vector<vector<SimplexId>> *
330 PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
332 if(vertexNeighborList_.empty()) {
333 Timer t;
334 vertexNeighborList_.resize(vertexNumber_);
335 for(SimplexId i = 0; i < vertexNumber_; ++i) {
336 vertexNeighborList_[i].resize(getVertexNeighborNumber(i));
337 for(SimplexId j = 0; j < (SimplexId)vertexNeighborList_[i].size(); ++j)
338 getVertexNeighbor(i, j, vertexNeighborList_[i][j]);
339 }
340
341 printMsg("Built " + to_string(vertexNumber_) + " vertex neighbors.", 1,
342 t.getElapsedTime(), 1);
343 }
344
345 return &vertexNeighborList_;
346}
347
352
353template <typename Derived>
355 const SimplexId &vertexId, const int &localEdgeId, SimplexId &edgeId) const {
356#ifndef TTK_ENABLE_KAMIKAZE
357 if(localEdgeId < 0 or localEdgeId >= getVertexEdgeNumberInternal(vertexId))
358 return -1;
359#endif
360
361 edgeId = -1;
362 const auto &p = this->underlying().getVertexCoords(vertexId);
363
364 if(dimensionality_ == 3) {
365 edgeId = getVertexEdge3d(p.data(), localEdgeId);
366 } else if(dimensionality_ == 2) {
367 edgeId = getVertexEdge2d(p.data(), localEdgeId);
368 } else if(dimensionality_ == 1) {
369 if(vertexId > 0 and vertexId < nbvoxels_[Di_]) {
370 // ab
371 edgeId = localEdgeId == 0 ? vertexId : vertexId - 1;
372 } else if(vertexId == 0) {
373 // a
374 edgeId = localEdgeId == 0 ? vertexId : 0;
375 } else {
376 // b
377 edgeId = localEdgeId == 0 ? 0 : vertexId - 1;
378 }
379 }
380
381 return 0;
382}
383
384const vector<vector<SimplexId>> *
386 if(vertexEdgeList_.empty()) {
387 Timer t;
388
390 for(SimplexId i = 0; i < vertexNumber_; ++i) {
392 for(SimplexId j = 0; j < (SimplexId)vertexEdgeList_[i].size(); ++j)
394 }
395
396 printMsg("Built " + to_string(vertexNumber_) + " vertex edges.", 1,
397 t.getElapsedTime(), 1);
398 }
399
400 return &vertexEdgeList_;
401}
402
404 const SimplexId &vertexId) const {
405#ifndef TTK_ENABLE_KAMIKAZE
406 if(vertexId < 0 or vertexId >= vertexNumber_)
407 return -1;
408#else
409 TTK_FORCE_USE(vertexId);
410#endif
411
412 if(dimensionality_ == 3) {
413 return 36; // abcdefgh
414 }
415
416 return 0;
417}
418
419template <typename Derived>
421 const SimplexId &vertexId,
422 const int &localTriangleId,
423 SimplexId &triangleId) const {
424#ifndef TTK_ENABLE_KAMIKAZE
425 if(localTriangleId < 0
426 or localTriangleId >= getVertexTriangleNumberInternal(vertexId))
427 return -1;
428#endif
429 triangleId = -1;
430
431 const auto &p = this->underlying().getVertexCoords(vertexId);
432
433 if(dimensionality_ == 3) {
434 triangleId = getVertexTriangle3d(p.data(), localTriangleId);
435 }
436
437 return 0;
438}
439
440const vector<vector<SimplexId>> *
442 if(vertexTriangleList_.empty()) {
443 Timer t;
444
446 for(SimplexId i = 0; i < vertexNumber_; ++i) {
448 for(SimplexId j = 0; j < (SimplexId)vertexTriangleList_[i].size(); ++j)
450 }
451
452 printMsg("Built " + to_string(vertexNumber_) + " vertex triangles.", 1,
453 t.getElapsedTime(), 1);
454 }
455
456 return &vertexTriangleList_;
457}
458
459SimplexId PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
460 getVertexLinkNumber)(const SimplexId &vertexId) const {
461 return getVertexStarNumber(vertexId);
462}
463
464template <typename Derived>
466 getVertexLink)(const SimplexId &vertexId,
467 const int &localLinkId,
468 SimplexId &linkId) const {
469#ifndef TTK_ENABLE_KAMIKAZE
470 if(localLinkId < 0 or localLinkId >= getVertexLinkNumber(vertexId))
471 return -1;
472#endif
473
474 linkId = -1;
475 const auto &p = this->underlying().getVertexCoords(vertexId);
476
477 if(dimensionality_ == 3) {
478 linkId = getVertexLink3d(p.data(), localLinkId);
479 } else if(dimensionality_ == 2) {
480 linkId = getVertexLink2d(p.data(), localLinkId); // abcd
481 }
482
483 return 0;
484}
485
486const vector<vector<SimplexId>> *
487 PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(getVertexLinks)() {
488 if(vertexLinkList_.empty()) {
489 Timer t;
490
491 vertexLinkList_.resize(vertexNumber_);
492 for(SimplexId i = 0; i < vertexNumber_; ++i) {
493 vertexLinkList_[i].resize(getVertexLinkNumber(i));
494 for(SimplexId j = 0; j < (SimplexId)vertexLinkList_[i].size(); ++j)
495 getVertexLink(i, j, vertexLinkList_[i][j]);
496 }
497
498 printMsg("Built " + to_string(vertexNumber_) + " vertex links.", 1,
499 t.getElapsedTime(), 1);
500 }
501
502 return &vertexLinkList_;
503}
504
505SimplexId PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
506 getVertexStarNumber)(const SimplexId &vertexId) const {
507#ifndef TTK_ENABLE_KAMIKAZE
508 if(vertexId < 0 or vertexId >= vertexNumber_)
509 return -1;
510#else
511 TTK_FORCE_USE(vertexId);
512#endif
513
514 if(dimensionality_ == 3) {
515 return 24; // abcdefgh
516 } else if(dimensionality_ == 2) {
517 return 6; // abcd
518 }
519
520 return 0;
521}
522
523template <typename Derived>
525 getVertexStar)(const SimplexId &vertexId,
526 const int &localStarId,
527 SimplexId &starId) const {
528#ifndef TTK_ENABLE_KAMIKAZE
529 if(localStarId < 0 or localStarId >= getVertexStarNumber(vertexId))
530 return -1;
531#endif
532
533 starId = -1;
534 const auto &p = this->underlying().getVertexCoords(vertexId);
535
536 if(dimensionality_ == 3) {
537 starId = getVertexStar3d(p.data(), localStarId);
538 } else if(dimensionality_ == 2) {
539 starId = getVertexStar2d(p.data(), localStarId);
540 }
541
542 return 0;
543}
544
545const vector<vector<SimplexId>> *
546 PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(getVertexStars)() {
547 if(vertexStarList_.empty()) {
548 Timer t;
549 vertexStarList_.resize(vertexNumber_);
550 for(SimplexId i = 0; i < vertexNumber_; ++i) {
551 vertexStarList_[i].resize(getVertexStarNumber(i));
552 for(SimplexId j = 0; j < (SimplexId)vertexStarList_[i].size(); ++j)
553 getVertexStar(i, j, vertexStarList_[i][j]);
554 }
555
556 printMsg("Built " + to_string(vertexNumber_) + " vertex stars.", 1,
557 t.getElapsedTime(), 1);
558 }
560 return &vertexStarList_;
561}
562
563#ifdef TTK_ENABLE_MPI
564
565void PeriodicImplicitTriangulation::setIsBoundaryPeriodic(
566 std::array<unsigned char, 6> boundary) {
567 this->isBoundaryPeriodic = boundary;
568}
569
570void PeriodicImplicitTriangulation::createMetaGrid(const double *const bounds) {
571 // only works with 2 processes or more
572 if(!ttk::isRunningWithMPI()) {
573 return;
574 }
575
576 // no need to create it anew?
577 if(this->metaGrid_ != nullptr) {
578 return;
579 }
580
581 // Reorganize bounds to only execute Allreduce twice
582 std::array<double, 6> tempBounds = {
583 bounds[0], bounds[2], bounds[4], bounds[1], bounds[3], bounds[5],
584 };
585
586 for(int i = 0; i < 3; i++) {
588 if(this->isBoundaryPeriodic[2 * i] == 1) {
589 tempBounds[i] += spacing_[i];
590 }
591 if(this->isBoundaryPeriodic[2 * i + 1] == 1) {
592 tempBounds[3 + i] -= spacing_[i];
593 }
594 }
595 }
596
597 std::array<double, 6> tempGlobalBounds{};
598 // Compute and send to all processes the lower bounds of the data set
599 MPI_Allreduce(tempBounds.data(), tempGlobalBounds.data(), 3, MPI_DOUBLE,
600 MPI_MIN, ttk::MPIcomm_);
601 // Compute and send to all processes the higher bounds of the data set
602 MPI_Allreduce(&tempBounds[3], &tempGlobalBounds[3], 3, MPI_DOUBLE, MPI_MAX,
603 ttk::MPIcomm_);
604
605 // re-order tempGlobalBounds
606 std::array<double, 6> globalBounds{
607 tempGlobalBounds[0], tempGlobalBounds[3], tempGlobalBounds[1],
608 tempGlobalBounds[4], tempGlobalBounds[2], tempGlobalBounds[5],
609 };
611 const std::array<ttk::SimplexId, 3> dimensions = {
612 static_cast<ttk::SimplexId>(
613 std::round((globalBounds[1] - globalBounds[0]) / this->spacing_[0]))
614 + 1,
615 static_cast<ttk::SimplexId>(
616 std::round((globalBounds[3] - globalBounds[2]) / this->spacing_[1]))
617 + 1,
618 static_cast<ttk::SimplexId>(
619 std::round((globalBounds[5] - globalBounds[4]) / this->spacing_[2]))
620 + 1,
621 };
622
623 this->localGridOffset_ = {
624 static_cast<SimplexId>(
625 std::round((this->origin_[0] - globalBounds[0]) / this->spacing_[0])),
626 static_cast<SimplexId>(
627 std::round((this->origin_[1] - globalBounds[2]) / this->spacing_[1])),
628 static_cast<SimplexId>(
629 std::round((this->origin_[2] - globalBounds[4]) / this->spacing_[2])),
630 };
632 this->metaGrid_ = std::make_shared<PeriodicNoPreconditions>();
633 this->metaGrid_->setInputGrid(globalBounds[0], globalBounds[1],
634 globalBounds[2], this->spacing_[0],
635 this->spacing_[1], this->spacing_[2],
636 dimensions[0], dimensions[1], dimensions[2]);
637}
638
639int PeriodicImplicitTriangulation::preconditionDistributedCells() {
640 if(this->hasPreconditionedDistributedCells_) {
641 return 0;
642 }
643 if(!ttk::isRunningWithMPI()) {
644 return -1;
645 }
646 if(this->metaGrid_ == nullptr) {
647 return 0;
648 }
649 if(this->cellGhost_ == nullptr) {
650 if(ttk::isRunningWithMPI()) {
651 this->printErr("Missing cell ghost array!");
652 }
653 return -3;
654 }
655
656 Timer tm{};
657
658 this->neighborCellBBoxes_.resize(ttk::MPIsize_);
659
660 const auto spacing{this->metaGrid_->spacing_};
661 const auto origin{this->metaGrid_->origin_};
662
663 this->neighborCellBBoxes_.resize(ttk::MPIsize_);
664
665 double globalBounds[6]{
666 origin[0], origin[0] + (this->metaGrid_->dimensions_[0] - 1) * spacing[0],
667 origin[1], origin[1] + (this->metaGrid_->dimensions_[1] - 1) * spacing[1],
668 origin[2], origin[2] + (this->metaGrid_->dimensions_[1] - 1) * spacing[2]};
669 auto &Bbox{this->neighborCellBBoxes_[ttk::MPIrank_]};
670 for(int i = 0; i < 3; i++) {
671 if(std::abs(globalBounds[2 * i] - boundingBox_[2 * i]) > spacing[i] / 2) {
672 Bbox[2 * i] = boundingBox_[2 * i] + spacing[i];
673 } else {
674 Bbox[2 * i] = boundingBox_[2 * i];
675 }
676 Bbox[2 * i] -= isBoundaryPeriodic[2 * i] * spacing[i];
677 if(std::abs(globalBounds[2 * i + 1] - boundingBox_[2 * i + 1])
678 > spacing[i] / 2) {
679 Bbox[2 * i + 1] = boundingBox_[2 * i + 1] - spacing[i];
680 } else {
681 Bbox[2 * i + 1] = boundingBox_[2 * i + 1];
682 }
683 Bbox[2 * i + 1] += isBoundaryPeriodic[2 * i + 1] * spacing[i];
684 }
685
686 for(size_t i = 0; i < this->neighborRanks_.size(); ++i) {
687 const auto neigh{this->neighborRanks_[i]};
688 MPI_Sendrecv(this->neighborCellBBoxes_[ttk::MPIrank_].data(), 6, MPI_DOUBLE,
689 neigh, ttk::MPIrank_, this->neighborCellBBoxes_[neigh].data(),
690 6, MPI_DOUBLE, neigh, neigh, ttk::MPIcomm_, MPI_STATUS_IGNORE);
691 }
692
693 this->hasPreconditionedDistributedCells_ = true;
694
695 return 0;
696}
697
698std::array<SimplexId, 3> PeriodicImplicitTriangulation::getVertGlobalCoords(
699 const SimplexId lvid) const {
700 // local vertex coordinates
701 std::array<SimplexId, 3> p{};
702 if(this->dimensionality_ == 3) {
703 this->vertexToPosition(lvid, p.data());
704 } else if(this->dimensionality_ == 2) {
705 this->vertexToPosition2d(lvid, p.data());
706 }
707 // global vertex coordinates
708 p[0] += this->localGridOffset_[0];
709 p[1] += this->localGridOffset_[1];
710 p[2] += this->localGridOffset_[2];
711
712 const auto &dims{this->metaGrid_->getGridDimensions()};
713
714 p[0] = (p[0] + dims[0]) % dims[0];
715 if(dimensionality_ > 1) {
716 p[1] = (p[1] + dims[1]) % dims[1];
717 if(dimensionality_ > 2)
718 p[2] = (p[2] + dims[2]) % dims[2];
719 }
720
721 return p;
722}
723
724std::array<SimplexId, 3> PeriodicImplicitTriangulation::getVertLocalCoords(
725 const SimplexId gvid) const {
726 // global vertex coordinates
727 std::array<SimplexId, 3> pGlobal{};
728 if(this->dimensionality_ == 3) {
729 this->metaGrid_->vertexToPosition(gvid, pGlobal.data());
730 } else if(this->dimensionality_ == 2) {
731 this->metaGrid_->vertexToPosition2d(gvid, pGlobal.data());
732 }
733 std::array<SimplexId, 3> p{pGlobal};
734 // local vertex coordinates
735 p[0] -= this->localGridOffset_[0];
736 p[1] -= this->localGridOffset_[1];
737 p[2] -= this->localGridOffset_[2];
738
739 const auto &dims{this->getGridDimensions()};
740
741 if(p[0] >= 0 && p[1] >= 0 && p[2] >= 0 && p[0] <= dims[0] - 1
742 && p[1] <= dims[1] - 1 && p[2] <= dims[2] - 1) {
743 return p;
744 }
745 for(int i = 0; i < 3; i++) {
746 if((p[i] < 0 || p[i] > dims[i] - 1) && pGlobal[i] == 0) {
747 p[i] = dims[i] - 1;
748 }
749 if((p[i] < 0 || p[i] > dims[i] - 1)
750 && pGlobal[i] == this->metaGrid_->dimensions_[i] - 1) {
751 p[i] = 0;
752 }
753 }
754
755 if(p[0] >= 0 && p[1] >= 0 && p[2] >= 0 && p[0] <= dims[0] - 1
756 && p[1] <= dims[1] - 1 && p[2] <= dims[2] - 1) {
757 if(this->vertexGhost_[p[0] + p[1] * dims[0] + p[2] * dims[0] * dims[1]]
758 != 0) {
759 return p;
760 }
761 }
762 return std::array<SimplexId, 3>{-1, -1, -1};
763}
764
765int ttk::PeriodicImplicitTriangulation::getCellRankInternal(
766 const SimplexId lcid) const {
767
768 const int nTetraPerCube{this->dimensionality_ == 3 ? 6 : 2};
769 const auto locCubeId{lcid / nTetraPerCube};
770
771 if(this->cellGhost_[locCubeId] == 0) {
772 return ttk::MPIrank_;
773 }
774
775#ifndef TTK_ENABLE_KAMIKAZE
776 if(this->neighborRanks_.empty()) {
777 this->printErr("Empty neighborsRanks_!");
778 return -1;
779 }
780#endif // TTK_ENABLE_KAMIKAZE
781
782 const auto nVertsCell{this->getCellVertexNumber(lcid)};
783 std::vector<bool> inRank(nVertsCell);
784 std::map<int, int> neighborOccurrences;
785 for(const auto neigh : this->neighborRanks_) {
786 std::fill(inRank.begin(), inRank.end(), false);
787 const auto &bbox{this->neighborCellBBoxes_[neigh]};
788 for(SimplexId i = 0; i < nVertsCell; ++i) {
789 SimplexId v{};
790 this->getCellVertex(lcid, i, v);
791 if(this->vertexGhost_[v] == 0) {
792 inRank[i] = true;
793 } else {
794 const auto p{this->getVertGlobalCoords(v)};
795 if(p[0] >= bbox[0] && p[0] <= bbox[1] && p[1] >= bbox[2]
796 && p[1] <= bbox[3] && p[2] >= bbox[4] && p[2] <= bbox[5]) {
797 inRank[i] = true;
798 }
799 }
800 }
801 if(std::all_of(
802 inRank.begin(), inRank.end(), [](const bool v) { return v; })) {
803 return neigh;
804 }
805 neighborOccurrences[neigh]
806 = std::accumulate(inRank.begin(), inRank.end(), 0);
807 }
808
809 auto pr = std::max_element(
810 std::begin(neighborOccurrences), std::end(neighborOccurrences),
811 [](const std::pair<int, int> &p1, const std::pair<int, int> &p2) {
812 return p1.second < p2.second;
813 });
814 return pr->first;
815}
816
817#endif // TTK_ENABLE_MPI
818
819template <typename Derived>
821 getVertexPoint)(const SimplexId &vertexId,
822 float &x,
823 float &y,
824 float &z) const {
825#ifndef TTK_ENABLE_KAMIKAZE
826 if(vertexId < 0 or vertexId >= vertexNumber_)
827 return -1;
828#endif
829
830 if(dimensionality_ == 3) {
831 const auto &p = this->underlying().getVertexCoords(vertexId);
832
833 x = origin_[0] + spacing_[0] * p[0];
834 y = origin_[1] + spacing_[1] * p[1];
835 z = origin_[2] + spacing_[2] * p[2];
836 } else if(dimensionality_ == 2) {
837 const auto &p = this->underlying().getVertexCoords(vertexId);
838
839 if(dimensions_[0] > 1 and dimensions_[1] > 1) {
840 x = origin_[0] + spacing_[0] * p[0];
841 y = origin_[1] + spacing_[1] * p[1];
842 z = origin_[2];
843 } else if(dimensions_[1] > 1 and dimensions_[2] > 1) {
844 x = origin_[0];
845 y = origin_[1] + spacing_[1] * p[0];
846 z = origin_[2] + spacing_[2] * p[1];
847 } else if(dimensions_[0] > 1 and dimensions_[2] > 1) {
848 x = origin_[0] + spacing_[0] * p[0];
849 y = origin_[1];
850 z = origin_[2] + spacing_[2] * p[1];
851 }
852 } else if(dimensionality_ == 1) {
853 if(dimensions_[0] > 1) {
854 x = origin_[0] + spacing_[0] * vertexId;
855 y = origin_[1];
856 z = origin_[2];
857 } else if(dimensions_[1] > 1) {
858 x = origin_[0];
859 y = origin_[1] + spacing_[1] * vertexId;
860 z = origin_[2];
861 } else if(dimensions_[2] > 1) {
862 x = origin_[0];
863 y = origin_[1];
864 z = origin_[2] + spacing_[2] * vertexId;
865 }
866 }
867
868 return 0;
869}
870
871template <typename Derived>
873 const SimplexId &edgeId,
874 const int &localVertexId,
875 SimplexId &vertexId) const {
876#ifndef TTK_ENABLE_KAMIKAZE
877 if(edgeId < 0 or edgeId >= edgeNumber_)
878 return -1;
879 if(localVertexId < 0 or localVertexId >= 2)
880 return -2;
881#endif
882
883 vertexId = -1;
884 const auto &p = this->underlying().getEdgeCoords(edgeId);
885 const SimplexId wrapXRight = (p[0] == nbvoxels_[0] ? -wrap_[0] : 0);
886 const SimplexId wrapYBottom = (p[1] == nbvoxels_[1] ? -wrap_[1] : 0);
887 const SimplexId wrapZFront = (p[2] == nbvoxels_[2] ? -wrap_[2] : 0);
888 const auto a = p[0] + this->underlying().getEdgeVertexAccelerated(edgeId);
889
890 switch(this->underlying().getEdgePosition(edgeId)) {
892 vertexId = a + (localVertexId == 0 ? 0 : (1 + wrapXRight));
893 break;
895 vertexId = a + (localVertexId == 0 ? 0 : (vshift_[0] + wrapYBottom));
896 break;
898 vertexId = a + (localVertexId == 0 ? 0 : (vshift_[1] + wrapZFront));
899 break;
901 vertexId = a
902 + (localVertexId == 0 ? (1 + wrapXRight)
903 : (vshift_[0] + wrapYBottom));
904 break;
906 vertexId = a
907 + (localVertexId == 0
908 ? 0
909 : (vshift_[0] + wrapYBottom + vshift_[1] + wrapZFront));
910 break;
912 vertexId
913 = a
914 + (localVertexId == 0 ? (1 + wrapXRight) : (vshift_[1] + wrapZFront));
915 break;
917 vertexId = a
918 + (localVertexId == 0
919 ? (1 + wrapXRight)
920 : (vshift_[0] + wrapYBottom + vshift_[1] + wrapZFront));
921 break;
923 vertexId = a + (localVertexId == 0 ? 0 : (1 + wrapXRight));
924 break;
926 vertexId = a + (localVertexId == 0 ? 0 : (vshift_[0] + wrapYBottom));
927 break;
929 vertexId = a
930 + (localVertexId == 0 ? (1 + wrapXRight)
931 : (vshift_[0] + wrapYBottom));
932 break;
934 vertexId = localVertexId == 0 ? 0 : 1;
935 break;
937 vertexId = localVertexId == 0 ? edgeId : 0;
938 break;
940 vertexId = localVertexId == 0 ? edgeId : edgeId + 1;
941 break;
942 default:
943 break;
944 }
945
946 return 0;
947}
948
949const vector<std::array<SimplexId, 2>> *
950 PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(getEdges)() {
951
952 if(edgeList_.empty()) {
953 Timer t;
954
955 edgeList_.resize(edgeNumber_);
956 for(SimplexId i = 0; i < edgeNumber_; ++i) {
957 SimplexId id0, id1;
958 getEdgeVertexInternal(i, 0, id0);
959 getEdgeVertexInternal(i, 1, id1);
960 edgeList_[i] = {id0, id1};
961 }
962
963 printMsg(
964 "Built " + to_string(edgeNumber_) + " edges.", 1, t.getElapsedTime(), 1);
965 }
966
967 return &edgeList_;
968}
969
970template <typename Derived>
973 const SimplexId &edgeId) const {
974#ifndef TTK_ENABLE_KAMIKAZE
975 if(edgeId < 0 or edgeId >= edgeNumber_)
976 return -1;
977#endif
978
979 switch(this->underlying().getEdgePosition(edgeId)) {
984 return 6;
988 return 4;
992 return 2;
993 default:
994 return 0;
995 }
996}
997
998template <typename Derived>
1000 const SimplexId &edgeId,
1001 const int &localTriangleId,
1002 SimplexId &triangleId) const {
1003#ifndef TTK_ENABLE_KAMIKAZE
1004 if(localTriangleId < 0
1005 or localTriangleId >= getEdgeTriangleNumberInternal(edgeId))
1006 return -1;
1007#endif
1008
1009 triangleId = -1;
1010 const auto &p = this->underlying().getEdgeCoords(edgeId);
1011
1012 switch(this->underlying().getEdgePosition(edgeId)) {
1013 case EdgePosition::L_3D:
1014 triangleId = getEdgeTriangle3dL(p.data(), localTriangleId);
1015 break;
1016 case EdgePosition::H_3D:
1017 triangleId = getEdgeTriangle3dH(p.data(), localTriangleId);
1018 break;
1019 case EdgePosition::P_3D:
1020 triangleId = getEdgeTriangle3dP(p.data(), localTriangleId);
1021 break;
1023 triangleId = getEdgeTriangle3dD1(p.data(), localTriangleId);
1024 break;
1026 triangleId = getEdgeTriangle3dD2(p.data(), localTriangleId);
1027 break;
1029 triangleId = getEdgeTriangle3dD3(p.data(), localTriangleId);
1030 break;
1032 triangleId = getEdgeTriangle3dD4(p.data(), localTriangleId);
1033 break;
1034 case EdgePosition::L_2D:
1035 triangleId = getEdgeTriangle2dL(p.data(), localTriangleId);
1036 break;
1037 case EdgePosition::H_2D:
1038 triangleId = getEdgeTriangle2dH(p.data(), localTriangleId);
1039 break;
1041 triangleId = getEdgeTriangle2dD1(p.data(), localTriangleId);
1042 break;
1043 default:
1044 break;
1045 }
1046
1047 return 0;
1048}
1049
1050const vector<vector<SimplexId>> *
1052 if(edgeTriangleList_.empty()) {
1053 Timer t;
1054
1056 for(SimplexId i = 0; i < edgeNumber_; ++i) {
1058 for(SimplexId j = 0; j < (SimplexId)edgeTriangleList_[i].size(); ++j)
1060 }
1061
1062 printMsg("Built " + to_string(edgeNumber_) + " edge triangles.", 1,
1063 t.getElapsedTime(), 1);
1064 }
1065
1066 return &edgeTriangleList_;
1067}
1068
1069SimplexId PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
1070 getEdgeLinkNumber)(const SimplexId &edgeId) const {
1071
1072 return getEdgeStarNumber(edgeId);
1073}
1074
1075template <typename Derived>
1077 getEdgeLink)(const SimplexId &edgeId,
1078 const int &localLinkId,
1079 SimplexId &linkId) const {
1080#ifndef TTK_ENABLE_KAMIKAZE
1081 if(localLinkId < 0 or localLinkId >= getEdgeLinkNumber(edgeId))
1082 return -1;
1083#endif
1084
1085 linkId = -1;
1086 const auto &p = this->underlying().getEdgeCoords(edgeId);
1087
1088 switch(this->underlying().getEdgePosition(edgeId)) {
1089 case EdgePosition::L_3D:
1090 linkId = getEdgeLinkL(p.data(), localLinkId);
1091 break;
1092 case EdgePosition::H_3D:
1093 linkId = getEdgeLinkH(p.data(), localLinkId);
1094 break;
1095 case EdgePosition::P_3D:
1096 linkId = getEdgeLinkP(p.data(), localLinkId);
1097 break;
1098 case EdgePosition::D1_3D:
1099 linkId = getEdgeLinkD1(p.data(), localLinkId);
1100 break;
1101 case EdgePosition::D2_3D:
1102 linkId = getEdgeLinkD2(p.data(), localLinkId);
1103 break;
1104 case EdgePosition::D3_3D:
1105 linkId = getEdgeLinkD3(p.data(), localLinkId);
1106 break;
1107 case EdgePosition::D4_3D:
1108 linkId = getEdgeLinkD4(p.data(), localLinkId);
1109 break;
1110 case EdgePosition::L_2D:
1111 linkId = getEdgeLink2dL(p.data(), localLinkId);
1112 break;
1113 case EdgePosition::H_2D:
1114 linkId = getEdgeLink2dH(p.data(), localLinkId);
1115 break;
1116 case EdgePosition::D1_2D:
1117 linkId = getEdgeLink2dD1(p.data(), localLinkId);
1118 break;
1119 default:
1120 break;
1121 }
1122
1123 return 0;
1124}
1125
1126const vector<vector<SimplexId>> *
1127 PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(getEdgeLinks)() {
1128
1129 if(edgeLinkList_.empty()) {
1130 Timer t;
1131
1132 edgeLinkList_.resize(edgeNumber_);
1133 for(SimplexId i = 0; i < edgeNumber_; ++i) {
1134 edgeLinkList_[i].resize(getEdgeLinkNumber(i));
1135 for(SimplexId j = 0; j < (SimplexId)edgeLinkList_[i].size(); ++j)
1136 getEdgeLink(i, j, edgeLinkList_[i][j]);
1137 }
1138
1139 printMsg("Built " + to_string(edgeNumber_) + " edge links.", 1,
1140 t.getElapsedTime(), 1);
1141 }
1142
1143 return &edgeLinkList_;
1144}
1145
1146template <typename Derived>
1149 getEdgeStarNumber)(const SimplexId &edgeId) const {
1150#ifndef TTK_ENABLE_KAMIKAZE
1151 if(edgeId < 0 or edgeId >= edgeNumber_)
1152 return -1;
1153#endif
1154
1155 switch(this->underlying().getEdgePosition(edgeId)) {
1156 case EdgePosition::L_3D:
1157 case EdgePosition::H_3D:
1158 case EdgePosition::P_3D:
1159 case EdgePosition::D4_3D:
1160 return 6;
1161 case EdgePosition::D1_3D:
1162 case EdgePosition::D2_3D:
1163 case EdgePosition::D3_3D:
1164 return 4;
1165 case EdgePosition::L_2D:
1166 case EdgePosition::H_2D:
1167 case EdgePosition::D1_2D:
1168 return 2;
1169 default:
1170 return 0;
1171 }
1172
1173 return 0;
1174}
1175
1176template <typename Derived>
1178 getEdgeStar)(const SimplexId &edgeId,
1179 const int &localStarId,
1180 SimplexId &starId) const {
1181#ifndef TTK_ENABLE_KAMIKAZE
1182 if(localStarId < 0 or localStarId >= getEdgeStarNumber(edgeId))
1183 return -1;
1184#endif
1185
1186 starId = -1;
1187 const auto &p = this->underlying().getEdgeCoords(edgeId);
1188
1189 switch(this->underlying().getEdgePosition(edgeId)) {
1190 case EdgePosition::L_3D:
1191 starId = getEdgeStarL(p.data(), localStarId);
1192 break;
1193 case EdgePosition::H_3D:
1194 starId = getEdgeStarH(p.data(), localStarId);
1195 break;
1196 case EdgePosition::P_3D:
1197 starId = getEdgeStarP(p.data(), localStarId);
1198 break;
1199 case EdgePosition::D1_3D:
1200 starId = getEdgeStarD1(p.data(), localStarId);
1201 break;
1202 case EdgePosition::D2_3D:
1203 starId = getEdgeStarD2(p.data(), localStarId);
1204 break;
1205 case EdgePosition::D3_3D:
1206 starId = getEdgeStarD3(p.data(), localStarId);
1207 break;
1208 case EdgePosition::D4_3D:
1209 starId
1210 = p[2] * tetshift_[1] + p[1] * tetshift_[0] + p[0] * 6 + localStarId;
1211 break;
1212 case EdgePosition::L_2D:
1213 starId = getEdgeStar2dL(p.data(), localStarId);
1214 break;
1215 case EdgePosition::H_2D:
1216 starId = getEdgeStar2dH(p.data(), localStarId);
1217 break;
1218 case EdgePosition::D1_2D:
1219 starId = p[0] * 2 + p[1] * tshift_[0] + localStarId;
1220 break;
1221 default:
1222 break;
1223 }
1224
1225 return 0;
1226}
1227
1228const vector<vector<SimplexId>> *
1229 PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(getEdgeStars)() {
1230
1231 if(edgeStarList_.empty()) {
1232 Timer t;
1233
1234 edgeStarList_.resize(edgeNumber_);
1235 for(SimplexId i = 0; i < edgeNumber_; ++i) {
1236 edgeStarList_[i].resize(getEdgeStarNumber(i));
1237 for(SimplexId j = 0; j < (SimplexId)edgeStarList_[i].size(); ++j)
1238 getEdgeStar(i, j, edgeStarList_[i][j]);
1239 }
1240
1241 printMsg("Built " + to_string(edgeNumber_) + " edge stars.", 1,
1242 t.getElapsedTime(), 1);
1243 }
1244
1245 return &edgeStarList_;
1246}
1247
1248template <typename Derived>
1250 const SimplexId &triangleId,
1251 const int &localVertexId,
1252 SimplexId &vertexId) const {
1253#ifndef TTK_ENABLE_KAMIKAZE
1254 if(triangleId < 0 or triangleId >= triangleNumber_)
1255 return -1;
1256 if(localVertexId < 0 or localVertexId >= 3)
1257 return -2;
1258#endif
1259
1260 vertexId = -1;
1261 const auto &p = this->underlying().getTriangleCoords(triangleId);
1262 const SimplexId wrapXRight = (p[0] == nbvoxels_[Di_]) ? -wrap_[0] : 0;
1263 const SimplexId wrapYBottom = (p[1] == nbvoxels_[Dj_]) ? -wrap_[1] : 0;
1264
1265 switch(this->underlying().getTrianglePosition(triangleId)) {
1267 vertexId = getTriangleVertexF(p.data(), localVertexId);
1268 break;
1270 vertexId = getTriangleVertexH(p.data(), localVertexId);
1271 break;
1273 vertexId = getTriangleVertexC(p.data(), localVertexId);
1274 break;
1276 vertexId = getTriangleVertexD1(p.data(), localVertexId);
1277 break;
1279 vertexId = getTriangleVertexD2(p.data(), localVertexId);
1280 break;
1282 vertexId = getTriangleVertexD3(p.data(), localVertexId);
1283 break;
1285 if(localVertexId == 0) {
1286 vertexId = p[0] + p[1] * vshift_[0];
1287 } else if(localVertexId == 1) {
1288 vertexId = p[0] + p[1] * vshift_[0] + 1 + wrapXRight;
1289 } else if(localVertexId == 2) {
1290 vertexId = p[0] + p[1] * vshift_[0] + vshift_[0] + wrapYBottom;
1291 }
1292 break;
1294 if(localVertexId == 0) {
1295 vertexId = p[0] + p[1] * vshift_[0] + 1 + wrapXRight;
1296 } else if(localVertexId == 1) {
1297 vertexId = p[0] + p[1] * vshift_[0] + vshift_[0] + 1 + wrapXRight
1298 + wrapYBottom;
1299 } else if(localVertexId == 2) {
1300 vertexId = p[0] + p[1] * vshift_[0] + vshift_[0] + wrapYBottom;
1301 }
1302 break;
1303 default:
1304 break;
1305 }
1306
1307 return 0;
1308}
1309
1310template <typename Derived>
1312 const SimplexId &triangleId,
1313 const int &localEdgeId,
1314 SimplexId &edgeId) const {
1315#ifndef TTK_ENABLE_KAMIKAZE
1316 if(triangleId < 0 or triangleId >= triangleNumber_)
1317 return -1;
1318 if(localEdgeId < 0 or localEdgeId >= 3)
1319 return -2;
1320#endif
1321
1322 edgeId = -1;
1323 const auto &p = this->underlying().getTriangleCoords(triangleId);
1324 const SimplexId wrapXRight = (p[0] == nbvoxels_[Di_]) ? -wrap_[0] : 0;
1325 const SimplexId wrapYBottom = (p[1] == nbvoxels_[Dj_]) ? -wrap_[1] : 0;
1326 const SimplexId id = triangleId % 2;
1327
1328 switch(this->underlying().getTrianglePosition(triangleId)) {
1330 edgeId = (id == 1) ? getTriangleEdgeF_1(p.data(), localEdgeId)
1331 : getTriangleEdgeF_0(p.data(), localEdgeId);
1332 break;
1334 edgeId = (id == 1) ? getTriangleEdgeH_1(p.data(), localEdgeId)
1335 : getTriangleEdgeH_0(p.data(), localEdgeId);
1336 break;
1338 edgeId = (id == 1) ? getTriangleEdgeC_1(p.data(), localEdgeId)
1339 : getTriangleEdgeC_0(p.data(), localEdgeId);
1340 break;
1342 edgeId = (id == 1) ? getTriangleEdgeD1_1(p.data(), localEdgeId)
1343 : getTriangleEdgeD1_0(p.data(), localEdgeId);
1344 break;
1346 edgeId = (id == 1) ? getTriangleEdgeD2_1(p.data(), localEdgeId)
1347 : getTriangleEdgeD2_0(p.data(), localEdgeId);
1348 break;
1350 edgeId = (id == 1) ? getTriangleEdgeD3_1(p.data(), localEdgeId)
1351 : getTriangleEdgeD3_0(p.data(), localEdgeId);
1352 break;
1354 if(localEdgeId == 0) {
1355 edgeId = p[0] + p[1] * eshift_[0];
1356 } else if(localEdgeId == 1) {
1357 edgeId = esetshift_[0] + p[0] + p[1] * eshift_[2];
1358 } else if(localEdgeId == 2) {
1359 edgeId = esetshift_[1] + p[0] + p[1] * eshift_[4];
1360 }
1361 break;
1363 if(localEdgeId == 0) {
1364 edgeId = p[0] + (p[1] + 1) * eshift_[0] + wrapYBottom;
1365 } else if(localEdgeId == 1) {
1366 edgeId = esetshift_[0] + (p[0] + 1) + p[1] * eshift_[2] + wrapXRight;
1367 } else if(localEdgeId == 2) {
1368 edgeId = esetshift_[1] + p[0] + p[1] * eshift_[4];
1369 }
1370 break;
1371 default:
1372 break;
1373 }
1374
1375 return 0;
1376}
1377
1379 vector<vector<SimplexId>> &edges) const {
1380 edges.resize(triangleNumber_);
1381 for(SimplexId i = 0; i < triangleNumber_; ++i) {
1382 edges[i].resize(3);
1383 for(int j = 0; j < 3; ++j)
1384 getTriangleEdgeInternal(i, j, edges[i][j]);
1385 }
1386 return 0;
1387}
1388
1389const vector<vector<SimplexId>> *
1391 if(triangleEdgeVector_.empty()) {
1392 Timer t;
1393
1395
1396 printMsg("Built " + to_string(triangleNumber_) + " triangle edges.", 1,
1397 t.getElapsedTime(), 1);
1398 }
1399
1400 return &triangleEdgeVector_;
1401}
1402
1403const vector<std::array<SimplexId, 3>> *
1404 PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(getTriangles)() {
1405
1406 if(triangleList_.empty()) {
1407 Timer t;
1408
1409 triangleList_.resize(triangleNumber_);
1410 for(SimplexId i = 0; i < triangleNumber_; ++i) {
1411 for(int j = 0; j < 3; ++j)
1412 getTriangleVertexInternal(i, j, triangleList_[i][j]);
1413 }
1414
1415 printMsg("Built " + to_string(triangleNumber_) + " triangles.", 1,
1416 t.getElapsedTime(), 1);
1417 }
1418
1419 return &triangleList_;
1420}
1421
1422template <typename Derived>
1424 getTriangleLink)(const SimplexId &triangleId,
1425 const int &localLinkId,
1426 SimplexId &linkId) const {
1427#ifndef TTK_ENABLE_KAMIKAZE
1428 if(localLinkId < 0 or localLinkId >= getTriangleLinkNumber(triangleId))
1429 return -1;
1430#endif
1431
1432 linkId = -1;
1433 const auto &p = this->underlying().getTriangleCoords(triangleId);
1434
1435 switch(this->underlying().getTrianglePosition(triangleId)) {
1436 case TrianglePosition::F_3D:
1437 linkId = getTriangleLinkF(p.data(), localLinkId);
1438 break;
1439 case TrianglePosition::H_3D:
1440 linkId = getTriangleLinkH(p.data(), localLinkId);
1441 break;
1442 case TrianglePosition::C_3D:
1443 linkId = getTriangleLinkC(p.data(), localLinkId);
1444 break;
1445 case TrianglePosition::D1_3D:
1446 linkId = getTriangleLinkD1(p.data(), localLinkId);
1447 break;
1448 case TrianglePosition::D2_3D:
1449 linkId = getTriangleLinkD2(p.data(), localLinkId);
1450 break;
1451 case TrianglePosition::D3_3D:
1452 linkId = getTriangleLinkD3(p.data(), localLinkId);
1453 break;
1454 default:
1455 break;
1456 }
1457
1458 return 0;
1459}
1460
1461SimplexId PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
1462 getTriangleLinkNumber)(const SimplexId &triangleId) const {
1463
1464 return getTriangleStarNumber(triangleId);
1465}
1466
1467const vector<vector<SimplexId>> *
1468 PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
1469 getTriangleLinks)() {
1470
1471 if(triangleLinkList_.empty()) {
1472 Timer t;
1473
1474 triangleLinkList_.resize(triangleNumber_);
1475 for(SimplexId i = 0; i < triangleNumber_; ++i) {
1476 triangleLinkList_[i].resize(getTriangleLinkNumber(i));
1477 for(SimplexId j = 0; j < (SimplexId)triangleLinkList_[i].size(); ++j)
1478 getTriangleLink(i, j, triangleLinkList_[i][j]);
1479 }
1480
1481 printMsg("Built " + to_string(triangleNumber_) + " triangle links.", 1,
1482 t.getElapsedTime(), 1);
1483 }
1484 return &triangleLinkList_;
1485}
1486
1487template <typename Derived>
1490 getTriangleStarNumber)(const SimplexId &triangleId) const {
1491#ifndef TTK_ENABLE_KAMIKAZE
1492 if(triangleId < 0 or triangleId >= triangleNumber_)
1493 return -1;
1494#else
1495 TTK_FORCE_USE(triangleId);
1496#endif
1497
1498 if(dimensionality_ == 3) {
1499 return 2;
1500 }
1501 return 0;
1502}
1503
1504template <typename Derived>
1506 getTriangleStar)(const SimplexId &triangleId,
1507 const int &localStarId,
1508 SimplexId &starId) const {
1509#ifndef TTK_ENABLE_KAMIKAZE
1510 if(localStarId < 0 or localStarId >= getTriangleStarNumber(triangleId))
1511 return -1;
1512#endif
1513
1514 starId = -1;
1515 const auto &p = this->underlying().getTriangleCoords(triangleId);
1516
1517 switch(this->underlying().getTrianglePosition(triangleId)) {
1518 case TrianglePosition::F_3D:
1519 starId = getTriangleStarF(p.data(), localStarId);
1520 break;
1521 case TrianglePosition::H_3D:
1522 starId = getTriangleStarH(p.data(), localStarId);
1523 break;
1524 case TrianglePosition::C_3D:
1525 starId = getTriangleStarC(p.data(), localStarId);
1526 break;
1527 case TrianglePosition::D1_3D:
1528 starId = getTriangleStarD1(p.data(), localStarId);
1529 break;
1530 case TrianglePosition::D2_3D:
1531 starId = getTriangleStarD2(p.data(), localStarId);
1532 break;
1533 case TrianglePosition::D3_3D:
1534 starId = getTriangleStarD3(p.data(), localStarId);
1535 break;
1536 default:
1537 break;
1538 }
1539
1540 return 0;
1541}
1542
1543const vector<vector<SimplexId>> *
1544 PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
1545 getTriangleStars)() {
1546
1547 if(triangleStarList_.empty()) {
1548 Timer t;
1549
1550 triangleStarList_.resize(triangleNumber_);
1551 for(SimplexId i = 0; i < triangleNumber_; ++i) {
1552 triangleStarList_[i].resize(getTriangleStarNumber(i));
1553 for(SimplexId j = 0; j < (SimplexId)triangleStarList_[i].size(); ++j)
1554 getTriangleStar(i, j, triangleStarList_[i][j]);
1555 }
1556
1557 printMsg("Built " + to_string(triangleNumber_) + " triangle stars.", 1,
1558 t.getElapsedTime(), 1);
1559 }
1560 return &triangleStarList_;
1561}
1562
1564 const SimplexId &triangleId) const {
1565#ifndef TTK_ENABLE_KAMIKAZE
1566 if(triangleId < 0 or triangleId >= triangleNumber_)
1567 return -1;
1568#endif
1569
1570 TTK_FORCE_USE(triangleId);
1571 if(dimensionality_ == 2) {
1572 return 3;
1573 }
1574
1575 return 0;
1576}
1577
1578template <typename Derived>
1580 const SimplexId &triangleId,
1581 const int &localNeighborId,
1582 SimplexId &neighborId) const {
1583#ifndef TTK_ENABLE_KAMIKAZE
1584 if(localNeighborId < 0
1585 or localNeighborId >= getTriangleNeighborNumber(triangleId))
1586 return -1;
1587#endif
1588
1589 neighborId = -1;
1590 const auto &p = this->underlying().getTriangleCoords(triangleId);
1591
1592 switch(this->underlying().getTrianglePosition(triangleId)) {
1594
1595 if(p[0] == nbvoxels_[Di_] and p[1] == nbvoxels_[Dj_]) {
1596 if(localNeighborId == 0) {
1597 neighborId = triangleId - 1;
1598 } else if(localNeighborId == 1) {
1599 neighborId = triangleId + 1 - wrap_[0] * 2;
1600 } else if(localNeighborId == 2) {
1601 neighborId = triangleId + tshift_[0] - 1 - wrap_[1] * 2;
1602 }
1603
1604 } else if(p[0] == nbvoxels_[Di_]) {
1605 if(localNeighborId == 0) {
1606 neighborId = triangleId - 1;
1607 } else if(localNeighborId == 1) {
1608 neighborId = triangleId + 1 - wrap_[0] * 2;
1609 } else if(localNeighborId == 2) {
1610 neighborId = triangleId + tshift_[0] - 1;
1611 }
1612
1613 } else if(p[1] == nbvoxels_[Dj_]) {
1614 if(localNeighborId == 0) {
1615 neighborId = triangleId - 1;
1616 } else if(localNeighborId == 1) {
1617 neighborId = triangleId + 1;
1618 } else if(localNeighborId == 2) {
1619 neighborId = triangleId + tshift_[0] - 1 - wrap_[1] * 2;
1620 }
1621
1622 } else {
1623 if(localNeighborId == 0) {
1624 neighborId = triangleId - 1;
1625 } else if(localNeighborId == 1) {
1626 neighborId = triangleId + 1;
1627 } else if(localNeighborId == 2) {
1628 neighborId = triangleId + tshift_[0] - 1;
1629 }
1630 }
1631 break;
1632
1634
1635 if(p[0] == 0 and p[1] == 0) {
1636 if(localNeighborId == 0) {
1637 neighborId = triangleId + 1;
1638 } else if(localNeighborId == 1) {
1639 neighborId = triangleId - 1 + wrap_[0] * 2;
1640 } else if(localNeighborId == 2) {
1641 neighborId = triangleId - tshift_[0] + 1 + wrap_[1] * 2;
1642 }
1643
1644 } else if(p[0] == 0) {
1645 if(localNeighborId == 0) {
1646 neighborId = triangleId + 1;
1647 } else if(localNeighborId == 1) {
1648 neighborId = triangleId - 1 + wrap_[0] * 2;
1649 } else if(localNeighborId == 2) {
1650 neighborId = triangleId - tshift_[0] + 1;
1651 }
1652
1653 } else if(p[1] == 0) {
1654 if(localNeighborId == 0) {
1655 neighborId = triangleId + 1;
1656 } else if(localNeighborId == 1) {
1657 neighborId = triangleId - 1;
1658 } else if(localNeighborId == 2) {
1659 neighborId = triangleId - tshift_[0] + 1 + wrap_[1] * 2;
1660 }
1661
1662 } else {
1663 if(localNeighborId == 0) {
1664 neighborId = triangleId + 1;
1665 } else if(localNeighborId == 1) {
1666 neighborId = triangleId - 1;
1667 } else if(localNeighborId == 2) {
1668 neighborId = triangleId - tshift_[0] + 1;
1669 }
1670 }
1671 break;
1672 default:
1673 break;
1674 }
1675
1676 return 0;
1677}
1678
1680 vector<vector<SimplexId>> &neighbors) {
1681 neighbors.resize(triangleNumber_);
1682 for(SimplexId i = 0; i < triangleNumber_; ++i) {
1683 neighbors[i].resize(getTriangleNeighborNumber(i));
1684 for(SimplexId j = 0; j < (SimplexId)neighbors[i].size(); ++j)
1685 getTriangleNeighbor(i, j, neighbors[i][j]);
1686 }
1687 return 0;
1688}
1689
1690template <typename Derived>
1692 const SimplexId &tetId, const int &localVertexId, SimplexId &vertexId) const {
1693#ifndef TTK_ENABLE_KAMIKAZE
1694 if(tetId < 0 or tetId >= tetrahedronNumber_)
1695 return -1;
1696 if(localVertexId < 0 or localVertexId >= 4)
1697 return -2;
1698#endif
1699
1700 vertexId = -1;
1701
1702 if(dimensionality_ == 3) {
1703 const auto &p = this->underlying().getTetrahedronCoords(tetId);
1704 const SimplexId id = tetId % 6;
1705
1706 switch(id) {
1707 case 0:
1708 vertexId = getTetrahedronVertexABCG(p.data(), localVertexId);
1709 break;
1710 case 1:
1711 vertexId = getTetrahedronVertexBCDG(p.data(), localVertexId);
1712 break;
1713 case 2:
1714 vertexId = getTetrahedronVertexABEG(p.data(), localVertexId);
1715 break;
1716 case 3:
1717 vertexId = getTetrahedronVertexBEFG(p.data(), localVertexId);
1718 break;
1719 case 4:
1720 vertexId = getTetrahedronVertexBFGH(p.data(), localVertexId);
1721 break;
1722 case 5:
1723 vertexId = getTetrahedronVertexBDGH(p.data(), localVertexId);
1724 break;
1725 }
1726 }
1727 return 0;
1728}
1729
1730template <typename Derived>
1732 const SimplexId &tetId, const int &localEdgeId, SimplexId &edgeId) const {
1733#ifndef TTK_ENABLE_KAMIKAZE
1734 if(tetId < 0 or tetId >= tetrahedronNumber_)
1735 return -1;
1736 if(localEdgeId < 0 or localEdgeId >= 6)
1737 return -2;
1738#endif
1739
1740 edgeId = -1;
1741
1742 if(dimensionality_ == 3) {
1743 const auto &p = this->underlying().getTetrahedronCoords(tetId);
1744 const SimplexId id = tetId % 6;
1745
1746 switch(id) {
1747 case 0:
1748 edgeId = getTetrahedronEdgeABCG(p.data(), localEdgeId);
1749 break;
1750 case 1:
1751 edgeId = getTetrahedronEdgeBCDG(p.data(), localEdgeId);
1752 break;
1753 case 2:
1754 edgeId = getTetrahedronEdgeABEG(p.data(), localEdgeId);
1755 break;
1756 case 3:
1757 edgeId = getTetrahedronEdgeBEFG(p.data(), localEdgeId);
1758 break;
1759 case 4:
1760 edgeId = getTetrahedronEdgeBFGH(p.data(), localEdgeId);
1761 break;
1762 case 5:
1763 edgeId = getTetrahedronEdgeBDGH(p.data(), localEdgeId);
1764 break;
1765 }
1766 }
1767
1768 return 0;
1769}
1770
1772 vector<vector<SimplexId>> &edges) const {
1773 edges.resize(tetrahedronNumber_);
1774 for(SimplexId i = 0; i < tetrahedronNumber_; ++i) {
1775 edges[i].resize(6);
1776 for(int j = 0; j < 6; ++j)
1777 getTetrahedronEdge(i, j, edges[i][j]);
1778 }
1779
1780 return 0;
1781}
1782
1783template <typename Derived>
1785 const SimplexId &tetId,
1786 const int &localTriangleId,
1787 SimplexId &triangleId) const {
1788#ifndef TTK_ENABLE_KAMIKAZE
1789 if(tetId < 0 or tetId >= tetrahedronNumber_)
1790 return -1;
1791 if(localTriangleId < 0 or localTriangleId >= 4)
1792 return -2;
1793#endif
1794
1795 triangleId = -1;
1796
1797 if(dimensionality_ == 3) {
1798 const auto &p = this->underlying().getTetrahedronCoords(tetId);
1799 const SimplexId id = tetId % 6;
1800
1801 switch(id) {
1802 case 0:
1803 triangleId = getTetrahedronTriangleABCG(p.data(), localTriangleId);
1804 break;
1805 case 1:
1806 triangleId = getTetrahedronTriangleBCDG(p.data(), localTriangleId);
1807 break;
1808 case 2:
1809 triangleId = getTetrahedronTriangleABEG(p.data(), localTriangleId);
1810 break;
1811 case 3:
1812 triangleId = getTetrahedronTriangleBEFG(p.data(), localTriangleId);
1813 break;
1814 case 4:
1815 triangleId = getTetrahedronTriangleBFGH(p.data(), localTriangleId);
1816 break;
1817 case 5:
1818 triangleId = getTetrahedronTriangleBDGH(p.data(), localTriangleId);
1819 break;
1820 }
1821 }
1822
1823 return 0;
1824}
1825
1827 vector<vector<SimplexId>> &triangles) const {
1828 triangles.resize(tetrahedronNumber_);
1829 for(SimplexId i = 0; i < tetrahedronNumber_; ++i) {
1830 triangles[i].resize(4);
1831 for(int j = 0; j < 4; ++j)
1832 getTetrahedronTriangle(i, j, triangles[i][j]);
1833 }
1834
1835 return 0;
1836}
1837
1839 const SimplexId &tetId) const {
1840#ifndef TTK_ENABLE_KAMIKAZE
1841 if(tetId < 0 or tetId >= tetrahedronNumber_)
1842 return -1;
1843#endif
1844
1845 TTK_FORCE_USE(tetId);
1846 if(dimensionality_ == 3) {
1847 return 4;
1848 }
1849
1850 return 0;
1851}
1852
1853template <typename Derived>
1855 const SimplexId &tetId,
1856 const int &localNeighborId,
1857 SimplexId &neighborId) const {
1858#ifndef TTK_ENABLE_KAMIKAZE
1859 if(localNeighborId < 0
1860 or localNeighborId >= getTetrahedronNeighborNumber(tetId))
1861 return -1;
1862#endif
1863
1864 neighborId = -1;
1865
1866 if(dimensionality_ == 3) {
1867 const auto &p = this->underlying().getTetrahedronCoords(tetId);
1868 const SimplexId id = tetId % 6;
1869
1870 switch(id) {
1871 case 0:
1872 neighborId
1873 = getTetrahedronNeighborABCG(tetId, p.data(), localNeighborId);
1874 break;
1875 case 1:
1876 neighborId
1877 = getTetrahedronNeighborBCDG(tetId, p.data(), localNeighborId);
1878 break;
1879 case 2:
1880 neighborId
1881 = getTetrahedronNeighborABEG(tetId, p.data(), localNeighborId);
1882 break;
1883 case 3:
1884 neighborId
1885 = getTetrahedronNeighborBEFG(tetId, p.data(), localNeighborId);
1886 break;
1887 case 4:
1888 neighborId
1889 = getTetrahedronNeighborBFGH(tetId, p.data(), localNeighborId);
1890 break;
1891 case 5:
1892 neighborId
1893 = getTetrahedronNeighborBDGH(tetId, p.data(), localNeighborId);
1894 break;
1895 }
1896 }
1897
1898 return 0;
1899}
1900
1902 vector<vector<SimplexId>> &neighbors) {
1903 neighbors.resize(tetrahedronNumber_);
1904 for(SimplexId i = 0; i < tetrahedronNumber_; ++i) {
1905 neighbors[i].resize(getTetrahedronNeighborNumber(i));
1906 for(SimplexId j = 0; j < (SimplexId)neighbors[i].size(); ++j)
1907 getTetrahedronNeighbor(i, j, neighbors[i][j]);
1908 }
1909
1910 return 0;
1911}
1912
1913SimplexId PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
1914 getCellVertexNumber)(const SimplexId &ttkNotUsed(cellId)) const {
1915
1916 return dimensionality_ + 1;
1917}
1918
1919int PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(getCellVertex)(
1920 const SimplexId &cellId,
1921 const int &localVertexId,
1922 SimplexId &vertexId) const {
1923
1924 if(dimensionality_ == 3)
1925 getTetrahedronVertex(cellId, localVertexId, vertexId);
1926 else if(dimensionality_ == 2)
1927 getTriangleVertexInternal(cellId, localVertexId, vertexId);
1928 else if(dimensionality_ == 1)
1929 getEdgeVertexInternal(cellId, localVertexId, vertexId);
1930
1931 return 0;
1932}
1933
1935 const SimplexId &ttkNotUsed(cellId)) const {
1936 if(dimensionality_ == 3)
1937 return 6;
1938 else if(dimensionality_ == 2)
1939 return 3;
1940
1941 return 0;
1942}
1943
1945 const SimplexId &cellId, const int &localEdgeId, SimplexId &edgeId) const {
1946 if(dimensionality_ == 3)
1947 getTetrahedronEdge(cellId, localEdgeId, edgeId);
1948 else if(dimensionality_ == 2)
1949 getTriangleEdgeInternal(cellId, localEdgeId, edgeId);
1950 else if(dimensionality_ == 1)
1951 getCellNeighbor(cellId, localEdgeId, edgeId);
1952
1953 return 0;
1954}
1955
1956const vector<vector<SimplexId>> *
1958 if(cellEdgeVector_.empty()) {
1959 Timer t;
1960
1961 if(dimensionality_ == 3)
1963 else if(dimensionality_ == 2)
1965
1966 printMsg("Built " + to_string(cellNumber_) + " cell edges.", 1,
1967 t.getElapsedTime(), 1);
1968 }
1969
1970 return &cellEdgeVector_;
1971}
1972
1974 const SimplexId &cellId,
1975 const int &localTriangleId,
1976 SimplexId &triangleId) const {
1977 if(dimensionality_ == 3)
1978 getTetrahedronTriangle(cellId, localTriangleId, triangleId);
1979
1980 return 0;
1981}
1982
1983const vector<vector<SimplexId>> *
1985 if(cellTriangleVector_.empty()) {
1986 Timer t;
1987
1988 if(dimensionality_ == 3)
1990
1991 printMsg("Built " + to_string(cellNumber_) + " cell triangles.", 1,
1992 t.getElapsedTime(), 1);
1993 }
1994
1995 return &cellTriangleVector_;
1996}
1997
1998SimplexId PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
1999 getCellNeighborNumber)(const SimplexId &cellId) const {
2000
2001 if(dimensionality_ == 3)
2002 return getTetrahedronNeighborNumber(cellId);
2003 else if(dimensionality_ == 2)
2004 return getTriangleNeighborNumber(cellId);
2005 else if(dimensionality_ == 1) {
2006 printErr("getCellNeighborNumber() not implemented in 1D! (TODO)");
2007 return -1;
2008 }
2009
2010 return 0;
2011}
2012
2013int PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(getCellNeighbor)(
2014 const SimplexId &cellId,
2015 const int &localNeighborId,
2016 SimplexId &neighborId) const {
2017
2018 if(dimensionality_ == 3)
2019 getTetrahedronNeighbor(cellId, localNeighborId, neighborId);
2020 else if(dimensionality_ == 2)
2021 getTriangleNeighbor(cellId, localNeighborId, neighborId);
2022 else if(dimensionality_ == 1) {
2023 printErr("getCellNeighbor() not implemented in 1D! (TODO)");
2024 return -1;
2025 }
2026
2027 return 0;
2028}
2029
2030const vector<vector<SimplexId>> *
2031 PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL(
2032 getCellNeighbors)() {
2033
2034 if(cellNeighborList_.empty()) {
2035 Timer t;
2036
2037 if(dimensionality_ == 3)
2038 getTetrahedronNeighbors(cellNeighborList_);
2039 else if(dimensionality_ == 2)
2040 getTriangleNeighbors(cellNeighborList_);
2041 else if(dimensionality_ == 1) {
2042 printErr("getCellNeighbors() not implemented in 1D! (TODO)");
2043 return nullptr;
2044 }
2045
2046 printMsg("Built " + to_string(cellNumber_) + " cell neighbors.", 1,
2047 t.getElapsedTime(), 1);
2048 }
2049
2050 return &cellNeighborList_;
2051}
2052
2053// explicit instantiations
2054template class ttk::PeriodicImplicitTriangulationCRTP<
2055 ttk::PeriodicWithPreconditions>;
2056template class ttk::PeriodicImplicitTriangulationCRTP<
2057 ttk::PeriodicNoPreconditions>;
#define TTK_FORCE_USE(x)
Force the compiler to use the function/method parameter.
Definition BaseClass.h:57
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
Definition BaseClass.h:47
bool ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL isTriangleOnBoundary(const SimplexId &triangleId) const
SimplexId ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getEdgeLinkNumber(const SimplexId &edgeId) const
int ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getCellNeighbor(const SimplexId &cellId, const int &localNeighborId, SimplexId &neighborId) const
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getVertexNeighbors()
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getEdgeLinks()
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getVertexStars()
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getEdgeStar(const SimplexId &edgeId, const int &localStarId, SimplexId &starId) const
const vector< std::array< SimplexId, 3 > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getTriangles()
SimplexId ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getVertexLinkNumber(const SimplexId &vertexId) const
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getEdgeStars()
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getTriangleLink(const SimplexId &triangleId, const int &localLinkId, SimplexId &linkId) const
SimplexId ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getTriangleStarNumber(const SimplexId &triangleId) const
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getVertexLink(const SimplexId &vertexId, const int &localLinkId, SimplexId &linkId) const
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getCellNeighbors()
SimplexId ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getEdgeStarNumber(const SimplexId &edgeId) const
bool ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL isEdgeOnBoundary(const SimplexId &edgeId) const
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getVertexPoint(const SimplexId &vertexId, float &x, float &y, float &z) const
int ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getCellVertex(const SimplexId &cellId, const int &localVertexId, SimplexId &vertexId) const
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getVertexStar(const SimplexId &vertexId, const int &localStarId, SimplexId &starId) const
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getVertexLinks()
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getTriangleStars()
bool ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL isVertexOnBoundary(const SimplexId &vertexId) const
SimplexId ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getCellNeighborNumber(const SimplexId &cellId) const
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getEdgeLink(const SimplexId &edgeId, const int &localLinkId, SimplexId &linkId) const
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getTriangleStar(const SimplexId &triangleId, const int &localStarId, SimplexId &starId) const
SimplexId ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getCellVertexNumber(const SimplexId &) const
SimplexId ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getVertexStarNumber(const SimplexId &vertexId) const
const vector< vector< SimplexId > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getTriangleLinks()
const vector< std::array< SimplexId, 2 > > *ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getEdges()
SimplexId ImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getTriangleLinkNumber(const SimplexId &triangleId) const
int PeriodicImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getVertexNeighbor(const SimplexId &vertexId, const int &localNeighborId, SimplexId &neighborId) const
SimplexId PeriodicImplicitTriangulation::TTK_TRIANGULATION_INTERNAL getVertexNeighborNumber(const SimplexId &vertexId) const
std::vector< std::vector< SimplexId > > vertexStarList_
virtual int getVertexTriangleInternal(const SimplexId &ttkNotUsed(vertexId), const int &ttkNotUsed(localTriangleId), SimplexId &ttkNotUsed(triangleId)) const
std::vector< std::vector< SimplexId > > vertexEdgeList_
std::vector< std::vector< SimplexId > > triangleEdgeVector_
virtual int getTriangleEdgeInternal(const SimplexId &ttkNotUsed(triangleId), const int &ttkNotUsed(localEdgeId), SimplexId &ttkNotUsed(edgeId)) const
virtual SimplexId getEdgeTriangleNumberInternal(const SimplexId &ttkNotUsed(edgeId)) const
virtual int getEdgeTriangleInternal(const SimplexId &ttkNotUsed(edgeId), const int &ttkNotUsed(localTriangleId), SimplexId &ttkNotUsed(triangleId)) const
virtual int getVertexEdgeInternal(const SimplexId &ttkNotUsed(vertexId), const int &ttkNotUsed(localEdgeId), SimplexId &ttkNotUsed(edgeId)) const
std::vector< std::vector< SimplexId > > vertexTriangleList_
std::vector< std::vector< SimplexId > > cellEdgeVector_
std::vector< std::vector< SimplexId > > cellTriangleVector_
std::vector< std::vector< SimplexId > > edgeTriangleList_
void setDebugMsgPrefix(const std::string &prefix)
Definition Debug.h:364
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition Debug.h:149
int getTetrahedronVertex(const SimplexId &tetId, const int &localVertexId, SimplexId &vertexId) const override
int getTetrahedronTriangle(const SimplexId &tetId, const int &id, SimplexId &triangleId) const override
int getTriangleVertexInternal(const SimplexId &triangleId, const int &localVertexId, SimplexId &vertexId) const override
int getEdgeVertexInternal(const SimplexId &edgeId, const int &localVertexId, SimplexId &vertexId) const override
int getVertexTriangleInternal(const SimplexId &vertexId, const int &id, SimplexId &triangleId) const override
int getTriangleEdgeInternal(const SimplexId &triangleId, const int &id, SimplexId &edgeId) const override
int getTetrahedronNeighbor(const SimplexId &tetId, const int &localNeighborId, SimplexId &neighborId) const override
int getVertexEdgeInternal(const SimplexId &vertexId, const int &id, SimplexId &edgeId) const override
SimplexId getEdgeTriangleNumberInternal(const SimplexId &edgeId) const override
int getEdgeTriangleInternal(const SimplexId &edgeId, const int &id, SimplexId &triangleId) const override
int getTetrahedronEdge(const SimplexId &tetId, const int &id, SimplexId &edgeId) const override
int getTriangleNeighbor(const SimplexId &triangleId, const int &localNeighborId, SimplexId &neighborId) const override
int getTriangleNeighbors(std::vector< std::vector< SimplexId > > &neighbors)
virtual int getTetrahedronNeighbor(const SimplexId &tetId, const int &localNeighborId, SimplexId &neighborId) const =0
int getCellTriangleInternal(const SimplexId &cellId, const int &id, SimplexId &triangleId) const override
int setInputGrid(const float &xOrigin, const float &yOrigin, const float &zOrigin, const float &xSpacing, const float &ySpacing, const float &zSpacing, const SimplexId &xDim, const SimplexId &yDim, const SimplexId &zDim) override
const std::vector< std::vector< SimplexId > > * getTriangleEdgesInternal() override
int getTetrahedronNeighbors(std::vector< std::vector< SimplexId > > &neighbors)
SimplexId getVertexEdgeNumberInternal(const SimplexId &vertexId) const override
SimplexId getCellEdgeNumberInternal(const SimplexId &cellId) const override
int getTetrahedronEdges(std::vector< std::vector< SimplexId > > &edges) const
SimplexId getTriangleNeighborNumber(const SimplexId &triangleId) const
const std::array< ttk::SimplexId, 3 > & getGridDimensions() const override
const std::vector< std::vector< SimplexId > > * getEdgeTrianglesInternal() override
virtual int getTriangleNeighbor(const SimplexId &triangleId, const int &localNeighborId, SimplexId &neighborId) const =0
bool isPowerOfTwo(unsigned long long int v, unsigned long long int &r)
int TTK_TRIANGULATION_INTERNAL getCellNeighbor(const SimplexId &cellId, const int &localNeighborId, SimplexId &neighborId) const override
SimplexId TTK_TRIANGULATION_INTERNAL getVertexNeighborNumber(const SimplexId &vertexId) const override
virtual int getTetrahedronEdge(const SimplexId &tetId, const int &id, SimplexId &edgeId) const =0
virtual int getTetrahedronTriangle(const SimplexId &tetId, const int &id, SimplexId &triangleId) const =0
const std::vector< std::vector< SimplexId > > * getVertexEdgesInternal() override
SimplexId getVertexTriangleNumberInternal(const SimplexId &vertexId) const override
int getTetrahedronTriangles(std::vector< std::vector< SimplexId > > &triangles) const
const std::vector< std::vector< SimplexId > > * getCellEdgesInternal() override
int getCellEdgeInternal(const SimplexId &cellId, const int &id, SimplexId &edgeId) const override
SimplexId getTetrahedronNeighborNumber(const SimplexId &tetId) const
const std::vector< std::vector< SimplexId > > * getCellTrianglesInternal() override
const std::vector< std::vector< SimplexId > > * getVertexTrianglesInternal() override
virtual void vertexToPosition(const SimplexId vertex, SimplexId p[3]) const =0
std::array< SimplexId, 3 > dimensions_
virtual void vertexToPosition2d(const SimplexId vertex, SimplexId p[2]) const =0
double getElapsedTime()
Definition Timer.h:15
TTK base package defining the standard types.
COMMON_EXPORTS int MPIsize_
Definition BaseClass.cpp:10
int SimplexId
Identifier type for simplices of any dimension.
Definition DataTypes.h:22
COMMON_EXPORTS int MPIrank_
Definition BaseClass.cpp:9
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/| (_) |"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)