6 : dimensionality_{-1} {
13 const auto nEdges = this->getVertexEdgeNumberInternal(v0);
16 std::array<SimplexId, 2> eVerts{};
17 this->getVertexEdgeInternal(v0, i, e);
18 this->getEdgeVertexInternal(e, 0, eVerts[0]);
19 this->getEdgeVertexInternal(e, 1, eVerts[1]);
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());
34 const auto nTriangles = this->getVertexTriangleNumberInternal(verts[0]);
35 for(
SimplexId i = 0; i < nTriangles; ++i) {
37 std::array<SimplexId, 3> tVerts{};
38 this->getVertexTriangleInternal(verts[0], i, t);
39 this->getTriangleVertexInternal(t, 0, tVerts[0]);
40 this->getTriangleVertexInternal(t, 1, tVerts[1]);
41 this->getTriangleVertexInternal(t, 2, tVerts[2]);
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]) {
77ttk::SimplexId ttk::RegularGridTriangulation::getVertexGlobalIdInternal(
79 if(!ttk::isRunningWithMPI()) {
83#ifndef TTK_ENABLE_KAMIKAZE
88 if(this->metaGrid_ ==
nullptr) {
93 const auto p{this->getVertGlobalCoords(lvid)};
94 const auto &dims{this->metaGrid_->getGridDimensions()};
97 return p[0] + p[1] * dims[0] + p[2] * dims[0] * dims[1];
100ttk::SimplexId ttk::RegularGridTriangulation::getVertexLocalIdInternal(
102 if(!ttk::isRunningWithMPI()) {
106#ifndef TTK_ENABLE_KAMIKAZE
107 if(this->metaGrid_ ==
nullptr) {
111 > this->metaGrid_->TTK_TRIANGULATION_INTERNAL(getNumberOfVertices)() - 1
117 const auto p{this->getVertLocalCoords(gvid)};
118 const auto &dims{this->getGridDimensions()};
120 if(p[0] < 0 || p[1] < 0 || p[2] < 0 || p[0] > dims[0] - 1
121 || p[1] > dims[1] - 1 || p[2] > dims[2] - 1) {
126 return p[0] + p[1] * dims[0] + p[2] * dims[0] * dims[1];
129ttk::SimplexId ttk::RegularGridTriangulation::getCellGlobalIdInternal(
131 if(!ttk::isRunningWithMPI()) {
135#ifndef TTK_ENABLE_KAMIKAZE
140 if(this->metaGrid_ ==
nullptr) {
146 std::array<SimplexId, 3> p{};
147 if(this->dimensionality_ == 3) {
148 this->tetrahedronToPosition(lcid, p.data());
149 }
else if(this->dimensionality_ == 2) {
150 this->triangleToPosition2d(lcid, p.data());
154 p[0] += this->localGridOffset_[0];
155 p[1] += this->localGridOffset_[1];
156 p[2] += this->localGridOffset_[2];
158 const auto &dims{this->metaGrid_->getGridDimensions()};
161 const auto globCubeId{p[0] + p[1] * (dims[0] - 1)
162 + p[2] * (dims[0] - 1) * (dims[1] - 1)};
164 const auto nCellsPerCube{this->dimensionality_ == 3 ? 6 : 2};
165 return globCubeId * nCellsPerCube + lcid % nCellsPerCube;
168ttk::SimplexId ttk::RegularGridTriangulation::getCellLocalIdInternal(
170 if(!ttk::isRunningWithMPI()) {
174#ifndef TTK_ENABLE_KAMIKAZE
175 if(this->metaGrid_ ==
nullptr) {
178 if(gcid > this->metaGrid_->TTK_TRIANGULATION_INTERNAL(getNumberOfCells)() - 1
185 std::array<SimplexId, 3> p{};
186 if(this->dimensionality_ == 3) {
187 this->metaGrid_->tetrahedronToPosition(gcid, p.data());
188 }
else if(this->dimensionality_ == 2) {
189 this->metaGrid_->triangleToPosition2d(gcid, p.data());
193 p[0] -= this->localGridOffset_[0];
194 p[1] -= this->localGridOffset_[1];
195 p[2] -= this->localGridOffset_[2];
197 const auto &dims{this->getGridDimensions()};
200 const auto locCubeId{p[0] + p[1] * (dims[0] - 1)
201 + p[2] * (dims[0] - 1) * (dims[1] - 1)};
203 const auto nCellsPerCube{this->dimensionality_ == 3 ? 6 : 2};
204 return locCubeId * nCellsPerCube + gcid % nCellsPerCube;
207ttk::SimplexId ttk::RegularGridTriangulation::getEdgeGlobalIdInternal(
209 if(!ttk::isRunningWithMPI()) {
213#ifndef TTK_ENABLE_KAMIKAZE
214 if(leid > this->getNumberOfEdgesInternal() - 1 || leid < 0) {
217 if(this->metaGrid_ ==
nullptr) {
222 if(this->dimensionality_ == 1) {
223 return this->getCellGlobalIdInternal(leid);
228 this->getEdgeVertexInternal(leid, 0, lv0);
229 this->getEdgeVertexInternal(leid, 1, lv1);
232 const auto gv0 = this->getVertexGlobalId(lv0);
233 const auto gv1 = this->getVertexGlobalId(lv1);
234 if(gv0 == -1 || gv1 == -1) {
238 return this->metaGrid_->findEdgeFromVertices(gv0, gv1);
241ttk::SimplexId ttk::RegularGridTriangulation::getEdgeLocalIdInternal(
243 if(!ttk::isRunningWithMPI()) {
247#ifndef TTK_ENABLE_KAMIKAZE
248 if(this->metaGrid_ ==
nullptr) {
251 if(geid > this->metaGrid_->getNumberOfEdgesInternal() - 1 || geid < 0) {
256 if(this->dimensionality_ == 1) {
257 return this->getCellLocalIdInternal(geid);
262 this->metaGrid_->getEdgeVertexInternal(geid, 0, gv0);
263 this->metaGrid_->getEdgeVertexInternal(geid, 1, gv1);
266 const auto lv0 = this->getVertexLocalId(gv0);
267 const auto lv1 = this->getVertexLocalId(gv1);
268 if(lv0 == -1 || lv1 == -1) {
272 return this->findEdgeFromVertices(lv0, lv1);
275ttk::SimplexId ttk::RegularGridTriangulation::getTriangleGlobalIdInternal(
277 if(!ttk::isRunningWithMPI()) {
281#ifndef TTK_ENABLE_KAMIKAZE
282 if(ltid > this->getNumberOfTrianglesInternal() - 1 || ltid < 0) {
285 if(this->metaGrid_ ==
nullptr) {
290 if(this->dimensionality_ == 2) {
291 return this->getCellGlobalIdInternal(ltid);
296 this->getTriangleVertexInternal(ltid, 0, lv0);
297 this->getTriangleVertexInternal(ltid, 1, lv1);
298 this->getTriangleVertexInternal(ltid, 2, lv2);
301 std::array<SimplexId, 3> globVerts{
302 this->getVertexGlobalId(lv0),
303 this->getVertexGlobalId(lv1),
304 this->getVertexGlobalId(lv2),
306 for(
const auto gv : globVerts) {
312 return this->metaGrid_->findTriangleFromVertices(globVerts);
315ttk::SimplexId ttk::RegularGridTriangulation::getTriangleLocalIdInternal(
317 if(!ttk::isRunningWithMPI()) {
321#ifndef TTK_ENABLE_KAMIKAZE
322 if(this->metaGrid_ ==
nullptr) {
325 if(gtid > this->metaGrid_->getNumberOfTrianglesInternal() - 1 || gtid < 0) {
330 if(this->dimensionality_ == 2) {
331 return this->getCellGlobalIdInternal(gtid);
336 this->metaGrid_->getTriangleVertexInternal(gtid, 0, gv0);
337 this->metaGrid_->getTriangleVertexInternal(gtid, 1, gv1);
338 this->metaGrid_->getTriangleVertexInternal(gtid, 2, gv2);
341 std::array<SimplexId, 3> locVerts{
342 this->getVertexLocalId(gv0),
343 this->getVertexLocalId(gv1),
344 this->getVertexLocalId(gv2),
346 for(
const auto lv : locVerts) {
352 return this->findTriangleFromVertices(locVerts);
355int ttk::RegularGridTriangulation::preconditionDistributedVertices() {
356 if(this->hasPreconditionedDistributedVertices_) {
359 if(!isRunningWithMPI()) {
362 if(this->vertexGhost_ ==
nullptr) {
363 if(ttk::isRunningWithMPI()) {
364 this->printErr(
"Missing vertex ghost array!");
369 const auto nLocVertices{this->getNumberOfVertices()};
374 + this->dimensions_[0]},
375 localBBox_y_min{this->localGridOffset_[1] + this->dimensions_[1]},
376 localBBox_z_min{this->localGridOffset_[2] + this->dimensions_[2]};
378 localBBox_y_max{this->localGridOffset_[1]},
379 localBBox_z_max{this->localGridOffset_[2]};
380#ifdef TTK_ENABLE_OPENMP
381#pragma omp parallel for reduction( \
383 : localBBox_x_min, localBBox_y_min, localBBox_z_min) \
385 : localBBox_x_max, localBBox_y_max, localBBox_z_max)
387 for(
SimplexId lvid = 0; lvid < nLocVertices; ++lvid) {
389 if(this->vertexGhost_[lvid] != 0) {
393 std::array<SimplexId, 3> p{};
394 p = this->getVertGlobalCoords(lvid);
396 if(p[0] < localBBox_x_min) {
397 localBBox_x_min = p[0];
399 if(p[0] > localBBox_x_max) {
400 localBBox_x_max = p[0];
402 if(p[1] < localBBox_y_min) {
403 localBBox_y_min = p[1];
405 if(p[1] > localBBox_y_max) {
406 localBBox_y_max = p[1];
408 if(p[2] < localBBox_z_min) {
409 localBBox_z_min = p[2];
411 if(p[2] > localBBox_z_max) {
412 localBBox_z_max = p[2];
417 localBBox_x_min, localBBox_x_max, localBBox_y_min,
418 localBBox_y_max, localBBox_z_min, localBBox_z_max,
421 for(
size_t i = 0; i < this->neighborRanks_.size(); ++i) {
422 const auto neigh{this->neighborRanks_[i]};
423 MPI_Sendrecv(this->neighborVertexBBoxes_[
ttk::MPIrank_].data(), 6,
425 this->neighborVertexBBoxes_[neigh].data(), 6,
426 ttk::getMPIType(
SimplexId{}), neigh, neigh, ttk::MPIcomm_,
430 this->hasPreconditionedDistributedVertices_ =
true;
435int ttk::RegularGridTriangulation::preconditionExchangeGhostCells() {
437 if(this->hasPreconditionedExchangeGhostCells_) {
440 if(!ttk::hasInitializedMPI()) {
445 const auto nLocCells{this->getNumberOfCells()};
449 cellRank = this->getCellRankInternal(lcid);
452 this->ghostCellsPerOwner_[cellRank].emplace_back(
453 this->getCellGlobalIdInternal(lcid));
464 for(
const auto neigh : this->neighborRanks_) {
466 const auto nCells{this->ghostCellsPerOwner_[neigh].size()};
467 MPI_Sendrecv(&nCells, 1, ttk::getMPIType(nCells), neigh,
ttk::MPIrank_,
468 &nOwnedGhostCellsPerRank[neigh], 1, ttk::getMPIType(nCells),
469 neigh, neigh, ttk::MPIcomm_, MPI_STATUS_IGNORE);
470 this->remoteGhostCells_[neigh].resize(nOwnedGhostCellsPerRank[neigh]);
473 MPI_Sendrecv(this->ghostCellsPerOwner_[neigh].data(),
474 this->ghostCellsPerOwner_[neigh].size(), MIT, neigh,
476 this->remoteGhostCells_[neigh].size(), MIT, neigh, neigh,
477 ttk::MPIcomm_, MPI_STATUS_IGNORE);
480 this->hasPreconditionedExchangeGhostCells_ =
true;
484int ttk::RegularGridTriangulation::preconditionExchangeGhostVertices() {
486 if(this->hasPreconditionedExchangeGhostVertices_) {
489 if((!ttk::hasInitializedMPI()) || (!ttk::isRunningWithMPI())) {
496 const auto nLocVertices{this->getNumberOfVertices()};
501 this->ghostVerticesPerOwner_[this->getVertexRankInternal(lvid)]
502 .emplace_back(this->getVertexGlobalIdInternal(lvid));
511 std::vector<size_t> nOwnedGhostVerticesPerRank(
ttk::MPIsize_);
513 for(
const auto neigh : this->neighborRanks_) {
515 const auto nVerts{this->ghostVerticesPerOwner_[neigh].size()};
516 MPI_Sendrecv(&nVerts, 1, ttk::getMPIType(nVerts), neigh,
ttk::MPIrank_,
517 &nOwnedGhostVerticesPerRank[neigh], 1, ttk::getMPIType(nVerts),
518 neigh, neigh, ttk::MPIcomm_, MPI_STATUS_IGNORE);
519 this->remoteGhostVertices_[neigh].resize(nOwnedGhostVerticesPerRank[neigh]);
522 MPI_Sendrecv(this->ghostVerticesPerOwner_[neigh].data(),
523 this->ghostVerticesPerOwner_[neigh].size(), MIT, neigh,
525 this->remoteGhostVertices_[neigh].size(), MIT, neigh, neigh,
526 ttk::MPIcomm_, MPI_STATUS_IGNORE);
529 this->hasPreconditionedExchangeGhostVertices_ =
true;
#define TTK_TRIANGULATION_INTERNAL(NAME)
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_
COMMON_EXPORTS int MPIrank_
long long int LongSimplexId
Identifier type for simplices of any dimension.
int SimplexId
Identifier type for simplices of any dimension.