ViennaLS
Loading...
Searching...
No Matches
lsReduce.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <lsDomain.hpp>
5#include <vcVectorType.hpp>
6
7namespace viennals {
8
9using namespace viennacore;
10
14template <class T, int D> class Reduce {
15 typedef typename Domain<T, D>::GridType GridType;
16 SmartPointer<Domain<T, D>> levelSet = nullptr;
17 int width = 0;
18 bool noNewSegment = false;
19 bool updatePointData = true;
20
21public:
22 Reduce() = default;
23
24 Reduce(SmartPointer<Domain<T, D>> passedlsDomain)
25 : levelSet(passedlsDomain){};
26
27 Reduce(SmartPointer<Domain<T, D>> passedlsDomain, int passedWidth,
28 bool passedNoNewSegment = false)
29 : levelSet(passedlsDomain), width(passedWidth),
30 noNewSegment(passedNoNewSegment){};
31
32 void setLevelSet(SmartPointer<Domain<T, D>> passedlsDomain) {
33 levelSet = passedlsDomain;
34 }
35
39 void setWidth(int passedWidth) { width = passedWidth; }
40
44 void setNoNewSegment(bool passedNoNewSegment) {
45 noNewSegment = passedNoNewSegment;
46 }
47
50 void setUpdatePointData(bool update) { updatePointData = update; }
51
55 void apply() {
56 if (levelSet == nullptr) {
57 Logger::getInstance()
58 .addWarning("No level set was passed to Reduce.")
59 .print();
60 return;
61 }
62
63 if (width >= levelSet->getLevelSetWidth())
64 return;
65
66 const T valueLimit = width * 0.5;
67
68 auto &grid = levelSet->getGrid();
69 auto newlsDomain = SmartPointer<Domain<T, D>>::New(levelSet->getGrid());
70 typename Domain<T, D>::DomainType &newDomain = newlsDomain->getDomain();
71 typename Domain<T, D>::DomainType &domain = levelSet->getDomain();
72
73 if (noNewSegment)
74 newDomain.initialize(domain.getSegmentation(), domain.getAllocation());
75 else
76 newDomain.initialize(domain.getNewSegmentation(), domain.getAllocation());
77
78 const bool updateData = updatePointData;
79 // save how data should be transferred to new level set
80 // list of indices into the old pointData vector
81 std::vector<std::vector<unsigned>> newDataSourceIds;
82 if (updateData)
83 newDataSourceIds.resize(newDomain.getNumberOfSegments());
84
85#pragma omp parallel num_threads(newDomain.getNumberOfSegments())
86 {
87 int p = 0;
88#ifdef _OPENMP
89 p = omp_get_thread_num();
90#endif
91
92 auto &domainSegment = newDomain.getDomainSegment(p);
93
94 viennahrle::Index<D> const startVector =
95 (p == 0) ? grid.getMinGridPoint()
96 : newDomain.getSegmentation()[p - 1];
97
98 viennahrle::Index<D> const endVector =
99 (p != static_cast<int>(newDomain.getNumberOfSegments() - 1))
100 ? newDomain.getSegmentation()[p]
101 : grid.incrementIndices(grid.getMaxGridPoint());
102
103 for (viennahrle::SparseIterator<typename Domain<T, D>::DomainType> it(
104 domain, startVector);
105 it.getStartIndices() < endVector; ++it) {
106 T currentValue = it.getValue();
107 if (it.isDefined() && std::abs(currentValue) <= valueLimit) {
108 domainSegment.insertNextDefinedPoint(it.getStartIndices(),
109 currentValue);
110 if (updateData)
111 newDataSourceIds[p].push_back(it.getPointId());
112 } else {
113 // TODO: use insertNextUndefinedRunType
114 domainSegment.insertNextUndefinedPoint(it.getStartIndices(),
115 (currentValue < 0)
118 }
119 }
120 }
121
122 // now copy old data into new level set
123 if (updateData) {
124 newlsDomain->getPointData().translateFromMultiData(
125 levelSet->getPointData(), newDataSourceIds);
126 }
127
128 // distribute evenly across segments and copy
129 newDomain.finalize();
130 if (!noNewSegment)
131 newDomain.segment();
132 levelSet->deepCopy(newlsDomain);
133 levelSet->finalize(width);
134 }
135};
136
137// add all template specialisations for this class
139
140} // namespace viennals
Class containing all information about the level set, including the dimensions of the domain,...
Definition lsDomain.hpp:27
viennahrle::Domain< T, D > DomainType
Definition lsDomain.hpp:32
viennahrle::Grid< D > GridType
Definition lsDomain.hpp:31
static constexpr T NEG_VALUE
Definition lsDomain.hpp:52
void deepCopy(const SmartPointer< Domain< T, D > > passedDomain)
copy all values of "passedDomain" to this Domain
Definition lsDomain.hpp:119
unsigned getNumberOfSegments() const
returns the number of segments, the levelset is split into. This is useful for algorithm parallelisat...
Definition lsDomain.hpp:148
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:112
static constexpr T POS_VALUE
Definition lsDomain.hpp:51
Reduce(SmartPointer< Domain< T, D > > passedlsDomain, int passedWidth, bool passedNoNewSegment=false)
Definition lsReduce.hpp:27
void apply()
Reduces the leveleSet to the specified number of layers. The largest value in the levelset is thus wi...
Definition lsReduce.hpp:55
void setUpdatePointData(bool update)
Set whether to update the point data stored in the LS during this algorithm. Defaults to true.
Definition lsReduce.hpp:50
void setLevelSet(SmartPointer< Domain< T, D > > passedlsDomain)
Definition lsReduce.hpp:32
Reduce()=default
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:39
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:44
Reduce(SmartPointer< Domain< T, D > > passedlsDomain)
Definition lsReduce.hpp:24
#define PRECOMPILE_PRECISION_DIMENSION(className)
Definition lsPreCompileMacros.hpp:24
Definition lsAdvect.hpp:36
double T
Definition pyWrap.cpp:68