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.
130140void
131141pylith::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