190d1c1a4SMatthew G. Knepley static char help[] = "Tests dof numberings for external integrators such as LibCEED.\n\n"; 290d1c1a4SMatthew G. Knepley 390d1c1a4SMatthew G. Knepley #include <petscdmplex.h> 490d1c1a4SMatthew G. Knepley #include <petscds.h> 590d1c1a4SMatthew G. Knepley 690d1c1a4SMatthew G. Knepley typedef struct { 75f06a3ddSJed Brown PetscInt check_face; 85f06a3ddSJed Brown PetscBool closure_tensor; 990d1c1a4SMatthew G. Knepley } AppCtx; 1090d1c1a4SMatthew G. Knepley 11d71ae5a4SJacob Faibussowitsch static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 12d71ae5a4SJacob Faibussowitsch { 1390d1c1a4SMatthew G. Knepley PetscFunctionBeginUser; 145f06a3ddSJed Brown options->check_face = 1; 155f06a3ddSJed Brown options->closure_tensor = PETSC_FALSE; 1690d1c1a4SMatthew G. Knepley PetscOptionsBegin(comm, "", "Dof Ordering Options", "DMPLEX"); 175f06a3ddSJed Brown PetscCall(PetscOptionsInt("-check_face", "Face set to report on", "ex49.c", options->check_face, &options->check_face, NULL)); 185f06a3ddSJed Brown PetscCall(PetscOptionsBool("-closure_tensor", "Use DMPlexSetClosurePermutationTensor()", "ex49.c", options->closure_tensor, &options->closure_tensor, NULL)); 1990d1c1a4SMatthew G. Knepley PetscOptionsEnd(); 2090d1c1a4SMatthew G. Knepley PetscFunctionReturn(0); 2190d1c1a4SMatthew G. Knepley } 2290d1c1a4SMatthew G. Knepley 23d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) 24d71ae5a4SJacob Faibussowitsch { 2590d1c1a4SMatthew G. Knepley PetscFunctionBeginUser; 2690d1c1a4SMatthew G. Knepley PetscCall(DMCreate(comm, dm)); 2790d1c1a4SMatthew G. Knepley PetscCall(DMSetType(*dm, DMPLEX)); 2890d1c1a4SMatthew G. Knepley PetscCall(DMSetFromOptions(*dm)); 2990d1c1a4SMatthew G. Knepley PetscCall(DMSetApplicationContext(*dm, user)); 3090d1c1a4SMatthew G. Knepley PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view")); 3190d1c1a4SMatthew G. Knepley PetscFunctionReturn(0); 3290d1c1a4SMatthew G. Knepley } 3390d1c1a4SMatthew G. Knepley 34d71ae5a4SJacob Faibussowitsch static PetscErrorCode SetupDiscretization(DM dm, AppCtx *user) 35d71ae5a4SJacob Faibussowitsch { 3690d1c1a4SMatthew G. Knepley DM cdm = dm; 3790d1c1a4SMatthew G. Knepley PetscFE fe; 3890d1c1a4SMatthew G. Knepley PetscInt dim; 3990d1c1a4SMatthew G. Knepley 4090d1c1a4SMatthew G. Knepley PetscFunctionBeginUser; 4190d1c1a4SMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 4290d1c1a4SMatthew G. Knepley PetscCall(PetscFECreateDefault(PETSC_COMM_SELF, dim, 1, PETSC_FALSE, NULL, -1, &fe)); 4390d1c1a4SMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)fe, "scalar")); 4490d1c1a4SMatthew G. Knepley PetscCall(DMSetField(dm, 0, NULL, (PetscObject)fe)); 4590d1c1a4SMatthew G. Knepley PetscCall(DMSetField(dm, 1, NULL, (PetscObject)fe)); 4690d1c1a4SMatthew G. Knepley PetscCall(PetscFEDestroy(&fe)); 4790d1c1a4SMatthew G. Knepley PetscCall(DMCreateDS(dm)); 4890d1c1a4SMatthew G. Knepley while (cdm) { 4990d1c1a4SMatthew G. Knepley PetscCall(DMCopyDisc(dm, cdm)); 5090d1c1a4SMatthew G. Knepley PetscCall(DMGetCoarseDM(cdm, &cdm)); 5190d1c1a4SMatthew G. Knepley } 5290d1c1a4SMatthew G. Knepley PetscFunctionReturn(0); 5390d1c1a4SMatthew G. Knepley } 5490d1c1a4SMatthew G. Knepley 555f06a3ddSJed Brown static PetscErrorCode CheckOffsets(DM dm, AppCtx *user, const char *domain_name, PetscInt label_value, PetscInt height) 56d71ae5a4SJacob Faibussowitsch { 5790d1c1a4SMatthew G. Knepley const char *height_name[] = {"cells", "faces"}; 5890d1c1a4SMatthew G. Knepley DMLabel domain_label = NULL; 5990d1c1a4SMatthew G. Knepley DM cdm; 6090d1c1a4SMatthew G. Knepley IS offIS; 6190d1c1a4SMatthew G. Knepley PetscInt *offsets, Ncell, Ncl, Nc, n; 6290d1c1a4SMatthew G. Knepley PetscInt Nf, f; 63f2c6b1a2SJed Brown ISLocalToGlobalMapping ltog; 6490d1c1a4SMatthew G. Knepley 6590d1c1a4SMatthew G. Knepley PetscFunctionBeginUser; 6690d1c1a4SMatthew G. Knepley if (domain_name) PetscCall(DMGetLabel(dm, domain_name, &domain_label)); 673e72e933SJed Brown PetscCall(PetscPrintf(PETSC_COMM_WORLD, "## %s: '%s' {%" PetscInt_FMT "}%s\n", height_name[height], domain_name ? domain_name : "default", label_value, domain_name && !domain_label ? " (null label)" : "")); 683e72e933SJed Brown if (domain_name && !domain_label) PetscFunctionReturn(0); 695f06a3ddSJed Brown if (user->closure_tensor) PetscCall(DMPlexSetClosurePermutationTensor(dm, PETSC_DETERMINE, NULL)); 7090d1c1a4SMatthew G. Knepley // Offsets for cell closures 7190d1c1a4SMatthew G. Knepley PetscCall(DMGetNumFields(dm, &Nf)); 7290d1c1a4SMatthew G. Knepley for (f = 0; f < Nf; ++f) { 7390d1c1a4SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 7490d1c1a4SMatthew G. Knepley 7590d1c1a4SMatthew G. Knepley PetscCall(DMPlexGetLocalOffsets(dm, domain_label, label_value, height, f, &Ncell, &Ncl, &Nc, &n, &offsets)); 7690d1c1a4SMatthew G. Knepley PetscCall(ISCreateGeneral(PETSC_COMM_SELF, Ncell * Ncl, offsets, PETSC_OWN_POINTER, &offIS)); 7790d1c1a4SMatthew G. Knepley PetscCall(PetscSNPrintf(name, PETSC_MAX_PATH_LEN, "Field %" PetscInt_FMT " Offsets", f)); 7890d1c1a4SMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)offIS, name)); 7990d1c1a4SMatthew G. Knepley PetscCall(ISViewFromOptions(offIS, NULL, "-offsets_view")); 8090d1c1a4SMatthew G. Knepley PetscCall(ISDestroy(&offIS)); 8190d1c1a4SMatthew G. Knepley } 82f2c6b1a2SJed Brown PetscCall(DMGetLocalToGlobalMapping(dm, <og)); 83f2c6b1a2SJed Brown PetscCall(ISLocalToGlobalMappingViewFromOptions(ltog, NULL, "-ltog_view")); 84f2c6b1a2SJed Brown 8590d1c1a4SMatthew G. Knepley // Offsets for coordinates 8690d1c1a4SMatthew G. Knepley { 8790d1c1a4SMatthew G. Knepley Vec X; 8890d1c1a4SMatthew G. Knepley PetscSection s; 8990d1c1a4SMatthew G. Knepley const PetscScalar *x; 9090d1c1a4SMatthew G. Knepley const char *cname; 9190d1c1a4SMatthew G. Knepley PetscInt cdim; 9290d1c1a4SMatthew G. Knepley PetscBool isDG = PETSC_FALSE; 9390d1c1a4SMatthew G. Knepley 9490d1c1a4SMatthew G. Knepley PetscCall(DMGetCellCoordinateDM(dm, &cdm)); 9590d1c1a4SMatthew G. Knepley if (!cdm) { 969371c9d4SSatish Balay PetscCall(DMGetCoordinateDM(dm, &cdm)); 979371c9d4SSatish Balay cname = "Coordinates"; 9890d1c1a4SMatthew G. Knepley PetscCall(DMGetCoordinatesLocal(dm, &X)); 9990d1c1a4SMatthew G. Knepley } else { 10090d1c1a4SMatthew G. Knepley isDG = PETSC_TRUE; 10190d1c1a4SMatthew G. Knepley cname = "DG Coordinates"; 10290d1c1a4SMatthew G. Knepley PetscCall(DMGetCellCoordinatesLocal(dm, &X)); 10390d1c1a4SMatthew G. Knepley } 10490d1c1a4SMatthew G. Knepley if (isDG && height) PetscFunctionReturn(0); 10590d1c1a4SMatthew G. Knepley if (domain_name) PetscCall(DMGetLabel(cdm, domain_name, &domain_label)); 1065f06a3ddSJed Brown if (user->closure_tensor) PetscCall(DMPlexSetClosurePermutationTensor(cdm, PETSC_DETERMINE, NULL)); 10790d1c1a4SMatthew G. Knepley PetscCall(DMPlexGetLocalOffsets(cdm, domain_label, label_value, height, 0, &Ncell, &Ncl, &Nc, &n, &offsets)); 10890d1c1a4SMatthew G. Knepley PetscCall(DMGetCoordinateDim(dm, &cdim)); 10990d1c1a4SMatthew G. Knepley PetscCheck(Nc == cdim, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Geometric dimension %" PetscInt_FMT " should be %" PetscInt_FMT, Nc, cdim); 11090d1c1a4SMatthew G. Knepley PetscCall(DMGetLocalSection(cdm, &s)); 11190d1c1a4SMatthew G. Knepley PetscCall(VecGetArrayRead(X, &x)); 1125f06a3ddSJed Brown PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%s by element in %s order\n", cname, user->closure_tensor ? "tensor" : "bfs")); 11390d1c1a4SMatthew G. Knepley for (PetscInt c = 0; c < Ncell; ++c) { 11490d1c1a4SMatthew G. Knepley for (PetscInt v = 0; v < Ncl; ++v) { 11590d1c1a4SMatthew G. Knepley PetscInt off = offsets[c * Ncl + v], dgdof; 11690d1c1a4SMatthew G. Knepley const PetscScalar *vx = &x[off]; 11790d1c1a4SMatthew G. Knepley 11890d1c1a4SMatthew G. Knepley if (isDG) { 11990d1c1a4SMatthew G. Knepley PetscCall(PetscSectionGetDof(s, c, &dgdof)); 12090d1c1a4SMatthew G. Knepley PetscCheck(Ncl * Nc == dgdof, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Offset size %" PetscInt_FMT " should be %" PetscInt_FMT, Ncl * Nc, dgdof); 12190d1c1a4SMatthew G. Knepley } 122eefd97a2SJed Brown switch (cdim) { 1233e72e933SJed Brown case 1: 1243e72e933SJed Brown PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%" PetscInt_FMT "] %" PetscInt_FMT " <-- %2" PetscInt_FMT " (% 4.2f)\n", c, v, off, (double)PetscRealPart(vx[0]))); 1253e72e933SJed Brown break; 126d71ae5a4SJacob Faibussowitsch case 2: 1273e72e933SJed Brown PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%" PetscInt_FMT "] %" PetscInt_FMT " <-- %2" PetscInt_FMT " (% 4.2f, % 4.2f)\n", c, v, off, (double)PetscRealPart(vx[0]), (double)PetscRealPart(vx[1]))); 128d71ae5a4SJacob Faibussowitsch break; 129eefd97a2SJed Brown case 3: 1303e72e933SJed Brown PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[%" PetscInt_FMT "] %" PetscInt_FMT " <-- %2" PetscInt_FMT " (% 4.2f, % 4.2f, % 4.2f)\n", c, v, off, (double)PetscRealPart(vx[0]), (double)PetscRealPart(vx[1]), (double)PetscRealPart(vx[2]))); 131eefd97a2SJed Brown } 13290d1c1a4SMatthew G. Knepley } 13390d1c1a4SMatthew G. Knepley } 1343e72e933SJed Brown PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, stdout)); 13590d1c1a4SMatthew G. Knepley PetscCall(VecRestoreArrayRead(X, &x)); 13690d1c1a4SMatthew G. Knepley PetscCall(PetscFree(offsets)); 137f2c6b1a2SJed Brown PetscCall(DMGetLocalToGlobalMapping(cdm, <og)); 138f2c6b1a2SJed Brown PetscCall(ISLocalToGlobalMappingViewFromOptions(ltog, NULL, "-coord_ltog_view")); 13990d1c1a4SMatthew G. Knepley } 14090d1c1a4SMatthew G. Knepley PetscFunctionReturn(0); 14190d1c1a4SMatthew G. Knepley } 14290d1c1a4SMatthew G. Knepley 143d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv) 144d71ae5a4SJacob Faibussowitsch { 14590d1c1a4SMatthew G. Knepley DM dm; 14690d1c1a4SMatthew G. Knepley AppCtx user; 1473e72e933SJed Brown PetscInt depth; 14890d1c1a4SMatthew G. Knepley 149327415f7SBarry Smith PetscFunctionBeginUser; 15090d1c1a4SMatthew G. Knepley PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 15190d1c1a4SMatthew G. Knepley PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user)); 15290d1c1a4SMatthew G. Knepley PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &dm)); 15390d1c1a4SMatthew G. Knepley PetscCall(SetupDiscretization(dm, &user)); 1545f06a3ddSJed Brown PetscCall(CheckOffsets(dm, &user, NULL, 0, 0)); 1553e72e933SJed Brown PetscCall(DMPlexGetDepth(dm, &depth)); 1565f06a3ddSJed Brown if (depth > 1) PetscCall(CheckOffsets(dm, &user, "Face Sets", user.check_face, 1)); 15790d1c1a4SMatthew G. Knepley PetscCall(DMDestroy(&dm)); 15890d1c1a4SMatthew G. Knepley PetscCall(PetscFinalize()); 15990d1c1a4SMatthew G. Knepley return 0; 16090d1c1a4SMatthew G. Knepley } 16190d1c1a4SMatthew G. Knepley 16290d1c1a4SMatthew G. Knepley /*TEST 16390d1c1a4SMatthew G. Knepley 16490d1c1a4SMatthew G. Knepley test: 16590d1c1a4SMatthew G. Knepley suffix: 0 16690d1c1a4SMatthew G. Knepley requires: triangle 16790d1c1a4SMatthew G. Knepley args: -dm_refine 1 -petscspace_degree 1 -dm_view -offsets_view 16890d1c1a4SMatthew G. Knepley 16990d1c1a4SMatthew G. Knepley test: 17090d1c1a4SMatthew G. Knepley suffix: 1 17190d1c1a4SMatthew G. Knepley args: -dm_plex_simplex 0 -dm_plex_box_bd periodic,none -dm_plex_box_faces 3,3 -dm_sparse_localize 0 -petscspace_degree 1 \ 17290d1c1a4SMatthew G. Knepley -dm_view -offsets_view 17390d1c1a4SMatthew G. Knepley 17490d1c1a4SMatthew G. Knepley test: 17590d1c1a4SMatthew G. Knepley suffix: cg_2d 17690d1c1a4SMatthew G. Knepley args: -dm_plex_simplex 0 -dm_plex_box_bd none,none -dm_plex_box_faces 3,3 -petscspace_degree 1 \ 17790d1c1a4SMatthew G. Knepley -dm_view -offsets_view 1783e72e933SJed Brown 1793e72e933SJed Brown test: 1803e72e933SJed Brown suffix: 1d_sfc 181*5dca41c3SJed Brown args: -dm_plex_simplex 0 -dm_plex_dim 1 -dm_plex_shape zbox -dm_plex_box_faces 3 1 -dm_view -coord_ltog_view 1823e72e933SJed Brown 1833e72e933SJed Brown test: 1843e72e933SJed Brown suffix: 2d_sfc 1853e72e933SJed Brown nsize: 2 186*5dca41c3SJed Brown args: -dm_plex_simplex 0 -dm_plex_dim 2 -dm_plex_shape zbox -dm_plex_box_faces 4,3 -dm_distribute 0 -petscspace_degree 1 -dm_view 1873e72e933SJed Brown 1884e2e9504SJed Brown test: 1894e2e9504SJed Brown suffix: 2d_sfc_periodic 1904e2e9504SJed Brown nsize: 2 191*5dca41c3SJed Brown args: -dm_plex_simplex 0 -dm_plex_dim 2 -dm_plex_shape zbox -dm_plex_box_faces 4,3 -dm_distribute 0 -petscspace_degree 1 -dm_plex_box_bd periodic,none -dm_view ::ascii_info_detail 1924e2e9504SJed Brown 1935f06a3ddSJed Brown testset: 194*5dca41c3SJed Brown args: -dm_plex_simplex 0 -dm_plex_dim 2 -dm_plex_shape zbox -dm_plex_box_faces 3,2 -petscspace_degree 1 -dm_plex_box_bd none,periodic -dm_view ::ascii_info_detail -closure_tensor 1955f06a3ddSJed Brown nsize: 2 1965f06a3ddSJed Brown test: 1975f06a3ddSJed Brown suffix: 2d_sfc_periodic_stranded 1985f06a3ddSJed Brown args: -dm_distribute 0 1995f06a3ddSJed Brown test: 2005f06a3ddSJed Brown suffix: 2d_sfc_periodic_stranded_dist 2015f06a3ddSJed Brown args: -dm_distribute 1 -petscpartitioner_type simple 2025f06a3ddSJed Brown 20390d1c1a4SMatthew G. Knepley TEST*/ 204