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:
25
26 FromMesh(SmartPointer<Domain<T, D>> passedLevelSet,
27 const 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 .addWarning("No level set was passed to FromMesh.")
44 .print();
45 return;
46 }
47 if (mesh == nullptr) {
48 Logger::getInstance()
49 .addWarning("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->cellData.getScalarData("LSValues", true);
57
58 if (values == nullptr) {
59 Logger::getInstance()
60 .addWarning("Mesh does not contain level set values (\"LSValues\").")
61 .print();
62 return;
63 }
64
65 domain.initialize();
66
67 // if there are no points, just initialize an empty hrleDomain
68 if (nodes.empty()) {
69 return;
70 }
71
72 const hrleGrid<D> &grid = domain.getGrid();
73 const T gridDelta = grid.getGridDelta();
74
75 if (hrleVectorType<T, D>(nodes.front()) != grid.getMinGridPoint()) {
76 domain.insertNextUndefinedPoint(0, grid.getMinGridPoint(),
77 (values->front() < 0)
80 }
81
82 hrleVectorType<hrleIndexType, D> lastIndex(nodes.front());
83 for (unsigned i = 0; i < D; ++i) {
84 lastIndex[i] = nodes.front()[i] / gridDelta;
85 }
86
87 auto pointDataIt = nodes.begin();
88 auto pointDataEnd = nodes.end();
89
90 auto valueIt = values->begin();
91 auto valueEnd = values->end();
92
93 hrleVectorType<bool, D> signs(values->front() <=
94 -std::numeric_limits<T>::epsilon());
95
96 while (pointDataIt != pointDataEnd && valueIt != valueEnd) {
97 // only read in points within the first 5 layers, to ignore
98 // undefined points
99 if (std::abs(*valueIt) > 2.5) {
100 ++pointDataIt;
101 ++valueIt;
102 continue;
103 }
104
105 bool setPoint = true;
106
107 hrleVectorType<hrleIndexType, D> currentIndex;
108 for (unsigned i = 0; i < D; ++i) {
109 currentIndex[i] = std::round(pointDataIt->at(i) / gridDelta);
110 }
111
112 // if boundary conditions are infinite always set the point
113 // if not, check, whether it is inside of domain
114 for (unsigned i = 0; i < D; ++i) {
115 if (grid.getBoundaryConditions(i) != hrleGrid<D>::INFINITE_BOUNDARY) {
116 if (currentIndex[i] > grid.getMaxBounds(i) ||
117 currentIndex[i] < grid.getMinBounds(i)) {
118 setPoint = false;
119 }
120 }
121 }
122
123 if (setPoint) {
124 // Add defined point as it appears in the list
125 domain.insertNextDefinedPoint(0, currentIndex, *valueIt);
126
127 // determine signs for next undefined runs
128 {
129 bool changeSign = false;
130 for (int i = D - 1; i >= 0; --i) {
131 changeSign = changeSign || (currentIndex[i] > lastIndex[i]);
132 if (changeSign) {
133 signs[i] = *valueIt <= -std::numeric_limits<T>::epsilon();
134 lastIndex[i] = currentIndex[i];
135 }
136 }
137 }
138 }
139
140 hrleVectorType<hrleIndexType, D> nextIndex;
141
142 ++pointDataIt;
143 ++valueIt;
144
145 // choose correct next index
146 if (pointDataIt == pointDataEnd) {
147 nextIndex = grid.getMaxGridPoint();
148 nextIndex[D - 1]++;
149 } else {
150 for (unsigned i = 0; i < D; ++i) {
151 nextIndex[i] = std::round(pointDataIt->at(i) / gridDelta);
152 }
153 }
154
155 // move current index by one grid spacing and see if the next
156 // point has the same index, if not, there must be an undefined
157 // run inbetween
158 for (int q = 0; q < D; q++) {
159 hrleVectorType<hrleIndexType, D> tmp = currentIndex;
160 tmp[q]++;
161 if (tmp[q] > grid.getMaxGridPoint(q))
162 continue;
163 for (int r = 0; r < q; ++r)
164 tmp[r] = grid.getMinGridPoint(r);
165
166 if (tmp >= nextIndex)
167 break;
168
169 domain.insertNextUndefinedPoint(0, tmp,
170 signs[q] ? Domain<T, D>::NEG_VALUE
172 }
173 }
174
175 domain.finalize();
176 }
177};
178
179// add all template specialisations for this class
181
182} // namespace viennals
Class containing all information about the level set, including the dimensions of the domain,...
Definition lsDomain.hpp:28
hrleDomain< T, D > DomainType
Definition lsDomain.hpp:33
Import the regular grid, on which the level set values are defined, from an explicit Mesh<>....
Definition lsFromMesh.hpp:16
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()
Definition lsFromMesh.hpp:24
FromMesh(SmartPointer< Domain< T, D > > passedLevelSet, const 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:21
#define PRECOMPILE_PRECISION_DIMENSION(className)
Definition lsPreCompileMacros.hpp:24
Definition lsAdvect.hpp:46
constexpr int D
Definition pyWrap.cpp:65
double T
Definition pyWrap.cpp:63