xref: /petsc/src/dm/impls/plex/tests/ex4.c (revision e600fa544e2bb197ca2af9b6e65ea465976dec56)
1 static char help[] = "Tests for refinement of meshes created by hand\n\n";
2 
3 #include <petscdmplex.h>
4 
5 typedef struct {
6   PetscInt  debug;          /* The debugging level */
7   PetscInt  dim;            /* The topological mesh dimension */
8   PetscBool cellHybrid;     /* Use a hybrid mesh */
9   PetscBool cellSimplex;    /* Use simplices or hexes */
10   PetscBool testPartition;  /* Use a fixed partitioning for testing */
11   PetscInt  testNum;        /* The particular mesh to test */
12   PetscBool uninterpolate;  /* Uninterpolate the mesh at the end */
13   PetscBool reinterpolate;  /* Reinterpolate the mesh at the end */
14 } AppCtx;
15 
16 PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
17 {
18   PetscErrorCode ierr;
19 
20   PetscFunctionBegin;
21   options->debug          = 0;
22   options->dim            = 2;
23   options->cellHybrid     = PETSC_TRUE;
24   options->cellSimplex    = PETSC_TRUE;
25   options->testPartition  = PETSC_TRUE;
26   options->testNum        = 0;
27   options->uninterpolate  = PETSC_FALSE;
28   options->reinterpolate  = PETSC_FALSE;
29 
30   ierr = PetscOptionsBegin(comm, "", "Meshing Problem Options", "DMPLEX");CHKERRQ(ierr);
31   ierr = PetscOptionsBoundedInt("-debug", "The debugging level", "ex4.c", options->debug, &options->debug, NULL,0);CHKERRQ(ierr);
32   ierr = PetscOptionsRangeInt("-dim", "The topological mesh dimension", "ex4.c", options->dim, &options->dim, NULL,1,3);CHKERRQ(ierr);
33   ierr = PetscOptionsBool("-cell_hybrid", "Use a hybrid mesh", "ex4.c", options->cellHybrid, &options->cellHybrid, NULL);CHKERRQ(ierr);
34   ierr = PetscOptionsBool("-cell_simplex", "Use simplices if true, otherwise hexes", "ex4.c", options->cellSimplex, &options->cellSimplex, NULL);CHKERRQ(ierr);
35   ierr = PetscOptionsBool("-test_partition", "Use a fixed partition for testing", "ex4.c", options->testPartition, &options->testPartition, NULL);CHKERRQ(ierr);
36   ierr = PetscOptionsBoundedInt("-test_num", "The particular mesh to test", "ex4.c", options->testNum, &options->testNum, NULL,0);CHKERRQ(ierr);
37   ierr = PetscOptionsBool("-uninterpolate", "Uninterpolate the mesh at the end", "ex4.c", options->uninterpolate, &options->uninterpolate, NULL);CHKERRQ(ierr);
38   ierr = PetscOptionsBool("-reinterpolate", "Reinterpolate the mesh at the end", "ex4.c", options->reinterpolate, &options->reinterpolate, NULL);CHKERRQ(ierr);
39   ierr = PetscOptionsEnd();CHKERRQ(ierr);
40   PetscFunctionReturn(0);
41 }
42 
43 /* Two segments
44 
45   2-------0-------3-------1-------4
46 
47 become
48 
49   4---0---7---1---5---2---8---3---6
50 
51 */
52 PetscErrorCode CreateSimplex_1D(MPI_Comm comm, DM *dm)
53 {
54   PetscInt       depth = 1;
55   PetscMPIInt    rank;
56   PetscErrorCode ierr;
57 
58   PetscFunctionBegin;
59   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
60   if (rank == 0) {
61     PetscInt    numPoints[2]         = {3, 2};
62     PetscInt    coneSize[5]          = {2, 2, 0, 0, 0};
63     PetscInt    cones[4]             = {2, 3,  3, 4};
64     PetscInt    coneOrientations[16] = {0, 0,  0, 0};
65     PetscScalar vertexCoords[3]      = {-1.0, 0.0, 1.0};
66 
67     ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
68   } else {
69     PetscInt numPoints[2] = {0, 0};
70 
71     ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr);
72   }
73   PetscFunctionReturn(0);
74 }
75 
76 /* Two triangles
77         4
78       / | \
79      8  |  10
80     /   |   \
81    2  0 7  1 5
82     \   |   /
83      6  |  9
84       \ | /
85         3
86 
87 Becomes
88            10
89           / | \
90         21  |  26
91         /   |   \
92       14 2 20 4  16
93       /|\   |   /|\
94     22 | 28 | 32 | 25
95     /  |  \ | /  | 6\
96    8  29 3 13  7 31  11
97     \0 |  / | \  |  /
98     17 | 27 | 30 | 24
99       \|/   |   \|/
100       12 1 19 5  15
101         \   |   /
102         18  |  23
103           \ | /
104             9
105 */
106 PetscErrorCode CreateSimplex_2D(MPI_Comm comm, DM *dm)
107 {
108   PetscInt       depth = 2;
109   PetscMPIInt    rank;
110   PetscErrorCode ierr;
111 
112   PetscFunctionBegin;
113   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
114   if (rank == 0) {
115     PetscInt    numPoints[3]         = {4, 5, 2};
116     PetscInt    coneSize[11]         = {3, 3, 0, 0, 0, 0, 2, 2, 2, 2, 2};
117     PetscInt    cones[16]            = {6, 7, 8,  7, 9, 10,  2, 3,  3, 4,  4, 2,  3, 5,  5, 4};
118     PetscInt    coneOrientations[16] = {0, 0, 0, -1, 0,  0,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0};
119     PetscScalar vertexCoords[8]      = {-0.5, 0.0,  0.0, -0.5,  0.0, 0.5,  0.5, 0.0};
120 
121     ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
122   } else {
123     PetscInt numPoints[3] = {0, 0, 0};
124 
125     ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr);
126   }
127   PetscFunctionReturn(0);
128 }
129 
130 /* Two triangles separated by a zero-volume cell with 4 vertices/2 edges
131         5--16--8
132       / |      | \
133     11  |      |  12
134     /   |      |   \
135    3  0 10  2 14 1  6
136     \   |      |   /
137      9  |      |  13
138       \ |      | /
139         4--15--7
140 */
141 PetscErrorCode CreateSimplexHybrid_2D(MPI_Comm comm, PetscInt testNum, DM *dm)
142 {
143   DM             idm, hdm = NULL;
144   DMLabel        faultLabel, hybridLabel;
145   PetscInt       p;
146   PetscMPIInt    rank;
147   PetscErrorCode ierr;
148 
149   PetscFunctionBegin;
150   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
151   if (rank == 0) {
152     switch (testNum) {
153     case 0:
154     {
155       PetscInt    numPoints[2]        = {4, 2};
156       PetscInt    coneSize[6]         = {3, 3, 0, 0, 0, 0};
157       PetscInt    cones[6]            = {2, 3, 4,  5, 4, 3};
158       PetscInt    coneOrientations[6] = {0, 0, 0,  0, 0, 0};
159       PetscScalar vertexCoords[8]     = {-1.0, -0.5,  0.0, -0.5,  0.0, 0.5,  1.0, 0.5};
160       PetscInt    faultPoints[2]      = {3, 4};
161 
162       ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
163       for (p = 0; p < 2; ++p) {ierr = DMSetLabelValue(*dm, "fault", faultPoints[p], 1);CHKERRQ(ierr);}
164     }
165     break;
166     case 1:
167     {
168       PetscInt    numPoints[2]         = {5, 4};
169       PetscInt    coneSize[9]          = {3, 3, 3, 3, 0, 0, 0, 0, 0};
170       PetscInt    cones[12]            = {4, 5, 6,  6, 7, 4,  6, 5, 8,  6, 8, 7};
171       PetscInt    coneOrientations[12] = {0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0};
172       PetscScalar vertexCoords[10]     = {-1.0, 0.0,  0.0, -1.0,  0.0, 0.0,  0.0, 1.0,  1.0, 0.0};
173       PetscInt    faultPoints[3]       = {5, 6, 7};
174 
175       ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
176       for (p = 0; p < 3; ++p) {ierr = DMSetLabelValue(*dm, "fault", faultPoints[p], 1);CHKERRQ(ierr);}
177     }
178     break;
179     default: SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %d", testNum);
180     }
181     ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr);
182     ierr = PetscObjectSetOptionsPrefix((PetscObject) idm, "in_");CHKERRQ(ierr);
183     ierr = DMPlexDistributeSetDefault(idm, PETSC_FALSE);CHKERRQ(ierr);
184     ierr = DMSetFromOptions(idm);CHKERRQ(ierr);
185     ierr = DMViewFromOptions(idm, NULL, "-dm_view");CHKERRQ(ierr);
186     ierr = DMGetLabel(*dm, "fault", &faultLabel);CHKERRQ(ierr);
187     ierr = DMPlexCreateHybridMesh(idm, faultLabel, NULL, &hybridLabel, NULL, NULL, &hdm);CHKERRQ(ierr);
188     ierr = DMLabelDestroy(&hybridLabel);CHKERRQ(ierr);
189     ierr = DMDestroy(&idm);CHKERRQ(ierr);
190     ierr = DMDestroy(dm);CHKERRQ(ierr);
191     *dm  = hdm;
192   } else {
193     PetscInt numPoints[2] = {0, 0};
194 
195     ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr);
196     ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr);
197     ierr = PetscObjectSetOptionsPrefix((PetscObject) idm, "in_");CHKERRQ(ierr);
198     ierr = DMPlexDistributeSetDefault(idm, PETSC_FALSE);CHKERRQ(ierr);
199     ierr = DMSetFromOptions(idm);CHKERRQ(ierr);
200     ierr = DMViewFromOptions(idm, NULL, "-dm_view");CHKERRQ(ierr);
201     ierr = DMPlexCreateHybridMesh(idm, NULL, NULL, NULL, NULL, NULL, &hdm);CHKERRQ(ierr);
202     ierr = DMDestroy(&idm);CHKERRQ(ierr);
203     ierr = DMDestroy(dm);CHKERRQ(ierr);
204     *dm  = hdm;
205   }
206   PetscFunctionReturn(0);
207 }
208 
209 /* Two quadrilaterals
210 
211   5----10-----4----14-----7
212   |           |           |
213   |           |           |
214   |           |           |
215  11     0     9     1     13
216   |           |           |
217   |           |           |
218   |           |           |
219   2-----8-----3----12-----6
220 */
221 PetscErrorCode CreateTensorProduct_2D(MPI_Comm comm, PetscInt testNum, DM *dm)
222 {
223   PetscInt       depth = 2;
224   PetscMPIInt    rank;
225   PetscErrorCode ierr;
226 
227   PetscFunctionBegin;
228   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
229   if (rank == 0) {
230     PetscInt    numPoints[3]         = {6, 7, 2};
231     PetscInt    coneSize[15]         = {4, 4, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2};
232     PetscInt    cones[22]            = {8, 9, 10, 11,  12, 13, 14,  9,  2, 3,  3, 4,  4, 5,  5, 2,  3, 6,  6, 7,  7, 4};
233     PetscInt    coneOrientations[22] = {0, 0,  0,  0,   0,  0,  0, -1,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0};
234     PetscScalar vertexCoords[12]     = {-1.0, -0.5,  0.0, -0.5,  0.0, 0.5,  -1.0, 0.5,  1.0, -0.5,  1.0, 0.5};
235 
236     ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
237   } else {
238     PetscInt numPoints[3] = {0, 0, 0};
239 
240     ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr);
241   }
242   PetscFunctionReturn(0);
243 }
244 
245 PetscErrorCode CreateTensorProductHybrid_2D(MPI_Comm comm, PetscInt testNum, DM *dm)
246 {
247   DM             idm, hdm = NULL;
248   DMLabel        faultLabel, hybridLabel;
249   PetscInt       p;
250   PetscMPIInt    rank;
251   PetscErrorCode ierr;
252 
253   PetscFunctionBegin;
254   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
255   if (rank == 0) {
256     PetscInt    numPoints[2]        = {6, 2};
257     PetscInt    coneSize[8]         = {4, 4, 0, 0, 0, 0, 0, 0};
258     PetscInt    cones[8]            = {2, 3, 4, 5,  3, 6, 7, 4,};
259     PetscInt    coneOrientations[8] = {0, 0, 0, 0,  0, 0, 0, 0};
260     PetscScalar vertexCoords[12]    = {-1.0, -0.5,  0.0, -0.5,  0.0, 0.5,  -1.0, 0.5,  1.0, -0.5,  1.0, 0.5};
261     PetscInt    faultPoints[2]      = {3, 4};
262 
263     ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
264     for (p = 0; p < 2; ++p) {ierr = DMSetLabelValue(*dm, "fault", faultPoints[p], 1);CHKERRQ(ierr);}
265     ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr);
266     ierr = PetscObjectSetOptionsPrefix((PetscObject) idm, "in_");CHKERRQ(ierr);
267     ierr = DMPlexDistributeSetDefault(idm, PETSC_FALSE);CHKERRQ(ierr);
268     ierr = DMSetFromOptions(idm);CHKERRQ(ierr);
269     ierr = DMViewFromOptions(idm, NULL, "-dm_view");CHKERRQ(ierr);
270     ierr = DMGetLabel(*dm, "fault", &faultLabel);CHKERRQ(ierr);
271     ierr = DMPlexCreateHybridMesh(idm, faultLabel, NULL, &hybridLabel, NULL, NULL, &hdm);CHKERRQ(ierr);
272     ierr = DMLabelDestroy(&hybridLabel);CHKERRQ(ierr);
273   } else {
274     PetscInt numPoints[3] = {0, 0, 0};
275 
276     ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr);
277     ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr);
278     ierr = PetscObjectSetOptionsPrefix((PetscObject) idm, "in_");CHKERRQ(ierr);
279     ierr = DMPlexDistributeSetDefault(idm, PETSC_FALSE);CHKERRQ(ierr);
280     ierr = DMSetFromOptions(idm);CHKERRQ(ierr);
281     ierr = DMViewFromOptions(idm, NULL, "-dm_view");CHKERRQ(ierr);
282     ierr = DMPlexCreateHybridMesh(idm, NULL, NULL, NULL, NULL, NULL, &hdm);CHKERRQ(ierr);
283   }
284   ierr = DMDestroy(&idm);CHKERRQ(ierr);
285   ierr = DMDestroy(dm);CHKERRQ(ierr);
286   *dm  = hdm;
287   PetscFunctionReturn(0);
288 }
289 
290 /* Two tetrahedrons
291 
292  cell   5          5______    cell
293  0    / | \        |\      \     1
294     17  |  18      | 18 13  21
295     /8 19 10\     19  \      \
296    2-14-|----4     |   4--22--6
297     \ 9 | 7 /      |10 /      /
298     16  |  15      | 15  12 20
299       \ | /        |/      /
300         3          3------
301 */
302 PetscErrorCode CreateSimplex_3D(MPI_Comm comm, PetscInt testNum, DM *dm)
303 {
304   DM             idm;
305   PetscInt       depth = 3;
306   PetscMPIInt    rank;
307   PetscErrorCode ierr;
308 
309   PetscFunctionBegin;
310   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
311   if (rank == 0) {
312     switch (testNum) {
313     case 0:
314     {
315       PetscInt    numPoints[4]         = {5, 9, 7, 2};
316       PetscInt    coneSize[23]         = {4, 4, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2};
317       PetscInt    cones[47]            = { 7,  8,  9, 10,  10, 11, 12, 13,  14, 15, 16,  17, 18, 14,  16, 19, 17,  15, 18, 19,  20, 21, 19,  15, 22, 20,  18, 21, 22,  2, 4,  4, 3,  3, 2,  2, 5,  5, 4,  3, 5,  3, 6,  6, 5,  4, 6};
318       PetscInt    coneOrientations[47] = { 0,  0,  0,  0,  -2,  0,  0,  0,   0,  0,  0,   0,  0, -1,  -1,  0, -1,  -1, -1, -1,   0,  0, -1,  -1,  0, -1,  -1, -1, -1,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0,  0, 0};
319       PetscScalar vertexCoords[15]     = {0.0, 0.0, -0.5,  0.0, -0.5, 0.0,  1.0, 0.0, 0.0,  0.0, 0.5, 0.0,  0.0, 0.0, 0.5};
320 
321       ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
322     }
323     break;
324     case 1:
325     {
326       PetscInt    numPoints[2]        = {5, 2};
327       PetscInt    coneSize[7]         = {4, 4, 0, 0, 0, 0, 0};
328       PetscInt    cones[8]            = {4, 3, 5, 2,  5, 3, 4, 6};
329       PetscInt    coneOrientations[8] = {0, 0, 0, 0,  0, 0, 0, 0};
330       PetscScalar vertexCoords[15]    = {-1.0, 0.0, 0.0,  0.0, -1.0, 0.0,  0.0, 0.0, 1.0,  0.0, 1.0, 0.0,  1.0, 0.0, 0.0};
331 
332       depth = 1;
333       ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
334       ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr);
335       ierr = DMViewFromOptions(idm, NULL, "-in_dm_view");CHKERRQ(ierr);
336       ierr = DMDestroy(dm);CHKERRQ(ierr);
337       *dm  = idm;
338     }
339     break;
340     case 2:
341     {
342       PetscInt    numPoints[2]        = {4, 1};
343       PetscInt    coneSize[5]         = {4, 0, 0, 0, 0};
344       PetscInt    cones[4]            = {2, 3, 4, 1};
345       PetscInt    coneOrientations[4] = {0, 0, 0, 0};
346       PetscScalar vertexCoords[12]    = {0.0, 0.0, 0.0,  1.0, 0.0, 0.0,  0.0, 1.0, 0.0,  0.0, 0.0, 1.0};
347 
348       depth = 1;
349       ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
350       ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr);
351       ierr = DMViewFromOptions(idm, NULL, "-in_dm_view");CHKERRQ(ierr);
352       ierr = DMDestroy(dm);CHKERRQ(ierr);
353       *dm  = idm;
354     }
355     break;
356     default: SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %d", testNum);
357     }
358   } else {
359     PetscInt numPoints[4] = {0, 0, 0, 0};
360 
361     ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr);
362     switch (testNum) {
363     case 1:
364       ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr);
365       ierr = DMViewFromOptions(idm, NULL, "-in_dm_view");CHKERRQ(ierr);
366       ierr = DMDestroy(dm);CHKERRQ(ierr);
367       *dm  = idm;
368       break;
369     }
370   }
371   PetscFunctionReturn(0);
372 }
373 
374 /* Two tetrahedrons separated by a zero-volume cell with 6 vertices
375 
376  cell   6 ___33___10______    cell
377  0    / | \        |\      \     1
378     21  |  23      | 29     27
379     /12 24 14\    30  \      \
380    3-20-|----5--32-|---9--26--7
381     \ 13| 11/      |18 /      /
382     19  |  22      | 28     25
383       \ | /        |/      /
384         4----31----8------
385          cell 2
386 */
387 PetscErrorCode CreateSimplexHybrid_3D(MPI_Comm comm, PetscInt testNum, DM *dm)
388 {
389   DM             idm, hdm = NULL;
390   DMLabel        faultLabel, hybridLabel;
391   PetscInt       p;
392   PetscMPIInt    rank;
393   PetscErrorCode ierr;
394 
395   PetscFunctionBegin;
396   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
397   if (rank == 0) {
398     switch (testNum) {
399     case 0:
400     {
401       PetscInt    numPoints[2]        = {5, 2};
402       PetscInt    coneSize[7]         = {4, 4, 0, 0, 0, 0, 0};
403       PetscInt    cones[8]            = {4, 3, 5, 2,  5, 3, 4, 6};
404       PetscInt    coneOrientations[8] = {0, 0, 0, 0,  0, 0, 0, 0};
405       PetscScalar vertexCoords[15]    = {-1.0, 0.0, 0.0,  0.0, -1.0, 0.0,  0.0, 0.0, 1.0,  0.0, 1.0, 0.0,  1.0, 0.0, 0.0};
406       PetscInt    faultPoints[3]      = {3, 4, 5};
407 
408       ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
409       for (p = 0; p < 3; ++p) {ierr = DMSetLabelValue(*dm, "fault", faultPoints[p], 1);CHKERRQ(ierr);}
410     }
411     break;
412     case 1:
413     {
414       /* Tets 0,3,5 and 1,2,4 */
415       PetscInt    numPoints[2]         = {9, 6};
416       PetscInt    coneSize[15]         = {4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0};
417       PetscInt    cones[24]            = { 7,  8,  9, 6,  11, 13,  9, 14,  10, 11, 13, 9,
418                                            9, 10, 11, 7,   9, 14, 13, 12,   7,  8, 11, 9};
419       PetscInt    coneOrientations[24] = { 0, 0,  0, 0,   0,  0,  0,  0,   0,  0,  0, 0,
420                                            0, 0,  0, 0,   0,  0,  0,  0,   0,  0,  0, 0};
421       PetscScalar vertexCoords[27]     = {-2.0, -1.0,  0.0,  -2.0,  0.0,  0.0,  -2.0,  0.0,  1.0,
422                                            0.0, -1.0,  0.0,   0.0,  0.0,  0.0,   0.0,  0.0,  1.0,
423                                            2.0, -1.0,  0.0,   2.0,  0.0,  0.0,   2.0,  0.0,  1.0};
424       PetscInt    faultPoints[3]       = {9, 10, 11};
425 
426       ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
427       for (p = 0; p < 3; ++p) {ierr = DMSetLabelValue(*dm, "fault", faultPoints[p], 1);CHKERRQ(ierr);}
428     }
429     break;
430     default: SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %d", testNum);
431     }
432     ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr);
433     ierr = PetscObjectSetOptionsPrefix((PetscObject) idm, "in_");CHKERRQ(ierr);
434     ierr = DMPlexDistributeSetDefault(idm, PETSC_FALSE);CHKERRQ(ierr);
435     ierr = DMSetFromOptions(idm);CHKERRQ(ierr);
436     ierr = DMViewFromOptions(idm, NULL, "-dm_view");CHKERRQ(ierr);
437     ierr = DMGetLabel(*dm, "fault", &faultLabel);CHKERRQ(ierr);
438     ierr = DMPlexCreateHybridMesh(idm, faultLabel, NULL, &hybridLabel, NULL, NULL, &hdm);CHKERRQ(ierr);
439     ierr = DMLabelDestroy(&hybridLabel);CHKERRQ(ierr);
440     ierr = DMDestroy(&idm);CHKERRQ(ierr);
441     ierr = DMDestroy(dm);CHKERRQ(ierr);
442     *dm  = hdm;
443   } else {
444     PetscInt numPoints[4] = {0, 0, 0, 0};
445 
446     ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr);
447     ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr);
448     ierr = PetscObjectSetOptionsPrefix((PetscObject) idm, "in_");CHKERRQ(ierr);
449     ierr = DMPlexDistributeSetDefault(idm, PETSC_FALSE);CHKERRQ(ierr);
450     ierr = DMSetFromOptions(idm);CHKERRQ(ierr);
451     ierr = DMViewFromOptions(idm, NULL, "-dm_view");CHKERRQ(ierr);
452     ierr = DMPlexCreateHybridMesh(idm, NULL, NULL, NULL, NULL, NULL, &hdm);CHKERRQ(ierr);
453     ierr = DMDestroy(&idm);CHKERRQ(ierr);
454     ierr = DMDestroy(dm);CHKERRQ(ierr);
455     *dm  = hdm;
456   }
457   PetscFunctionReturn(0);
458 }
459 
460 PetscErrorCode CreateTensorProduct_3D(MPI_Comm comm, PetscInt testNum, DM *dm)
461 {
462   DM             idm;
463   PetscMPIInt    rank;
464   PetscErrorCode ierr;
465 
466   PetscFunctionBegin;
467   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
468   if (rank == 0) {
469     switch (testNum) {
470     case 0:
471     {
472       PetscInt    numPoints[2]         = {12, 2};
473       PetscInt    coneSize[14]         = {8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
474       PetscInt    cones[16]            = {2, 3, 4, 5, 6, 7, 8, 9,  5, 4, 10, 11, 7, 12, 13, 8};
475       PetscInt    coneOrientations[16] = {0, 0, 0, 0, 0, 0, 0, 0,  0, 0,  0,  0, 0,  0,  0, 0};
476       PetscScalar vertexCoords[36]     = {-1.0, -0.5, -0.5,  -1.0,  0.5, -0.5,  0.0,  0.5, -0.5,   0.0, -0.5, -0.5,
477                                           -1.0, -0.5,  0.5,   0.0, -0.5,  0.5,  0.0,  0.5,  0.5,  -1.0,  0.5,  0.5,
478                                           1.0,  0.5, -0.5,   1.0, -0.5, -0.5,  1.0, -0.5,  0.5,   1.0,  0.5,  0.5};
479 
480       ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
481     }
482     break;
483     case 1:
484     {
485       PetscInt    numPoints[2]        = {8, 1};
486       PetscInt    coneSize[9]         = {8, 0, 0, 0, 0, 0, 0, 0, 0};
487       PetscInt    cones[8]            = {1, 2, 3, 4, 5, 6, 7, 8};
488       PetscInt    coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0};
489       PetscScalar vertexCoords[24]    = {-1.0, -1.0, -1.0,  -1.0,  1.0, -1.0,  1.0,  1.0, -1.0,   1.0, -1.0, -1.0,
490                                          -1.0, -1.0,  1.0,   1.0, -1.0,  1.0,  1.0,  1.0,  1.0,  -1.0,  1.0,  1.0};
491 
492       ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
493     }
494     break;
495     default: SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %d", testNum);
496     }
497   } else {
498     PetscInt numPoints[4] = {0, 0, 0, 0};
499 
500     ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr);
501   }
502   ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr);
503   ierr = DMViewFromOptions(idm, NULL, "-in_dm_view");CHKERRQ(ierr);
504   ierr = DMDestroy(dm);CHKERRQ(ierr);
505   *dm  = idm;
506   PetscFunctionReturn(0);
507 }
508 
509 PetscErrorCode CreateTensorProductHybrid_3D(MPI_Comm comm, PetscInt testNum, DM *dm)
510 {
511   DM             idm, hdm = NULL;
512   DMLabel        faultLabel;
513   PetscInt       p;
514   PetscMPIInt    rank;
515   PetscErrorCode ierr;
516 
517   PetscFunctionBegin;
518   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
519   if (rank == 0) {
520     switch (testNum) {
521     case 0:
522     {
523       PetscInt    numPoints[2]         = {12, 2};
524       PetscInt    coneSize[14]         = {8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
525       PetscInt    cones[16]            = {2, 3, 4, 5, 6, 7, 8, 9,  5, 4, 10, 11, 7, 12, 13, 8};
526       PetscInt    coneOrientations[16] = {0, 0, 0, 0, 0, 0, 0, 0,  0, 0,  0,  0, 0,  0,  0, 0};
527       PetscScalar vertexCoords[36]     = {-1.0, -0.5, -0.5,  -1.0,  0.5, -0.5,  0.0,  0.5, -0.5,   0.0, -0.5, -0.5,
528                                           -1.0, -0.5,  0.5,   0.0, -0.5,  0.5,  0.0,  0.5,  0.5,  -1.0,  0.5,  0.5,
529                                           1.0,  0.5, -0.5,   1.0, -0.5, -0.5,  1.0, -0.5,  0.5,   1.0,  0.5,  0.5};
530       PetscInt    faultPoints[4]       = {2, 3, 5, 6};
531 
532       ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
533       for (p = 0; p < 4; ++p) {ierr = DMSetLabelValue(*dm, "fault", faultPoints[p], 1);CHKERRQ(ierr);}
534     }
535     break;
536     case 1:
537     {
538       PetscInt    numPoints[2]         = {30, 7};
539       PetscInt    coneSize[37]         = {8,8,8,8,8,8,8, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
540       PetscInt    cones[56]            = { 8, 21, 20,  7, 13, 12, 23, 24,
541                                           14, 15, 10,  9, 13,  8, 21, 24,
542                                           15, 16, 11, 10, 24, 21, 22, 25,
543                                           30, 29, 28, 21, 35, 24, 33, 34,
544                                           24, 21, 30, 35, 25, 36, 31, 22,
545                                           27, 20, 21, 28, 32, 33, 24, 23,
546                                           15, 24, 13, 14, 19, 18, 17, 26};
547       PetscInt    coneOrientations[56] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
548       PetscScalar vertexCoords[90]     = {-2.0, -2.0, -2.0,  -2.0, -1.0, -2.0,  -3.0,  0.0, -2.0,  -2.0,  1.0, -2.0,  -2.0,  2.0, -2.0,  -2.0, -2.0,  0.0,
549                                           -2.0, -1.0,  0.0,  -3.0,  0.0,  0.0,  -2.0,  1.0,  0.0,  -2.0,  2.0,  0.0,  -2.0, -1.0,  2.0,  -3.0,  0.0,  2.0,
550                                           -2.0,  1.0,  2.0,   0.0, -2.0, -2.0,   0.0,  0.0, -2.0,   0.0,  2.0, -2.0,   0.0, -2.0,  0.0,   0.0,  0.0,  0.0,
551                                            0.0,  2.0,  0.0,   0.0,  0.0,  2.0,   2.0, -2.0, -2.0,   2.0, -1.0, -2.0,   3.0,  0.0, -2.0,   2.0,  1.0, -2.0,
552                                            2.0,  2.0, -2.0,   2.0, -2.0,  0.0,   2.0, -1.0,  0.0,   3.0,  0.0,  0.0,   2.0,  1.0,  0.0,   2.0,  2.0,  0.0};
553       PetscInt    faultPoints[6]       = {20, 21, 22, 23, 24, 25};
554 
555       ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr);
556       for (p = 0; p < 6; ++p) {ierr = DMSetLabelValue(*dm, "fault", faultPoints[p], 1);CHKERRQ(ierr);}
557     }
558     break;
559     default: SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %d", testNum);
560     }
561     ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr);
562     ierr = PetscObjectSetOptionsPrefix((PetscObject) idm, "in_");CHKERRQ(ierr);
563     ierr = DMPlexDistributeSetDefault(idm, PETSC_FALSE);CHKERRQ(ierr);
564     ierr = DMSetFromOptions(idm);CHKERRQ(ierr);
565     ierr = DMViewFromOptions(idm, NULL, "-dm_view");CHKERRQ(ierr);
566     ierr = DMGetLabel(*dm, "fault", &faultLabel);CHKERRQ(ierr);
567     ierr = DMPlexCreateHybridMesh(idm, faultLabel, NULL, NULL, NULL, NULL, &hdm);CHKERRQ(ierr);
568     ierr = DMDestroy(&idm);CHKERRQ(ierr);
569     ierr = DMDestroy(dm);CHKERRQ(ierr);
570     *dm  = hdm;
571   } else {
572     PetscInt numPoints[4] = {0, 0, 0, 0};
573 
574     ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr);
575     ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr);
576     ierr = PetscObjectSetOptionsPrefix((PetscObject) idm, "in_");CHKERRQ(ierr);
577     ierr = DMPlexDistributeSetDefault(idm, PETSC_FALSE);CHKERRQ(ierr);
578     ierr = DMSetFromOptions(idm);CHKERRQ(ierr);
579     ierr = DMViewFromOptions(idm, NULL, "-dm_view");CHKERRQ(ierr);
580     ierr = DMPlexCreateHybridMesh(idm, NULL, NULL, NULL, NULL, NULL, &hdm);CHKERRQ(ierr);
581     ierr = DMDestroy(&idm);CHKERRQ(ierr);
582     ierr = DMDestroy(dm);CHKERRQ(ierr);
583     *dm  = hdm;
584   }
585   PetscFunctionReturn(0);
586 }
587 
588 PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm)
589 {
590   PetscInt       dim         = user->dim;
591   PetscBool      cellHybrid  = user->cellHybrid;
592   PetscBool      cellSimplex = user->cellSimplex;
593   PetscMPIInt    rank, size;
594   PetscErrorCode ierr;
595 
596   PetscFunctionBegin;
597   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
598   ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr);
599   ierr = DMCreate(comm, dm);CHKERRQ(ierr);
600   ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr);
601   ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr);
602   switch (dim) {
603   case 1:
604     PetscCheckFalse(cellHybrid,comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make hybrid meshes for dimension %d", dim);
605     ierr = CreateSimplex_1D(comm, dm);CHKERRQ(ierr);
606     break;
607   case 2:
608     if (cellSimplex) {
609       if (cellHybrid) {
610         ierr = CreateSimplexHybrid_2D(comm, user->testNum, dm);CHKERRQ(ierr);
611       } else {
612         ierr = CreateSimplex_2D(comm, dm);CHKERRQ(ierr);
613       }
614     } else {
615       if (cellHybrid) {
616         ierr = CreateTensorProductHybrid_2D(comm, user->testNum, dm);CHKERRQ(ierr);
617       } else {
618         ierr = CreateTensorProduct_2D(comm, user->testNum, dm);CHKERRQ(ierr);
619       }
620     }
621     break;
622   case 3:
623     if (cellSimplex) {
624       if (cellHybrid) {
625         ierr = CreateSimplexHybrid_3D(comm, user->testNum, dm);CHKERRQ(ierr);
626       } else {
627         ierr = CreateSimplex_3D(comm, user->testNum, dm);CHKERRQ(ierr);
628       }
629     } else {
630       if (cellHybrid) {
631         ierr = CreateTensorProductHybrid_3D(comm, user->testNum, dm);CHKERRQ(ierr);
632       } else {
633         ierr = CreateTensorProduct_3D(comm, user->testNum, dm);CHKERRQ(ierr);
634       }
635     }
636     break;
637   default:
638     SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make meshes for dimension %d", dim);
639   }
640   if (user->testPartition && size > 1) {
641     PetscPartitioner part;
642     PetscInt  *sizes  = NULL;
643     PetscInt  *points = NULL;
644 
645     if (rank == 0) {
646       if (dim == 2 && cellSimplex && !cellHybrid && size == 2) {
647         switch (user->testNum) {
648         case 0: {
649           PetscInt triSizes_p2[2]  = {1, 1};
650           PetscInt triPoints_p2[2] = {0, 1};
651 
652           ierr = PetscMalloc2(2, &sizes, 2, &points);CHKERRQ(ierr);
653           ierr = PetscArraycpy(sizes,  triSizes_p2, 2);CHKERRQ(ierr);
654           ierr = PetscArraycpy(points, triPoints_p2, 2);CHKERRQ(ierr);break;}
655         default:
656           SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for triangular mesh on 2 procs", user->testNum);
657         }
658       } else if (dim == 2 && cellSimplex && cellHybrid && size == 2) {
659         switch (user->testNum) {
660         case 0: {
661           PetscInt triSizes_p2[2]  = {1, 2};
662           PetscInt triPoints_p2[3] = {0, 1, 2};
663 
664           ierr = PetscMalloc2(2, &sizes, 3, &points);CHKERRQ(ierr);
665           ierr = PetscArraycpy(sizes,  triSizes_p2, 2);CHKERRQ(ierr);
666           ierr = PetscArraycpy(points, triPoints_p2, 3);CHKERRQ(ierr);break;}
667         default:
668           SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for triangular hybrid mesh on 2 procs", user->testNum);
669         }
670       } else if (dim == 2 && !cellSimplex && !cellHybrid && size == 2) {
671         switch (user->testNum) {
672         case 0: {
673           PetscInt quadSizes_p2[2]  = {1, 1};
674           PetscInt quadPoints_p2[2] = {0, 1};
675 
676           ierr = PetscMalloc2(2, &sizes, 2, &points);CHKERRQ(ierr);
677           ierr = PetscArraycpy(sizes,  quadSizes_p2, 2);CHKERRQ(ierr);
678           ierr = PetscArraycpy(points, quadPoints_p2, 2);CHKERRQ(ierr);break;}
679         default:
680           SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for quadrilateral mesh on 2 procs", user->testNum);
681         }
682       } else if (dim == 2 && !cellSimplex && cellHybrid && size == 2) {
683         switch (user->testNum) {
684         case 0: {
685           PetscInt quadSizes_p2[2]  = {1, 2};
686           PetscInt quadPoints_p2[3] = {0, 1, 2};
687 
688           ierr = PetscMalloc2(2, &sizes, 3, &points);CHKERRQ(ierr);
689           ierr = PetscArraycpy(sizes,  quadSizes_p2, 2);CHKERRQ(ierr);
690           ierr = PetscArraycpy(points, quadPoints_p2, 3);CHKERRQ(ierr);break;}
691         default:
692           SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for quadrilateral hybrid mesh on 2 procs", user->testNum);
693         }
694       } else if (dim == 3 && cellSimplex && !cellHybrid && size == 2) {
695         switch (user->testNum) {
696         case 0: {
697           PetscInt tetSizes_p2[2]  = {1, 1};
698           PetscInt tetPoints_p2[2] = {0, 1};
699 
700           ierr = PetscMalloc2(2, &sizes, 2, &points);CHKERRQ(ierr);
701           ierr = PetscArraycpy(sizes,  tetSizes_p2, 2);CHKERRQ(ierr);
702           ierr = PetscArraycpy(points, tetPoints_p2, 2);CHKERRQ(ierr);break;}
703         case 1: {
704           PetscInt tetSizes_p2[2]  = {1, 1};
705           PetscInt tetPoints_p2[2] = {0, 1};
706 
707           ierr = PetscMalloc2(2, &sizes, 2, &points);CHKERRQ(ierr);
708           ierr = PetscArraycpy(sizes,  tetSizes_p2, 2);CHKERRQ(ierr);
709           ierr = PetscArraycpy(points, tetPoints_p2, 2);CHKERRQ(ierr);break;}
710         default:
711           SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for tetrahedral mesh on 2 procs", user->testNum);
712         }
713       } else if (dim == 3 && cellSimplex && cellHybrid && size == 2) {
714         switch (user->testNum) {
715         case 0: {
716           PetscInt tetSizes_p2[2]  = {1, 2};
717           PetscInt tetPoints_p2[3] = {0, 1, 2};
718 
719           ierr = PetscMalloc2(2, &sizes, 3, &points);CHKERRQ(ierr);
720           ierr = PetscArraycpy(sizes,  tetSizes_p2, 2);CHKERRQ(ierr);
721           ierr = PetscArraycpy(points, tetPoints_p2, 3);CHKERRQ(ierr);break;}
722         case 1: {
723           PetscInt tetSizes_p2[2]  = {3, 4};
724           PetscInt tetPoints_p2[7] = {0, 3, 5, 1, 2, 4, 6};
725 
726           ierr = PetscMalloc2(2, &sizes, 7, &points);CHKERRQ(ierr);
727           ierr = PetscArraycpy(sizes,  tetSizes_p2, 2);CHKERRQ(ierr);
728           ierr = PetscArraycpy(points, tetPoints_p2, 7);CHKERRQ(ierr);break;}
729         default:
730           SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for tetrahedral hybrid mesh on 2 procs", user->testNum);
731         }
732       } else if (dim == 3 && !cellSimplex && !cellHybrid && size == 2) {
733         switch (user->testNum) {
734         case 0: {
735           PetscInt hexSizes_p2[2]  = {1, 1};
736           PetscInt hexPoints_p2[2] = {0, 1};
737 
738           ierr = PetscMalloc2(2, &sizes, 2, &points);CHKERRQ(ierr);
739           ierr = PetscArraycpy(sizes,  hexSizes_p2, 2);CHKERRQ(ierr);
740           ierr = PetscArraycpy(points, hexPoints_p2, 2);CHKERRQ(ierr);break;}
741         default:
742           SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for hexahedral mesh on 2 procs", user->testNum);
743         }
744       } else if (dim == 3 && !cellSimplex && cellHybrid && size == 2) {
745         switch (user->testNum) {
746         case 0: {
747           PetscInt hexSizes_p2[2]  = {1, 1};
748           PetscInt hexPoints_p2[2] = {0, 1};
749 
750           ierr = PetscMalloc2(2, &sizes, 2, &points);CHKERRQ(ierr);
751           ierr = PetscArraycpy(sizes,  hexSizes_p2, 2);CHKERRQ(ierr);
752           ierr = PetscArraycpy(points, hexPoints_p2, 2);CHKERRQ(ierr);break;}
753         case 1: {
754           PetscInt hexSizes_p2[2]  = {5, 4};
755           PetscInt hexPoints_p2[9] = {3, 4, 5, 7, 8, 0, 1, 2, 6};
756 
757           ierr = PetscMalloc2(2, &sizes, 9, &points);CHKERRQ(ierr);
758           ierr = PetscArraycpy(sizes,  hexSizes_p2, 2);CHKERRQ(ierr);
759           ierr = PetscArraycpy(points, hexPoints_p2, 9);CHKERRQ(ierr);break;}
760         default:
761           SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for hexahedral hybrid mesh on 2 procs", user->testNum);
762         }
763       } else SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test partition");
764     }
765     ierr = DMPlexGetPartitioner(*dm, &part);CHKERRQ(ierr);
766     ierr = PetscPartitionerSetType(part, PETSCPARTITIONERSHELL);CHKERRQ(ierr);
767     ierr = PetscPartitionerShellSetPartition(part, size, sizes, points);CHKERRQ(ierr);
768     ierr = PetscFree2(sizes, points);CHKERRQ(ierr);
769   } else {
770     PetscPartitioner part;
771 
772     ierr = DMPlexGetPartitioner(*dm,&part);CHKERRQ(ierr);
773     ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr);
774   }
775   {
776     DM pdm = NULL;
777 
778     ierr = DMPlexDistribute(*dm, 0, NULL, &pdm);CHKERRQ(ierr);
779     if (pdm) {
780       ierr = DMViewFromOptions(pdm, NULL, "-dm_view");CHKERRQ(ierr);
781       ierr = DMDestroy(dm);CHKERRQ(ierr);
782       *dm  = pdm;
783     }
784   }
785   ierr = DMPlexDistributeSetDefault(*dm, PETSC_FALSE);CHKERRQ(ierr);
786   ierr = DMViewFromOptions(*dm, NULL, "-dm_view_pre");CHKERRQ(ierr);
787   ierr = DMSetFromOptions(*dm);CHKERRQ(ierr);
788   if (user->uninterpolate || user->reinterpolate) {
789     DM udm = NULL;
790 
791     ierr = DMPlexUninterpolate(*dm, &udm);CHKERRQ(ierr);
792     ierr = DMPlexCopyCoordinates(*dm, udm);CHKERRQ(ierr);
793     ierr = DMDestroy(dm);CHKERRQ(ierr);
794     *dm  = udm;
795   }
796   if (user->reinterpolate) {
797     DM idm = NULL;
798 
799     ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr);
800     ierr = DMPlexCopyCoordinates(*dm, idm);CHKERRQ(ierr);
801     ierr = DMDestroy(dm);CHKERRQ(ierr);
802     *dm  = idm;
803   }
804   ierr = DMPlexDistributeSetDefault(*dm, PETSC_FALSE);CHKERRQ(ierr);
805   ierr = PetscObjectSetName((PetscObject) *dm, "Hybrid Mesh");CHKERRQ(ierr);
806   ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr);
807   ierr = PetscObjectSetOptionsPrefix((PetscObject) *dm, "hyb_");CHKERRQ(ierr);
808   ierr = DMSetFromOptions(*dm);CHKERRQ(ierr);
809   PetscFunctionReturn(0);
810 }
811 
812 int main(int argc, char **argv)
813 {
814   DM             dm;
815   AppCtx         user;                 /* user-defined work context */
816   PetscErrorCode ierr;
817 
818   ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return ierr;
819   ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr);
820   ierr = CreateMesh(PETSC_COMM_WORLD, &user, &dm);CHKERRQ(ierr);
821   ierr = DMDestroy(&dm);CHKERRQ(ierr);
822   ierr = PetscFinalize();
823   return ierr;
824 }
825 
826 /*TEST
827 
828   # 1D Simplex 29-31
829   testset:
830     args: -dim 1 -cell_hybrid 0 -hyb_dm_plex_check_all -dm_plex_check_all
831     test:
832       suffix: 29
833     test:
834       suffix: 30
835       args: -dm_refine 1
836     test:
837       suffix: 31
838       args: -dm_refine 5
839 
840   # 2D Simplex 0-3
841   testset:
842     args: -dim 2 -cell_hybrid 0 -hyb_dm_plex_check_all -dm_plex_check_all
843     test:
844       suffix: 0
845       args: -hyb_dm_plex_check_faces
846     test:
847       suffix: 1
848       args: -dm_refine 1 -hyb_dm_plex_check_faces
849     test:
850       suffix: 2
851       nsize: 2
852       args: -hyb_dm_plex_check_faces
853     test:
854       suffix: 3
855       nsize: 2
856       args: -dm_refine 1 -hyb_dm_plex_check_faces
857     test:
858       suffix: 32
859       args: -dm_refine 1 -uninterpolate
860     test:
861       suffix: 33
862       nsize: 2
863       args: -dm_refine 1 -uninterpolate
864     test:
865       suffix: 34
866       nsize: 2
867       args: -dm_refine 3 -uninterpolate
868 
869   # 2D Hybrid Simplex 4-7
870   testset:
871     args: -dim 2 -hyb_dm_plex_check_all -in_dm_plex_check_all -dm_plex_check_all
872     test:
873       suffix: 4
874     test:
875       suffix: 5
876       args: -dm_refine 1
877     test:
878       suffix: 6
879       nsize: 2
880     test:
881       suffix: 7
882       nsize: 2
883       args: -dm_refine 1
884     test:
885       suffix: 24
886       args: -test_num 1 -dm_refine 1
887 
888   # 2D Quad 12-13
889   testset:
890     args: -dim 2 -cell_simplex 0 -cell_hybrid 0 -hyb_dm_plex_check_all -dm_plex_check_all
891     test:
892       suffix: 12
893       args: -dm_refine 1
894     test:
895       suffix: 13
896       nsize: 2
897       args: -dm_refine 1
898 
899   # 2D Hybrid Quad 27-28
900   testset:
901     args: -dim 2 -cell_simplex 0 -hyb_dm_plex_check_all -in_dm_plex_check_all -dm_plex_check_all
902     test:
903       suffix: 27
904       args: -dm_refine 1
905     test:
906       suffix: 28
907       nsize: 2
908       args: -dm_refine 1
909 
910   # 3D Simplex 8-11
911   testset:
912     args: -dim 3 -cell_hybrid 0 -hyb_dm_plex_check_all -dm_plex_check_all
913     test:
914       suffix: 8
915       args: -dm_refine 1
916     test:
917       suffix: 9
918       nsize: 2
919       args: -dm_refine 1
920     test:
921       suffix: 10
922       args: -test_num 1 -dm_refine 1
923     test:
924       suffix: 11
925       nsize: 2
926       args: -test_num 1 -dm_refine 1
927     test:
928       suffix: 25
929       args: -test_num 2 -dm_refine 2
930 
931   # 3D Hybrid Simplex 16-19
932   testset:
933     args: -dim 3 -hyb_dm_plex_check_all -in_dm_plex_check_all -dm_plex_check_all
934     test:
935       suffix: 16
936       args: -dm_refine 1
937     test:
938       suffix: 17
939       nsize: 2
940       args: -dm_refine 1
941     test:
942       suffix: 18
943       args: -test_num 1 -dm_refine 1
944     test:
945       suffix: 19
946       nsize: 2
947       args: -test_num 1 -dm_refine 1
948 
949   # 3D Hex 14-15
950   testset:
951     args: -dim 3 -cell_simplex 0 -cell_hybrid 0 -hyb_dm_plex_check_all -dm_plex_check_all
952     test:
953       suffix: 14
954       args: -dm_refine 1
955     test:
956       suffix: 15
957       nsize: 2
958      args: -dm_refine 1
959     test:
960       suffix: 26
961       args: -test_num 1 -dm_refine 2
962 
963   # 3D Hybrid Hex 20-23
964   testset:
965     args: -dim 3 -cell_simplex 0 -hyb_dm_plex_check_all -in_dm_plex_check_all -dm_plex_check_all
966     test:
967       suffix: 20
968       args: -dm_refine 1
969     test:
970       suffix: 21
971       nsize: 2
972       args: -dm_refine 1
973     test:
974       suffix: 22
975       args: -test_num 1 -dm_refine 1
976     test:
977       suffix: 23
978       nsize: 2
979       args: -test_num 1 -dm_refine 1
980 
981   # Hybrid interpolation
982   #   TODO Setup new tests (like -reinterpolate) that interpolate hybrid cells
983   testset:
984     nsize: 2
985     args: -test_partition 0 -petscpartitioner_type simple -dm_view -hyb_dm_plex_check_all -in_dm_plex_check_all -dm_plex_check_all
986     test:
987       suffix: hybint_2d_0
988       args: -dim 2 -dm_refine 2
989     test:
990       suffix: hybint_2d_1
991       args: -dim 2 -dm_refine 2 -test_num 1
992     test:
993       suffix: hybint_3d_0
994       args: -dim 3 -dm_refine 1
995     test:
996       suffix: hybint_3d_1
997       args: -dim 3 -dm_refine 1 -test_num 1
998 
999 TEST*/
1000