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