ViennaLS
Loading...
Searching...
No Matches
lsCheck.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <ostream>
4#include <string>
5
6#include <hrleSparseStarIterator.hpp>
7
8#include <lsDomain.hpp>
9
10namespace viennals {
11
12using namespace viennacore;
13
14enum struct CheckStatusEnum : unsigned {
15 SUCCESS = 0,
16 FAILED = 1,
17 UNCHECKED = 2
18};
19
22template <class T, int D> class Check {
23 SmartPointer<Domain<T, D>> levelSet = nullptr;
25 std::string errors = "Level Set has not been checked yet!";
26 bool printMessage = false;
27
28 std::string getDirectionString(int i) {
29 std::string result = "";
30 if (i < D) {
31 result += "-";
32 } else {
33 i -= D;
34 result += "+";
35 }
36 if (i == 0) {
37 result += "x";
38 } else if (i == 1) {
39 result += "y";
40 } else if (i == 2) {
41 result += "z";
42 } else {
43 Logger::getInstance().addError("Check: " + std::to_string(i) +
44 " is not a valid direction index!");
45 }
46 return result;
47 }
48
49 bool isNegative(T val) { return val <= -std::numeric_limits<T>::epsilon(); }
50
51 int GetStatusFromDistance(T value) {
52 int x = static_cast<int>(value);
53 if (value >= 0.) {
54 return (value <= static_cast<T>(x) + static_cast<T>(0.5)) ? x : x + 1;
55 } else {
56 return (value >= static_cast<T>(x) - static_cast<T>(0.5)) ? x : x - 1;
57 }
58 }
59
60public:
61 Check() {}
62
63 Check(SmartPointer<Domain<T, D>> passedLevelSet, bool print = false)
64 : levelSet(passedLevelSet), printMessage(print) {}
65
66 void setLevelSet(SmartPointer<Domain<T, D>> passedLevelSet) {
67 levelSet = passedLevelSet;
68 }
69
70 void setPrintMessage(bool print) { printMessage = print; }
71
72 CheckStatusEnum getStatus() const { return status; }
73
74 bool isValid() const { return status == CheckStatusEnum::SUCCESS; }
75
76 std::string what() const { return errors; }
77
78 void apply() {
79 if (levelSet == nullptr) {
80 Logger::getInstance()
81 .addWarning("No level set was passed to Check.")
82 .print();
83 return;
84 }
85
86 std::ostringstream oss;
87
88 for (hrleConstSparseStarIterator<hrleDomain<T, D>, 1> it(
89 levelSet->getDomain());
90 !it.isFinished(); it.next()) {
91
92 if (it.getCenter().isDefined()) {
93 for (int i = 0; i < 2 * D; ++i) {
94 if (it.getNeighbor(i).isDefined()) {
95 if (std::abs(GetStatusFromDistance(it.getCenter().getValue()) -
96 GetStatusFromDistance(it.getNeighbor(i).getValue())) >
97 1) {
98 oss << "The defined point " << it.getCenter().getStartIndices()
99 << " has an inconsistent defined neighbor in direction "
100 << getDirectionString(i) << "!" << std::endl;
101 oss.precision(24);
102 oss << "Value center point: " << it.getCenter().getValue()
103 << " Value neighbor point: " << it.getNeighbor(i).getValue()
104 << std::endl;
105 }
106 } else {
107 if (it.getNeighbor(i).getValue() >= 0.) { // TODO POS_SIGN
108 if (it.getCenter().getValue() < T(-0.5)) {
109 oss << "The defined point " << it.getCenter().getStartIndices()
110 << " has a level set value less than -0.5 but has an "
111 "undefined positive neighbor in direction "
112 << getDirectionString(i) << "!" << std::endl;
113 }
114 } else {
115 if (it.getCenter().getValue() > T(0.5)) {
116 oss << "The defined point " << it.getCenter().getStartIndices()
117 << " has a level set value greater than 0.5 but has an "
118 "undefined negative neighbor in direction "
119 << getDirectionString(i) << "!" << std::endl;
120 }
121 }
122 }
123 }
124 } else {
125 for (int i = 0; i < 2 * D; ++i) {
126 if (!it.getNeighbor(i).isDefined()) {
127 if (isNegative(it.getCenter().getValue()) !=
128 isNegative(it.getNeighbor(i).getValue())) {
129 oss << "The undefined run from "
130 << it.getCenter().getStartIndices() << " to "
131 << it.getCenter().getEndIndices()
132 << " has undefined neighbor grid points of opposite sign in "
133 "direction "
134 << getDirectionString(i) << "!" << std::endl;
135 }
136 }
137 }
138 }
139 }
140
141 // output any faults as error
142 if (std::string s = oss.str(); !s.empty()) {
144 errors = s;
145 if (printMessage) {
146 std::string message = "Report from Check:\n" + s;
147 Logger::getInstance().addError(s);
148 }
149 } else {
151 errors = "";
152 }
153 }
154};
155
156} // namespace viennals
This class is used to find errors in the underlying level set structure, like invalid neighbours of d...
Definition lsCheck.hpp:22
CheckStatusEnum getStatus() const
Definition lsCheck.hpp:72
bool isValid() const
Definition lsCheck.hpp:74
void setPrintMessage(bool print)
Definition lsCheck.hpp:70
void apply()
Definition lsCheck.hpp:78
Check(SmartPointer< Domain< T, D > > passedLevelSet, bool print=false)
Definition lsCheck.hpp:63
Check()
Definition lsCheck.hpp:61
void setLevelSet(SmartPointer< Domain< T, D > > passedLevelSet)
Definition lsCheck.hpp:66
std::string what() const
Definition lsCheck.hpp:76
Class containing all information about the level set, including the dimensions of the domain,...
Definition lsDomain.hpp:28
Definition lsAdvect.hpp:46
CheckStatusEnum
Definition lsCheck.hpp:14
constexpr int D
Definition pyWrap.cpp:65
double T
Definition pyWrap.cpp:63