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