TTK
Loading...
Searching...
No Matches
ScalarFieldSmoother.h
Go to the documentation of this file.
1
58
59#pragma once
60
61// base code includes
62#include <Triangulation.h>
63
64namespace ttk {
65
66 class ScalarFieldSmoother : virtual public Debug {
67
68 public:
71
72 inline void setDimensionNumber(const int &dimensionNumber) {
73 dimensionNumber_ = dimensionNumber;
74 }
75
76 inline void setInputDataPointer(void *data) {
77 inputData_ = data;
78 }
79
80 inline void setOutputDataPointer(void *data) {
81 outputData_ = data;
82 }
83
84 inline void setMaskDataPointer(const char *const mask) {
85 mask_ = mask;
86 }
87
89 // Pre-condition functions.
90 if(triangulation) {
91 triangulation->preconditionVertexNeighbors();
92#ifdef TTK_ENABLE_MPI
93 triangulation->preconditionExchangeGhostVertices();
94#endif // TTK_ENABLE_MPI
95 }
96 return 0;
97 }
98
99 template <class dataType, class triangulationType = AbstractTriangulation>
100 int smooth(const triangulationType *triangulation,
101 const int &numberOfIterations) const;
102
103 protected:
105 void *inputData_{nullptr}, *outputData_{nullptr};
106 const char *mask_{nullptr};
107 };
108
109} // namespace ttk
110
111// template functions
112template <class dataType, class triangulationType>
113int ttk::ScalarFieldSmoother::smooth(const triangulationType *triangulation,
114 const int &numberOfIterations) const {
115
116 Timer t;
117
118#ifndef TTK_ENABLE_KAMIKAZE
119 if(!triangulation)
120 return -1;
122 return -2;
123 if(!inputData_)
124 return -3;
125 if(!outputData_)
126 return -4;
127#endif
128
129 SimplexId const vertexNumber = triangulation->getNumberOfVertices();
130
131 std::vector<dataType> tmpData(vertexNumber * dimensionNumber_, 0);
132
133 dataType *outputData = (dataType *)outputData_;
134 dataType *inputData = (dataType *)inputData_;
135 // init the output
136#ifdef TTK_ENABLE_OPENMP
137#pragma omp parallel for num_threads(threadNumber_)
138#endif // TTK_ENABLE_OPENMP
139 for(SimplexId i = 0; i < vertexNumber; i++) {
140 for(int j = 0; j < dimensionNumber_; j++) {
141 outputData[dimensionNumber_ * i + j]
142 = inputData[dimensionNumber_ * i + j];
143 }
144 }
145
146 printMsg("Smoothing " + std::to_string(vertexNumber) + " vertices", 0, 0,
148
149 int timeBuckets = 10;
150 if(numberOfIterations < timeBuckets)
151 timeBuckets = numberOfIterations;
152
153 for(int it = 0; it < numberOfIterations; it++) {
154#ifdef TTK_ENABLE_OPENMP
155#pragma omp parallel for num_threads(threadNumber_)
156#endif
157 for(SimplexId i = 0; i < vertexNumber; i++) {
158
159 // avoid to process masked vertices
160 if(mask_ != nullptr && mask_[i] == 0)
161 continue;
162
163 for(int j = 0; j < dimensionNumber_; j++) {
164 const auto curr{dimensionNumber_ * i + j};
165 tmpData[curr] = outputData[curr];
166
167 const auto neighborNumber = triangulation->getVertexNeighborNumber(i);
168 for(SimplexId k = 0; k < neighborNumber; k++) {
169 SimplexId neighborId = -1;
170 triangulation->getVertexNeighbor(i, k, neighborId);
171 tmpData[curr] += outputData[dimensionNumber_ * (neighborId) + j];
172 }
173 tmpData[curr] /= static_cast<double>(neighborNumber + 1);
174 }
175 }
176
177 if(numberOfIterations) {
178 // assign the tmpData back to the output
179#ifdef TTK_ENABLE_OPENMP
180#pragma omp parallel for num_threads(threadNumber_)
181#endif // TTK_ENABLE_OPENMP
182 for(SimplexId i = 0; i < vertexNumber; i++) {
183 for(int j = 0; j < dimensionNumber_; j++) {
184 // only set value for unmasked points
185 if(mask_ == nullptr || mask_[i] != 0) {
186 outputData[dimensionNumber_ * i + j]
187 = tmpData[dimensionNumber_ * i + j];
188 }
189 }
190 }
191 }
192#ifdef TTK_ENABLE_MPI
193 if(ttk::isRunningWithMPI()) {
194 // after each iteration we need to exchange the ghostcell values with our
195 // neighbors
196 exchangeGhostVertices<dataType, triangulationType>(
197 outputData, triangulation, ttk::MPIcomm_, dimensionNumber_);
198 }
199#endif // TTK_ENABLE_MPI
200
201 if(debugLevel_ >= (int)(debug::Priority::INFO)) {
202 if(!(it % ((numberOfIterations) / timeBuckets))) {
203 printMsg("Smoothing " + std::to_string(vertexNumber) + " vertices",
204 (it / (float)numberOfIterations), t.getElapsedTime(),
206 }
207 }
208 }
209
210 printMsg("Smoothed " + std::to_string(vertexNumber) + " vertices", 1,
212
213 return 0;
214}
AbstractTriangulation is an interface class that defines an interface for efficient traversal methods...
int debugLevel_
Definition Debug.h:379
void setMaskDataPointer(const char *const mask)
int preconditionTriangulation(AbstractTriangulation *triangulation)
void setDimensionNumber(const int &dimensionNumber)
void setOutputDataPointer(void *data)
~ScalarFieldSmoother() override
int smooth(const triangulationType *triangulation, const int &numberOfIterations) const
void setInputDataPointer(void *data)
double getElapsedTime()
Definition Timer.h:15
TTK base package defining the standard types.
int SimplexId
Identifier type for simplices of any dimension.
Definition DataTypes.h:22
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/| (_) |"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)