59 .addWarning(
"No grid has been set in FromVolumeMesh.")
63 if (mesh ==
nullptr) {
65 .addWarning(
"No mesh was passed to FromVolumeMesh.")
71 std::vector<int> materialInts;
73 mesh->cellData.getScalarData(
"Material",
true);
74 if (materialData !=
nullptr) {
77 std::vector<int>(materialData->begin(), materialData->end());
78 std::sort(materialInts.begin(), materialInts.end());
79 auto it = std::unique(materialInts.begin(), materialInts.end());
80 materialInts.erase(it, materialInts.end());
83 materialInts.push_back(0);
87 typedef std::map<hrleVectorType<unsigned int, D>, std::pair<int, int>>
89 triangleMapType surfaceElements;
91 unsigned numberOfElements =
92 (
D == 3) ? mesh->tetras.size() : mesh->triangles.size();
93 for (
unsigned int i = 0; i < numberOfElements; ++i) {
94 for (
int j = 0; j <
D + 1; j++) {
95 hrleVectorType<unsigned int, D> currentSurfaceElement;
96 for (
int k = 0; k <
D; k++) {
97 currentSurfaceElement[k] =
98 mesh->template getElements<D + 1>()[i][(j + k) % (
D + 1)];
126 currentSurfaceElement.sort();
128 hrleVectorType<double, D> currentElementPoints[
D + 1];
129 for (
int k = 0; k <
D; k++) {
130 currentElementPoints[k] = mesh->nodes[currentSurfaceElement[k]];
134 currentElementPoints[
D] =
135 mesh->nodes[mesh->template getElements<D + 1>()[i]
136 [(j +
D) % (
D + 1)]];
138 typename triangleMapType::iterator it =
139 surfaceElements.lower_bound(currentSurfaceElement);
140 if ((it != surfaceElements.end()) &&
141 (it->first == currentSurfaceElement)) {
142 if (Orientation(currentElementPoints)) {
143 if (it->second.second != materialInts.back() + 1) {
144 Logger::getInstance()
146 "Coinciding surface elements with same orientation in "
152 (materialData ==
nullptr) ? 0 : (*materialData)[i];
154 if (it->second.first != materialInts.back() + 1) {
155 Logger::getInstance()
157 "Coinciding surface elements with same orientation in "
163 (materialData ==
nullptr) ? 0 : (*materialData)[i];
166 if (it->second.first == it->second.second)
167 surfaceElements.erase(it);
170 if (Orientation(currentElementPoints)) {
171 surfaceElements.insert(
172 it, std::make_pair(currentSurfaceElement,
173 std::make_pair(materialInts.back() + 1,
174 (materialData ==
nullptr)
176 : (*materialData)[i])));
178 surfaceElements.insert(
179 it, std::make_pair(currentSurfaceElement,
180 std::make_pair((materialData ==
nullptr)
182 : (*materialData)[i],
183 materialInts.back() + 1)));
193 for (
unsigned i = 0; i < materialInts.size(); ++i) {
194 auto ls = LevelSetType::New(grid);
195 levelSets.push_back(
ls);
199 auto levelSetIterator = levelSets.begin();
200 for (
auto matIt = materialInts.begin(); matIt != materialInts.end();
202 auto currentSurface = SmartPointer<Mesh<T>>::New();
203 auto &meshElements = currentSurface->template getElements<D>();
204 for (
auto it = surfaceElements.begin(); it != surfaceElements.end();
206 if (((*matIt) >= it->second.first) && ((*matIt) < it->second.second)) {
207 std::array<unsigned, D> element{it->first[0], it->first[1]};
208 if constexpr (
D == 3)
209 element[2] = it->first[2];
210 meshElements.push_back(element);
211 }
else if (((*matIt) >= it->second.second) &&
212 ((*matIt) < it->second.first)) {
214 std::array<unsigned, D> element{it->first[1], it->first[0]};
215 if constexpr (
D == 3)
216 element[2] = it->first[2];
217 meshElements.push_back(element);
222 const unsigned int undefined_node =
223 std::numeric_limits<unsigned int>::max();
224 std::vector<unsigned int> nodeReplacements(mesh->nodes.size(),
226 unsigned int NodeCounter = 0;
228 for (
unsigned int k = 0; k < meshElements.size(); ++k) {
229 for (
int h = 0; h <
D; h++) {
230 unsigned int origin_node = meshElements[k][h];
231 if (nodeReplacements[origin_node] == undefined_node) {
232 nodeReplacements[origin_node] = NodeCounter++;
233 currentSurface->nodes.push_back(mesh->nodes[origin_node]);
235 meshElements[k][h] = nodeReplacements[origin_node];
241 removeBoundaryTriangles)