xref: /petsc/src/dm/impls/plex/tests/ex56.c (revision e600fa544e2bb197ca2af9b6e65ea465976dec56)
11d5c9e23SVaclav Hapla #include <petscdmplex.h>
21d5c9e23SVaclav Hapla #include <petscviewerhdf5.h>
31d5c9e23SVaclav Hapla #include <petscsf.h>
41d5c9e23SVaclav Hapla 
51d5c9e23SVaclav Hapla static const char help[] = "Load and save the mesh to the native HDF5 format\n\n";
61d5c9e23SVaclav Hapla static const char EX[] = "ex56.c";
71d5c9e23SVaclav Hapla static const char LABEL_NAME[] = "BoundaryVertices";
81d5c9e23SVaclav Hapla static const PetscInt LABEL_VALUE = 12345;
91d5c9e23SVaclav Hapla typedef struct {
101d5c9e23SVaclav Hapla   MPI_Comm    comm;
111d5c9e23SVaclav Hapla   const char *meshname;                     /* Mesh name */
121d5c9e23SVaclav Hapla   PetscBool   compare;                      /* Compare the meshes using DMPlexEqual() and DMCompareLabels() */
131d5c9e23SVaclav Hapla   PetscBool   compare_labels;               /* Compare labels in the meshes using DMCompareLabels() */
141d5c9e23SVaclav Hapla   PetscBool   compare_boundary;             /* Check label I/O via boundary vertex coordinates */
151d5c9e23SVaclav Hapla   PetscBool   compare_pre_post;             /* Compare labels loaded before distribution with those loaded after distribution */
161d5c9e23SVaclav Hapla   char        outfile[PETSC_MAX_PATH_LEN];  /* Output file */
171d5c9e23SVaclav Hapla   PetscBool   use_low_level_functions;      /* Use low level functions for viewing and loading */
181d5c9e23SVaclav Hapla   //TODO This is meant as temporary option; can be removed once we have full parallel loading in place
191d5c9e23SVaclav Hapla   PetscBool   distribute_after_topo_load;   /* Distribute topology right after DMPlexTopologyLoad(), if use_low_level_functions=true */
201d5c9e23SVaclav Hapla   PetscBool   verbose;
211d5c9e23SVaclav Hapla } AppCtx;
221d5c9e23SVaclav Hapla 
231d5c9e23SVaclav Hapla static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
241d5c9e23SVaclav Hapla {
251d5c9e23SVaclav Hapla   PetscErrorCode ierr;
261d5c9e23SVaclav Hapla 
271d5c9e23SVaclav Hapla   PetscFunctionBeginUser;
281d5c9e23SVaclav Hapla   options->comm                       = comm;
291d5c9e23SVaclav Hapla   options->compare                    = PETSC_FALSE;
301d5c9e23SVaclav Hapla   options->compare_labels             = PETSC_FALSE;
311d5c9e23SVaclav Hapla   options->compare_boundary           = PETSC_FALSE;
321d5c9e23SVaclav Hapla   options->compare_pre_post           = PETSC_FALSE;
331d5c9e23SVaclav Hapla   options->outfile[0]                 = '\0';
341d5c9e23SVaclav Hapla   options->use_low_level_functions    = PETSC_FALSE;
351d5c9e23SVaclav Hapla   options->distribute_after_topo_load = PETSC_FALSE;
361d5c9e23SVaclav Hapla   options->verbose                    = PETSC_FALSE;
371d5c9e23SVaclav Hapla 
381d5c9e23SVaclav Hapla   ierr = PetscOptionsBegin(comm, "", "Meshing Problem Options", "DMPLEX");CHKERRQ(ierr);
391d5c9e23SVaclav Hapla   ierr = PetscOptionsBool("-compare", "Compare the meshes using DMPlexEqual() and DMCompareLabels()", EX, options->compare, &options->compare, NULL);CHKERRQ(ierr);
401d5c9e23SVaclav Hapla   ierr = PetscOptionsBool("-compare_labels", "Compare labels in the meshes using DMCompareLabels()", "ex55.c", options->compare_labels, &options->compare_labels, NULL);CHKERRQ(ierr);
411d5c9e23SVaclav Hapla   ierr = PetscOptionsBool("-compare_boundary", "Check label I/O via boundary vertex coordinates", "ex55.c", options->compare_boundary, &options->compare_boundary, NULL);CHKERRQ(ierr);
421d5c9e23SVaclav Hapla   ierr = PetscOptionsBool("-compare_pre_post", "Compare labels loaded before distribution with those loaded after distribution", "ex55.c", options->compare_pre_post, &options->compare_pre_post, NULL);CHKERRQ(ierr);
431d5c9e23SVaclav Hapla   ierr = PetscOptionsString("-outfile", "Output mesh file", EX, options->outfile, options->outfile, sizeof(options->outfile), NULL);CHKERRQ(ierr);
441d5c9e23SVaclav Hapla   ierr = PetscOptionsBool("-use_low_level_functions", "Use low level functions for viewing and loading", EX, options->use_low_level_functions, &options->use_low_level_functions, NULL);CHKERRQ(ierr);
451d5c9e23SVaclav Hapla   ierr = PetscOptionsBool("-distribute_after_topo_load", "Distribute topology right after DMPlexTopologyLoad(), if use_low_level_functions=true", EX, options->distribute_after_topo_load, &options->distribute_after_topo_load, NULL);CHKERRQ(ierr);
461d5c9e23SVaclav Hapla   ierr = PetscOptionsBool("-verbose", "Verbose printing", EX, options->verbose, &options->verbose, NULL);CHKERRQ(ierr);
471d5c9e23SVaclav Hapla   ierr = PetscOptionsEnd();CHKERRQ(ierr);
481d5c9e23SVaclav Hapla   PetscFunctionReturn(0);
491d5c9e23SVaclav Hapla };
501d5c9e23SVaclav Hapla 
511d5c9e23SVaclav Hapla static PetscErrorCode CreateMesh(AppCtx *options, DM *newdm)
521d5c9e23SVaclav Hapla {
531d5c9e23SVaclav Hapla   DM             dm;
541d5c9e23SVaclav Hapla   PetscErrorCode ierr;
551d5c9e23SVaclav Hapla 
561d5c9e23SVaclav Hapla   PetscFunctionBeginUser;
571d5c9e23SVaclav Hapla   ierr = DMCreate(options->comm, &dm);CHKERRQ(ierr);
581d5c9e23SVaclav Hapla   ierr = DMSetType(dm, DMPLEX);CHKERRQ(ierr);
591d5c9e23SVaclav Hapla   ierr = DMSetFromOptions(dm);CHKERRQ(ierr);
601d5c9e23SVaclav Hapla   ierr = PetscObjectGetName((PetscObject)dm, &options->meshname);CHKERRQ(ierr);
611d5c9e23SVaclav Hapla   ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr);
621d5c9e23SVaclav Hapla   *newdm = dm;
631d5c9e23SVaclav Hapla   PetscFunctionReturn(0);
641d5c9e23SVaclav Hapla }
651d5c9e23SVaclav Hapla 
661d5c9e23SVaclav Hapla static PetscErrorCode SaveMesh(AppCtx *options, DM dm)
671d5c9e23SVaclav Hapla {
681d5c9e23SVaclav Hapla   PetscViewer    v;
691d5c9e23SVaclav Hapla   PetscErrorCode ierr;
701d5c9e23SVaclav Hapla 
711d5c9e23SVaclav Hapla   PetscFunctionBeginUser;
721d5c9e23SVaclav Hapla   ierr = PetscViewerHDF5Open(PetscObjectComm((PetscObject) dm), options->outfile, FILE_MODE_WRITE, &v);CHKERRQ(ierr);
731d5c9e23SVaclav Hapla   if (options->use_low_level_functions) {
741d5c9e23SVaclav Hapla     ierr = DMPlexTopologyView(dm, v);CHKERRQ(ierr);
751d5c9e23SVaclav Hapla     ierr = DMPlexCoordinatesView(dm, v);CHKERRQ(ierr);
761d5c9e23SVaclav Hapla     ierr = DMPlexLabelsView(dm, v);CHKERRQ(ierr);
771d5c9e23SVaclav Hapla   } else {
781d5c9e23SVaclav Hapla     ierr = DMView(dm, v);CHKERRQ(ierr);
791d5c9e23SVaclav Hapla   }
801d5c9e23SVaclav Hapla   ierr = PetscViewerDestroy(&v);CHKERRQ(ierr);
811d5c9e23SVaclav Hapla   PetscFunctionReturn(0);
821d5c9e23SVaclav Hapla }
831d5c9e23SVaclav Hapla 
841d5c9e23SVaclav Hapla typedef enum {NONE=0, PRE_DIST=1, POST_DIST=2} AuxObjLoadMode;
851d5c9e23SVaclav Hapla 
861d5c9e23SVaclav Hapla static PetscErrorCode LoadMeshLowLevel(AppCtx *options, PetscViewer v, PetscBool explicitDistribute, AuxObjLoadMode mode, DM *newdm)
871d5c9e23SVaclav Hapla {
881d5c9e23SVaclav Hapla   DM              dm;
891d5c9e23SVaclav Hapla   PetscSF         sfXC;
901d5c9e23SVaclav Hapla   PetscErrorCode  ierr;
911d5c9e23SVaclav Hapla 
921d5c9e23SVaclav Hapla   PetscFunctionBeginUser;
931d5c9e23SVaclav Hapla   ierr = DMCreate(options->comm, &dm);CHKERRQ(ierr);
941d5c9e23SVaclav Hapla   ierr = DMSetType(dm, DMPLEX);CHKERRQ(ierr);
951d5c9e23SVaclav Hapla   ierr = PetscObjectSetName((PetscObject) dm, options->meshname);CHKERRQ(ierr);
961d5c9e23SVaclav Hapla   ierr = DMPlexTopologyLoad(dm, v, &sfXC);CHKERRQ(ierr);
971d5c9e23SVaclav Hapla   if (mode == PRE_DIST) {
981d5c9e23SVaclav Hapla     ierr = DMPlexCoordinatesLoad(dm, v, sfXC);CHKERRQ(ierr);
991d5c9e23SVaclav Hapla     ierr = DMPlexLabelsLoad(dm, v, sfXC);CHKERRQ(ierr);
1001d5c9e23SVaclav Hapla   }
1011d5c9e23SVaclav Hapla   if (explicitDistribute) {
1021d5c9e23SVaclav Hapla     DM      dmdist;
1031d5c9e23SVaclav Hapla     PetscSF sfXB = sfXC, sfBC;
1041d5c9e23SVaclav Hapla 
1051d5c9e23SVaclav Hapla     ierr = DMPlexDistribute(dm, 0, &sfBC, &dmdist);CHKERRQ(ierr);
1061d5c9e23SVaclav Hapla     if (dmdist) {
1071d5c9e23SVaclav Hapla       const char *name;
1081d5c9e23SVaclav Hapla 
1091d5c9e23SVaclav Hapla       ierr = PetscObjectGetName((PetscObject) dm, &name);CHKERRQ(ierr);
1101d5c9e23SVaclav Hapla       ierr = PetscObjectSetName((PetscObject) dmdist, name);CHKERRQ(ierr);
1111d5c9e23SVaclav Hapla       ierr = PetscSFCompose(sfXB, sfBC, &sfXC);CHKERRQ(ierr);
1121d5c9e23SVaclav Hapla       ierr = PetscSFDestroy(&sfXB);CHKERRQ(ierr);
1131d5c9e23SVaclav Hapla       ierr = PetscSFDestroy(&sfBC);CHKERRQ(ierr);
1141d5c9e23SVaclav Hapla       ierr = DMDestroy(&dm);CHKERRQ(ierr);
1151d5c9e23SVaclav Hapla       dm   = dmdist;
1161d5c9e23SVaclav Hapla     }
1171d5c9e23SVaclav Hapla   }
1181d5c9e23SVaclav Hapla   if (mode == POST_DIST) {
1191d5c9e23SVaclav Hapla     ierr = DMPlexCoordinatesLoad(dm, v, sfXC);CHKERRQ(ierr);
1201d5c9e23SVaclav Hapla     ierr = DMPlexLabelsLoad(dm, v, sfXC);CHKERRQ(ierr);
1211d5c9e23SVaclav Hapla   }
1221d5c9e23SVaclav Hapla   ierr = PetscSFDestroy(&sfXC);CHKERRQ(ierr);
1231d5c9e23SVaclav Hapla   *newdm = dm;
1241d5c9e23SVaclav Hapla   PetscFunctionReturn(0);
1251d5c9e23SVaclav Hapla }
1261d5c9e23SVaclav Hapla 
1271d5c9e23SVaclav Hapla static PetscErrorCode LoadMesh(AppCtx *options, DM *dmnew)
1281d5c9e23SVaclav Hapla {
1291d5c9e23SVaclav Hapla   DM             dm;
1301d5c9e23SVaclav Hapla   PetscViewer    v;
1311d5c9e23SVaclav Hapla   PetscErrorCode ierr;
1321d5c9e23SVaclav Hapla 
1331d5c9e23SVaclav Hapla   PetscFunctionBeginUser;
1341d5c9e23SVaclav Hapla   ierr = PetscViewerHDF5Open(options->comm, options->outfile, FILE_MODE_READ, &v);CHKERRQ(ierr);
1351d5c9e23SVaclav Hapla   if (options->use_low_level_functions) {
1361d5c9e23SVaclav Hapla     if (options->compare_pre_post) {
1371d5c9e23SVaclav Hapla       DM dm0;
1381d5c9e23SVaclav Hapla 
1391d5c9e23SVaclav Hapla       ierr = LoadMeshLowLevel(options, v, PETSC_TRUE, PRE_DIST, &dm0);CHKERRQ(ierr);
1401d5c9e23SVaclav Hapla       ierr = LoadMeshLowLevel(options, v, PETSC_TRUE, POST_DIST, &dm);CHKERRQ(ierr);
1411d5c9e23SVaclav Hapla       ierr = DMCompareLabels(dm0, dm, NULL, NULL);CHKERRQ(ierr);
1421d5c9e23SVaclav Hapla       ierr = DMDestroy(&dm0);CHKERRQ(ierr);
1431d5c9e23SVaclav Hapla     } else {
1441d5c9e23SVaclav Hapla       ierr = LoadMeshLowLevel(options, v, options->distribute_after_topo_load, POST_DIST, &dm);CHKERRQ(ierr);
1451d5c9e23SVaclav Hapla     }
1461d5c9e23SVaclav Hapla   } else {
1471d5c9e23SVaclav Hapla     ierr = DMCreate(options->comm, &dm);CHKERRQ(ierr);
1481d5c9e23SVaclav Hapla     ierr = DMSetType(dm, DMPLEX);CHKERRQ(ierr);
1491d5c9e23SVaclav Hapla     ierr = PetscObjectSetName((PetscObject) dm, options->meshname);CHKERRQ(ierr);
1501d5c9e23SVaclav Hapla     ierr = DMLoad(dm, v);CHKERRQ(ierr);
1511d5c9e23SVaclav Hapla   }
1521d5c9e23SVaclav Hapla   ierr = PetscViewerDestroy(&v);CHKERRQ(ierr);
1531d5c9e23SVaclav Hapla 
1541d5c9e23SVaclav Hapla   ierr = DMSetOptionsPrefix(dm, "load_");CHKERRQ(ierr);
1551d5c9e23SVaclav Hapla   ierr = DMSetFromOptions(dm);CHKERRQ(ierr);
1561d5c9e23SVaclav Hapla   ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr);
1571d5c9e23SVaclav Hapla   *dmnew = dm;
1581d5c9e23SVaclav Hapla   PetscFunctionReturn(0);
1591d5c9e23SVaclav Hapla }
1601d5c9e23SVaclav Hapla 
1611d5c9e23SVaclav Hapla static PetscErrorCode CompareMeshes(AppCtx *options, DM dm0, DM dm1)
1621d5c9e23SVaclav Hapla {
1631d5c9e23SVaclav Hapla   PetscBool       flg;
1641d5c9e23SVaclav Hapla   PetscErrorCode  ierr;
1651d5c9e23SVaclav Hapla 
1661d5c9e23SVaclav Hapla   PetscFunctionBeginUser;
1671d5c9e23SVaclav Hapla   if (options->compare) {
1681d5c9e23SVaclav Hapla     ierr = DMPlexEqual(dm0, dm1, &flg);CHKERRQ(ierr);
1692c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!flg,options->comm, PETSC_ERR_ARG_INCOMP, "DMs are not equal");
1701d5c9e23SVaclav Hapla     ierr = PetscPrintf(options->comm,"DMs equal\n");CHKERRQ(ierr);
1711d5c9e23SVaclav Hapla   }
1721d5c9e23SVaclav Hapla   if (options->compare_labels) {
1731d5c9e23SVaclav Hapla     ierr = DMCompareLabels(dm0, dm1, NULL, NULL);CHKERRQ(ierr);
1741d5c9e23SVaclav Hapla     ierr = PetscPrintf(options->comm,"DMLabels equal\n");CHKERRQ(ierr);
1751d5c9e23SVaclav Hapla   }
1761d5c9e23SVaclav Hapla   PetscFunctionReturn(0);
1771d5c9e23SVaclav Hapla }
1781d5c9e23SVaclav Hapla 
1791d5c9e23SVaclav Hapla static PetscErrorCode MarkBoundaryVertices(DM dm, PetscInt value, DMLabel *label)
1801d5c9e23SVaclav Hapla {
1811d5c9e23SVaclav Hapla   DMLabel         l;
1821d5c9e23SVaclav Hapla   IS              points;
1831d5c9e23SVaclav Hapla   const PetscInt *idx;
1841d5c9e23SVaclav Hapla   PetscInt        i, n;
1851d5c9e23SVaclav Hapla   PetscErrorCode  ierr;
1861d5c9e23SVaclav Hapla 
1871d5c9e23SVaclav Hapla   PetscFunctionBeginUser;
1881d5c9e23SVaclav Hapla   ierr = DMLabelCreate(PetscObjectComm((PetscObject)dm), LABEL_NAME, &l);CHKERRQ(ierr);
1891d5c9e23SVaclav Hapla   ierr = DMPlexMarkBoundaryFaces(dm, value, l);CHKERRQ(ierr);
1901d5c9e23SVaclav Hapla   ierr = DMPlexLabelComplete(dm, l);CHKERRQ(ierr);
1911d5c9e23SVaclav Hapla   ierr = DMLabelGetStratumIS(l, value, &points);CHKERRQ(ierr);
1921d5c9e23SVaclav Hapla 
1931d5c9e23SVaclav Hapla   ierr = ISGetLocalSize(points, &n);CHKERRQ(ierr);
1941d5c9e23SVaclav Hapla   ierr = ISGetIndices(points, &idx);CHKERRQ(ierr);
1951d5c9e23SVaclav Hapla   for (i=0; i<n; i++) {
1961d5c9e23SVaclav Hapla     const PetscInt p = idx[i];
1971d5c9e23SVaclav Hapla     PetscInt       d;
1981d5c9e23SVaclav Hapla 
1991d5c9e23SVaclav Hapla     ierr = DMPlexGetPointDepth(dm, p, &d);CHKERRQ(ierr);
2001d5c9e23SVaclav Hapla     if (d != 0) {
2011d5c9e23SVaclav Hapla       ierr = DMLabelClearValue(l, p, value);CHKERRQ(ierr);
2021d5c9e23SVaclav Hapla     }
2031d5c9e23SVaclav Hapla   }
2041d5c9e23SVaclav Hapla   ierr = ISRestoreIndices(points, &idx);CHKERRQ(ierr);
2051d5c9e23SVaclav Hapla   ierr = ISDestroy(&points);CHKERRQ(ierr);
2061d5c9e23SVaclav Hapla   *label = l;
2071d5c9e23SVaclav Hapla   PetscFunctionReturn(0);
2081d5c9e23SVaclav Hapla }
2091d5c9e23SVaclav Hapla 
2101d5c9e23SVaclav Hapla static PetscErrorCode VertexCoordinatesToAll(DM dm, IS vertices, Vec *allCoords)
2111d5c9e23SVaclav Hapla {
2121d5c9e23SVaclav Hapla   Vec             coords, allCoords_;
2131d5c9e23SVaclav Hapla   VecScatter      sc;
2141d5c9e23SVaclav Hapla   MPI_Comm        comm;
2151d5c9e23SVaclav Hapla   PetscErrorCode  ierr;
2161d5c9e23SVaclav Hapla 
2171d5c9e23SVaclav Hapla   PetscFunctionBeginUser;
2181d5c9e23SVaclav Hapla   ierr = PetscObjectGetComm((PetscObject)dm, &comm);CHKERRQ(ierr);
2191d5c9e23SVaclav Hapla   ierr = DMGetCoordinatesLocalSetUp(dm);CHKERRQ(ierr);
2201d5c9e23SVaclav Hapla   if (vertices) {
2211d5c9e23SVaclav Hapla     ierr = DMGetCoordinatesLocalTuple(dm, vertices, NULL, &coords);CHKERRQ(ierr);
2221d5c9e23SVaclav Hapla   } else {
2231d5c9e23SVaclav Hapla     ierr = VecCreateSeq(PETSC_COMM_SELF, 0, &coords);CHKERRQ(ierr);
2241d5c9e23SVaclav Hapla   }
2251d5c9e23SVaclav Hapla   {
2261d5c9e23SVaclav Hapla     PetscInt  n;
2271d5c9e23SVaclav Hapla     Vec       mpivec;
2281d5c9e23SVaclav Hapla 
2291d5c9e23SVaclav Hapla     ierr = VecGetLocalSize(coords, &n);CHKERRQ(ierr);
2301d5c9e23SVaclav Hapla     ierr = VecCreateMPI(comm, n, PETSC_DECIDE, &mpivec);CHKERRQ(ierr);
2311d5c9e23SVaclav Hapla     ierr = VecCopy(coords, mpivec);CHKERRQ(ierr);
2321d5c9e23SVaclav Hapla     ierr = VecDestroy(&coords);CHKERRQ(ierr);
2331d5c9e23SVaclav Hapla     coords = mpivec;
2341d5c9e23SVaclav Hapla   }
2351d5c9e23SVaclav Hapla 
2361d5c9e23SVaclav Hapla   ierr = VecScatterCreateToAll(coords, &sc, &allCoords_);CHKERRQ(ierr);
2371d5c9e23SVaclav Hapla   ierr = VecScatterBegin(sc,coords,allCoords_,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2381d5c9e23SVaclav Hapla   ierr = VecScatterEnd(sc,coords,allCoords_,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
2391d5c9e23SVaclav Hapla   ierr = VecScatterDestroy(&sc);CHKERRQ(ierr);
2401d5c9e23SVaclav Hapla   ierr = VecDestroy(&coords);CHKERRQ(ierr);
2411d5c9e23SVaclav Hapla   *allCoords = allCoords_;
2421d5c9e23SVaclav Hapla   PetscFunctionReturn(0);
2431d5c9e23SVaclav Hapla }
2441d5c9e23SVaclav Hapla 
2451d5c9e23SVaclav Hapla /* Compute boundary label, remember boundary vertices using coordinates, save and load label, check it is defined on the original boundary vertices */
2461d5c9e23SVaclav Hapla static PetscErrorCode DMAddBoundaryLabel_GetCoordinateRepresentation(DM dm, Vec *allCoords)
2471d5c9e23SVaclav Hapla {
2481d5c9e23SVaclav Hapla   DMLabel         label;
2491d5c9e23SVaclav Hapla   IS              vertices;
2501d5c9e23SVaclav Hapla   PetscErrorCode  ierr;
2511d5c9e23SVaclav Hapla 
2521d5c9e23SVaclav Hapla   PetscFunctionBeginUser;
2531d5c9e23SVaclav Hapla   ierr = MarkBoundaryVertices(dm, LABEL_VALUE, &label);CHKERRQ(ierr);
2541d5c9e23SVaclav Hapla   ierr = DMLabelGetStratumIS(label, LABEL_VALUE, &vertices);CHKERRQ(ierr);
2551d5c9e23SVaclav Hapla   ierr = VertexCoordinatesToAll(dm, vertices, allCoords);CHKERRQ(ierr);
2561d5c9e23SVaclav Hapla   ierr = DMAddLabel(dm, label);CHKERRQ(ierr);
2571d5c9e23SVaclav Hapla   ierr = DMLabelDestroy(&label);CHKERRQ(ierr);
2581d5c9e23SVaclav Hapla   ierr = ISDestroy(&vertices);CHKERRQ(ierr);
2591d5c9e23SVaclav Hapla   PetscFunctionReturn(0);
2601d5c9e23SVaclav Hapla }
2611d5c9e23SVaclav Hapla 
2621d5c9e23SVaclav Hapla static PetscErrorCode DMGetBoundaryLabel_CompareWithCoordinateRepresentation(AppCtx *user, DM dm, Vec allCoords)
2631d5c9e23SVaclav Hapla {
2641d5c9e23SVaclav Hapla   DMLabel         label;
2651d5c9e23SVaclav Hapla   IS              pointsIS;
2661d5c9e23SVaclav Hapla   const PetscInt *points;
2671d5c9e23SVaclav Hapla   PetscInt        i, n;
2681d5c9e23SVaclav Hapla   PetscBool       fail = PETSC_FALSE;
2691d5c9e23SVaclav Hapla   MPI_Comm        comm;
2701d5c9e23SVaclav Hapla   PetscMPIInt     rank;
2711d5c9e23SVaclav Hapla   PetscErrorCode  ierr;
2721d5c9e23SVaclav Hapla 
2731d5c9e23SVaclav Hapla   PetscFunctionBeginUser;
2741d5c9e23SVaclav Hapla   ierr = PetscObjectGetComm((PetscObject)dm, &comm);CHKERRQ(ierr);
2751d5c9e23SVaclav Hapla   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
2761d5c9e23SVaclav Hapla   ierr = DMGetLabel(dm, LABEL_NAME, &label);CHKERRQ(ierr);
2772c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!label,PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label \"%s\" was not loaded", LABEL_NAME);
2781d5c9e23SVaclav Hapla   {
2791d5c9e23SVaclav Hapla     PetscInt pStart, pEnd;
2801d5c9e23SVaclav Hapla 
2811d5c9e23SVaclav Hapla     ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
2821d5c9e23SVaclav Hapla     ierr = DMLabelCreateIndex(label, pStart, pEnd);CHKERRQ(ierr);
2831d5c9e23SVaclav Hapla   }
2841d5c9e23SVaclav Hapla   ierr = DMPlexFindVertices(dm, allCoords, 0.0, &pointsIS);CHKERRQ(ierr);
2851d5c9e23SVaclav Hapla   ierr = ISGetIndices(pointsIS, &points);CHKERRQ(ierr);
2861d5c9e23SVaclav Hapla   ierr = ISGetLocalSize(pointsIS, &n);CHKERRQ(ierr);
2871d5c9e23SVaclav Hapla   if (user->verbose) {ierr = DMLabelView(label, PETSC_VIEWER_STDOUT_(comm));CHKERRQ(ierr);}
2881d5c9e23SVaclav Hapla   for (i=0; i<n; i++) {
2891d5c9e23SVaclav Hapla     const PetscInt  p = points[i];
2901d5c9e23SVaclav Hapla     PetscBool       has;
2911d5c9e23SVaclav Hapla     PetscInt        v;
2921d5c9e23SVaclav Hapla 
2931d5c9e23SVaclav Hapla     if (p < 0) continue;
2941d5c9e23SVaclav Hapla     ierr = DMLabelHasPoint(label, p, &has);CHKERRQ(ierr);
2951d5c9e23SVaclav Hapla     if (!has) {
2961d5c9e23SVaclav Hapla       ierr = PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] Label does not have point %D\n", rank, p);CHKERRQ(ierr);
2971d5c9e23SVaclav Hapla       fail = PETSC_TRUE;
2981d5c9e23SVaclav Hapla       continue;
2991d5c9e23SVaclav Hapla     }
3001d5c9e23SVaclav Hapla     ierr = DMLabelGetValue(label, p, &v);CHKERRQ(ierr);
3011d5c9e23SVaclav Hapla     if (v != LABEL_VALUE) {
3021d5c9e23SVaclav Hapla       ierr = PetscSynchronizedFPrintf(comm, PETSC_STDERR, "Point %D has bad value %D", p, v);CHKERRQ(ierr);
3031d5c9e23SVaclav Hapla       fail = PETSC_TRUE;
3041d5c9e23SVaclav Hapla       continue;
3051d5c9e23SVaclav Hapla     }
3061d5c9e23SVaclav Hapla     if (user->verbose) {ierr = PetscSynchronizedPrintf(comm, "[%d] OK point %D\n", rank, p);CHKERRQ(ierr);}
3071d5c9e23SVaclav Hapla   }
3081d5c9e23SVaclav Hapla   ierr = PetscSynchronizedFlush(comm, PETSC_STDOUT);CHKERRQ(ierr);
3091d5c9e23SVaclav Hapla   ierr = PetscSynchronizedFlush(comm, PETSC_STDERR);CHKERRQ(ierr);
3101d5c9e23SVaclav Hapla   ierr = ISRestoreIndices(pointsIS, &points);CHKERRQ(ierr);
3111d5c9e23SVaclav Hapla   ierr = ISDestroy(&pointsIS);CHKERRQ(ierr);
3121d5c9e23SVaclav Hapla   ierr = MPI_Allreduce(MPI_IN_PLACE, &fail, 1, MPIU_BOOL, MPI_LOR, comm);CHKERRMPI(ierr);
3132c71b3e2SJacob Faibussowitsch   PetscCheckFalse(fail,comm, PETSC_ERR_PLIB, "Label \"%s\" was not loaded correctly - see details above", LABEL_NAME);
3141d5c9e23SVaclav Hapla   PetscFunctionReturn(0);
3151d5c9e23SVaclav Hapla }
3161d5c9e23SVaclav Hapla 
3171d5c9e23SVaclav Hapla int main(int argc, char **argv)
3181d5c9e23SVaclav Hapla {
3191d5c9e23SVaclav Hapla   DM             dm, dmnew;
3201d5c9e23SVaclav Hapla   AppCtx         user;
3211d5c9e23SVaclav Hapla   Vec            allCoords = NULL;
3221d5c9e23SVaclav Hapla   PetscErrorCode ierr;
3231d5c9e23SVaclav Hapla 
3241d5c9e23SVaclav Hapla   ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return ierr;
3251d5c9e23SVaclav Hapla   ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr);
3261d5c9e23SVaclav Hapla   ierr = CreateMesh(&user, &dm);CHKERRQ(ierr);
3271d5c9e23SVaclav Hapla   if (user.compare_boundary) {
3281d5c9e23SVaclav Hapla     ierr = DMAddBoundaryLabel_GetCoordinateRepresentation(dm, &allCoords);CHKERRQ(ierr);
3291d5c9e23SVaclav Hapla   }
3301d5c9e23SVaclav Hapla   ierr = SaveMesh(&user, dm);CHKERRQ(ierr);
3311d5c9e23SVaclav Hapla   ierr = LoadMesh(&user, &dmnew);CHKERRQ(ierr);
3321d5c9e23SVaclav Hapla   ierr = CompareMeshes(&user, dm, dmnew);CHKERRQ(ierr);
3331d5c9e23SVaclav Hapla   if (user.compare_boundary) {
3341d5c9e23SVaclav Hapla     ierr = DMGetBoundaryLabel_CompareWithCoordinateRepresentation(&user, dmnew, allCoords);CHKERRQ(ierr);
3351d5c9e23SVaclav Hapla   }
3361d5c9e23SVaclav Hapla   ierr = DMDestroy(&dm);CHKERRQ(ierr);
3371d5c9e23SVaclav Hapla   ierr = DMDestroy(&dmnew);CHKERRQ(ierr);
3381d5c9e23SVaclav Hapla   ierr = VecDestroy(&allCoords);CHKERRQ(ierr);
3391d5c9e23SVaclav Hapla   ierr = PetscFinalize();
3401d5c9e23SVaclav Hapla   return ierr;
3411d5c9e23SVaclav Hapla }
3421d5c9e23SVaclav Hapla 
3431d5c9e23SVaclav Hapla //TODO we can -compare once the new parallel topology format is in place
3441d5c9e23SVaclav Hapla /*TEST
3451d5c9e23SVaclav Hapla   build:
3461d5c9e23SVaclav Hapla     requires: hdf5
3471d5c9e23SVaclav Hapla 
3481d5c9e23SVaclav Hapla   # load old format, save in new format, reload, distribute
3491d5c9e23SVaclav Hapla   testset:
3501d5c9e23SVaclav Hapla     suffix: 1
3511d5c9e23SVaclav Hapla     requires: !complex datafilespath
3521d5c9e23SVaclav Hapla     args: -dm_plex_name plex
3531d5c9e23SVaclav Hapla     args: -dm_plex_check_all -dm_plex_view_hdf5_storage_version 2.0.0
354*e600fa54SMatthew G. Knepley     args: -dm_plex_interpolate
3551d5c9e23SVaclav Hapla     args: -load_dm_plex_check_all
356*e600fa54SMatthew G. Knepley     args: -use_low_level_functions {{0 1}} -compare_boundary
3571d5c9e23SVaclav Hapla     args: -outfile ex56_1.h5
3581d5c9e23SVaclav Hapla     nsize: {{1 3}}
3591d5c9e23SVaclav Hapla     test:
3601d5c9e23SVaclav Hapla       suffix: a
3611d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/annulus-20.h5
3621d5c9e23SVaclav Hapla     test:
3631d5c9e23SVaclav Hapla       suffix: b
3641d5c9e23SVaclav Hapla       TODO: broken
3651d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/barycentricallyrefinedcube.h5
3661d5c9e23SVaclav Hapla     test:
3671d5c9e23SVaclav Hapla       suffix: c
3681d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/blockcylinder-50.h5
3691d5c9e23SVaclav Hapla     test:
3701d5c9e23SVaclav Hapla       suffix: d
3711d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/cube-hexahedra-refined.h5
3721d5c9e23SVaclav Hapla     test:
3731d5c9e23SVaclav Hapla       suffix: e
3741d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/hybrid_hexwedge.h5
3751d5c9e23SVaclav Hapla     test:
3761d5c9e23SVaclav Hapla       suffix: f
3771d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/square.h5
3781d5c9e23SVaclav Hapla 
3791d5c9e23SVaclav Hapla   # load old format, save in new format, reload topology, distribute, load geometry and labels
3801d5c9e23SVaclav Hapla   testset:
3811d5c9e23SVaclav Hapla     suffix: 2
3821d5c9e23SVaclav Hapla     requires: !complex datafilespath
3831d5c9e23SVaclav Hapla     args: -dm_plex_name plex
3841d5c9e23SVaclav Hapla     args: -dm_plex_check_all -dm_plex_view_hdf5_storage_version 2.0.0
385*e600fa54SMatthew G. Knepley     args: -dm_plex_interpolate
3861d5c9e23SVaclav Hapla     args: -load_dm_plex_check_all
387*e600fa54SMatthew G. Knepley     args: -use_low_level_functions -load_dm_distribute 0 -distribute_after_topo_load -compare_boundary
3881d5c9e23SVaclav Hapla     args: -outfile ex56_2.h5
3891d5c9e23SVaclav Hapla     nsize: 3
3901d5c9e23SVaclav Hapla     test:
3911d5c9e23SVaclav Hapla       suffix: a
3921d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/annulus-20.h5
3931d5c9e23SVaclav Hapla     test:
3941d5c9e23SVaclav Hapla       suffix: b
3951d5c9e23SVaclav Hapla       TODO: broken
3961d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/barycentricallyrefinedcube.h5
3971d5c9e23SVaclav Hapla     test:
3981d5c9e23SVaclav Hapla       suffix: c
3991d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/blockcylinder-50.h5
4001d5c9e23SVaclav Hapla     test:
4011d5c9e23SVaclav Hapla       suffix: d
4021d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/cube-hexahedra-refined.h5
4031d5c9e23SVaclav Hapla     test:
4041d5c9e23SVaclav Hapla       suffix: e
4051d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/hybrid_hexwedge.h5
4061d5c9e23SVaclav Hapla     test:
4071d5c9e23SVaclav Hapla       suffix: f
4081d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/square.h5
4091d5c9e23SVaclav Hapla 
4101d5c9e23SVaclav Hapla   # load old format, save in new format, reload topology, distribute, load geometry and labels
4111d5c9e23SVaclav Hapla   testset:
4121d5c9e23SVaclav Hapla     suffix: 3
4131d5c9e23SVaclav Hapla     requires: !complex datafilespath
4141d5c9e23SVaclav Hapla     args: -dm_plex_name plex
4151d5c9e23SVaclav Hapla     args: -dm_plex_view_hdf5_storage_version 2.0.0
416*e600fa54SMatthew G. Knepley     args: -dm_plex_interpolate -load_dm_distribute 0
4171d5c9e23SVaclav Hapla     args: -use_low_level_functions -compare_pre_post
4181d5c9e23SVaclav Hapla     args: -outfile ex56_3.h5
4191d5c9e23SVaclav Hapla     nsize: 3
4201d5c9e23SVaclav Hapla     test:
4211d5c9e23SVaclav Hapla       suffix: a
4221d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/annulus-20.h5
4231d5c9e23SVaclav Hapla     test:
4241d5c9e23SVaclav Hapla       suffix: b
4251d5c9e23SVaclav Hapla       TODO: broken
4261d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/barycentricallyrefinedcube.h5
4271d5c9e23SVaclav Hapla     test:
4281d5c9e23SVaclav Hapla       suffix: c
4291d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/blockcylinder-50.h5
4301d5c9e23SVaclav Hapla     test:
4311d5c9e23SVaclav Hapla       suffix: d
4321d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/cube-hexahedra-refined.h5
4331d5c9e23SVaclav Hapla     test:
4341d5c9e23SVaclav Hapla       suffix: e
4351d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/hybrid_hexwedge.h5
4361d5c9e23SVaclav Hapla     test:
4371d5c9e23SVaclav Hapla       suffix: f
4381d5c9e23SVaclav Hapla       args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/square.h5
4391d5c9e23SVaclav Hapla TEST*/
440