11d5c9e23SVaclav Hapla #include <petscdmplex.h> 21d5c9e23SVaclav Hapla #include <petscviewerhdf5.h> 31d5c9e23SVaclav Hapla #include <petscsf.h> 41d5c9e23SVaclav Hapla 5e22c0602SVaclav Hapla static const char help[] = "Test DMLabel I/O with PETSc native HDF5 mesh format\n\n"; 61d5c9e23SVaclav Hapla static const char EX[] = "ex56.c"; 71d5c9e23SVaclav Hapla typedef struct { 81d5c9e23SVaclav Hapla MPI_Comm comm; 91d5c9e23SVaclav Hapla const char *meshname; /* Mesh name */ 105c820da0SVaclav Hapla PetscInt num_labels; /* Asserted number of labels in loaded mesh */ 111d5c9e23SVaclav Hapla PetscBool compare; /* Compare the meshes using DMPlexEqual() and DMCompareLabels() */ 121d5c9e23SVaclav Hapla PetscBool compare_labels; /* Compare labels in the meshes using DMCompareLabels() */ 131d5c9e23SVaclav Hapla PetscBool compare_boundary; /* Check label I/O via boundary vertex coordinates */ 141d5c9e23SVaclav Hapla PetscBool compare_pre_post; /* Compare labels loaded before distribution with those loaded after distribution */ 151d5c9e23SVaclav Hapla char outfile[PETSC_MAX_PATH_LEN]; /* Output file */ 161d5c9e23SVaclav Hapla PetscBool use_low_level_functions; /* Use low level functions for viewing and loading */ 171d5c9e23SVaclav Hapla //TODO This is meant as temporary option; can be removed once we have full parallel loading in place 181d5c9e23SVaclav Hapla PetscBool distribute_after_topo_load; /* Distribute topology right after DMPlexTopologyLoad(), if use_low_level_functions=true */ 195c820da0SVaclav Hapla PetscInt verbose; 201d5c9e23SVaclav Hapla } AppCtx; 211d5c9e23SVaclav Hapla 22d71ae5a4SJacob Faibussowitsch static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 23d71ae5a4SJacob Faibussowitsch { 241d5c9e23SVaclav Hapla PetscFunctionBeginUser; 251d5c9e23SVaclav Hapla options->comm = comm; 265c820da0SVaclav Hapla options->num_labels = -1; 271d5c9e23SVaclav Hapla options->compare = PETSC_FALSE; 281d5c9e23SVaclav Hapla options->compare_labels = PETSC_FALSE; 291d5c9e23SVaclav Hapla options->compare_boundary = PETSC_FALSE; 301d5c9e23SVaclav Hapla options->compare_pre_post = PETSC_FALSE; 311d5c9e23SVaclav Hapla options->outfile[0] = '\0'; 321d5c9e23SVaclav Hapla options->use_low_level_functions = PETSC_FALSE; 331d5c9e23SVaclav Hapla options->distribute_after_topo_load = PETSC_FALSE; 345c820da0SVaclav Hapla options->verbose = 0; 351d5c9e23SVaclav Hapla 36d0609cedSBarry Smith PetscOptionsBegin(comm, "", "Meshing Problem Options", "DMPLEX"); 375c820da0SVaclav Hapla PetscCall(PetscOptionsInt("-num_labels", "Asserted number of labels in meshfile; don't count depth and celltype; -1 to deactivate", EX, options->num_labels, &options->num_labels, NULL)); 389566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-compare", "Compare the meshes using DMPlexEqual() and DMCompareLabels()", EX, options->compare, &options->compare, NULL)); 399566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-compare_labels", "Compare labels in the meshes using DMCompareLabels()", "ex55.c", options->compare_labels, &options->compare_labels, NULL)); 409566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-compare_boundary", "Check label I/O via boundary vertex coordinates", "ex55.c", options->compare_boundary, &options->compare_boundary, NULL)); 419566063dSJacob Faibussowitsch PetscCall(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)); 429566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-outfile", "Output mesh file", EX, options->outfile, options->outfile, sizeof(options->outfile), NULL)); 439566063dSJacob Faibussowitsch PetscCall(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)); 449566063dSJacob Faibussowitsch PetscCall(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)); 455c820da0SVaclav Hapla PetscCall(PetscOptionsInt("-verbose", "Verbosity level", EX, options->verbose, &options->verbose, NULL)); 46d0609cedSBarry Smith PetscOptionsEnd(); 473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48*f4f49eeaSPierre Jolivet } 491d5c9e23SVaclav Hapla 50d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateMesh(AppCtx *options, DM *newdm) 51d71ae5a4SJacob Faibussowitsch { 521d5c9e23SVaclav Hapla DM dm; 531d5c9e23SVaclav Hapla 541d5c9e23SVaclav Hapla PetscFunctionBeginUser; 559566063dSJacob Faibussowitsch PetscCall(DMCreate(options->comm, &dm)); 569566063dSJacob Faibussowitsch PetscCall(DMSetType(dm, DMPLEX)); 579566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(dm)); 589566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)dm, &options->meshname)); 599566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(dm, NULL, "-dm_view")); 601d5c9e23SVaclav Hapla *newdm = dm; 613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 621d5c9e23SVaclav Hapla } 631d5c9e23SVaclav Hapla 64d71ae5a4SJacob Faibussowitsch static PetscErrorCode SaveMesh(AppCtx *options, DM dm) 65d71ae5a4SJacob Faibussowitsch { 661d5c9e23SVaclav Hapla PetscViewer v; 671d5c9e23SVaclav Hapla 681d5c9e23SVaclav Hapla PetscFunctionBeginUser; 699566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5Open(PetscObjectComm((PetscObject)dm), options->outfile, FILE_MODE_WRITE, &v)); 701d5c9e23SVaclav Hapla if (options->use_low_level_functions) { 719566063dSJacob Faibussowitsch PetscCall(DMPlexTopologyView(dm, v)); 729566063dSJacob Faibussowitsch PetscCall(DMPlexCoordinatesView(dm, v)); 739566063dSJacob Faibussowitsch PetscCall(DMPlexLabelsView(dm, v)); 741d5c9e23SVaclav Hapla } else { 759566063dSJacob Faibussowitsch PetscCall(DMView(dm, v)); 761d5c9e23SVaclav Hapla } 779566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&v)); 783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 791d5c9e23SVaclav Hapla } 801d5c9e23SVaclav Hapla 819371c9d4SSatish Balay typedef enum { 829371c9d4SSatish Balay NONE = 0, 839371c9d4SSatish Balay PRE_DIST = 1, 849371c9d4SSatish Balay POST_DIST = 2 859371c9d4SSatish Balay } AuxObjLoadMode; 861d5c9e23SVaclav Hapla 87d71ae5a4SJacob Faibussowitsch static PetscErrorCode LoadMeshLowLevel(AppCtx *options, PetscViewer v, PetscBool explicitDistribute, AuxObjLoadMode mode, DM *newdm) 88d71ae5a4SJacob Faibussowitsch { 891d5c9e23SVaclav Hapla DM dm; 901d5c9e23SVaclav Hapla PetscSF sfXC; 911d5c9e23SVaclav Hapla 921d5c9e23SVaclav Hapla PetscFunctionBeginUser; 939566063dSJacob Faibussowitsch PetscCall(DMCreate(options->comm, &dm)); 949566063dSJacob Faibussowitsch PetscCall(DMSetType(dm, DMPLEX)); 959566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)dm, options->meshname)); 969566063dSJacob Faibussowitsch PetscCall(DMPlexTopologyLoad(dm, v, &sfXC)); 971d5c9e23SVaclav Hapla if (mode == PRE_DIST) { 989566063dSJacob Faibussowitsch PetscCall(DMPlexCoordinatesLoad(dm, v, sfXC)); 999566063dSJacob Faibussowitsch PetscCall(DMPlexLabelsLoad(dm, v, sfXC)); 1001d5c9e23SVaclav Hapla } 1011d5c9e23SVaclav Hapla if (explicitDistribute) { 1021d5c9e23SVaclav Hapla DM dmdist; 1031d5c9e23SVaclav Hapla PetscSF sfXB = sfXC, sfBC; 1041d5c9e23SVaclav Hapla 1059566063dSJacob Faibussowitsch PetscCall(DMPlexDistribute(dm, 0, &sfBC, &dmdist)); 1061d5c9e23SVaclav Hapla if (dmdist) { 1071d5c9e23SVaclav Hapla const char *name; 1081d5c9e23SVaclav Hapla 1099566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)dm, &name)); 1109566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)dmdist, name)); 1119566063dSJacob Faibussowitsch PetscCall(PetscSFCompose(sfXB, sfBC, &sfXC)); 1129566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfXB)); 1139566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfBC)); 1149566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 1151d5c9e23SVaclav Hapla dm = dmdist; 1161d5c9e23SVaclav Hapla } 1171d5c9e23SVaclav Hapla } 1181d5c9e23SVaclav Hapla if (mode == POST_DIST) { 1199566063dSJacob Faibussowitsch PetscCall(DMPlexLabelsLoad(dm, v, sfXC)); 12021027e53SStefano Zampini PetscCall(DMPlexCoordinatesLoad(dm, v, sfXC)); 1211d5c9e23SVaclav Hapla } 1229566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfXC)); 1231d5c9e23SVaclav Hapla *newdm = dm; 1243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1251d5c9e23SVaclav Hapla } 1261d5c9e23SVaclav Hapla 127d71ae5a4SJacob Faibussowitsch static PetscErrorCode LoadMesh(AppCtx *options, DM *dmnew) 128d71ae5a4SJacob Faibussowitsch { 1291d5c9e23SVaclav Hapla DM dm; 1301d5c9e23SVaclav Hapla PetscViewer v; 1311d5c9e23SVaclav Hapla 1321d5c9e23SVaclav Hapla PetscFunctionBeginUser; 1339566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5Open(options->comm, options->outfile, FILE_MODE_READ, &v)); 1341d5c9e23SVaclav Hapla if (options->use_low_level_functions) { 1351d5c9e23SVaclav Hapla if (options->compare_pre_post) { 1361d5c9e23SVaclav Hapla DM dm0; 1371d5c9e23SVaclav Hapla 1389566063dSJacob Faibussowitsch PetscCall(LoadMeshLowLevel(options, v, PETSC_TRUE, PRE_DIST, &dm0)); 1399566063dSJacob Faibussowitsch PetscCall(LoadMeshLowLevel(options, v, PETSC_TRUE, POST_DIST, &dm)); 1409566063dSJacob Faibussowitsch PetscCall(DMCompareLabels(dm0, dm, NULL, NULL)); 1419566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm0)); 1421d5c9e23SVaclav Hapla } else { 1439566063dSJacob Faibussowitsch PetscCall(LoadMeshLowLevel(options, v, options->distribute_after_topo_load, POST_DIST, &dm)); 1441d5c9e23SVaclav Hapla } 1451d5c9e23SVaclav Hapla } else { 1469566063dSJacob Faibussowitsch PetscCall(DMCreate(options->comm, &dm)); 1479566063dSJacob Faibussowitsch PetscCall(DMSetType(dm, DMPLEX)); 1489566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)dm, options->meshname)); 1499566063dSJacob Faibussowitsch PetscCall(DMLoad(dm, v)); 1501d5c9e23SVaclav Hapla } 1519566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&v)); 1521d5c9e23SVaclav Hapla 1539566063dSJacob Faibussowitsch PetscCall(DMSetOptionsPrefix(dm, "load_")); 1549566063dSJacob Faibussowitsch PetscCall(DMSetFromOptions(dm)); 1559566063dSJacob Faibussowitsch PetscCall(DMViewFromOptions(dm, NULL, "-dm_view")); 1561d5c9e23SVaclav Hapla *dmnew = dm; 1573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1581d5c9e23SVaclav Hapla } 1591d5c9e23SVaclav Hapla 160d71ae5a4SJacob Faibussowitsch static PetscErrorCode CompareMeshes(AppCtx *options, DM dm0, DM dm1) 161d71ae5a4SJacob Faibussowitsch { 1621d5c9e23SVaclav Hapla PetscBool flg; 1631d5c9e23SVaclav Hapla 1641d5c9e23SVaclav Hapla PetscFunctionBeginUser; 1651d5c9e23SVaclav Hapla if (options->compare) { 1669566063dSJacob Faibussowitsch PetscCall(DMPlexEqual(dm0, dm1, &flg)); 16728b400f6SJacob Faibussowitsch PetscCheck(flg, options->comm, PETSC_ERR_ARG_INCOMP, "DMs are not equal"); 1689566063dSJacob Faibussowitsch PetscCall(PetscPrintf(options->comm, "DMs equal\n")); 1691d5c9e23SVaclav Hapla } 1701d5c9e23SVaclav Hapla if (options->compare_labels) { 1719566063dSJacob Faibussowitsch PetscCall(DMCompareLabels(dm0, dm1, NULL, NULL)); 1729566063dSJacob Faibussowitsch PetscCall(PetscPrintf(options->comm, "DMLabels equal\n")); 1731d5c9e23SVaclav Hapla } 1743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1751d5c9e23SVaclav Hapla } 1761d5c9e23SVaclav Hapla 177d71ae5a4SJacob Faibussowitsch static PetscErrorCode MarkBoundary(DM dm, const char name[], PetscInt value, PetscBool verticesOnly, DMLabel *label) 178d71ae5a4SJacob Faibussowitsch { 1791d5c9e23SVaclav Hapla DMLabel l; 1805c820da0SVaclav Hapla 1815c820da0SVaclav Hapla PetscFunctionBeginUser; 1825c820da0SVaclav Hapla PetscCall(DMLabelCreate(PetscObjectComm((PetscObject)dm), name, &l)); 1835c820da0SVaclav Hapla PetscCall(DMAddLabel(dm, l)); 1845c820da0SVaclav Hapla PetscCall(DMPlexMarkBoundaryFaces(dm, value, l)); 1855c820da0SVaclav Hapla PetscCall(DMPlexLabelComplete(dm, l)); 1865c820da0SVaclav Hapla if (verticesOnly) { 1871d5c9e23SVaclav Hapla IS points; 1881d5c9e23SVaclav Hapla const PetscInt *idx; 189704d4d0eSMatthew G. Knepley PetscInt i, n = 0; 1901d5c9e23SVaclav Hapla 1919566063dSJacob Faibussowitsch PetscCall(DMLabelGetStratumIS(l, value, &points)); 192704d4d0eSMatthew G. Knepley if (points) { 1939566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(points, &n)); 1949566063dSJacob Faibussowitsch PetscCall(ISGetIndices(points, &idx)); 195704d4d0eSMatthew G. Knepley } 1961d5c9e23SVaclav Hapla for (i = 0; i < n; i++) { 1971d5c9e23SVaclav Hapla const PetscInt p = idx[i]; 1981d5c9e23SVaclav Hapla PetscInt d; 1991d5c9e23SVaclav Hapla 2009566063dSJacob Faibussowitsch PetscCall(DMPlexGetPointDepth(dm, p, &d)); 20148a46eb9SPierre Jolivet if (d != 0) PetscCall(DMLabelClearValue(l, p, value)); 2021d5c9e23SVaclav Hapla } 203704d4d0eSMatthew G. Knepley if (points) PetscCall(ISRestoreIndices(points, &idx)); 2049566063dSJacob Faibussowitsch PetscCall(ISDestroy(&points)); 2055c820da0SVaclav Hapla } 2065c820da0SVaclav Hapla if (label) *label = l; 2075c820da0SVaclav Hapla else PetscCall(DMLabelDestroy(&l)); 2083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2091d5c9e23SVaclav Hapla } 2101d5c9e23SVaclav Hapla 211d71ae5a4SJacob Faibussowitsch static PetscErrorCode VertexCoordinatesToAll(DM dm, IS vertices, Vec *allCoords) 212d71ae5a4SJacob Faibussowitsch { 2131d5c9e23SVaclav Hapla Vec coords, allCoords_; 2141d5c9e23SVaclav Hapla VecScatter sc; 2151d5c9e23SVaclav Hapla MPI_Comm comm; 2161d5c9e23SVaclav Hapla 2171d5c9e23SVaclav Hapla PetscFunctionBeginUser; 2189566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 2199566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocalSetUp(dm)); 2201d5c9e23SVaclav Hapla if (vertices) { 2219566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocalTuple(dm, vertices, NULL, &coords)); 2221d5c9e23SVaclav Hapla } else { 22377433607SBarry Smith PetscCall(VecCreateFromOptions(PETSC_COMM_SELF, NULL, 1, 0, 0, &coords)); 2241d5c9e23SVaclav Hapla } 2251d5c9e23SVaclav Hapla { 2261d5c9e23SVaclav Hapla PetscInt n; 2271d5c9e23SVaclav Hapla Vec mpivec; 2281d5c9e23SVaclav Hapla 2299566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(coords, &n)); 23077433607SBarry Smith PetscCall(VecCreateFromOptions(comm, NULL, 1, n, PETSC_DECIDE, &mpivec)); 2319566063dSJacob Faibussowitsch PetscCall(VecCopy(coords, mpivec)); 2329566063dSJacob Faibussowitsch PetscCall(VecDestroy(&coords)); 2331d5c9e23SVaclav Hapla coords = mpivec; 2341d5c9e23SVaclav Hapla } 2351d5c9e23SVaclav Hapla 2369566063dSJacob Faibussowitsch PetscCall(VecScatterCreateToAll(coords, &sc, &allCoords_)); 2379566063dSJacob Faibussowitsch PetscCall(VecScatterBegin(sc, coords, allCoords_, INSERT_VALUES, SCATTER_FORWARD)); 2389566063dSJacob Faibussowitsch PetscCall(VecScatterEnd(sc, coords, allCoords_, INSERT_VALUES, SCATTER_FORWARD)); 2399566063dSJacob Faibussowitsch PetscCall(VecScatterDestroy(&sc)); 2409566063dSJacob Faibussowitsch PetscCall(VecDestroy(&coords)); 2411d5c9e23SVaclav Hapla *allCoords = allCoords_; 2423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2431d5c9e23SVaclav Hapla } 2441d5c9e23SVaclav Hapla 245d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelGetCoordinateRepresentation(DM dm, DMLabel label, PetscInt value, Vec *allCoords) 246d71ae5a4SJacob Faibussowitsch { 2471d5c9e23SVaclav Hapla IS vertices; 2481d5c9e23SVaclav Hapla 2491d5c9e23SVaclav Hapla PetscFunctionBeginUser; 2505c820da0SVaclav Hapla PetscCall(DMLabelGetStratumIS(label, value, &vertices)); 2519566063dSJacob Faibussowitsch PetscCall(VertexCoordinatesToAll(dm, vertices, allCoords)); 2529566063dSJacob Faibussowitsch PetscCall(ISDestroy(&vertices)); 2533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2541d5c9e23SVaclav Hapla } 2551d5c9e23SVaclav Hapla 256d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMLabelCompareWithCoordinateRepresentation(DM dm, DMLabel label, PetscInt value, Vec allCoords, PetscInt verbose) 257d71ae5a4SJacob Faibussowitsch { 2585c820da0SVaclav Hapla const char *labelName; 2591d5c9e23SVaclav Hapla IS pointsIS; 2601d5c9e23SVaclav Hapla const PetscInt *points; 2611d5c9e23SVaclav Hapla PetscInt i, n; 2621d5c9e23SVaclav Hapla PetscBool fail = PETSC_FALSE; 2631d5c9e23SVaclav Hapla MPI_Comm comm; 2641d5c9e23SVaclav Hapla PetscMPIInt rank; 2651d5c9e23SVaclav Hapla 2661d5c9e23SVaclav Hapla PetscFunctionBeginUser; 2675c820da0SVaclav Hapla PetscCheck(label, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Label not loaded"); 2689566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 2695c820da0SVaclav Hapla PetscCall(PetscObjectGetName((PetscObject)label, &labelName)); 2709566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 2711d5c9e23SVaclav Hapla { 2721d5c9e23SVaclav Hapla PetscInt pStart, pEnd; 2731d5c9e23SVaclav Hapla 2749566063dSJacob Faibussowitsch PetscCall(DMPlexGetChart(dm, &pStart, &pEnd)); 2759566063dSJacob Faibussowitsch PetscCall(DMLabelCreateIndex(label, pStart, pEnd)); 2761d5c9e23SVaclav Hapla } 2779566063dSJacob Faibussowitsch PetscCall(DMPlexFindVertices(dm, allCoords, 0.0, &pointsIS)); 2789566063dSJacob Faibussowitsch PetscCall(ISGetIndices(pointsIS, &points)); 2799566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(pointsIS, &n)); 2805c820da0SVaclav Hapla if (verbose > 1) PetscCall(DMLabelView(label, PETSC_VIEWER_STDOUT_(comm))); 2811d5c9e23SVaclav Hapla for (i = 0; i < n; i++) { 2821d5c9e23SVaclav Hapla const PetscInt p = points[i]; 2831d5c9e23SVaclav Hapla PetscBool has; 2841d5c9e23SVaclav Hapla PetscInt v; 2851d5c9e23SVaclav Hapla 2861d5c9e23SVaclav Hapla if (p < 0) continue; 2879566063dSJacob Faibussowitsch PetscCall(DMLabelHasPoint(label, p, &has)); 2881d5c9e23SVaclav Hapla if (!has) { 28963a3b9bcSJacob Faibussowitsch if (verbose) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] Label \"%s\" does not have point %" PetscInt_FMT "\n", rank, labelName, p)); 2901d5c9e23SVaclav Hapla fail = PETSC_TRUE; 2911d5c9e23SVaclav Hapla continue; 2921d5c9e23SVaclav Hapla } 2939566063dSJacob Faibussowitsch PetscCall(DMLabelGetValue(label, p, &v)); 2945c820da0SVaclav Hapla if (v != value) { 29563a3b9bcSJacob Faibussowitsch if (verbose) PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "Point %" PetscInt_FMT " has bad value %" PetscInt_FMT " in label \"%s\"", p, v, labelName)); 2961d5c9e23SVaclav Hapla fail = PETSC_TRUE; 2971d5c9e23SVaclav Hapla continue; 2981d5c9e23SVaclav Hapla } 29963a3b9bcSJacob Faibussowitsch if (verbose > 1) PetscCall(PetscSynchronizedPrintf(comm, "[%d] OK point %" PetscInt_FMT "\n", rank, p)); 3001d5c9e23SVaclav Hapla } 3019566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDOUT)); 3029566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 3039566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(pointsIS, &points)); 3049566063dSJacob Faibussowitsch PetscCall(ISDestroy(&pointsIS)); 305712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &fail, 1, MPIU_BOOL, MPI_LOR, comm)); 3065c820da0SVaclav Hapla PetscCheck(!fail, comm, PETSC_ERR_PLIB, "Label \"%s\" was not loaded correctly%s", labelName, verbose ? " - see details above" : ""); 3073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3085c820da0SVaclav Hapla } 3095c820da0SVaclav Hapla 310d71ae5a4SJacob Faibussowitsch static PetscErrorCode CheckNumLabels(DM dm, AppCtx *ctx) 311d71ae5a4SJacob Faibussowitsch { 3125c820da0SVaclav Hapla PetscInt actualNum; 3135c820da0SVaclav Hapla PetscBool fail = PETSC_FALSE; 3145c820da0SVaclav Hapla MPI_Comm comm; 3155c820da0SVaclav Hapla PetscMPIInt rank; 3165c820da0SVaclav Hapla 3175c820da0SVaclav Hapla PetscFunctionBeginUser; 3183ba16761SJacob Faibussowitsch if (ctx->num_labels < 0) PetscFunctionReturn(PETSC_SUCCESS); 3195c820da0SVaclav Hapla PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 3205c820da0SVaclav Hapla PetscCallMPI(MPI_Comm_rank(comm, &rank)); 3215c820da0SVaclav Hapla PetscCall(DMGetNumLabels(dm, &actualNum)); 3225c820da0SVaclav Hapla if (ctx->num_labels != actualNum) { 3235c820da0SVaclav Hapla fail = PETSC_TRUE; 3245c820da0SVaclav Hapla if (ctx->verbose) { 3255c820da0SVaclav Hapla PetscInt i; 3265c820da0SVaclav Hapla 32763a3b9bcSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] Asserted number of labels: %" PetscInt_FMT ", actual: %" PetscInt_FMT "\n", rank, ctx->num_labels, actualNum)); 3285c820da0SVaclav Hapla for (i = 0; i < actualNum; i++) { 3295c820da0SVaclav Hapla DMLabel label; 3305c820da0SVaclav Hapla const char *name; 3315c820da0SVaclav Hapla 3325c820da0SVaclav Hapla PetscCall(DMGetLabelByNum(dm, i, &label)); 3335c820da0SVaclav Hapla PetscCall(PetscObjectGetName((PetscObject)label, &name)); 33463a3b9bcSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf(comm, PETSC_STDERR, "[%d] Label %" PetscInt_FMT " \"%s\"\n", rank, i, name)); 3355c820da0SVaclav Hapla } 3365c820da0SVaclav Hapla PetscCall(PetscSynchronizedFlush(comm, PETSC_STDERR)); 3375c820da0SVaclav Hapla } 3385c820da0SVaclav Hapla } 339712fec58SPierre Jolivet PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &fail, 1, MPIU_BOOL, MPI_LOR, comm)); 3405c820da0SVaclav Hapla PetscCheck(!fail, comm, PETSC_ERR_PLIB, "Wrong number of labels%s", ctx->verbose ? " - see details above" : ""); 3413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3425c820da0SVaclav Hapla } 3435c820da0SVaclav Hapla 344d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode IncrementNumLabels(AppCtx *ctx) 345d71ae5a4SJacob Faibussowitsch { 3465c820da0SVaclav Hapla PetscFunctionBeginUser; 3475c820da0SVaclav Hapla if (ctx->num_labels >= 0) ctx->num_labels++; 3483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3491d5c9e23SVaclav Hapla } 3501d5c9e23SVaclav Hapla 351d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 352d71ae5a4SJacob Faibussowitsch { 3535c820da0SVaclav Hapla const char BOUNDARY_NAME[] = "Boundary"; 3545c820da0SVaclav Hapla const char BOUNDARY_VERTICES_NAME[] = "BoundaryVertices"; 3555c820da0SVaclav Hapla const PetscInt BOUNDARY_VALUE = 12345; 3565c820da0SVaclav Hapla const PetscInt BOUNDARY_VERTICES_VALUE = 6789; 3571d5c9e23SVaclav Hapla DM dm, dmnew; 3581d5c9e23SVaclav Hapla AppCtx user; 3591d5c9e23SVaclav Hapla Vec allCoords = NULL; 3601d5c9e23SVaclav Hapla 361327415f7SBarry Smith PetscFunctionBeginUser; 3629566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 3639566063dSJacob Faibussowitsch PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user)); 3649566063dSJacob Faibussowitsch PetscCall(CreateMesh(&user, &dm)); 3655c820da0SVaclav Hapla PetscCall(MarkBoundary(dm, BOUNDARY_NAME, BOUNDARY_VALUE, PETSC_FALSE, NULL)); 3665c820da0SVaclav Hapla PetscCall(IncrementNumLabels(&user)); 3671d5c9e23SVaclav Hapla if (user.compare_boundary) { 3685c820da0SVaclav Hapla DMLabel label; 3695c820da0SVaclav Hapla 3705c820da0SVaclav Hapla PetscCall(MarkBoundary(dm, BOUNDARY_VERTICES_NAME, BOUNDARY_VERTICES_VALUE, PETSC_TRUE, &label)); 3715c820da0SVaclav Hapla PetscCall(IncrementNumLabels(&user)); 3725c820da0SVaclav Hapla PetscCall(DMLabelGetCoordinateRepresentation(dm, label, BOUNDARY_VERTICES_VALUE, &allCoords)); 3735c820da0SVaclav Hapla PetscCall(DMLabelDestroy(&label)); 3741d5c9e23SVaclav Hapla } 3759566063dSJacob Faibussowitsch PetscCall(SaveMesh(&user, dm)); 3765c820da0SVaclav Hapla 3779566063dSJacob Faibussowitsch PetscCall(LoadMesh(&user, &dmnew)); 3785c820da0SVaclav Hapla PetscCall(IncrementNumLabels(&user)); /* account for depth label */ 3795c820da0SVaclav Hapla PetscCall(IncrementNumLabels(&user)); /* account for celltype label */ 3805c820da0SVaclav Hapla PetscCall(CheckNumLabels(dm, &user)); 3819566063dSJacob Faibussowitsch PetscCall(CompareMeshes(&user, dm, dmnew)); 3821d5c9e23SVaclav Hapla if (user.compare_boundary) { 3835c820da0SVaclav Hapla DMLabel label; 3845c820da0SVaclav Hapla 3855c820da0SVaclav Hapla PetscCall(DMGetLabel(dmnew, BOUNDARY_VERTICES_NAME, &label)); 3865c820da0SVaclav Hapla PetscCall(DMLabelCompareWithCoordinateRepresentation(dmnew, label, BOUNDARY_VERTICES_VALUE, allCoords, user.verbose)); 3871d5c9e23SVaclav Hapla } 3889566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dm)); 3899566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dmnew)); 3909566063dSJacob Faibussowitsch PetscCall(VecDestroy(&allCoords)); 3919566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 392b122ec5aSJacob Faibussowitsch return 0; 3931d5c9e23SVaclav Hapla } 3941d5c9e23SVaclav Hapla 3951d5c9e23SVaclav Hapla //TODO we can -compare once the new parallel topology format is in place 3961d5c9e23SVaclav Hapla /*TEST 3971d5c9e23SVaclav Hapla build: 3981d5c9e23SVaclav Hapla requires: hdf5 3991d5c9e23SVaclav Hapla 4001d5c9e23SVaclav Hapla # load old format, save in new format, reload, distribute 4011d5c9e23SVaclav Hapla testset: 4021d5c9e23SVaclav Hapla suffix: 1 4031d5c9e23SVaclav Hapla requires: !complex datafilespath 4041d5c9e23SVaclav Hapla args: -dm_plex_name plex 4051d5c9e23SVaclav Hapla args: -dm_plex_check_all -dm_plex_view_hdf5_storage_version 2.0.0 406704d4d0eSMatthew G. Knepley args: -dm_plex_interpolate -petscpartitioner_type simple 4071d5c9e23SVaclav Hapla args: -load_dm_plex_check_all 408e600fa54SMatthew G. Knepley args: -use_low_level_functions {{0 1}} -compare_boundary 4095c820da0SVaclav Hapla args: -num_labels 1 4101d5c9e23SVaclav Hapla args: -outfile ex56_1.h5 4111d5c9e23SVaclav Hapla nsize: {{1 3}} 4121d5c9e23SVaclav Hapla test: 4131d5c9e23SVaclav Hapla suffix: a 4141d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/annulus-20.h5 4151d5c9e23SVaclav Hapla test: 4161d5c9e23SVaclav Hapla suffix: b 4171d5c9e23SVaclav Hapla TODO: broken 4181d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/barycentricallyrefinedcube.h5 4191d5c9e23SVaclav Hapla test: 4201d5c9e23SVaclav Hapla suffix: c 4211d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/blockcylinder-50.h5 4221d5c9e23SVaclav Hapla test: 4231d5c9e23SVaclav Hapla suffix: d 4245c820da0SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/cube-hexahedra-refined.h5 -num_labels 0 4251d5c9e23SVaclav Hapla test: 4261d5c9e23SVaclav Hapla suffix: e 4271d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/hybrid_hexwedge.h5 4281d5c9e23SVaclav Hapla test: 4291d5c9e23SVaclav Hapla suffix: f 4301d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/square.h5 4311d5c9e23SVaclav Hapla 4321d5c9e23SVaclav Hapla # load old format, save in new format, reload topology, distribute, load geometry and labels 4331d5c9e23SVaclav Hapla testset: 4341d5c9e23SVaclav Hapla suffix: 2 4351d5c9e23SVaclav Hapla requires: !complex datafilespath 4361d5c9e23SVaclav Hapla args: -dm_plex_name plex 4371d5c9e23SVaclav Hapla args: -dm_plex_check_all -dm_plex_view_hdf5_storage_version 2.0.0 438704d4d0eSMatthew G. Knepley args: -dm_plex_interpolate -petscpartitioner_type simple 4391d5c9e23SVaclav Hapla args: -load_dm_plex_check_all 440e600fa54SMatthew G. Knepley args: -use_low_level_functions -load_dm_distribute 0 -distribute_after_topo_load -compare_boundary 4415c820da0SVaclav Hapla args: -num_labels 1 4421d5c9e23SVaclav Hapla args: -outfile ex56_2.h5 4431d5c9e23SVaclav Hapla nsize: 3 4441d5c9e23SVaclav Hapla test: 4451d5c9e23SVaclav Hapla suffix: a 4461d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/annulus-20.h5 4471d5c9e23SVaclav Hapla test: 4481d5c9e23SVaclav Hapla suffix: b 4491d5c9e23SVaclav Hapla TODO: broken 4501d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/barycentricallyrefinedcube.h5 4511d5c9e23SVaclav Hapla test: 4521d5c9e23SVaclav Hapla suffix: c 4531d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/blockcylinder-50.h5 4541d5c9e23SVaclav Hapla test: 4551d5c9e23SVaclav Hapla suffix: d 4565c820da0SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/cube-hexahedra-refined.h5 -num_labels 0 4571d5c9e23SVaclav Hapla test: 4581d5c9e23SVaclav Hapla suffix: e 4591d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/hybrid_hexwedge.h5 4601d5c9e23SVaclav Hapla test: 4611d5c9e23SVaclav Hapla suffix: f 4621d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/square.h5 4631d5c9e23SVaclav Hapla 4641d5c9e23SVaclav Hapla # load old format, save in new format, reload topology, distribute, load geometry and labels 4651d5c9e23SVaclav Hapla testset: 4661d5c9e23SVaclav Hapla suffix: 3 4671d5c9e23SVaclav Hapla requires: !complex datafilespath 4681d5c9e23SVaclav Hapla args: -dm_plex_name plex 4691d5c9e23SVaclav Hapla args: -dm_plex_view_hdf5_storage_version 2.0.0 470704d4d0eSMatthew G. Knepley args: -dm_plex_interpolate -load_dm_distribute 0 -petscpartitioner_type simple 4711d5c9e23SVaclav Hapla args: -use_low_level_functions -compare_pre_post 4725c820da0SVaclav Hapla args: -num_labels 1 4731d5c9e23SVaclav Hapla args: -outfile ex56_3.h5 4741d5c9e23SVaclav Hapla nsize: 3 4751d5c9e23SVaclav Hapla test: 4761d5c9e23SVaclav Hapla suffix: a 4771d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/annulus-20.h5 4781d5c9e23SVaclav Hapla test: 4791d5c9e23SVaclav Hapla suffix: b 4801d5c9e23SVaclav Hapla TODO: broken 4811d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/barycentricallyrefinedcube.h5 4821d5c9e23SVaclav Hapla test: 4831d5c9e23SVaclav Hapla suffix: c 4841d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/blockcylinder-50.h5 4851d5c9e23SVaclav Hapla test: 4861d5c9e23SVaclav Hapla suffix: d 4875c820da0SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/cube-hexahedra-refined.h5 -num_labels 0 4881d5c9e23SVaclav Hapla test: 4891d5c9e23SVaclav Hapla suffix: e 4901d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/hybrid_hexwedge.h5 4911d5c9e23SVaclav Hapla test: 4921d5c9e23SVaclav Hapla suffix: f 4931d5c9e23SVaclav Hapla args: -dm_plex_filename ${DATAFILESPATH}/meshes/hdf5-petsc/petsc-v3.16.0/v1.0.0/square.h5 4941d5c9e23SVaclav Hapla TEST*/ 495