TTK
Loading...
Searching...
No Matches
DiscreteGradient.cpp
Go to the documentation of this file.
1#include <DiscreteGradient.h>
2
3using namespace std;
4using namespace ttk;
5using namespace dcg;
6
8 return dimensionality_;
9}
10
12 return dimensionality_ + 1;
13}
14
15void DiscreteGradient::initMemory(const AbstractTriangulation &triangulation) {
16
17 Timer tm{};
18 const int numberOfDimensions = this->getNumberOfDimensions();
19
20 // init number of cells by dimension
21 std::vector<SimplexId> numberOfCells(numberOfDimensions);
22 for(int i = 0; i < numberOfDimensions; ++i) {
23 numberOfCells[i] = this->getNumberOfCells(i, triangulation);
24 }
25
26 // clear & init gradient memory
27 for(int i = 0; i < dimensionality_; ++i) {
28 (*gradient_)[2 * i].clear();
29 (*gradient_)[2 * i].resize(numberOfCells[i], -1);
30 (*gradient_)[2 * i + 1].clear();
31 (*gradient_)[2 * i + 1].resize(numberOfCells[i + 1], -1);
32 }
33
34 std::vector<std::vector<std::string>> rows{
35 {"#Vertices", std::to_string(numberOfCells[0])},
36 {"#Edges", std::to_string(numberOfCells[1])},
37 };
38
39 if(dimensionality_ >= 2) {
40 rows.emplace_back(
41 std::vector<std::string>{"#Triangles", std::to_string(numberOfCells[2])});
42 }
43
44 if(dimensionality_ == 3) {
45 rows.emplace_back(
46 std::vector<std::string>{"#Tetras", std::to_string(numberOfCells[3])});
47 }
48
49 this->printMsg(rows);
50 this->printMsg("Initialized discrete gradient memory", 1.0,
51 tm.getElapsedTime(), this->threadNumber_);
52}
53
54std::pair<size_t, SimplexId>
55 DiscreteGradient::numUnpairedFaces(const CellExt &c,
56 const lowerStarType &ls) const {
57 // c.dim_ cannot be <= 1
58 if(c.dim_ == 2) {
59 return numUnpairedFacesTriangle(c, ls);
60 } else if(c.dim_ == 3) {
61 return numUnpairedFacesTetra(c, ls);
62 }
63
64 return {0, -1};
65}
66
67std::pair<size_t, SimplexId>
68 DiscreteGradient::numUnpairedFacesTriangle(const CellExt &c,
69 const lowerStarType &ls) const {
70 // number of unpaired faces
71 std::pair<size_t, SimplexId> res{0, -1};
72
73 // loop over edge faces of triangle
74 // (2 edges per triangle in lower star)
75 for(size_t i = 0; i < 2; ++i) {
76 if(!ls[1][c.faces_[i]].paired_) {
77 res.first++;
78 res.second = c.faces_[i];
79 }
80 }
81
82 return res;
83}
84
85std::pair<size_t, SimplexId>
86 DiscreteGradient::numUnpairedFacesTetra(const CellExt &c,
87 const lowerStarType &ls) const {
88 // number of unpaired faces
89 std::pair<size_t, SimplexId> res{0, -1};
90
91 // loop over triangle faces of tetra
92 for(const auto f : c.faces_) {
93 if(!ls[2][f].paired_) {
94 res.first++;
95 res.second = f;
96 }
97 }
98
99 return res;
100}
101
103 DiscreteGradient::criticalTypeFromCellDimension(const int dim) const {
104 if(dim == 0) {
106 } else if(dim == 1) {
108 } else if(dim == 2 && dimensionality_ == 3) {
110 } else if(dim == dimensionality_) {
112 } else {
114 }
115}
116
117bool DiscreteGradient::isMinimum(const Cell &cell) const {
118 if(cell.dim_ == 0) {
119 return ((*gradient_)[0][cell.id_] == -1);
120 }
121
122 return false;
123}
124
125bool DiscreteGradient::isSaddle1(const Cell &cell) const {
126 if(cell.dim_ == 1) {
127 return ((*gradient_)[1][cell.id_] == -1
128 and (*gradient_)[2][cell.id_] == -1);
129 }
130
131 return false;
132}
133
134bool DiscreteGradient::isSaddle2(const Cell &cell) const {
135 if(dimensionality_ == 3 and cell.dim_ == 2) {
136 return ((*gradient_)[3][cell.id_] == -1
137 and (*gradient_)[4][cell.id_] == -1);
138 }
139
140 return false;
141}
142
143bool DiscreteGradient::isMaximum(const Cell &cell) const {
144 if(dimensionality_ == 1 and cell.dim_ == 1) {
145 return ((*gradient_)[1][cell.id_] == -1);
146 }
147
148 if(dimensionality_ == 2 and cell.dim_ == 2) {
149 return ((*gradient_)[3][cell.id_] == -1);
150 }
151
152 if(dimensionality_ == 3 and cell.dim_ == 3) {
153 return ((*gradient_)[5][cell.id_] == -1);
154 }
155
156 return false;
157}
158
159bool DiscreteGradient::isCellCritical(const int cellDim,
160 const SimplexId cellId) const {
161
162 if(cellDim > this->dimensionality_) {
163 return false;
164 }
165
166 if(cellDim == 0) {
167 return ((*gradient_)[0][cellId] == NULL_GRADIENT);
168 }
169
170 if(cellDim == 1) {
171 return (
172 (*gradient_)[1][cellId] == NULL_GRADIENT
173 && (dimensionality_ == 1 || (*gradient_)[2][cellId] == NULL_GRADIENT));
174 }
175
176 if(cellDim == 2) {
177 return (
178 (*gradient_)[3][cellId] == NULL_GRADIENT
179 && (dimensionality_ == 2 || (*gradient_)[4][cellId] == NULL_GRADIENT));
180 }
181
182 if(cellDim == 3) {
183 return ((*gradient_)[5][cellId] == NULL_GRADIENT);
184 }
185
186 return false;
187}
188
189bool DiscreteGradient::isCellCritical(const Cell &cell) const {
190 return isCellCritical(cell.dim_, cell.id_);
191}
192
194 const std::array<std::vector<SimplexId>, 4> &criticalCellsByDim,
195 const SimplexId *const ascendingManifold,
196 const SimplexId *const descendingManifold,
197 std::vector<SimplexId> &manifoldSize) const {
198
199 const auto nCritPoints{
200 criticalCellsByDim[0].size() + criticalCellsByDim[1].size()
201 + criticalCellsByDim[2].size() + criticalCellsByDim[3].size()};
202
203 const auto dim{this->dimensionality_};
204
205 if(nCritPoints == 0
206 || (criticalCellsByDim[0].empty() && criticalCellsByDim[dim].empty())) {
207 // no critical points || no extrema
208 return 0;
209 }
210
211 manifoldSize.resize(nCritPoints, 0);
212
213 // descending manifold cells size
214 if(!criticalCellsByDim[0].empty()) {
215 for(SimplexId i = 0; i < numberOfVertices_; ++i) {
216 if(descendingManifold[i] != -1) {
217 manifoldSize[descendingManifold[i]]++;
218 }
219 }
220 }
221
222 if(!criticalCellsByDim[dim].empty()) {
223 // index of first maximum in critical points array
224 const auto nFirstMaximum{nCritPoints - criticalCellsByDim[dim].size()};
225
226 // ascending manifold cells size
227 for(SimplexId i = 0; i < numberOfVertices_; ++i) {
228 if(ascendingManifold[i] != -1) {
229 manifoldSize[ascendingManifold[i] + nFirstMaximum]++;
230 }
231 }
232 }
233
234 return 0;
235}
236
237#ifdef TTK_ENABLE_MPI
238void DiscreteGradient::setCellToGhost(const int cellDim,
239 const SimplexId cellId) {
240 if(cellDim == 0) {
241 (*gradient_)[0][cellId] = GHOST_GRADIENT;
242 }
243
244 if(cellDim == 1) {
245 (*gradient_)[1][cellId] = GHOST_GRADIENT;
246 (*gradient_)[2][cellId] = GHOST_GRADIENT;
247 }
248
249 if(cellDim == 2) {
250 (*gradient_)[3][cellId] = GHOST_GRADIENT;
251 (*gradient_)[4][cellId] = GHOST_GRADIENT;
252 }
253
254 if(cellDim == 3) {
255 (*gradient_)[5][cellId] = GHOST_GRADIENT;
256 }
257}
258#endif
AbstractTriangulation is an interface class that defines an interface for efficient traversal methods...
int printMsg(const std::string &msg, const debug::Priority &priority=debug::Priority::INFO, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cout) const
Definition: Debug.h:118
bool isMinimum(const Cell &cell) const
bool isSaddle1(const Cell &cell) const
bool isMaximum(const Cell &cell) const
bool isSaddle2(const Cell &cell) const
int setManifoldSize(const std::array< std::vector< SimplexId >, 4 > &criticalCellsByDim, const SimplexId *const ascendingManifold, const SimplexId *const descendingManifold, std::vector< SimplexId > &manifoldSize) const
SimplexId getNumberOfCells(const int dimension, const triangulationType &triangulation) const
bool isCellCritical(const int cellDim, const SimplexId cellId) const
AbstractTriangulation::gradientType * gradient_
The Topology ToolKit.
CriticalType
default value for critical index
Definition: DataTypes.h:80
int SimplexId
Identifier type for simplices of any dimension.
Definition: DataTypes.h:22
Extended Cell structure for processLowerStars.
const std::array< uint8_t, 3 > faces_