Skip to content

Commit 9bbb13d

Browse files
Merge pull request #522 from geodynamics/baagaard/fix-meshiopetsc-labels
Fix boundary labels in MeshIOPetsc
2 parents 0af7a82 + 270f667 commit 9bbb13d

File tree

6 files changed

+110
-6
lines changed

6 files changed

+110
-6
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

pylith/meshio/gmsh_utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,4 +189,5 @@ def _add_arguments(parser):
189189
pass
190190

191191

192-
# End of file
192+
# End of file
193+

tests/mmstests/linearelasticity/data/generate_gmsh_2d.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def __init__(self):
2222
"required": True,
2323
"choices": ["tri", "quad"],
2424
}
25+
self.filename = "tri.msh"
2526

2627
def create_geometry(self):
2728
"""Create geometry.

tests/mmstests/linearelasticity/data/generate_gmsh_3d.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ class App(GenerateMesh):
88
Block is DOMAIN_X by DOMAIN_Y by DOMAIN_Z with discretization size DX.
99
"""
1010
DOMAIN_X = DOMAIN_Y = DOMAIN_Z = 8.0e+3
11-
DX = 4.0e+3
11+
DX = 2.0e+3
1212

1313
def __init__(self):
1414
self.cell_choices = {
1515
"required": True,
1616
"choices": ["tet", "hex"],
1717
}
18+
self.filename = "tet.msh"
1819

1920
def create_geometry(self):
2021
"""Create geometry.
16 KB
Binary file not shown.
18 KB
Binary file not shown.

0 commit comments

Comments
 (0)