ViennaLS
Loading...
Searching...
No Matches
lsFromMesh.hpp
Go to the documentation of this file.
1#pragma once
2
4
5#include <lsDomain.hpp>
6#include <lsMesh.hpp>
7
8namespace viennals {
9
10using namespace viennacore;
11
16template <class T, int D> class FromMesh {
17 typedef typename Domain<T, D>::DomainType hrleDomainType;
18
19 SmartPointer<Domain<T, D>> levelSet = nullptr;
20 SmartPointer<Mesh<T>> mesh = nullptr;
21 bool sortPointList = true;
22
23public:
24 FromMesh() = default;
25
26 FromMesh(SmartPointer<Domain<T, D>> passedLevelSet,
27 SmartPointer<Mesh<T>> passedMesh)
28 : levelSet(passedLevelSet), mesh(passedMesh) {}
29
30 void setLevelSet(SmartPointer<Domain<T, D>> passedlsDomain) {
31 levelSet = passedlsDomain;
32 }
33
34 void setMesh(const SmartPointer<Mesh<T>> passedMesh) { mesh = passedMesh; }
35
36 void setSortPointList(bool passedSortPointList) {
37 sortPointList = passedSortPointList;
38 }
39
40 void apply() {
41 if (levelSet == nullptr) {
42 Logger::getInstance()
43 .addError("No level set was passed to FromMesh.")
44 .print();
45 return;
46 }
47 if (mesh == nullptr) {
48 Logger::getInstance()
49 .addError("No Mesh was supplied to FromMesh.")
50 .print();
51 return;
52 }
53
54 auto &domain = levelSet->getDomain();
55 auto &nodes = mesh->getNodes();
56 auto values = mesh->getPointData().getScalarData("LSValues", true);
57 if (values == nullptr) {
58 values = mesh->getCellData().getScalarData("LSValues", true);
59 }
60
61 if (values == nullptr) {
62 Logger::getInstance()
63 .addError("Mesh does not contain level set values (\"LSValues\").")
64 .print();
65 return;
66 }
67
68 domain.initialize();
69
70 // if there are no points, just initialize an empty hrleDomain
71 if (nodes.empty()) {
72 return;
73 }
74
75 const viennahrle::Grid<D> &grid = domain.getGrid();
76 const T gridDelta = grid.getGridDelta();
77
78 viennahrle::Index<D> lastIndex;
79 for (unsigned i = 0; i < D; ++i) {
80 lastIndex[i] = nodes.front()[i] / gridDelta;
81 }
82
83 if (lastIndex != grid.getMinGridPoint()) {
84 domain.insertNextUndefinedPoint(0, grid.getMinGridPoint(),
85 (values->front() < 0)
88 }
89
90 auto pointDataIt = nodes.begin();
91 auto pointDataEnd = nodes.end();
92
93 auto valueIt = values->begin();
94 auto valueEnd = values->end();
95
96 VectorType<bool, D> signs;
97 std::fill(signs.begin(), signs.end(),
98 values->front() <= -std::numeric_limits<T>::epsilon());
99
100 while (pointDataIt != pointDataEnd && valueIt != valueEnd) {
101 // only read in points within the first 5 layers, to ignore
102 // undefined points
103 if (std::abs(*valueIt) > 2.5) {
104 ++pointDataIt;
105 ++valueIt;
106 continue;
107 }
108
109 bool setPoint = true;
110
111 viennahrle::Index<D> currentIndex;
112 for (unsigned i = 0; i < D; ++i) {
113 currentIndex[i] = std::round(pointDataIt->at(i) / gridDelta);
114 }
115
116 // if boundary conditions are infinite always set the point
117 // if not, check, whether it is inside of domain
118 for (unsigned i = 0; i < D; ++i) {
119 if (grid.getBoundaryConditions(i) !=
120 viennahrle::BoundaryType::INFINITE_BOUNDARY) {
121 if (currentIndex[i] > grid.getMaxBounds(i) ||
122 currentIndex[i] < grid.getMinBounds(i)) {
123 setPoint = false;
124 }
125 }
126 }
127
128 if (setPoint) {
129 // Add defined point as it appears in the list
130 domain.insertNextDefinedPoint(0, currentIndex, *valueIt);
131
132 // determine signs for next undefined runs
133 {
134 bool changeSign = false;
135 for (int i = D - 1; i >= 0; --i) {
136 changeSign = changeSign || (currentIndex[i] > lastIndex[i]);
137 if (changeSign) {
138 signs[i] = *valueIt <= -std::numeric_limits<T>::epsilon();
139 lastIndex[i] = currentIndex[i];
140 }
141 }
142 }
143 }
144
145 viennahrle::Index<D> nextIndex;
146
147 ++pointDataIt;
148 ++valueIt;
149
150 // choose correct next index
151 if (pointDataIt == pointDataEnd) {
152 nextIndex = grid.getMaxGridPoint();
153 ++nextIndex[D - 1];
154 } else {
155 for (unsigned i = 0; i < D; ++i) {
156 nextIndex[i] = std::round(pointDataIt->at(i) / gridDelta);
157 }
158 }
159
160 // move current index by one grid spacing and see if the next
161 // point has the same index, if not, there must be an undefined
162 // run inbetween
163 for (int q = 0; q < D; q++) {
164 viennahrle::Index<D> tmp = currentIndex;
165 ++tmp[q];
166 if (tmp[q] > grid.getMaxGridPoint(q))
167 continue;
168 for (int r = 0; r < q; ++r)
169 tmp[r] = grid.getMinGridPoint(r);
170
171 if (tmp >= nextIndex)
172 break;
173
174 domain.insertNextUndefinedPoint(0, tmp,
175 signs[q] ? Domain<T, D>::NEG_VALUE
177 }
178 }
179
180 domain.finalize();
181 }
182};
183
184// add all template specialisations for this class
186
187} // namespace viennals
constexpr int D
Definition Epitaxy.cpp:11
double T
Definition Epitaxy.cpp:12
Class containing all information about the level set, including the dimensions of the domain,...
Definition lsDomain.hpp:28
viennahrle::Domain< T, D > DomainType
Definition lsDomain.hpp:33
static constexpr T NEG_VALUE
Definition lsDomain.hpp:53
static constexpr T POS_VALUE
Definition lsDomain.hpp:52
void setMesh(const SmartPointer< Mesh< T > > passedMesh)
Definition lsFromMesh.hpp:34
void setSortPointList(bool passedSortPointList)
Definition lsFromMesh.hpp:36
void setLevelSet(SmartPointer< Domain< T, D > > passedlsDomain)
Definition lsFromMesh.hpp:30
void apply()
Definition lsFromMesh.hpp:40
FromMesh(SmartPointer< Domain< T, D > > passedLevelSet, SmartPointer< Mesh< T > > passedMesh)
Definition lsFromMesh.hpp:26
This class holds an explicit mesh, which is always given in 3 dimensions. If it describes a 2D mesh,...
Definition lsMesh.hpp:22
#define PRECOMPILE_PRECISION_DIMENSION(className)
Definition lsPreCompileMacros.hpp:24
Definition lsAdvect.hpp:41