Actual source code: ex44.c
1: static const char help[] = "Tests for mesh extrusion";
3: #include <petscdmplex.h>
4: #include <petscdmforest.h>
6: typedef struct {
7: char bdLabel[PETSC_MAX_PATH_LEN]; /* The boundary label name */
8: PetscInt Nbd; /* The number of boundary markers to extrude, 0 for all */
9: PetscInt bd[64]; /* The boundary markers to be extruded */
10: PetscBool testForest; /* Convert the mesh to a forest and back */
11: } AppCtx;
13: PETSC_EXTERN PetscErrorCode pyramidNormal(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *);
15: /* The pyramid apex is at (0.5, 0.5, -1) */
16: PetscErrorCode pyramidNormal(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt r, PetscScalar u[], PetscCtx ctx)
17: {
18: PetscReal apex[3] = {0.5, 0.5, -1.0};
20: for (PetscInt d = 0; d < dim; ++d) u[d] = x[d] - apex[d];
21: for (PetscInt d = dim; d < 3; ++d) u[d] = 0.0 - apex[d];
22: return PETSC_SUCCESS;
23: }
25: static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
26: {
27: PetscInt n = 64;
28: PetscBool flg;
30: PetscFunctionBeginUser;
31: PetscCall(PetscStrncpy(options->bdLabel, "marker", sizeof(options->bdLabel)));
32: PetscOptionsBegin(comm, "", "Parallel Mesh Adaptation Options", "DMPLEX");
33: PetscCall(PetscOptionsString("-label", "The boundary label name", "ex44.c", options->bdLabel, options->bdLabel, sizeof(options->bdLabel), NULL));
34: PetscCall(PetscOptionsIntArray("-bd", "The boundaries to be extruded", "ex44.c", options->bd, &n, &flg));
35: options->Nbd = flg ? n : 0;
36: options->testForest = PETSC_FALSE;
37: PetscCall(PetscOptionsBool("-test_forest", "Create a DMForest and then convert to DMPlex before testing", "ex44.c", PETSC_FALSE, &options->testForest, NULL));
38: PetscOptionsEnd();
39: PetscFunctionReturn(PETSC_SUCCESS);
40: }
42: static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *ctx, DM *dm)
43: {
44: PetscFunctionBegin;
45: PetscCall(DMCreate(comm, dm));
46: PetscCall(DMSetType(*dm, DMPLEX));
47: PetscCall(DMSetFromOptions(*dm));
48: if (ctx->testForest) {
49: DM dmForest;
50: PetscInt dim;
51: PetscCall(DMGetDimension(*dm, &dim));
52: PetscCall(DMCreate(PETSC_COMM_WORLD, &dmForest));
53: PetscCall(DMSetType(dmForest, (dim == 2) ? DMP4EST : DMP8EST));
54: PetscCall(DMForestSetBaseDM(dmForest, *dm));
55: PetscCall(DMSetUp(dmForest));
56: PetscCall(DMDestroy(dm));
57: PetscCall(DMConvert(dmForest, DMPLEX, dm));
58: PetscCall(DMDestroy(&dmForest));
59: PetscCall(PetscObjectSetName((PetscObject)*dm, "forest"));
60: }
61: PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view"));
62: PetscFunctionReturn(PETSC_SUCCESS);
63: }
65: static PetscErrorCode CreateAdaptLabel(DM dm, AppCtx *ctx, DMLabel *adaptLabel)
66: {
67: DMLabel label;
69: PetscFunctionBegin;
70: if (!ctx->Nbd) {
71: *adaptLabel = NULL;
72: PetscFunctionReturn(PETSC_SUCCESS);
73: }
74: PetscCall(DMGetLabel(dm, ctx->bdLabel, &label));
75: PetscCall(DMLabelCreate(PETSC_COMM_SELF, "Adaptation Label", adaptLabel));
76: for (PetscInt b = 0; b < ctx->Nbd; ++b) {
77: IS bdIS;
78: const PetscInt *points;
79: PetscInt n;
81: PetscCall(DMLabelGetStratumIS(label, ctx->bd[b], &bdIS));
82: if (!bdIS) continue;
83: PetscCall(ISGetLocalSize(bdIS, &n));
84: PetscCall(ISGetIndices(bdIS, &points));
85: for (PetscInt i = 0; i < n; ++i) PetscCall(DMLabelSetValue(*adaptLabel, points[i], DM_ADAPT_REFINE));
86: PetscCall(ISRestoreIndices(bdIS, &points));
87: PetscCall(ISDestroy(&bdIS));
88: }
89: PetscFunctionReturn(PETSC_SUCCESS);
90: }
92: int main(int argc, char **argv)
93: {
94: DM dm, dma;
95: DMLabel adaptLabel;
96: AppCtx ctx;
98: PetscFunctionBeginUser;
99: PetscCall(PetscInitialize(&argc, &argv, NULL, help));
100: PetscCall(ProcessOptions(PETSC_COMM_WORLD, &ctx));
101: PetscCall(CreateMesh(PETSC_COMM_WORLD, &ctx, &dm));
102: PetscCall(CreateAdaptLabel(dm, &ctx, &adaptLabel));
103: if (adaptLabel) PetscCall(DMAdaptLabel(dm, adaptLabel, &dma));
104: else PetscCall(DMExtrude(dm, 3, &dma));
105: PetscCall(PetscObjectSetName((PetscObject)dma, "Adapted Mesh"));
106: PetscCall(DMLabelDestroy(&adaptLabel));
107: PetscCall(DMDestroy(&dm));
108: PetscCall(DMViewFromOptions(dma, NULL, "-adapt_dm_view"));
109: PetscCall(DMDestroy(&dma));
110: PetscCall(PetscFinalize());
111: return 0;
112: }
114: /*TEST
116: testset:
117: args: -dm_view -adapt_dm_view -dm_plex_check_all
119: test:
120: suffix: seg_periodic_0
121: args: -dm_plex_dim 1 -dm_plex_box_faces 3 -dm_plex_transform_extrude_periodic -dm_plex_transform_extrude_use_tensor 0
123: test:
124: suffix: seg_periodic_1
125: args: -dm_plex_dim 1 -dm_plex_box_faces 4 -dm_plex_box_bd periodic \
126: -dm_plex_transform_extrude_layers 3 -dm_plex_transform_extrude_use_tensor 0
128: test:
129: suffix: tri_tensor_0
130: requires: triangle
131: args: -dm_plex_transform_extrude_use_tensor {{0 1}separate output}
133: test:
134: suffix: quad_tensor_0
135: args: -dm_plex_simplex 0 -dm_plex_transform_extrude_use_tensor {{0 1}separate output}
137: test:
138: suffix: quad_tensor_0_forest
139: requires: p4est
140: args: -dm_plex_simplex 0 -dm_plex_transform_extrude_use_tensor {{0 1}separate output} -test_forest 1
142: test:
143: suffix: quad_normal_0
144: args: -dm_plex_simplex 0 -dm_plex_transform_extrude_normal 0,1,1
146: test:
147: suffix: quad_normal_0_forest
148: requires: p4est
149: args: -dm_plex_simplex 0 -dm_plex_transform_extrude_normal 0,1,1 -test_forest 1
151: test:
152: suffix: quad_normal_1
153: args: -dm_plex_simplex 0 -dm_plex_transform_extrude_normal_function pyramidNormal
155: test:
156: suffix: quad_normal_1_forest
157: requires: p4est
158: args: -dm_plex_simplex 0 -dm_plex_transform_extrude_normal_function pyramidNormal -test_forest 1
160: test:
161: suffix: quad_symmetric_0
162: args: -dm_plex_simplex 0 -dm_plex_transform_extrude_symmetric
164: test:
165: suffix: quad_symmetric_0_forest
166: requires: p4est
167: args: -dm_plex_simplex 0 -dm_plex_transform_extrude_symmetric -test_forest 1
169: test:
170: suffix: quad_label
171: args: -dm_plex_simplex 0 -dm_plex_transform_label_replica_inc {{0 100}separate output}
173: test:
174: suffix: quad_periodic_0
175: args: -dm_plex_simplex 0 -dm_plex_transform_extrude_periodic -dm_plex_transform_extrude_use_tensor 0
177: testset:
178: args: -dm_adaptor cellrefiner -dm_plex_transform_type extrude \
179: -dm_view -adapt_dm_view -dm_plex_check_all
181: test:
182: suffix: tri_adapt_0
183: requires: triangle
184: args: -dm_plex_box_faces 2,2 -dm_plex_separate_marker -bd 1,3 \
185: -dm_plex_transform_extrude_thickness 0.5
187: test:
188: suffix: tri_adapt_1
189: requires: triangle
190: nsize: 2
191: args: -dm_plex_box_faces 2,2 -bd 1 \
192: -dm_plex_transform_extrude_thickness 0.5 -petscpartitioner_type simple
194: test:
195: suffix: quad_adapt_0
196: args: -dm_plex_simplex 0 -dm_plex_box_faces 2,2 -dm_plex_separate_marker -bd 1,3 \
197: -dm_plex_transform_extrude_thickness 0.5
199: test:
200: suffix: quad_adapt_1
201: nsize: 2
202: args: -dm_plex_simplex 0 -dm_plex_box_faces 2,2 -bd 1 \
203: -dm_plex_transform_extrude_thickness 0.5 -petscpartitioner_type simple
205: test:
206: suffix: quad_adapt_1_forest
207: requires: p4est
208: nsize: 2
209: args: -dm_plex_simplex 0 -dm_plex_box_faces 2,2 -bd 1 \
210: -dm_plex_transform_extrude_thickness 0.5 -petscpartitioner_type simple \
211: -test_forest 1
213: test:
214: suffix: tet_adapt_0
215: requires: ctetgen
216: args: -dm_plex_dim 3 -dm_plex_box_faces 2,2,2 -dm_plex_separate_marker -bd 1,3 \
217: -dm_plex_transform_extrude_thickness 0.5
219: test:
220: suffix: tet_adapt_1
221: requires: ctetgen
222: nsize: 2
223: args: -dm_plex_dim 3 -dm_plex_box_faces 2,2,2 -bd 1 \
224: -dm_plex_transform_extrude_thickness 0.5 -petscpartitioner_type simple
226: test:
227: suffix: hex_adapt_0
228: args: -dm_plex_simplex 0 -dm_plex_dim 3 -dm_plex_box_faces 2,2,2 -dm_plex_separate_marker -bd 1,3 \
229: -dm_plex_transform_extrude_thickness 0.5
231: TEST*/