Actual source code: ex108.c
1: static char help[] = "Reload a DMPLEX converted from a DMFOREST (p8est) from HDF5 in parallel and check its point SF.\n\
2: A DMPLEX converted from a DMFOREST orders its strata cells, faces, edges, vertices instead of cells, vertices, faces, edges.\n\n";
4: #include <petscdmplex.h>
5: #include <petscdmforest.h>
6: #include <petscviewerhdf5.h>
7: #include <petscsf.h>
9: int main(int argc, char **argv)
10: {
11: DM base, forest, plex, dm;
12: PetscViewer viewer;
13: PetscSF sfXC;
14: PetscInt faces[3] = {4, 4, 4};
16: PetscFunctionBeginUser;
17: PetscCall(PetscInitialize(&argc, &argv, NULL, help));
19: // Unrefined p8est forest over a box, converted to DMPLEX (strata ordered cells, faces, edges, vertices)
20: PetscCall(DMPlexCreateBoxMesh(PETSC_COMM_WORLD, 3, PETSC_FALSE, faces, NULL, NULL, NULL, PETSC_TRUE, 0, PETSC_TRUE, &base));
21: PetscCall(DMCreate(PETSC_COMM_WORLD, &forest));
22: PetscCall(DMSetType(forest, DMP8EST));
23: PetscCall(DMForestSetBaseDM(forest, base));
24: PetscCall(DMSetUp(forest));
25: PetscCall(DMConvert(forest, DMPLEX, &plex));
26: PetscCall(PetscObjectSetName((PetscObject)plex, "plex"));
28: // Save the topology, with storage version 3.1.0 (the default 1.0.0 loader reorders the strata to cells, vertices, faces, edges)
29: PetscCall(PetscViewerHDF5Open(PETSC_COMM_WORLD, "forest_pointsf.h5", FILE_MODE_WRITE, &viewer));
30: {
31: struct _n_DMPlexStorageVersion version = {3, 1, 0};
33: PetscCall(PetscViewerHDF5SetDMPlexStorageVersionWriting(viewer, &version));
34: }
35: PetscCall(DMPlexTopologyView(plex, viewer));
36: PetscCall(PetscViewerDestroy(&viewer));
38: // Load it back; the loaded DM has no tree, so DMPlexCheckPointSF() performs its depth check
39: PetscCall(PetscViewerHDF5Open(PETSC_COMM_WORLD, "forest_pointsf.h5", FILE_MODE_READ, &viewer));
40: PetscCall(DMCreate(PETSC_COMM_WORLD, &dm));
41: PetscCall(DMSetType(dm, DMPLEX));
42: PetscCall(PetscObjectSetName((PetscObject)dm, "plex"));
43: PetscCall(DMPlexTopologyLoad(dm, viewer, &sfXC));
44: PetscCall(PetscViewerDestroy(&viewer));
46: // Without order-independent depth lookup this fails on 2+ ranks with "Leaf .. has depth 2 but remote (.., ..) depth is 3"
47: PetscCall(DMPlexCheckPointSF(dm, NULL, PETSC_FALSE));
48: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Point SF of the reloaded forest-ordered DMPLEX is consistent\n"));
50: PetscCall(PetscSFDestroy(&sfXC));
51: PetscCall(DMDestroy(&dm));
52: PetscCall(DMDestroy(&plex));
53: PetscCall(DMDestroy(&forest));
54: PetscCall(DMDestroy(&base));
55: PetscCall(PetscFinalize());
56: return 0;
57: }
59: /*TEST
61: build:
62: requires: p4est hdf5
64: test:
65: suffix: 0
66: nsize: 2
68: TEST*/