211 this->
dms_.setComputeMinSad(data);
212#if defined(TTK_ENABLE_MPI) && defined(TTK_ENABLE_OPENMP)
213 this->dmsMPI_.setComputeMinSad(data);
217 this->
dms_.setComputeSadSad(data);
218#if defined(TTK_ENABLE_MPI) && defined(TTK_ENABLE_OPENMP)
219 this->dmsMPI_.setComputeSadSad(data);
223 this->
dms_.setComputeSadMax(data);
224#if defined(TTK_ENABLE_MPI) && defined(TTK_ENABLE_OPENMP)
225 this->dmsMPI_.setComputeSadMax(data);
233 template <
typename scalarType,
typename triangulationType>
236 const scalarType *
const scalars,
237 const triangulationType *triangulation);
246 template <
typename scalarType>
250 std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool>> &pairs,
251 std::vector<PersistencePair> &diagram)
const;
261 template <
typename scalarType,
class triangulationType>
262 int execute(std::vector<PersistencePair> &CTDiagram,
263 const scalarType *inputScalars,
264 const size_t scalarsMTime,
266 const triangulationType *triangulation,
267 const std::vector<bool> *updateMask =
nullptr);
269 template <
typename scalarType,
class triangulationType>
270 int executeFTM(std::vector<PersistencePair> &CTDiagram,
271 const scalarType *inputScalars,
273 const triangulationType *triangulation);
275 template <
class triangulationType>
278 const triangulationType *triangulation);
279 template <
typename scalarType,
class triangulationType>
281 const scalarType *inputScalars,
282 const triangulationType *triangulation);
284 template <
class triangulationType>
287 const triangulationType *triangulation);
290 template <
typename scalarType,
class triangulationType>
291 int executeDiscreteMorseSandwichMPI(std::vector<PersistencePair> &CTDiagram,
292 const scalarType *inputScalars,
293 const size_t scalarsMTime,
295 const triangulationType *triangulation);
298 template <
typename scalarType,
class triangulationType>
300 const scalarType *inputScalars,
301 const size_t scalarsMTime,
303 const triangulationType *triangulation,
304 const std::vector<bool> *updateMask
307 template <
class triangulationType>
310 template <
class triangulationType>
311 void checkManifold(
const triangulationType *
const triangulation);
327 dms_.preconditionTriangulation(triangulation);
330#if defined(TTK_ENABLE_MPI) && defined(TTK_ENABLE_OPENMP)
334 dmsMPI_.preconditionTriangulation(triangulation);
341 psp_.preconditionTriangulation(triangulation);
365#if defined(TTK_ENABLE_MPI) && defined(TTK_ENABLE_OPENMP)
388template <
typename scalarType>
392 std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool>> &pairs,
393 std::vector<PersistencePair> &diagram)
const {
396 diagram.resize(numberOfPairs);
400 const bool type = std::get<3>(pairs[i]);
435 diagram.back().isFinite =
false;
440template <
typename scalarType,
typename triangulationType>
442 std::vector<PersistencePair> &persistencePairs,
443 const scalarType *
const scalars,
444 const triangulationType *triangulation) {
446#ifdef TTK_ENABLE_OPENMP
447#pragma omp parallel for num_threads(threadNumber_)
449 for(std::size_t i = 0; i < persistencePairs.size(); ++i) {
450 auto &pair{persistencePairs[i]};
451 triangulation->getVertexPoint(pair.birth.id, pair.birth.coords[0],
452 pair.birth.coords[1], pair.birth.coords[2]);
453 pair.birth.sfValue = scalars[pair.birth.id];
454 triangulation->getVertexPoint(pair.death.id, pair.death.coords[0],
455 pair.death.coords[1], pair.death.coords[2]);
456 pair.death.sfValue = scalars[pair.death.id];
460template <
typename scalarType,
class triangulationType>
462 const scalarType *inputScalars,
463 const size_t scalarsMTime,
465 const triangulationType *triangulation,
466 const std::vector<bool> *updateMask) {
481 inputOffsets, triangulation, updateMask);
490 executeFTM(CTDiagram, inputScalars, inputOffsets, triangulation);
494 executeDiscreteMorseSandwichMPI(
495 CTDiagram, inputScalars, scalarsMTime, inputOffsets, triangulation);
497 this->
printWrn(
"TTK is not compiled with MPI. Running sequentially.");
498 this->
printWrn(
"If you want to run TTK with MPI, compile it with "
499 "TTK_ENABLE_MPI to ON.");
501 CTDiagram, inputScalars, scalarsMTime, inputOffsets, triangulation);
508 this->
printMsg(
"Complete", 1.0, tm.getElapsedTime(), this->threadNumber_);
510 if(!isRunningWithMPI()) {
526template <
class triangulationType>
528 std::vector<PersistencePair> &CTDiagram,
530 const triangulationType *triangulation) {
533 const auto dim = triangulation->getDimensionality();
535 std::vector<ttk::PersistentSimplexPairs::PersistencePair> pairs{};
539 psp_.computePersistencePairs(pairs, inputOffsets, *triangulation);
540 dms_.setInputOffsets(inputOffsets);
545#ifdef TTK_ENABLE_OPENMP
546#pragma omp parallel for num_threads(threadNumber_)
548 for(
size_t i = 0; i < pairs.size(); ++i) {
549 auto &pair{pairs[i]};
551 pair.birth =
dms_.getCellGreaterVertex(
552 Cell{pair.type, pair.birth}, *triangulation);
554 if(pair.death != -1) {
555 pair.death =
dms_.getCellGreaterVertex(
556 Cell{pair.type + 1, pair.death}, *triangulation);
560 CTDiagram.reserve(pairs.size() + 1);
563 const auto nVerts = triangulation->getNumberOfVertices();
565 inputOffsets, std::max_element(inputOffsets, inputOffsets + nVerts));
568 for(
const auto &p : pairs) {
569 const auto isFinite = (p.death >= 0);
570 const auto death = isFinite ? p.death : globmax;
572 const auto deathType = (isFinite && dim > 1)
578 }
else if(p.type == 1) {
581 const auto deathType = (isFinite && dim == 3)
587 }
else if(p.type == 2) {
598template <
typename scalarType,
class triangulationType>
600 std::vector<PersistencePair> &CTDiagram,
601 const scalarType *inputScalars,
602 const size_t scalarsMTime,
604 const triangulationType *triangulation,
605 const std::vector<bool> *updateMask) {
608 const auto dim = triangulation->getDimensionality();
612 inputScalars, scalarsMTime, inputOffsets, *triangulation, updateMask);
613 std::vector<DiscreteMorseSandwich::PersistencePair> dms_pairs{};
614 dms_.computePersistencePairs(
616 CTDiagram.resize(dms_pairs.size());
620#ifdef TTK_ENABLE_OPENMP
621#pragma omp parallel for num_threads(threadNumber_)
623 for(
size_t i = 0; i < dms_pairs.size(); ++i) {
624 auto &pair{dms_pairs[i]};
626 pair.birth =
dms_.getCellGreaterVertex(
627 Cell{pair.type, pair.birth}, *triangulation);
629 if(pair.death != -1) {
630 pair.death =
dms_.getCellGreaterVertex(
631 Cell{pair.type + 1, pair.death}, *triangulation);
636 const auto nVerts = triangulation->getNumberOfVertices();
638 inputOffsets, std::max_element(inputOffsets, inputOffsets + nVerts));
641#ifdef TTK_ENABLE_OPENMP
642#pragma omp parallel for num_threads(threadNumber_)
644 for(
size_t i = 0; i < dms_pairs.size(); ++i) {
645 const auto &p{dms_pairs[i]};
646 const auto isFinite = (p.death >= 0);
647 const auto death = isFinite ? p.death : globmax;
655 }
else if(p.type == 1) {
663 }
else if(p.type == 2) {
676#if defined(TTK_ENABLE_MPI) && defined(TTK_ENABLE_OPENMP)
677template <
typename scalarType,
class triangulationType>
678int ttk::PersistenceDiagram::executeDiscreteMorseSandwichMPI(
679 std::vector<PersistencePair> &CTDiagram,
680 const scalarType *inputScalars,
681 const size_t scalarsMTime,
683 const triangulationType *triangulation) {
686 const auto dim = triangulation->getDimensionality();
687 dmsMPI_.setUseTasks(UseTasks);
689 dmsMPI_.buildGradient(
690 inputScalars, scalarsMTime, inputOffsets, *triangulation);
691 std::vector<DiscreteMorseSandwichMPI::PersistencePair> dms_pairs{};
692 dmsMPI_.computePersistencePairs(
693 dms_pairs, inputOffsets, *triangulation, this->IgnoreBoundary);
694 CTDiagram.resize(dms_pairs.size());
705 const auto nVerts = triangulation->getNumberOfVertices();
706 const SimplexId localMaxId = std::distance(
707 inputOffsets, std::max_element(inputOffsets, inputOffsets + nVerts));
708 MPI_Datatype MPI_SimplexId = getMPIType(localMaxId);
712 } localMax, globalMax;
713 localMax.rank = triangulation->getVertexRank(localMaxId);
714 localMax.offset =
static_cast<long int>(inputOffsets[localMaxId]);
716 &localMax, &globalMax, 1, MPI_LONG_INT, MPI_MAXLOC, ttk::MPIcomm_);
718 double maxMetaData[4];
721 globmax = triangulation->getVertexGlobalId(localMaxId);
722 triangulation->getVertexPoint(localMaxId, coords[0], coords[1], coords[2]);
723 maxMetaData[0] = coords[0];
724 maxMetaData[1] = coords[1];
725 maxMetaData[2] = coords[2];
726 maxMetaData[3] = inputScalars[localMaxId];
728 MPI_Bcast(&globmax, 1, MPI_SimplexId, globalMax.rank, ttk::MPIcomm_);
729 MPI_Bcast(maxMetaData, 4, MPI_DOUBLE, globalMax.rank, ttk::MPIcomm_);
731 std::vector<std::vector<dataRequest>> sendRecvBuffer(
ttk::MPIsize_);
733 const auto createDataRequestMPIType =
734 [&MPI_SimplexId](MPI_Datatype &MPI_MessageType) {
735 MPI_Datatype types[] = {MPI_SimplexId, MPI_SimplexId, MPI_CHAR, MPI_CHAR};
736 int lengths[] = {1, 1, 1, 1};
737 const long int mpi_offsets[]
738 = {offsetof(dataRequest, gid_), offsetof(dataRequest, lid_),
739 offsetof(dataRequest, dim_), offsetof(dataRequest, isBirth_)};
740 MPI_Type_create_struct(4, lengths, mpi_offsets, types, &MPI_MessageType);
741 MPI_Type_commit(&MPI_MessageType);
744 struct dataResponse {
748 float coords_[3] = {0, 0, 0};
753 const auto createDataResponseMPIType =
754 [&MPI_SimplexId](MPI_Datatype &MPI_MessageType) {
755 MPI_Datatype types[] = {MPI_SimplexId, MPI_SimplexId, MPI_SimplexId,
756 MPI_FLOAT, MPI_DOUBLE, MPI_CHAR};
757 int lengths[] = {1, 1, 1, 3, 1, 1};
758 const long int mpi_offsets[]
759 = {offsetof(dataResponse, lid_), offsetof(dataResponse, vertexGid_),
760 offsetof(dataResponse, offset_), offsetof(dataResponse, coords_),
761 offsetof(dataResponse, sfValue_), offsetof(dataResponse, isBirth_)};
762 MPI_Type_create_struct(6, lengths, mpi_offsets, types, &MPI_MessageType);
763 MPI_Type_commit(&MPI_MessageType);
766 const auto fillBirthData
768 DiscreteMorseSandwichMPI::PersistencePair &p,
770 CTPair.birth.id = birthId;
773 }
else if(p.type == 1) {
776 }
else if(p.type == 2) {
777 CTPair.birth.type = ((p.death >= 0) || dim == 3)
783 const auto augmentBirthPersistence =
784 [&triangulation, &inputOffsets](
786 triangulation->getVertexPoint(lid, CTPair.birth.coords[0],
787 CTPair.birth.coords[1],
788 CTPair.birth.coords[2]);
789 CTPair.birth.sfValue = scalars[lid];
790 CTPair.birth.offset = inputOffsets[lid];
793 const auto fillDeathData = [&dim](
795 DiscreteMorseSandwichMPI::PersistencePair &p,
797 const auto isFinite = (p.death >= 0);
798 CTPair.death.id = deathId;
802 }
else if(p.type == 1) {
805 }
else if(p.type == 2) {
810 const auto augmentDeathPersistence =
811 [&triangulation, &inputOffsets](
813 triangulation->getVertexPoint(lid, CTPair.death.coords[0],
814 CTPair.death.coords[1],
815 CTPair.death.coords[2]);
816 CTPair.death.sfValue = scalars[lid];
817 CTPair.death.offset = inputOffsets[lid];
820 const auto getBirthSimplexType = [&dim](
const int type) {
835 const auto getDeathSimplexType = [&dim](
const int type) {
849 for(
ttk::SimplexId i = 0; i < static_cast<ttk::SimplexId>(dms_pairs.size());
851 auto &pair{dms_pairs[i]};
852 int simplexType = getBirthSimplexType(pair.type);
854 = triangulation->getSimplexLocalId(pair.birth, simplexType);
856 && triangulation->getSimplexRank(lid, simplexType) ==
ttk::MPIrank_) {
859 = dmsMPI_.getCellGreaterVertex(Cell{pair.type, lid}, *triangulation);
860 pair.birth = triangulation->getVertexGlobalId(lid);
862 CTDiagram[i].dim = pair.type;
863 CTDiagram[i].isFinite = (pair.death >= 0);
865 fillBirthData(CTDiagram[i], pair, pair.birth);
866 augmentBirthPersistence(CTDiagram[i], lid, inputScalars);
869 dataRequest{pair.birth, i,
static_cast<char>(pair.type), 1});
871 if(pair.death == -1) {
872 CTDiagram[i].dim = pair.type;
873 CTDiagram[i].isFinite = (pair.death >= 0);
874 pair.death = globmax;
875 fillDeathData(CTDiagram[i], pair, pair.death);
876 CTDiagram[i].death.coords[0] = maxMetaData[0];
877 CTDiagram[i].death.coords[1] = maxMetaData[1];
878 CTDiagram[i].death.coords[2] = maxMetaData[2];
879 CTDiagram[i].death.sfValue = maxMetaData[3];
880 CTDiagram[i].death.offset = globalMax.offset;
882 simplexType = getDeathSimplexType(pair.type);
883 lid = triangulation->getSimplexLocalId(pair.death, simplexType);
885 && triangulation->getSimplexRank(lid, simplexType) ==
ttk::MPIrank_) {
886 CTDiagram[i].dim = pair.type;
887 CTDiagram[i].isFinite = (pair.death >= 0);
888 lid = dmsMPI_.getCellGreaterVertex(
889 Cell{pair.type + 1, lid}, *triangulation);
890 pair.death = triangulation->getVertexGlobalId(lid);
891 fillDeathData(CTDiagram[i], pair, pair.death);
892 augmentDeathPersistence(CTDiagram[i], lid, inputScalars);
895 dataRequest{pair.death, i,
static_cast<char>(pair.type), 0});
904 MPI_Bcast(&recvBufferSize[i], 1, MPI_INTEGER, i, ttk::MPIcomm_);
906 sendRecvBuffer[i].resize(recvBufferSize[i]);
910 MPI_Datatype MPI_requestDataType;
911 createDataRequestMPIType(MPI_requestDataType);
913 MPI_Bcast(sendRecvBuffer[i].data(), recvBufferSize[i], MPI_requestDataType,
916 std::vector<std::vector<dataResponse>> response(
ttk::MPIsize_);
922 for(
int j = 0; j < recvBufferSize[i]; j++) {
923 auto &element{sendRecvBuffer[i][j]};
925 if(element.isBirth_) {
926 simplexType = getBirthSimplexType(element.dim_);
928 simplexType = getDeathSimplexType(element.dim_);
931 = triangulation->getSimplexLocalId(element.gid_, simplexType);
934 && triangulation->getSimplexRank(lid, simplexType)
937 struct dataResponse res {
938 .lid_ = element.lid_, .isBirth_ = element.isBirth_
941 Cell{element.dim_ + (1 - element.isBirth_), lid}, *triangulation);
942 res.vertexGid_ = triangulation->getVertexGlobalId(vLid);
943 res.offset_ = inputOffsets[vLid];
944 triangulation->getVertexPoint(
945 vLid, res.coords_[0], res.coords_[1], res.coords_[2]);
946 res.sfValue_ = inputScalars[vLid];
948 response[i].emplace_back(res);
955 std::vector<dataResponse> responseBuffer;
959 std::vector<dataResponse> recvBuffer;
961 sendBufferSize[0] = response[0].size();
962 responseBuffer.insert(
963 responseBuffer.end(), response[0].begin(), response[0].end());
965 sendBufferSize[i] = response[i].size();
966 sendDispls[i] = sendDispls[i - 1] + sendBufferSize[i - 1];
967 responseBuffer.insert(
968 responseBuffer.end(), response[i].begin(), response[i].end());
970 MPI_Alltoall(sendBufferSize.data(), 1, MPI_INTEGER, recvBufferSize.data(), 1,
971 MPI_INTEGER, ttk::MPIcomm_);
973 recvDispls[i] = recvDispls[i - 1] + recvBufferSize[i - 1];
975 recvBuffer.resize(recvDispls.back() + recvBufferSize.back());
976 MPI_Datatype MPI_responseDataType;
977 createDataResponseMPIType(MPI_responseDataType);
980 MPI_Alltoallv(responseBuffer.data(), sendBufferSize.data(), sendDispls.data(),
981 MPI_responseDataType, recvBuffer.data(), recvBufferSize.data(),
982 recvDispls.data(), MPI_responseDataType, ttk::MPIcomm_);
984 for(
const auto &element : recvBuffer) {
985 auto &CTPair{CTDiagram[element.lid_]};
986 if(element.isBirth_) {
987 fillBirthData(CTPair, dms_pairs[element.lid_], element.vertexGid_);
988 CTPair.birth.coords[0] = element.coords_[0];
989 CTPair.birth.coords[1] = element.coords_[1];
990 CTPair.birth.coords[2] = element.coords_[2];
991 CTPair.birth.sfValue = element.sfValue_;
992 CTPair.birth.offset = element.offset_;
994 fillDeathData(CTPair, dms_pairs[element.lid_], element.vertexGid_);
995 CTPair.death.coords[0] = element.coords_[0];
996 CTPair.death.coords[1] = element.coords_[1];
997 CTPair.death.coords[2] = element.coords_[2];
998 CTPair.death.sfValue = element.sfValue_;
999 CTPair.death.offset = element.offset_;
1003 const auto createCriticalVertexMPIType =
1004 [&MPI_SimplexId](MPI_Datatype &MPI_MessageType) {
1005 MPI_Datatype types[]
1006 = {MPI_SimplexId, MPI_DOUBLE, MPI_SimplexId, MPI_FLOAT, MPI_INTEGER};
1007 int lengths[] = {1, 1, 1, 3, 1};
1008 const long int mpi_offsets[]
1012 MPI_Type_create_struct(5, lengths, mpi_offsets, types, &MPI_MessageType);
1014 MPI_Type_commit(&MPI_MessageType);
1016 MPI_Datatype MPI_CriticalVertex;
1017 createCriticalVertexMPIType(MPI_CriticalVertex);
1019 const auto createPersistencePairMPIType =
1020 [&MPI_CriticalVertex, &MPI_SimplexId](MPI_Datatype &MPI_MessageType) {
1021 MPI_Datatype types[]
1022 = {MPI_CriticalVertex, MPI_CriticalVertex, MPI_SimplexId, MPI_CHAR};
1023 int lengths[] = {1, 1, 1, 1};
1024 const long int mpi_offsets[]
1027 MPI_Type_create_struct(4, lengths, mpi_offsets, types, &MPI_MessageType);
1028 MPI_Type_commit(&MPI_MessageType);
1030 MPI_Datatype MPI_PersistencePair;
1031 createPersistencePairMPIType(MPI_PersistencePair);
1033 std::vector<ttk::SimplexId> vertexDistribution(
ttk::MPIsize_);
1035 MPI_Allgather(&localVertexNumber, 1, MPI_SimplexId, vertexDistribution.data(),
1036 1, MPI_SimplexId, ttk::MPIcomm_);
1037 p_sort::parallel_sort<PersistencePair>(
1039 vertexDistribution, MPI_PersistencePair, MPI_SimplexId, threadNumber_);
1044template <
typename scalarType,
class triangulationType>
1046 std::vector<PersistencePair> &CTDiagram,
1047 const scalarType *inputScalars,
1048 const triangulationType *triangulation) {
1056 approxT_.setPreallocateMemory(
true);
1059 std::vector<ApproximateTopology::PersistencePair> resultDiagram{};
1066 for(
const auto &p : resultDiagram) {
1067 if(p.pairType == 0) {
1072 }
else if(p.pairType == 2) {
1077 }
else if(p.pairType == -1) {
1081 p.pairType,
false});
1088template <
class triangulationType>
1090 std::vector<PersistencePair> &CTDiagram,
1092 const triangulationType *triangulation) {
1102 progT_.setPreallocateMemory(
true);
1104 std::vector<ProgressiveTopology::PersistencePair> resultDiagram{};
1106 progT_.computeProgressivePD(resultDiagram, inputOffsets);
1109 for(
const auto &p : resultDiagram) {
1110 if(p.pairType == 0) {
1115 }
else if(p.pairType == 2) {
1120 }
else if(p.pairType == -1) {
1131template <
typename scalarType,
class triangulationType>
1133 std::vector<PersistencePair> &CTDiagram,
1134 const scalarType *inputScalars,
1136 const triangulationType *triangulation) {
1145 std::vector<std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType>> JTPairs;
1146 std::vector<std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType>> STPairs;
1147 contourTree_.computePersistencePairs<scalarType>(JTPairs,
true);
1148 contourTree_.computePersistencePairs<scalarType>(STPairs,
false);
1151 const auto JTSize = JTPairs.size();
1152 const auto STSize = STPairs.size();
1153 std::vector<std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool>>
1154 CTPairs(JTSize + STSize);
1155 for(
size_t i = 0; i < JTSize; ++i) {
1156 const auto &x = JTPairs[i];
1158 = std::make_tuple(std::get<0>(x), std::get<1>(x), std::get<2>(x),
true);
1160 for(
size_t i = 0; i < STSize; ++i) {
1161 const auto &x = STPairs[i];
1163 = std::make_tuple(std::get<0>(x), std::get<1>(x), std::get<2>(x),
false);
1167 if(!CTPairs.empty()) {
1170 const std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool> &a,
1171 const std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool> &b) {
1172 return std::get<2>(a) < std::get<2>(b);
1175 std::sort(CTPairs.begin(), CTPairs.end(), cmp);
1176 CTPairs.erase(CTPairs.end() - 1);
1185template <
class triangulationType>
1187 const triangulationType *
ttkNotUsed(triangulation)) {
1191 && !std::is_same<ttk::ImplicitWithPreconditions, triangulationType>::value
1192 && !std::is_same<ttk::ImplicitNoPreconditions, triangulationType>::value) {
1194 printWrn(
"Explicit, Compact or Periodic triangulation detected.");
1195 printWrn(
"Defaulting to the FTM backend.");
1201template <
class triangulationType>
1203 const triangulationType *
const triangulation) {
1210 if(!triangulation->isManifold()) {
1211 this->
printWrn(
"Non-manifold data-set detected.");
1212 this->
printWrn(
"Defaulting to the Persistence Simplex backend.");
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
AbstractTriangulation is an interface class that defines an interface for efficient traversal methods...
virtual int preconditionBoundaryVertices()
virtual int preconditionManifold()
TTK processing package for progressive Topological Data Analysis.
int printWrn(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
TTK DiscreteMorseSandwichMPI processing package.
TTK DiscreteMorseSandwich processing package.
ImplicitTriangulation is a class that provides time and memory efficient traversal methods on triangu...
int executePersistentSimplex(std::vector< PersistencePair > &CTDiagram, const SimplexId *inputOffsets, const triangulationType *triangulation)
int StoppingResolutionLevel
ftm::FTMTreePP contourTree_
void setComputeSadSad(const bool data)
void setOutputMonotonyOffsets(void *data)
void sortPersistenceDiagram(std::vector< PersistencePair > &diagram, const SimplexId *const offsets) const
void preconditionTriangulation(AbstractTriangulation *triangulation)
ttk::ProgressiveTopology progT_
void setDeltaApproximate(double data)
void setBackend(const BACKEND be)
ttk::CriticalType getNodeType(ftm::FTMTree_MT *tree, ftm::TreeType treeType, const SimplexId vertexId) const
void checkProgressivityRequirement(const triangulationType *triangulation)
void setOutputScalars(void *data)
@ DISCRETE_MORSE_SANDWICH
@ DISCRETE_MORSE_SANDWICH_MPI
int executeFTM(std::vector< PersistencePair > &CTDiagram, const scalarType *inputScalars, const SimplexId *inputOffsets, const triangulationType *triangulation)
dcg::DiscreteGradient dcg_
int executeProgressiveTopology(std::vector< PersistencePair > &CTDiagram, const SimplexId *inputOffsets, const triangulationType *triangulation)
int execute(std::vector< PersistencePair > &CTDiagram, const scalarType *inputScalars, const size_t scalarsMTime, const SimplexId *inputOffsets, const triangulationType *triangulation, const std::vector< bool > *updateMask=nullptr)
ttk::ApproximateTopology approxT_
DiscreteMorseSandwich dms_
int executeDiscreteMorseSandwich(std::vector< PersistencePair > &CTDiagram, const scalarType *inputScalars, const size_t scalarsMTime, const SimplexId *inputOffsets, const triangulationType *triangulation, const std::vector< bool > *updateMask=nullptr)
void setComputeMinSad(const bool data)
void setOutputOffsets(void *data)
void augmentPersistenceDiagram(std::vector< PersistencePair > &persistencePairs, const scalarType *const scalars, const triangulationType *triangulation)
Complete a ttk::DiagramType instance with scalar field values (useful for persistence) and 3D coordin...
void setComputeSadMax(const bool data)
void * outputMonotonyOffsets_
int executeApproximateTopology(std::vector< PersistencePair > &CTDiagram, const scalarType *inputScalars, const triangulationType *triangulation)
PersistentSimplexPairs psp_
void checkManifold(const triangulationType *const triangulation)
int StartingResolutionLevel
int computeCTPersistenceDiagram(ftm::FTMTreePP &tree, const std::vector< std::tuple< ttk::SimplexId, ttk::SimplexId, scalarType, bool > > &pairs, std::vector< PersistencePair > &diagram) const
Textbook algorithm to find persistence pairs.
TTK processing package for progressive Topological Data Analysis.
TTK discreteGradient processing package.
FTMTree_MT * getSplitTree()
FTMTree_MT * getJoinTree()
bool comp(const PersistencePair a, const PersistencePair b)
bool oppositeComp(const PersistencePair a, const PersistencePair b)
TTK base package defining the standard types.
COMMON_EXPORTS int MPIsize_
int SimplexId
Identifier type for simplices of any dimension.
CriticalType
default value for critical index
COMMON_EXPORTS int MPIrank_
ttk::CriticalVertex birth
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/| (_) |"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)