208 this->
dms_.setComputeMinSad(data);
209#if defined(TTK_ENABLE_MPI) && defined(TTK_ENABLE_OPENMP)
210 this->dmsMPI_.setComputeMinSad(data);
214 this->
dms_.setComputeSadSad(data);
215#if defined(TTK_ENABLE_MPI) && defined(TTK_ENABLE_OPENMP)
216 this->dmsMPI_.setComputeSadSad(data);
220 this->
dms_.setComputeSadMax(data);
221#if defined(TTK_ENABLE_MPI) && defined(TTK_ENABLE_OPENMP)
222 this->dmsMPI_.setComputeSadMax(data);
230 template <
typename scalarType,
typename triangulationType>
233 const scalarType *
const scalars,
234 const triangulationType *triangulation);
243 template <
typename scalarType>
247 std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool>> &pairs,
248 std::vector<PersistencePair> &diagram)
const;
258 template <
typename scalarType,
class triangulationType>
259 int execute(std::vector<PersistencePair> &CTDiagram,
260 const scalarType *inputScalars,
261 const size_t scalarsMTime,
263 const triangulationType *triangulation,
264 const std::vector<bool> *updateMask =
nullptr);
266 template <
typename scalarType,
class triangulationType>
267 int executeFTM(std::vector<PersistencePair> &CTDiagram,
268 const scalarType *inputScalars,
270 const triangulationType *triangulation);
272 template <
class triangulationType>
275 const triangulationType *triangulation);
276 template <
typename scalarType,
class triangulationType>
278 const scalarType *inputScalars,
279 const triangulationType *triangulation);
281 template <
class triangulationType>
284 const triangulationType *triangulation);
287 template <
typename scalarType,
class triangulationType>
288 int executeDiscreteMorseSandwichMPI(std::vector<PersistencePair> &CTDiagram,
289 const scalarType *inputScalars,
290 const size_t scalarsMTime,
292 const triangulationType *triangulation);
295 template <
typename scalarType,
class triangulationType>
297 const scalarType *inputScalars,
298 const size_t scalarsMTime,
300 const triangulationType *triangulation,
301 const std::vector<bool> *updateMask
304 template <
class triangulationType>
307 template <
class triangulationType>
308 void checkManifold(
const triangulationType *
const triangulation);
324 dms_.preconditionTriangulation(triangulation);
327#if defined(TTK_ENABLE_MPI) && defined(TTK_ENABLE_OPENMP)
331 dmsMPI_.preconditionTriangulation(triangulation);
338 psp_.preconditionTriangulation(triangulation);
362#if defined(TTK_ENABLE_MPI) && defined(TTK_ENABLE_OPENMP)
385template <
typename scalarType>
389 std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool>> &pairs,
390 std::vector<PersistencePair> &diagram)
const {
393 diagram.resize(numberOfPairs);
397 const bool type = std::get<3>(pairs[i]);
432 diagram.back().isFinite =
false;
437template <
typename scalarType,
typename triangulationType>
439 std::vector<PersistencePair> &persistencePairs,
440 const scalarType *
const scalars,
441 const triangulationType *triangulation) {
443#ifdef TTK_ENABLE_OPENMP
444#pragma omp parallel for num_threads(threadNumber_)
446 for(std::size_t i = 0; i < persistencePairs.size(); ++i) {
447 auto &pair{persistencePairs[i]};
448 triangulation->getVertexPoint(pair.birth.id, pair.birth.coords[0],
449 pair.birth.coords[1], pair.birth.coords[2]);
450 pair.birth.sfValue = scalars[pair.birth.id];
451 triangulation->getVertexPoint(pair.death.id, pair.death.coords[0],
452 pair.death.coords[1], pair.death.coords[2]);
453 pair.death.sfValue = scalars[pair.death.id];
457template <
typename scalarType,
class triangulationType>
459 const scalarType *inputScalars,
460 const size_t scalarsMTime,
462 const triangulationType *triangulation,
463 const std::vector<bool> *updateMask) {
478 inputOffsets, triangulation, updateMask);
487 executeFTM(CTDiagram, inputScalars, inputOffsets, triangulation);
491 executeDiscreteMorseSandwichMPI(
492 CTDiagram, inputScalars, scalarsMTime, inputOffsets, triangulation);
494 this->
printWrn(
"TTK is not compiled with MPI. Running sequentially.");
495 this->
printWrn(
"If you want to run TTK with MPI, compile it with "
496 "TTK_ENABLE_MPI to ON.");
498 CTDiagram, inputScalars, scalarsMTime, inputOffsets, triangulation);
505 this->
printMsg(
"Complete", 1.0, tm.getElapsedTime(), this->threadNumber_);
507 if(!isRunningWithMPI()) {
523template <
class triangulationType>
525 std::vector<PersistencePair> &CTDiagram,
527 const triangulationType *triangulation) {
530 const auto dim = triangulation->getDimensionality();
532 std::vector<ttk::PersistentSimplexPairs::PersistencePair> pairs{};
536 psp_.computePersistencePairs(pairs, inputOffsets, *triangulation);
537 dms_.setInputOffsets(inputOffsets);
542#ifdef TTK_ENABLE_OPENMP
543#pragma omp parallel for num_threads(threadNumber_)
545 for(
size_t i = 0; i < pairs.size(); ++i) {
546 auto &pair{pairs[i]};
548 pair.birth =
dms_.getCellGreaterVertex(
549 Cell{pair.type, pair.birth}, *triangulation);
551 if(pair.death != -1) {
552 pair.death =
dms_.getCellGreaterVertex(
553 Cell{pair.type + 1, pair.death}, *triangulation);
557 CTDiagram.reserve(pairs.size() + 1);
560 const auto nVerts = triangulation->getNumberOfVertices();
562 inputOffsets, std::max_element(inputOffsets, inputOffsets + nVerts));
565 for(
const auto &p : pairs) {
566 const auto isFinite = (p.death >= 0);
567 const auto death = isFinite ? p.death : globmax;
569 const auto deathType = (isFinite && dim > 1)
575 }
else if(p.type == 1) {
578 const auto deathType = (isFinite && dim == 3)
584 }
else if(p.type == 2) {
595template <
typename scalarType,
class triangulationType>
597 std::vector<PersistencePair> &CTDiagram,
598 const scalarType *inputScalars,
599 const size_t scalarsMTime,
601 const triangulationType *triangulation,
602 const std::vector<bool> *updateMask) {
605 const auto dim = triangulation->getDimensionality();
609 inputScalars, scalarsMTime, inputOffsets, *triangulation, updateMask);
610 std::vector<DiscreteMorseSandwich::PersistencePair> dms_pairs{};
611 dms_.computePersistencePairs(
613 CTDiagram.resize(dms_pairs.size());
617#ifdef TTK_ENABLE_OPENMP
618#pragma omp parallel for num_threads(threadNumber_)
620 for(
size_t i = 0; i < dms_pairs.size(); ++i) {
621 auto &pair{dms_pairs[i]};
623 pair.birth =
dms_.getCellGreaterVertex(
624 Cell{pair.type, pair.birth}, *triangulation);
626 if(pair.death != -1) {
627 pair.death =
dms_.getCellGreaterVertex(
628 Cell{pair.type + 1, pair.death}, *triangulation);
633 const auto nVerts = triangulation->getNumberOfVertices();
635 inputOffsets, std::max_element(inputOffsets, inputOffsets + nVerts));
638#ifdef TTK_ENABLE_OPENMP
639#pragma omp parallel for num_threads(threadNumber_)
641 for(
size_t i = 0; i < dms_pairs.size(); ++i) {
642 const auto &p{dms_pairs[i]};
643 const auto isFinite = (p.death >= 0);
644 const auto death = isFinite ? p.death : globmax;
652 }
else if(p.type == 1) {
660 }
else if(p.type == 2) {
673#if defined(TTK_ENABLE_MPI) && defined(TTK_ENABLE_OPENMP)
674template <
typename scalarType,
class triangulationType>
675int ttk::PersistenceDiagram::executeDiscreteMorseSandwichMPI(
676 std::vector<PersistencePair> &CTDiagram,
677 const scalarType *inputScalars,
678 const size_t scalarsMTime,
680 const triangulationType *triangulation) {
683 const auto dim = triangulation->getDimensionality();
684 dmsMPI_.setUseTasks(UseTasks);
686 dmsMPI_.buildGradient(
687 inputScalars, scalarsMTime, inputOffsets, *triangulation);
688 std::vector<DiscreteMorseSandwichMPI::PersistencePair> dms_pairs{};
689 dmsMPI_.computePersistencePairs(
690 dms_pairs, inputOffsets, *triangulation, this->IgnoreBoundary);
691 CTDiagram.resize(dms_pairs.size());
702 const auto nVerts = triangulation->getNumberOfVertices();
703 const SimplexId localMaxId = std::distance(
704 inputOffsets, std::max_element(inputOffsets, inputOffsets + nVerts));
705 MPI_Datatype MPI_SimplexId = getMPIType(localMaxId);
709 } localMax, globalMax;
710 localMax.rank = triangulation->getVertexRank(localMaxId);
711 localMax.offset =
static_cast<long int>(inputOffsets[localMaxId]);
713 &localMax, &globalMax, 1, MPI_LONG_INT, MPI_MAXLOC, ttk::MPIcomm_);
715 double maxMetaData[4];
718 globmax = triangulation->getVertexGlobalId(localMaxId);
719 triangulation->getVertexPoint(localMaxId, coords[0], coords[1], coords[2]);
720 maxMetaData[0] = coords[0];
721 maxMetaData[1] = coords[1];
722 maxMetaData[2] = coords[2];
723 maxMetaData[3] = inputScalars[localMaxId];
725 MPI_Bcast(&globmax, 1, MPI_SimplexId, globalMax.rank, ttk::MPIcomm_);
726 MPI_Bcast(maxMetaData, 4, MPI_DOUBLE, globalMax.rank, ttk::MPIcomm_);
728 std::vector<std::vector<dataRequest>> sendRecvBuffer(
ttk::MPIsize_);
730 const auto createDataRequestMPIType =
731 [&MPI_SimplexId](MPI_Datatype &MPI_MessageType) {
732 MPI_Datatype types[] = {MPI_SimplexId, MPI_SimplexId, MPI_CHAR, MPI_CHAR};
733 int lengths[] = {1, 1, 1, 1};
734 const long int mpi_offsets[]
735 = {offsetof(dataRequest, gid_), offsetof(dataRequest, lid_),
736 offsetof(dataRequest, dim_), offsetof(dataRequest, isBirth_)};
737 MPI_Type_create_struct(4, lengths, mpi_offsets, types, &MPI_MessageType);
738 MPI_Type_commit(&MPI_MessageType);
741 struct dataResponse {
745 float coords_[3] = {0, 0, 0};
750 const auto createDataResponseMPIType =
751 [&MPI_SimplexId](MPI_Datatype &MPI_MessageType) {
752 MPI_Datatype types[] = {MPI_SimplexId, MPI_SimplexId, MPI_SimplexId,
753 MPI_FLOAT, MPI_DOUBLE, MPI_CHAR};
754 int lengths[] = {1, 1, 1, 3, 1, 1};
755 const long int mpi_offsets[]
756 = {offsetof(dataResponse, lid_), offsetof(dataResponse, vertexGid_),
757 offsetof(dataResponse, offset_), offsetof(dataResponse, coords_),
758 offsetof(dataResponse, sfValue_), offsetof(dataResponse, isBirth_)};
759 MPI_Type_create_struct(6, lengths, mpi_offsets, types, &MPI_MessageType);
760 MPI_Type_commit(&MPI_MessageType);
763 const auto fillBirthData
765 DiscreteMorseSandwichMPI::PersistencePair &p,
767 CTPair.birth.id = birthId;
770 }
else if(p.type == 1) {
773 }
else if(p.type == 2) {
774 CTPair.birth.type = ((p.death >= 0) || dim == 3)
780 const auto augmentBirthPersistence =
781 [&triangulation, &inputOffsets](
783 triangulation->getVertexPoint(lid, CTPair.birth.coords[0],
784 CTPair.birth.coords[1],
785 CTPair.birth.coords[2]);
786 CTPair.birth.sfValue = scalars[lid];
787 CTPair.birth.offset = inputOffsets[lid];
790 const auto fillDeathData = [&dim](
792 DiscreteMorseSandwichMPI::PersistencePair &p,
794 const auto isFinite = (p.death >= 0);
795 CTPair.death.id = deathId;
799 }
else if(p.type == 1) {
802 }
else if(p.type == 2) {
807 const auto augmentDeathPersistence =
808 [&triangulation, &inputOffsets](
810 triangulation->getVertexPoint(lid, CTPair.death.coords[0],
811 CTPair.death.coords[1],
812 CTPair.death.coords[2]);
813 CTPair.death.sfValue = scalars[lid];
814 CTPair.death.offset = inputOffsets[lid];
817 const auto getBirthSimplexType = [&dim](
const int type) {
832 const auto getDeathSimplexType = [&dim](
const int type) {
846 for(
ttk::SimplexId i = 0; i < static_cast<ttk::SimplexId>(dms_pairs.size());
848 auto &pair{dms_pairs[i]};
849 int simplexType = getBirthSimplexType(pair.type);
851 = triangulation->getSimplexLocalId(pair.birth, simplexType);
853 && triangulation->getSimplexRank(lid, simplexType) ==
ttk::MPIrank_) {
856 = dmsMPI_.getCellGreaterVertex(Cell{pair.type, lid}, *triangulation);
857 pair.birth = triangulation->getVertexGlobalId(lid);
859 CTDiagram[i].dim = pair.type;
860 CTDiagram[i].isFinite = (pair.death >= 0);
862 fillBirthData(CTDiagram[i], pair, pair.birth);
863 augmentBirthPersistence(CTDiagram[i], lid, inputScalars);
866 dataRequest{pair.birth, i,
static_cast<char>(pair.type), 1});
868 if(pair.death == -1) {
869 CTDiagram[i].dim = pair.type;
870 CTDiagram[i].isFinite = (pair.death >= 0);
871 pair.death = globmax;
872 fillDeathData(CTDiagram[i], pair, pair.death);
873 CTDiagram[i].death.coords[0] = maxMetaData[0];
874 CTDiagram[i].death.coords[1] = maxMetaData[1];
875 CTDiagram[i].death.coords[2] = maxMetaData[2];
876 CTDiagram[i].death.sfValue = maxMetaData[3];
877 CTDiagram[i].death.offset = globalMax.offset;
879 simplexType = getDeathSimplexType(pair.type);
880 lid = triangulation->getSimplexLocalId(pair.death, simplexType);
882 && triangulation->getSimplexRank(lid, simplexType) ==
ttk::MPIrank_) {
883 CTDiagram[i].dim = pair.type;
884 CTDiagram[i].isFinite = (pair.death >= 0);
885 lid = dmsMPI_.getCellGreaterVertex(
886 Cell{pair.type + 1, lid}, *triangulation);
887 pair.death = triangulation->getVertexGlobalId(lid);
888 fillDeathData(CTDiagram[i], pair, pair.death);
889 augmentDeathPersistence(CTDiagram[i], lid, inputScalars);
892 dataRequest{pair.death, i,
static_cast<char>(pair.type), 0});
901 MPI_Bcast(&recvBufferSize[i], 1, MPI_INTEGER, i, ttk::MPIcomm_);
903 sendRecvBuffer[i].resize(recvBufferSize[i]);
907 MPI_Datatype MPI_requestDataType;
908 createDataRequestMPIType(MPI_requestDataType);
910 MPI_Bcast(sendRecvBuffer[i].data(), recvBufferSize[i], MPI_requestDataType,
913 std::vector<std::vector<dataResponse>> response(
ttk::MPIsize_);
919 for(
int j = 0; j < recvBufferSize[i]; j++) {
920 auto &element{sendRecvBuffer[i][j]};
922 if(element.isBirth_) {
923 simplexType = getBirthSimplexType(element.dim_);
925 simplexType = getDeathSimplexType(element.dim_);
928 = triangulation->getSimplexLocalId(element.gid_, simplexType);
931 && triangulation->getSimplexRank(lid, simplexType)
934 struct dataResponse res {
935 .lid_ = element.lid_, .isBirth_ = element.isBirth_
938 Cell{element.dim_ + (1 - element.isBirth_), lid}, *triangulation);
939 res.vertexGid_ = triangulation->getVertexGlobalId(vLid);
940 res.offset_ = inputOffsets[vLid];
941 triangulation->getVertexPoint(
942 vLid, res.coords_[0], res.coords_[1], res.coords_[2]);
943 res.sfValue_ = inputScalars[vLid];
945 response[i].emplace_back(res);
952 std::vector<dataResponse> responseBuffer;
956 std::vector<dataResponse> recvBuffer;
958 sendBufferSize[0] = response[0].size();
959 responseBuffer.insert(
960 responseBuffer.end(), response[0].begin(), response[0].end());
962 sendBufferSize[i] = response[i].size();
963 sendDispls[i] = sendDispls[i - 1] + sendBufferSize[i - 1];
964 responseBuffer.insert(
965 responseBuffer.end(), response[i].begin(), response[i].end());
967 MPI_Alltoall(sendBufferSize.data(), 1, MPI_INTEGER, recvBufferSize.data(), 1,
968 MPI_INTEGER, ttk::MPIcomm_);
970 recvDispls[i] = recvDispls[i - 1] + recvBufferSize[i - 1];
972 recvBuffer.resize(recvDispls.back() + recvBufferSize.back());
973 MPI_Datatype MPI_responseDataType;
974 createDataResponseMPIType(MPI_responseDataType);
977 MPI_Alltoallv(responseBuffer.data(), sendBufferSize.data(), sendDispls.data(),
978 MPI_responseDataType, recvBuffer.data(), recvBufferSize.data(),
979 recvDispls.data(), MPI_responseDataType, ttk::MPIcomm_);
981 for(
const auto &element : recvBuffer) {
982 auto &CTPair{CTDiagram[element.lid_]};
983 if(element.isBirth_) {
984 fillBirthData(CTPair, dms_pairs[element.lid_], element.vertexGid_);
985 CTPair.birth.coords[0] = element.coords_[0];
986 CTPair.birth.coords[1] = element.coords_[1];
987 CTPair.birth.coords[2] = element.coords_[2];
988 CTPair.birth.sfValue = element.sfValue_;
989 CTPair.birth.offset = element.offset_;
991 fillDeathData(CTPair, dms_pairs[element.lid_], element.vertexGid_);
992 CTPair.death.coords[0] = element.coords_[0];
993 CTPair.death.coords[1] = element.coords_[1];
994 CTPair.death.coords[2] = element.coords_[2];
995 CTPair.death.sfValue = element.sfValue_;
996 CTPair.death.offset = element.offset_;
1000 const auto createCriticalVertexMPIType =
1001 [&MPI_SimplexId](MPI_Datatype &MPI_MessageType) {
1002 MPI_Datatype types[]
1003 = {MPI_SimplexId, MPI_DOUBLE, MPI_SimplexId, MPI_FLOAT, MPI_INTEGER};
1004 int lengths[] = {1, 1, 1, 3, 1};
1005 const long int mpi_offsets[]
1009 MPI_Type_create_struct(5, lengths, mpi_offsets, types, &MPI_MessageType);
1011 MPI_Type_commit(&MPI_MessageType);
1013 MPI_Datatype MPI_CriticalVertex;
1014 createCriticalVertexMPIType(MPI_CriticalVertex);
1016 const auto createPersistencePairMPIType =
1017 [&MPI_CriticalVertex, &MPI_SimplexId](MPI_Datatype &MPI_MessageType) {
1018 MPI_Datatype types[]
1019 = {MPI_CriticalVertex, MPI_CriticalVertex, MPI_SimplexId, MPI_CHAR};
1020 int lengths[] = {1, 1, 1, 1};
1021 const long int mpi_offsets[]
1024 MPI_Type_create_struct(4, lengths, mpi_offsets, types, &MPI_MessageType);
1025 MPI_Type_commit(&MPI_MessageType);
1027 MPI_Datatype MPI_PersistencePair;
1028 createPersistencePairMPIType(MPI_PersistencePair);
1030 std::vector<ttk::SimplexId> vertexDistribution(
ttk::MPIsize_);
1032 MPI_Allgather(&localVertexNumber, 1, MPI_SimplexId, vertexDistribution.data(),
1033 1, MPI_SimplexId, ttk::MPIcomm_);
1034 p_sort::parallel_sort<PersistencePair>(
1036 vertexDistribution, MPI_PersistencePair, MPI_SimplexId, threadNumber_);
1041template <
typename scalarType,
class triangulationType>
1043 std::vector<PersistencePair> &CTDiagram,
1044 const scalarType *inputScalars,
1045 const triangulationType *triangulation) {
1053 approxT_.setPreallocateMemory(
true);
1056 std::vector<ApproximateTopology::PersistencePair> resultDiagram{};
1063 for(
const auto &p : resultDiagram) {
1064 if(p.pairType == 0) {
1069 }
else if(p.pairType == 2) {
1074 }
else if(p.pairType == -1) {
1078 p.pairType,
false});
1085template <
class triangulationType>
1087 std::vector<PersistencePair> &CTDiagram,
1089 const triangulationType *triangulation) {
1099 progT_.setPreallocateMemory(
true);
1101 std::vector<ProgressiveTopology::PersistencePair> resultDiagram{};
1103 progT_.computeProgressivePD(resultDiagram, inputOffsets);
1106 for(
const auto &p : resultDiagram) {
1107 if(p.pairType == 0) {
1112 }
else if(p.pairType == 2) {
1117 }
else if(p.pairType == -1) {
1128template <
typename scalarType,
class triangulationType>
1130 std::vector<PersistencePair> &CTDiagram,
1131 const scalarType *inputScalars,
1133 const triangulationType *triangulation) {
1142 std::vector<std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType>> JTPairs;
1143 std::vector<std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType>> STPairs;
1144 contourTree_.computePersistencePairs<scalarType>(JTPairs,
true);
1145 contourTree_.computePersistencePairs<scalarType>(STPairs,
false);
1148 const auto JTSize = JTPairs.size();
1149 const auto STSize = STPairs.size();
1150 std::vector<std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool>>
1151 CTPairs(JTSize + STSize);
1152 for(
size_t i = 0; i < JTSize; ++i) {
1153 const auto &x = JTPairs[i];
1155 = std::make_tuple(std::get<0>(x), std::get<1>(x), std::get<2>(x),
true);
1157 for(
size_t i = 0; i < STSize; ++i) {
1158 const auto &x = STPairs[i];
1160 = std::make_tuple(std::get<0>(x), std::get<1>(x), std::get<2>(x),
false);
1164 if(!CTPairs.empty()) {
1167 const std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool> &a,
1168 const std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool> &b) {
1169 return std::get<2>(a) < std::get<2>(b);
1172 std::sort(CTPairs.begin(), CTPairs.end(), cmp);
1173 CTPairs.erase(CTPairs.end() - 1);
1182template <
class triangulationType>
1184 const triangulationType *
ttkNotUsed(triangulation)) {
1188 && !std::is_same<ttk::ImplicitWithPreconditions, triangulationType>::value
1189 && !std::is_same<ttk::ImplicitNoPreconditions, triangulationType>::value) {
1191 printWrn(
"Explicit, Compact or Periodic triangulation detected.");
1192 printWrn(
"Defaulting to the FTM backend.");
1198template <
class triangulationType>
1200 const triangulationType *
const triangulation) {
1207 if(!triangulation->isManifold()) {
1208 this->
printWrn(
"Non-manifold data-set detected.");
1209 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)