Skip to content

Commit ff64be8

Browse files
committed
FIX: Remove everything but vertices in boundary condition labels for MeshIOPetsc.
1 parent 108e507 commit ff64be8

File tree

1 file changed

+105
-4
lines changed

1 file changed

+105
-4
lines changed

libsrc/pylith/meshio/MeshIOPetsc.cc

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,8 @@
2929
#include "pylith/utils/error.hh" // USES PYLITH_METHOD_*
3030
#include "pylith/utils/journals.hh" // USES PYLITH_COMPONENT_*
3131

32-
#include <iomanip> // USES setw(), setiosflags(), resetiosflags()
33-
#include <strings.h> // USES strcasecmp()
32+
#include <set> // USES std::set
3433
#include <cassert> // USES assert()
35-
#include <fstream> // USES std::ifstream, std::ofstream
3634
#include <stdexcept> // USES std::runtime_error
3735
#include <sstream> // USES std::ostringstream
3836
#include <typeinfo> // USES std::typeid
@@ -50,6 +48,17 @@ namespace pylith {
5048
static
5149
void fixMaterialLabel(PetscDM* dmMesh);
5250

51+
/** Create labels for boundaries based on vertices.
52+
*
53+
* For each boundary condition label:
54+
* 1. Remove all points that are not vertices from label.
55+
* 2. Add edges and faces to label based upon vertices.
56+
*
57+
* @param[inout] dmMesh PETSc DM for mesh.
58+
*/
59+
static
60+
void fixBoundaryLabels(PetscDM* dmMesh);
61+
5362
}; // _MeshIOPetsc
5463
} // meshio
5564
} // pylith
@@ -113,6 +122,7 @@ pylith::meshio::MeshIOPetsc::_read(void) {
113122
err = DMPlexDistributeSetDefault(dmMesh, PETSC_FALSE);PYLITH_CHECK_ERROR(err);
114123
err = DMSetFromOptions(dmMesh);PYLITH_CHECK_ERROR(err);
115124
_MeshIOPetsc::fixMaterialLabel(&dmMesh);
125+
_MeshIOPetsc::fixBoundaryLabels(&dmMesh);
116126
_mesh->setDM(dmMesh);
117127

118128
PYLITH_METHOD_END;
@@ -126,7 +136,7 @@ pylith::meshio::MeshIOPetsc::_write(void) const { }
126136

127137

128138
// ------------------------------------------------------------------------------------------------
129-
// Fix material label;
139+
// Remove everything but cells from label for materials.
130140
void
131141
pylith::meshio::_MeshIOPetsc::fixMaterialLabel(PetscDM* dmMesh) {
132142
PYLITH_METHOD_BEGIN;
@@ -161,3 +171,94 @@ pylith::meshio::_MeshIOPetsc::fixMaterialLabel(PetscDM* dmMesh) {
161171

162172
PYLITH_METHOD_END;
163173
} // fixMaterialLabel
174+
175+
176+
// ------------------------------------------------------------------------------------------------
177+
// Fix boundary condition labels. Remove points other than vertices from all labels other
178+
// than the material label.
179+
void
180+
pylith::meshio::_MeshIOPetsc::fixBoundaryLabels(PetscDM* dmMesh) {
181+
PYLITH_METHOD_BEGIN;
182+
assert(dmMesh);
183+
PetscErrorCode err = 0;
184+
185+
// Create set with labels to ignore.
186+
std::set<std::string> labelsIgnore;
187+
labelsIgnore.insert(std::string(pylith::topology::Mesh::cells_label_name));
188+
labelsIgnore.insert("celltype");
189+
labelsIgnore.insert("depth");
190+
191+
const PetscInt vertexDepth = 0;
192+
PetscInt vStart = -1, vEnd = -1;
193+
err = DMPlexGetDepthStratum(*dmMesh, vertexDepth, &vStart, &vEnd);PYLITH_CHECK_ERROR(err);
194+
195+
PetscInt numLabels = 0;
196+
err = DMGetNumLabels(*dmMesh, &numLabels);PYLITH_CHECK_ERROR(err);
197+
for (PetscInt iLabel = 0; iLabel < numLabels; ++iLabel) {
198+
const char* labelName = NULL;
199+
err = DMGetLabelName(*dmMesh, iLabel, &labelName);PYLITH_CHECK_ERROR(err);
200+
if (labelsIgnore.count(std::string(labelName)) > 0) { continue; }
201+
202+
PetscDMLabel dmLabel = NULL;
203+
err = DMGetLabelByNum(*dmMesh, iLabel, &dmLabel);PYLITH_CHECK_ERROR(err);
204+
PetscInt pStart = -1, pEnd = -1;
205+
err = DMLabelGetBounds(dmLabel, &pStart, &pEnd);PYLITH_CHECK_ERROR(err);
206+
207+
for (PetscInt point = pStart; point < pEnd; ++point) {
208+
if ((point >= vStart) && (point < vEnd)) { continue; }
209+
PetscBool hasLabel = PETSC_FALSE;
210+
err = DMLabelHasPoint(dmLabel, point, &hasLabel);PYLITH_CHECK_ERROR(err);
211+
if (hasLabel) {
212+
PetscInt labelValue;
213+
err = DMLabelGetValue(dmLabel, point, &labelValue);PYLITH_CHECK_ERROR(err);
214+
err = DMLabelClearValue(dmLabel, point, labelValue);PYLITH_CHECK_ERROR(err);
215+
} // if
216+
} // for
217+
err = DMLabelDestroyIndex(dmLabel);PYLITH_CHECK_ERROR(err);
218+
219+
// Readd edges and faces based upon vertices.
220+
// Add any non-cells which have all vertices in label.
221+
PetscInt cStart = -1, cEnd = -1;
222+
err = DMPlexGetHeightStratum(*dmMesh, 0, &cStart, &cEnd);PYLITH_CHECK_ERROR(err);
223+
224+
err = DMLabelComputeIndex(dmLabel);PYLITH_CHECK_ERROR(err);
225+
err = DMLabelGetBounds(dmLabel, &pStart, &pEnd);PYLITH_CHECK_ERROR(err);
226+
err = DMLabelDestroyIndex(dmLabel);PYLITH_CHECK_ERROR(err);
227+
for (PetscInt vertex = pStart; vertex < pEnd; ++vertex) {
228+
PetscInt labelValue = -1;
229+
err = DMLabelGetValue(dmLabel, vertex, &labelValue);PYLITH_CHECK_ERROR(err);
230+
if (labelValue < 1) { continue; }
231+
232+
PetscInt *star = NULL, starSize;
233+
err = DMPlexGetTransitiveClosure(*dmMesh, vertex, PETSC_FALSE, &starSize, &star);PYLITH_CHECK_ERROR(err);
234+
for (PetscInt s = 0; s < starSize*2; s += 2) {
235+
const PetscInt point = star[s];
236+
237+
if ((point >= cStart) && (point < cEnd)) { continue;}
238+
239+
// All vertices in closure must be in label to add point to label.
240+
PetscInt *closure = NULL, closureSize, value;
241+
PetscBool mark = PETSC_TRUE;
242+
err = DMPlexGetTransitiveClosure(*dmMesh, point, PETSC_TRUE, &closureSize, &closure);PYLITH_CHECK_ERROR(err);
243+
for (PetscInt c = 0; c < closureSize*2; c += 2) {
244+
if ((closure[c] >= vStart) && (closure[c] < vEnd)) {
245+
err = DMLabelGetValue(dmLabel, closure[c], &value);PYLITH_CHECK_ERROR(err);
246+
if (value != labelValue) {
247+
mark = PETSC_FALSE;
248+
break;
249+
} // if
250+
} // if
251+
} // for
252+
err = DMPlexRestoreTransitiveClosure(*dmMesh, point, PETSC_TRUE, &closureSize, &closure);PYLITH_CHECK_ERROR(err);
253+
if (mark) {
254+
err = DMLabelSetValue(dmLabel, point, labelValue);PYLITH_CHECK_ERROR(err);
255+
} // if
256+
} // for
257+
err = DMPlexRestoreTransitiveClosure(*dmMesh, vertex, PETSC_FALSE, &starSize, &star);PYLITH_CHECK_ERROR(err);
258+
} // for
259+
err = DMLabelComputeIndex(dmLabel);PYLITH_CHECK_ERROR(err);
260+
261+
} // for
262+
263+
PYLITH_METHOD_END;
264+
} // fixBoundaryLabels

0 commit comments

Comments
 (0)