ViennaLS
Loading...
Searching...
No Matches
lsReduce.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include <hrleSparseStarIterator.hpp>
6#include <hrleVectorType.hpp>
7#include <lsDomain.hpp>
8
9namespace viennals {
10
11using namespace viennacore;
12
16template <class T, int D> class Reduce {
17 typedef typename Domain<T, D>::GridType GridType;
18 SmartPointer<Domain<T, D>> levelSet = nullptr;
19 int width = 0;
20 bool noNewSegment = false;
21 bool updatePointData = true;
22
23public:
24 Reduce() {}
25
26 Reduce(SmartPointer<Domain<T, D>> passedlsDomain)
27 : levelSet(passedlsDomain){};
28
29 Reduce(SmartPointer<Domain<T, D>> passedlsDomain, int passedWidth,
30 bool passedNoNewSegment = false)
31 : levelSet(passedlsDomain), width(passedWidth),
32 noNewSegment(passedNoNewSegment){};
33
34 void setLevelSet(SmartPointer<Domain<T, D>> passedlsDomain) {
35 levelSet = passedlsDomain;
36 }
37
41 void setWidth(int passedWidth) { width = passedWidth; }
42
46 void setNoNewSegment(bool passedNoNewSegment) {
47 noNewSegment = passedNoNewSegment;
48 }
49
52 void setUpdatePointData(bool update) { updatePointData = update; }
53
57 void apply() {
58 if (levelSet == nullptr) {
59 Logger::getInstance()
60 .addWarning("No level set was passed to Reduce.")
61 .print();
62 return;
63 }
64
65 if (width >= levelSet->getLevelSetWidth())
66 return;
67
68 const T valueLimit = width * 0.5;
69
70 auto &grid = levelSet->getGrid();
71 auto newlsDomain = SmartPointer<Domain<T, D>>::New(levelSet->getGrid());
72 typename Domain<T, D>::DomainType &newDomain = newlsDomain->getDomain();
73 typename Domain<T, D>::DomainType &domain = levelSet->getDomain();
74
75 if (noNewSegment)
76 newDomain.initialize(domain.getSegmentation(), domain.getAllocation());
77 else
78 newDomain.initialize(domain.getNewSegmentation(), domain.getAllocation());
79
80 const bool updateData = updatePointData;
81 // save how data should be transferred to new level set
82 // list of indices into the old pointData vector
83 std::vector<std::vector<unsigned>> newDataSourceIds;
84 if (updateData)
85 newDataSourceIds.resize(newDomain.getNumberOfSegments());
86
87#pragma omp parallel num_threads(newDomain.getNumberOfSegments())
88 {
89 int p = 0;
90#ifdef _OPENMP
91 p = omp_get_thread_num();
92#endif
93
94 auto &domainSegment = newDomain.getDomainSegment(p);
95
96 hrleVectorType<hrleIndexType, D> startVector =
97 (p == 0) ? grid.getMinGridPoint()
98 : newDomain.getSegmentation()[p - 1];
99
100 hrleVectorType<hrleIndexType, D> endVector =
101 (p != static_cast<int>(newDomain.getNumberOfSegments() - 1))
102 ? newDomain.getSegmentation()[p]
103 : grid.incrementIndices(grid.getMaxGridPoint());
104
105 for (hrleSparseIterator<typename Domain<T, D>::DomainType> it(
106 domain, startVector);
107 it.getStartIndices() < endVector; ++it) {
108 T currentValue = it.getValue();
109 if (it.isDefined() && std::abs(currentValue) <= valueLimit) {
110 domainSegment.insertNextDefinedPoint(it.getStartIndices(),
111 currentValue);
112 if (updateData)
113 newDataSourceIds[p].push_back(it.getPointId());
114 } else {
115 // TODO: use insertNextUndefinedRunType
116 domainSegment.insertNextUndefinedPoint(it.getStartIndices(),
117 (currentValue < 0)
120 }
121 }
122 }
123
124 // now copy old data into new level set
125 if (updateData) {
127 levelSet->getPointData(), newDataSourceIds);
128 }
129
130 // distribute evenly across segments and copy
131 newDomain.finalize();
132 if (!noNewSegment)
133 newDomain.segment();
134 levelSet->deepCopy(newlsDomain);
135 levelSet->finalize(width);
136 }
137};
138
139// add all template specialisations for this class
141
142} // namespace viennals
Class containing all information about the level set, including the dimensions of the domain,...
Definition lsDomain.hpp:28
hrleGrid< D > GridType
Definition lsDomain.hpp:32
void deepCopy(const SmartPointer< Domain< T, D > > passedDomain)
copy all values of "passedDomain" to this Domain
Definition lsDomain.hpp:121
unsigned getNumberOfSegments() const
returns the number of segments, the levelset is split into. This is useful for algorithm parallelisat...
Definition lsDomain.hpp:150
void finalize(int newWidth)
this function sets a new levelset width and finalizes the levelset, so it is ready for use by other a...
Definition lsDomain.hpp:114
PointDataType & getPointData()
get reference to point data saved in the level set
Definition lsDomain.hpp:163
hrleDomain< T, D > DomainType
Definition lsDomain.hpp:33
void translateFromMultiData(const PointData &source, const std::vector< std::vector< unsigned > > &indicesVector)
Same as translateFromData, but the indices are given as a vector, as is the case when collecting indi...
Definition lsPointData.hpp:249
Reduce the level set size to the specified width. This means all level set points with value <= 0....
Definition lsReduce.hpp:16
Reduce(SmartPointer< Domain< T, D > > passedlsDomain, int passedWidth, bool passedNoNewSegment=false)
Definition lsReduce.hpp:29
void apply()
Reduces the leveleSet to the specified number of layers. The largest value in the levelset is thus wi...
Definition lsReduce.hpp:57
void setUpdatePointData(bool update)
Set whether to update the point data stored in the LS during this algorithm. Defaults to true.
Definition lsReduce.hpp:52
void setLevelSet(SmartPointer< Domain< T, D > > passedlsDomain)
Definition lsReduce.hpp:34
Reduce()
Definition lsReduce.hpp:24
void setWidth(int passedWidth)
Set which level set points should be kept. All points with a level set value >0.5*width will be remov...
Definition lsReduce.hpp:41
void setNoNewSegment(bool passedNoNewSegment)
Set whether to segment the level set after algorithm is finished. This means points will be evenly di...
Definition lsReduce.hpp:46
Reduce(SmartPointer< Domain< T, D > > passedlsDomain)
Definition lsReduce.hpp:26
#define PRECOMPILE_PRECISION_DIMENSION(className)
Definition lsPreCompileMacros.hpp:24
Definition lsAdvect.hpp:46
double T
Definition pyWrap.cpp:63