16 std::array<SimplexId, 2> eVerts{};
20 if((v0 == eVerts[0] && v1 == eVerts[1])
21 || (v0 == eVerts[1] && v1 == eVerts[0])) {
30 std::array<SimplexId, 3> &verts)
const {
31 std::sort(verts.begin(), verts.end());
35 for(
SimplexId i = 0; i < nTriangles; ++i) {
37 std::array<SimplexId, 3> tVerts{};
42 std::sort(tVerts.begin(), tVerts.end());
53int ttk::RegularGridTriangulation::getVertexRankInternal(
56 if(this->vertexGhost_[lvid] == 0) {
60#ifndef TTK_ENABLE_KAMIKAZE
61 if(this->neighborRanks_.empty()) {
62 this->printErr(
"Empty neighborsRanks_!");
66 const auto p{this->getVertGlobalCoords(lvid)};
67 for(
const auto neigh : this->neighborRanks_) {
68 const auto &bbox{this->neighborVertexBBoxes_[neigh]};
69 if(p[0] >= bbox[0] && p[0] <= bbox[1] && p[1] >= bbox[2] && p[1] <= bbox[3]
70 && p[2] >= bbox[4] && p[2] <= bbox[5]) {
77int ttk::RegularGridTriangulation::getEdgeRankInternal(
84 cellMinRank = this->getCellRankInternal(minId);
90 int cellRank = this->getCellRankInternal(sid);
91 if(cellRank < cellMinRank) {
92 cellMinRank = cellRank;
98int ttk::RegularGridTriangulation::getTriangleRankInternal(
106 cellMinRank = this->getCellRankInternal(minId);
112 int cellRank = this->getCellRankInternal(sid);
113 if(cellRank < cellMinRank) {
114 cellMinRank = cellRank;
120ttk::SimplexId ttk::RegularGridTriangulation::getVertexGlobalIdInternal(
122 if(!ttk::isRunningWithMPI()) {
126#ifndef TTK_ENABLE_KAMIKAZE
131 if(this->metaGrid_ ==
nullptr) {
136 const auto p{this->getVertGlobalCoords(lvid)};
137 const auto &dims{this->metaGrid_->getGridDimensions()};
140 return p[0] + p[1] * dims[0] + p[2] * dims[0] * dims[1];
143ttk::SimplexId ttk::RegularGridTriangulation::getVertexLocalIdInternal(
145 if(!ttk::isRunningWithMPI()) {
149#ifndef TTK_ENABLE_KAMIKAZE
150 if(this->metaGrid_ ==
nullptr) {
154 > this->metaGrid_->TTK_TRIANGULATION_INTERNAL(getNumberOfVertices)() - 1
160 const auto p{this->getVertLocalCoords(gvid)};
161 const auto &dims{this->getGridDimensions()};
163 if(p[0] < 0 || p[1] < 0 || p[2] < 0 || p[0] > dims[0] - 1
164 || p[1] > dims[1] - 1 || p[2] > dims[2] - 1) {
169 return p[0] + p[1] * dims[0] + p[2] * dims[0] * dims[1];
172ttk::SimplexId ttk::RegularGridTriangulation::getCellGlobalIdInternal(
174 if(!ttk::isRunningWithMPI()) {
178#ifndef TTK_ENABLE_KAMIKAZE
183 if(this->metaGrid_ ==
nullptr) {
189 std::array<SimplexId, 3> p{};
190 if(this->dimensionality_ == 3) {
191 this->tetrahedronToPosition(lcid, p.data());
192 }
else if(this->dimensionality_ == 2) {
193 this->triangleToPosition2d(lcid, p.data());
197 p[0] += this->localGridOffset_[0];
198 p[1] += this->localGridOffset_[1];
199 p[2] += this->localGridOffset_[2];
201 const auto &dims{this->metaGrid_->getGridDimensions()};
204 const auto globCubeId{p[0] + p[1] * (dims[0] - 1)
205 + p[2] * (dims[0] - 1) * (dims[1] - 1)};
207 const auto nCellsPerCube{this->dimensionality_ == 3 ? 6 : 2};
208 return globCubeId * nCellsPerCube + lcid % nCellsPerCube;
211ttk::SimplexId ttk::RegularGridTriangulation::getCellLocalIdInternal(
213 if(!ttk::isRunningWithMPI()) {
217#ifndef TTK_ENABLE_KAMIKAZE
218 if(this->metaGrid_ ==
nullptr) {
221 if(gcid > this->metaGrid_->TTK_TRIANGULATION_INTERNAL(getNumberOfCells)() - 1
228 std::array<SimplexId, 3> p{};
229 if(this->dimensionality_ == 3) {
230 this->metaGrid_->tetrahedronToPosition(gcid, p.data());
231 }
else if(this->dimensionality_ == 2) {
232 this->metaGrid_->triangleToPosition2d(gcid, p.data());
236 p[0] -= this->localGridOffset_[0];
237 p[1] -= this->localGridOffset_[1];
238 p[2] -= this->localGridOffset_[2];
240 const auto &dims{this->getGridDimensions()};
241 if(p[0] < 0 || p[1] < 0 || p[2] < 0 || p[0] >= dims[0] - 1
242 || p[1] >= dims[1] - 1 || (p[2] >= dims[2] - 1 && dims[2] != 1)) {
246 const auto locCubeId{p[0] + p[1] * (dims[0] - 1)
247 + p[2] * (dims[0] - 1) * (dims[1] - 1)};
249 const auto nCellsPerCube{this->dimensionality_ == 3 ? 6 : 2};
250 return locCubeId * nCellsPerCube + gcid % nCellsPerCube;
253ttk::SimplexId ttk::RegularGridTriangulation::getEdgeGlobalIdInternal(
255 if(!ttk::isRunningWithMPI()) {
259#ifndef TTK_ENABLE_KAMIKAZE
260 if(leid > this->getNumberOfEdgesInternal() - 1 || leid < 0) {
263 if(this->metaGrid_ ==
nullptr) {
268 if(this->dimensionality_ == 1) {
269 return this->getCellGlobalIdInternal(leid);
274 this->getEdgeVertexInternal(leid, 0, lv0);
275 this->getEdgeVertexInternal(leid, 1, lv1);
278 const auto gv0 = this->getVertexGlobalId(lv0);
279 const auto gv1 = this->getVertexGlobalId(lv1);
280 if(gv0 == -1 || gv1 == -1) {
284 return this->metaGrid_->findEdgeFromVertices(gv0, gv1);
287ttk::SimplexId ttk::RegularGridTriangulation::getEdgeLocalIdInternal(
289 if(!ttk::isRunningWithMPI()) {
293#ifndef TTK_ENABLE_KAMIKAZE
294 if(this->metaGrid_ ==
nullptr) {
297 if(geid > this->metaGrid_->getNumberOfEdgesInternal() - 1 || geid < 0) {
302 if(this->dimensionality_ == 1) {
303 return this->getCellLocalIdInternal(geid);
308 this->metaGrid_->getEdgeVertexInternal(geid, 0, gv0);
309 this->metaGrid_->getEdgeVertexInternal(geid, 1, gv1);
312 const auto lv0 = this->getVertexLocalId(gv0);
313 const auto lv1 = this->getVertexLocalId(gv1);
314 if(lv0 == -1 || lv1 == -1) {
318 return this->findEdgeFromVertices(lv0, lv1);
321ttk::SimplexId ttk::RegularGridTriangulation::getTriangleGlobalIdInternal(
323 if(!ttk::isRunningWithMPI()) {
327#ifndef TTK_ENABLE_KAMIKAZE
328 if(ltid > this->getNumberOfTrianglesInternal() - 1 || ltid < 0) {
331 if(this->metaGrid_ ==
nullptr) {
336 if(this->dimensionality_ == 2) {
337 return this->getCellGlobalIdInternal(ltid);
342 this->getTriangleVertexInternal(ltid, 0, lv0);
343 this->getTriangleVertexInternal(ltid, 1, lv1);
344 this->getTriangleVertexInternal(ltid, 2, lv2);
347 std::array<SimplexId, 3> globVerts{
348 this->getVertexGlobalId(lv0),
349 this->getVertexGlobalId(lv1),
350 this->getVertexGlobalId(lv2),
352 for(
const auto gv : globVerts) {
358 return this->metaGrid_->findTriangleFromVertices(globVerts);
361ttk::SimplexId ttk::RegularGridTriangulation::getTriangleLocalIdInternal(
363 if(!ttk::isRunningWithMPI()) {
367#ifndef TTK_ENABLE_KAMIKAZE
368 if(this->metaGrid_ ==
nullptr) {
371 if(gtid > this->metaGrid_->getNumberOfTrianglesInternal() - 1 || gtid < 0) {
376 if(this->dimensionality_ == 2) {
377 return this->getCellGlobalIdInternal(gtid);
382 this->metaGrid_->getTriangleVertexInternal(gtid, 0, gv0);
383 this->metaGrid_->getTriangleVertexInternal(gtid, 1, gv1);
384 this->metaGrid_->getTriangleVertexInternal(gtid, 2, gv2);
387 std::array<SimplexId, 3> locVerts{
388 this->getVertexLocalId(gv0),
389 this->getVertexLocalId(gv1),
390 this->getVertexLocalId(gv2),
392 for(
const auto lv : locVerts) {
398 return this->findTriangleFromVertices(locVerts);
401int ttk::RegularGridTriangulation::preconditionDistributedVertices() {
402 if(this->hasPreconditionedDistributedVertices_) {
405 if(!isRunningWithMPI()) {
408 if(this->vertexGhost_ ==
nullptr) {
409 if(ttk::isRunningWithMPI()) {
410 this->printErr(
"Missing vertex ghost array!");
415 const auto nLocVertices{this->getNumberOfVertices()};
420 + this->dimensions_[0]},
421 localBBox_y_min{this->localGridOffset_[1] + this->dimensions_[1]},
422 localBBox_z_min{this->localGridOffset_[2] + this->dimensions_[2]};
424 localBBox_y_max{this->localGridOffset_[1]},
425 localBBox_z_max{this->localGridOffset_[2]};
426#ifdef TTK_ENABLE_OPENMP
427#pragma omp parallel for reduction( \
429 : localBBox_x_min, localBBox_y_min, localBBox_z_min) \
431 : localBBox_x_max, localBBox_y_max, localBBox_z_max)
433 for(
SimplexId lvid = 0; lvid < nLocVertices; ++lvid) {
435 if(this->vertexGhost_[lvid] != 0) {
439 std::array<SimplexId, 3> p{};
440 p = this->getVertGlobalCoords(lvid);
442 if(p[0] < localBBox_x_min) {
443 localBBox_x_min = p[0];
445 if(p[0] > localBBox_x_max) {
446 localBBox_x_max = p[0];
448 if(p[1] < localBBox_y_min) {
449 localBBox_y_min = p[1];
451 if(p[1] > localBBox_y_max) {
452 localBBox_y_max = p[1];
454 if(p[2] < localBBox_z_min) {
455 localBBox_z_min = p[2];
457 if(p[2] > localBBox_z_max) {
458 localBBox_z_max = p[2];
463 localBBox_x_min, localBBox_x_max, localBBox_y_min,
464 localBBox_y_max, localBBox_z_min, localBBox_z_max,
467 for(
size_t i = 0; i < this->neighborRanks_.size(); ++i) {
468 const auto neigh{this->neighborRanks_[i]};
469 MPI_Sendrecv(this->neighborVertexBBoxes_[
ttk::MPIrank_].data(), 6,
471 this->neighborVertexBBoxes_[neigh].data(), 6,
472 ttk::getMPIType(
SimplexId{}), neigh, neigh, ttk::MPIcomm_,
476 this->hasPreconditionedDistributedVertices_ =
true;
481int ttk::RegularGridTriangulation::preconditionExchangeGhostCells() {
483 if(this->hasPreconditionedExchangeGhostCells_) {
486 if(!ttk::hasInitializedMPI()) {
491 const auto nLocCells{this->getNumberOfCells()};
495 cellRank = this->getCellRankInternal(lcid);
498 this->ghostCellsPerOwner_[cellRank].emplace_back(
499 this->getCellGlobalIdInternal(lcid));
510 for(
const auto neigh : this->neighborRanks_) {
512 const auto nCells{this->ghostCellsPerOwner_[neigh].size()};
513 MPI_Sendrecv(&nCells, 1, ttk::getMPIType(nCells), neigh,
ttk::MPIrank_,
514 &nOwnedGhostCellsPerRank[neigh], 1, ttk::getMPIType(nCells),
515 neigh, neigh, ttk::MPIcomm_, MPI_STATUS_IGNORE);
516 this->remoteGhostCells_[neigh].resize(nOwnedGhostCellsPerRank[neigh]);
519 MPI_Sendrecv(this->ghostCellsPerOwner_[neigh].data(),
520 this->ghostCellsPerOwner_[neigh].size(), MIT, neigh,
522 this->remoteGhostCells_[neigh].size(), MIT, neigh, neigh,
523 ttk::MPIcomm_, MPI_STATUS_IGNORE);
526 this->hasPreconditionedExchangeGhostCells_ =
true;
530int ttk::RegularGridTriangulation::preconditionExchangeGhostVertices() {
532 if(this->hasPreconditionedExchangeGhostVertices_) {
535 if((!ttk::hasInitializedMPI()) || (!ttk::isRunningWithMPI())) {
542 const auto nLocVertices{this->getNumberOfVertices()};
547 this->ghostVerticesPerOwner_[this->getVertexRankInternal(lvid)]
548 .emplace_back(this->getVertexGlobalIdInternal(lvid));
557 std::vector<size_t> nOwnedGhostVerticesPerRank(
ttk::MPIsize_);
559 for(
const auto neigh : this->neighborRanks_) {
561 const auto nVerts{this->ghostVerticesPerOwner_[neigh].size()};
562 MPI_Sendrecv(&nVerts, 1, ttk::getMPIType(nVerts), neigh,
ttk::MPIrank_,
563 &nOwnedGhostVerticesPerRank[neigh], 1, ttk::getMPIType(nVerts),
564 neigh, neigh, ttk::MPIcomm_, MPI_STATUS_IGNORE);
565 this->remoteGhostVertices_[neigh].resize(nOwnedGhostVerticesPerRank[neigh]);
568 MPI_Sendrecv(this->ghostVerticesPerOwner_[neigh].data(),
569 this->ghostVerticesPerOwner_[neigh].size(), MIT, neigh,
571 this->remoteGhostVertices_[neigh].size(), MIT, neigh, neigh,
572 ttk::MPIcomm_, MPI_STATUS_IGNORE);
575 this->hasPreconditionedExchangeGhostVertices_ =
true;
#define TTK_TRIANGULATION_INTERNAL(NAME)
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getEdgeStar(const SimplexId &edgeId, const int &localStarId, SimplexId &starId) const
SimplexId ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getTriangleStarNumber(const SimplexId &triangleId) const
SimplexId ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getEdgeStarNumber(const SimplexId &edgeId) const
int ImplicitTriangulationCRTP< Derived >::TTK_TRIANGULATION_INTERNAL getTriangleStar(const SimplexId &triangleId, const int &localStarId, SimplexId &starId) const
virtual SimplexId getVertexEdgeNumberInternal(const SimplexId &ttkNotUsed(vertexId)) const
virtual int getEdgeVertexInternal(const SimplexId &ttkNotUsed(edgeId), const int &ttkNotUsed(localVertexId), SimplexId &ttkNotUsed(vertexId)) const
virtual SimplexId getVertexTriangleNumberInternal(const SimplexId &ttkNotUsed(vertexId)) const
virtual int getVertexTriangleInternal(const SimplexId &ttkNotUsed(vertexId), const int &ttkNotUsed(localTriangleId), SimplexId &ttkNotUsed(triangleId)) const
virtual int getTriangleVertexInternal(const SimplexId &ttkNotUsed(triangleId), const int &ttkNotUsed(localVertexId), SimplexId &ttkNotUsed(vertexId)) const
virtual int getVertexEdgeInternal(const SimplexId &ttkNotUsed(vertexId), const int &ttkNotUsed(localEdgeId), SimplexId &ttkNotUsed(edgeId)) const
void setDebugMsgPrefix(const std::string &prefix)
SimplexId findEdgeFromVertices(const SimplexId v0, const SimplexId v1) const
SimplexId findTriangleFromVertices(std::array< SimplexId, 3 > &verts) const
RegularGridTriangulation()
COMMON_EXPORTS int MPIsize_
int SimplexId
Identifier type for simplices of any dimension.
COMMON_EXPORTS int MPIrank_
long long int LongSimplexId
Identifier type for simplices of any dimension.