59 .addError(
"No grid has been set in FromVolumeMesh.")
63 if (mesh ==
nullptr) {
65 .addError(
"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<VectorType<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 VectorType<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)];
127 std::sort(currentSurfaceElement.begin(), currentSurfaceElement.end());
129 Vec3D<T> currentElementPoints[
D + 1];
130 for (
int k = 0; k <
D; k++) {
131 currentElementPoints[k] = mesh->nodes[currentSurfaceElement[k]];
135 currentElementPoints[
D] =
136 mesh->nodes[mesh->template getElements<D + 1>()[i]
137 [(j +
D) % (
D + 1)]];
139 typename triangleMapType::iterator it =
140 surfaceElements.lower_bound(currentSurfaceElement);
141 if ((it != surfaceElements.end()) &&
142 (it->first == currentSurfaceElement)) {
143 if (Orientation(currentElementPoints)) {
144 if (it->second.second != materialInts.back() + 1) {
145 VIENNACORE_LOG_WARNING(
146 "Coinciding surface elements with same orientation in "
151 (materialData ==
nullptr) ? 0 : (*materialData)[i];
153 if (it->second.first != materialInts.back() + 1) {
154 VIENNACORE_LOG_WARNING(
155 "Coinciding surface elements with same orientation in "
160 (materialData ==
nullptr) ? 0 : (*materialData)[i];
163 if (it->second.first == it->second.second)
164 surfaceElements.erase(it);
167 if (Orientation(currentElementPoints)) {
168 surfaceElements.insert(
169 it, std::make_pair(currentSurfaceElement,
170 std::make_pair(materialInts.back() + 1,
171 (materialData ==
nullptr)
173 : (*materialData)[i])));
175 surfaceElements.insert(
176 it, std::make_pair(currentSurfaceElement,
177 std::make_pair((materialData ==
nullptr)
179 : (*materialData)[i],
180 materialInts.back() + 1)));
190 for (
unsigned i = 0; i < materialInts.size(); ++i) {
191 auto ls = LevelSetType::New(grid);
192 levelSets.push_back(
ls);
196 auto levelSetIterator = levelSets.begin();
197 for (
int &materialInt : materialInts) {
198 auto currentSurface = SmartPointer<Mesh<T>>::New();
199 auto &meshElements = currentSurface->template getElements<D>();
200 for (
auto it = surfaceElements.begin(); it != surfaceElements.end();
202 if ((materialInt >= it->second.first) &&
203 (materialInt < it->second.second)) {
204 std::array<unsigned, D> element{it->first[0], it->first[1]};
205 if constexpr (
D == 3)
206 element[2] = it->first[2];
207 meshElements.push_back(element);
208 }
else if ((materialInt >= it->second.second) &&
209 (materialInt < it->second.first)) {
211 std::array<unsigned, D> element{it->first[1], it->first[0]};
212 if constexpr (
D == 3)
213 element[2] = it->first[2];
214 meshElements.push_back(element);
219 constexpr unsigned int undefined_node =
220 std::numeric_limits<unsigned int>::max();
221 std::vector<unsigned int> nodeReplacements(mesh->nodes.size(),
223 unsigned int NodeCounter = 0;
225 for (
unsigned int k = 0; k < meshElements.size(); ++k) {
226 for (
int h = 0; h <
D; h++) {
227 unsigned int origin_node = meshElements[k][h];
228 if (nodeReplacements[origin_node] == undefined_node) {
229 nodeReplacements[origin_node] = NodeCounter++;
230 currentSurface->nodes.push_back(mesh->nodes[origin_node]);
232 meshElements[k][h] = nodeReplacements[origin_node];
238 removeBoundaryTriangles)