Actual source code: ex41.c
1: static const char help[] = "Tests for adaptive refinement";
3: #include <petscdmplex.h>
5: typedef struct {
6: PetscBool metric; /* Flag to use metric adaptation, instead of tagging */
7: PetscInt *refcell; /* A cell to be refined on each process */
8: } AppCtx;
10: static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
11: {
12: PetscMPIInt size;
13: PetscInt n;
15: PetscFunctionBeginUser;
16: options->metric = PETSC_FALSE;
17: PetscCallMPI(MPI_Comm_size(comm, &size));
18: PetscCall(PetscCalloc1(size, &options->refcell));
19: n = size;
21: PetscOptionsBegin(comm, "", "Parallel Mesh Adaptation Options", "DMPLEX");
22: PetscCall(PetscOptionsBool("-metric", "Flag for metric refinement", "ex41.c", options->metric, &options->metric, NULL));
23: PetscCall(PetscOptionsIntArray("-refcell", "The cell to be refined", "ex41.c", options->refcell, &n, NULL));
24: if (n) PetscCheck(n == size, comm, PETSC_ERR_ARG_SIZ, "Only gave %" PetscInt_FMT " cells to refine, must give one for all %d processes", n, size);
25: PetscOptionsEnd();
26: PetscFunctionReturn(PETSC_SUCCESS);
27: }
29: static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *ctx, DM *dm)
30: {
31: PetscFunctionBegin;
32: PetscCall(DMCreate(comm, dm));
33: PetscCall(DMSetType(*dm, DMPLEX));
34: PetscCall(DMSetFromOptions(*dm));
35: PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view"));
36: PetscFunctionReturn(PETSC_SUCCESS);
37: }
39: static PetscErrorCode CreateAdaptLabel(DM dm, AppCtx *ctx, DMLabel *adaptLabel)
40: {
41: PetscMPIInt rank;
43: PetscFunctionBegin;
44: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank));
45: PetscCall(DMLabelCreate(PETSC_COMM_SELF, "Adaptation Label", adaptLabel));
46: if (ctx->refcell[rank] >= 0) PetscCall(DMLabelSetValue(*adaptLabel, ctx->refcell[rank], DM_ADAPT_REFINE));
47: PetscFunctionReturn(PETSC_SUCCESS);
48: }
50: int main(int argc, char **argv)
51: {
52: DM dm, dma;
53: DMLabel adaptLabel;
54: AppCtx ctx;
56: PetscFunctionBeginUser;
57: PetscCall(PetscInitialize(&argc, &argv, NULL, help));
58: PetscCall(ProcessOptions(PETSC_COMM_WORLD, &ctx));
59: PetscCall(CreateMesh(PETSC_COMM_WORLD, &ctx, &dm));
60: PetscCall(CreateAdaptLabel(dm, &ctx, &adaptLabel));
61: PetscCall(DMAdaptLabel(dm, adaptLabel, &dma));
62: PetscCall(PetscObjectSetName((PetscObject)dma, "Adapted Mesh"));
63: PetscCall(DMLabelDestroy(&adaptLabel));
64: PetscCall(DMDestroy(&dm));
65: PetscCall(DMViewFromOptions(dma, NULL, "-adapt_dm_view"));
66: PetscCall(DMDestroy(&dma));
67: PetscCall(PetscFree(ctx.refcell));
68: PetscCall(PetscFinalize());
69: return 0;
70: }
72: /*TEST
74: testset:
75: args: -dm_adaptor cellrefiner -dm_plex_transform_type refine_sbr
77: test:
78: suffix: 0
79: requires: triangle
80: args: -dm_view -adapt_dm_view
82: test:
83: suffix: 1
84: requires: triangle
85: args: -dm_coord_space 0 -refcell 2 -dm_view ::ascii_info_detail -adapt_dm_view ::ascii_info_detail
87: test:
88: suffix: 2
89: requires: triangle
90: nsize: 2
91: args: -refcell 2,-1 -petscpartitioner_type simple -dm_view -adapt_dm_view
93: TEST*/