xref: /petsc/src/dm/impls/plex/tests/ex5.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
1c4762a1bSJed Brown static char help[] = "Tests for creation of hybrid meshes\n\n";
2c4762a1bSJed Brown 
3c4762a1bSJed Brown /* TODO
4c4762a1bSJed Brown  - Propagate hybridSize with distribution
5c4762a1bSJed Brown  - Test with multiple fault segments
6c4762a1bSJed Brown  - Test with embedded fault
7c4762a1bSJed Brown  - Test with multiple faults
8c4762a1bSJed Brown  - Move over all PyLith tests?
9c4762a1bSJed Brown */
10c4762a1bSJed Brown 
11c4762a1bSJed Brown #include <petscdmplex.h>
12b253942bSMatthew G. Knepley #include <petscds.h>
13b253942bSMatthew G. Knepley #include <petsc/private/dmpleximpl.h>
14c4762a1bSJed Brown /* List of test meshes
15c4762a1bSJed Brown 
16c4762a1bSJed Brown Triangle
17c4762a1bSJed Brown --------
18c4762a1bSJed Brown Test 0:
19c4762a1bSJed Brown Two triangles sharing a face
20c4762a1bSJed Brown 
21c4762a1bSJed Brown         4
22c4762a1bSJed Brown       / | \
23c4762a1bSJed Brown      8  |  9
24c4762a1bSJed Brown     /   |   \
25c4762a1bSJed Brown    2  0 7 1  5
26c4762a1bSJed Brown     \   |   /
27c4762a1bSJed Brown      6  |  10
28c4762a1bSJed Brown       \ | /
29c4762a1bSJed Brown         3
30c4762a1bSJed Brown 
31c4762a1bSJed Brown should become two triangles separated by a zero-volume cell with 4 vertices
32c4762a1bSJed Brown 
33c4762a1bSJed Brown         5--16--8              4--12--6 3
34c4762a1bSJed Brown       / |      | \          / |      | | \
35c4762a1bSJed Brown     11  |      |  12       9  |      | |  4
36c4762a1bSJed Brown     /   |      |   \      /   |      | |   \
37c4762a1bSJed Brown    3  0 10  2 14 1  6    2  0 8  1  10 6 0  1
38c4762a1bSJed Brown     \   |      |   /      \   |      | |   /
39c4762a1bSJed Brown      9  |      |  13       7  |      | |  5
40c4762a1bSJed Brown       \ |      | /          \ |      | | /
41c4762a1bSJed Brown         4--15--7              3--11--5 2
42c4762a1bSJed Brown 
43c4762a1bSJed Brown Test 1:
44c4762a1bSJed Brown Four triangles sharing two faces which are oriented against each other
45c4762a1bSJed Brown 
46c4762a1bSJed Brown           9
47c4762a1bSJed Brown          / \
48c4762a1bSJed Brown         /   \
49c4762a1bSJed Brown       17  2  16
50c4762a1bSJed Brown       /       \
51c4762a1bSJed Brown      /         \
52c4762a1bSJed Brown     8-----15----5
53c4762a1bSJed Brown      \         /|\
54c4762a1bSJed Brown       \       / | \
55c4762a1bSJed Brown       18  3  12 |  14
56c4762a1bSJed Brown         \   /   |   \
57c4762a1bSJed Brown          \ /    |    \
58c4762a1bSJed Brown           4  0 11  1  7
59c4762a1bSJed Brown            \    |    /
60c4762a1bSJed Brown             \   |   /
61c4762a1bSJed Brown             10  |  13
62c4762a1bSJed Brown               \ | /
63c4762a1bSJed Brown                \|/
64c4762a1bSJed Brown                 6
65c4762a1bSJed Brown 
66c4762a1bSJed Brown Fault mesh
67c4762a1bSJed Brown 
68c4762a1bSJed Brown 0 --> 0
69c4762a1bSJed Brown 1 --> 1
70c4762a1bSJed Brown 2 --> 2
71c4762a1bSJed Brown 3 --> 3
72c4762a1bSJed Brown 4 --> 5
73c4762a1bSJed Brown 5 --> 6
74c4762a1bSJed Brown 6 --> 8
75c4762a1bSJed Brown 7 --> 11
76c4762a1bSJed Brown 8 --> 15
77c4762a1bSJed Brown 
78c4762a1bSJed Brown        2
79c4762a1bSJed Brown        |
80c4762a1bSJed Brown   6----8----4
81c4762a1bSJed Brown        |    |
82c4762a1bSJed Brown        3    |
83c4762a1bSJed Brown           0-7-1
84c4762a1bSJed Brown             |
85c4762a1bSJed Brown             |
86c4762a1bSJed Brown             5
87c4762a1bSJed Brown 
88c4762a1bSJed Brown should become four triangles separated by two zero-volume cells with 4 vertices
89c4762a1bSJed Brown 
90c4762a1bSJed Brown           11
91c4762a1bSJed Brown           / \
92c4762a1bSJed Brown          /   \
93c4762a1bSJed Brown         /     \
94c4762a1bSJed Brown       22   2   21
95c4762a1bSJed Brown       /         \
96c4762a1bSJed Brown      /           \
97c4762a1bSJed Brown    10-----20------7
98c4762a1bSJed Brown 28  |     5    26/ \
99c4762a1bSJed Brown    14----25----12   \
100c4762a1bSJed Brown      \         /|   |\
101c4762a1bSJed Brown       \       / |   | \
102c4762a1bSJed Brown       23  3  17 |   |  19
103c4762a1bSJed Brown         \   /   |   |   \
104c4762a1bSJed Brown          \ /    |   |    \
105c4762a1bSJed Brown           6  0 24 4 16 1  9
106c4762a1bSJed Brown            \    |   |    /
107c4762a1bSJed Brown             \   |   |   /
108c4762a1bSJed Brown             15  |   |  18
109c4762a1bSJed Brown               \ |   | /
110c4762a1bSJed Brown                \|   |/
111c4762a1bSJed Brown                13---8
112c4762a1bSJed Brown                  27
113c4762a1bSJed Brown 
1145b9dfbb6SMatthew G. Knepley Test 2:
1155b9dfbb6SMatthew G. Knepley Six triangles sharing one face
1165b9dfbb6SMatthew G. Knepley 
1175b9dfbb6SMatthew G. Knepley 11-----12------13
1185b9dfbb6SMatthew G. Knepley  |     /|\     |
1195b9dfbb6SMatthew G. Knepley  | 1  / | \ 4  |
1205b9dfbb6SMatthew G. Knepley  |   /  |  \   |
1215b9dfbb6SMatthew G. Knepley  |  /   |   \  |
1225b9dfbb6SMatthew G. Knepley  | /    |    \ |
1235b9dfbb6SMatthew G. Knepley  |/     |     \|
1245b9dfbb6SMatthew G. Knepley  9  2   |   5  10
1255b9dfbb6SMatthew G. Knepley  |\     |     /|
1265b9dfbb6SMatthew G. Knepley  | \    |    / |
1275b9dfbb6SMatthew G. Knepley  |  \   |   /  |
1285b9dfbb6SMatthew G. Knepley  |   \  |  /   |
1295b9dfbb6SMatthew G. Knepley  | 0  \ | / 3  |
1305b9dfbb6SMatthew G. Knepley  |     \|/     |
1315b9dfbb6SMatthew G. Knepley  6------7------8
1325b9dfbb6SMatthew G. Knepley 
1335b9dfbb6SMatthew G. Knepley Test 3:
1345b9dfbb6SMatthew G. Knepley This is Test 2 on two processes. After the fault, we have
1355b9dfbb6SMatthew G. Knepley 
1365b9dfbb6SMatthew G. Knepley  6--12--7    7--20-10--16-8
1375b9dfbb6SMatthew G. Knepley  |     /|    |     |\     |
1385b9dfbb6SMatthew G. Knepley  | 1  / |    |     | \  1 |
1395b9dfbb6SMatthew G. Knepley 13  11  |    |     |  17  15
1405b9dfbb6SMatthew G. Knepley  |  /   |    |     |   \  |
1415b9dfbb6SMatthew G. Knepley  | /    |    |     |    \ |
1425b9dfbb6SMatthew G. Knepley  |/     |    |     |     \|
1435b9dfbb6SMatthew G. Knepley  5   2  14  11  3 18  2   6
1445b9dfbb6SMatthew G. Knepley  |\     |    |     |     /|
1455b9dfbb6SMatthew G. Knepley  | \    |    |     |    / |
1465b9dfbb6SMatthew G. Knepley  |  \   |    |     |   /  |
1475b9dfbb6SMatthew G. Knepley 10   9  |    |     |  14  13
1485b9dfbb6SMatthew G. Knepley  | 0  \ |    |     | /  0 |
1495b9dfbb6SMatthew G. Knepley  |     \|    |     |/     |
1505b9dfbb6SMatthew G. Knepley  3---8--4    4--19-9--12--5
1515b9dfbb6SMatthew G. Knepley 
1525b9dfbb6SMatthew G. Knepley Test 4:
1535b9dfbb6SMatthew G. Knepley This is Test 2 on six processes. After the fault, we have
1545b9dfbb6SMatthew G. Knepley 
1553bdf08b3SMatthew G. Knepley Test 5:
1563bdf08b3SMatthew G. Knepley 
1573bdf08b3SMatthew G. Knepley   Fault only on points 2 and 5:
1583bdf08b3SMatthew G. Knepley 
1593bdf08b3SMatthew G. Knepley         6
1603bdf08b3SMatthew G. Knepley       / | \
1613bdf08b3SMatthew G. Knepley     13  |  17
1623bdf08b3SMatthew G. Knepley     /  15   \
1633bdf08b3SMatthew G. Knepley    7  0 | 1  9
1643bdf08b3SMatthew G. Knepley    |\   |   /|
1653bdf08b3SMatthew G. Knepley    | 14 | 16 |
1663bdf08b3SMatthew G. Knepley    |  \ | /  |
1673bdf08b3SMatthew G. Knepley  18| 2  8  3 |21
1683bdf08b3SMatthew G. Knepley    |  / | \  |
1693bdf08b3SMatthew G. Knepley    | 19 | 20 |
1703bdf08b3SMatthew G. Knepley    |/   |   \|
1713bdf08b3SMatthew G. Knepley   10  4 | 5  12
1723bdf08b3SMatthew G. Knepley     \  23   /
1733bdf08b3SMatthew G. Knepley     22  |  24
1743bdf08b3SMatthew G. Knepley       \ | /
1753bdf08b3SMatthew G. Knepley        11
1763bdf08b3SMatthew G. Knepley 
177c4762a1bSJed Brown Tetrahedron
178c4762a1bSJed Brown -----------
179c4762a1bSJed Brown Test 0:
180c4762a1bSJed Brown Two tets sharing a face
181c4762a1bSJed Brown 
182c4762a1bSJed Brown  cell   5 _______    cell
183c4762a1bSJed Brown  0    / | \      \       1
184c4762a1bSJed Brown     16  |  18     22
185c4762a1bSJed Brown     /8 19 10\      \
186c4762a1bSJed Brown    2-15-|----4--21--6
187c4762a1bSJed Brown     \  9| 7 /      /
188c4762a1bSJed Brown     14  |  17     20
189c4762a1bSJed Brown       \ | /      /
190c4762a1bSJed Brown         3-------
191c4762a1bSJed Brown 
192c4762a1bSJed Brown should become two tetrahedrons separated by a zero-volume cell with 3 faces/3 edges/6 vertices
193c4762a1bSJed Brown 
194c4762a1bSJed Brown  cell   6 ___36___10______    cell
195c4762a1bSJed Brown  0    / | \        |\      \     1
196c4762a1bSJed Brown     24  |  26      | 32     30
197c4762a1bSJed Brown     /12 27 14\    33  \      \
198c4762a1bSJed Brown    3-23-|----5--35-|---9--29--7
199c4762a1bSJed Brown     \ 13| 11/      |18 /      /
200c4762a1bSJed Brown     22  |  25      | 31     28
201c4762a1bSJed Brown       \ | /        |/      /
202c4762a1bSJed Brown         4----34----8------
203c4762a1bSJed Brown          cell 2
204c4762a1bSJed Brown 
205c4762a1bSJed Brown In parallel,
206c4762a1bSJed Brown 
207c4762a1bSJed Brown  cell   5 ___28____8      4______    cell
208c4762a1bSJed Brown  0    / | \        |\     |\      \     0
209c4762a1bSJed Brown     19  |   21     | 24   | 13  6  11
210c4762a1bSJed Brown     /10 22 12\    25  \   |8 \      \
211c4762a1bSJed Brown    2-18-|----4--27-|---7  14  3--10--1
212c4762a1bSJed Brown     \ 11| 9 /      |13 /  |  /      /
213c4762a1bSJed Brown     17  |  20      | 23   | 12  5  9
214c4762a1bSJed Brown       \ | /        |/     |/      /
215c4762a1bSJed Brown         3----26----6      2------
216c4762a1bSJed Brown          cell 1
217c4762a1bSJed Brown 
218c4762a1bSJed Brown Test 1:
219c4762a1bSJed Brown Four tets sharing two faces
220c4762a1bSJed Brown 
221c4762a1bSJed Brown Cells:    0-3,4-5
222c4762a1bSJed Brown Vertices: 6-15
223c4762a1bSJed Brown Faces:    16-29,30-34
224c4762a1bSJed Brown Edges:    35-52,53-56
225c4762a1bSJed Brown 
226c4762a1bSJed Brown Quadrilateral
227c4762a1bSJed Brown -------------
228c4762a1bSJed Brown Test 0:
229c4762a1bSJed Brown Two quads sharing a face
230c4762a1bSJed Brown 
231c4762a1bSJed Brown    5--10---4--14---7
232c4762a1bSJed Brown    |       |       |
233c4762a1bSJed Brown   11   0   9   1  13
234c4762a1bSJed Brown    |       |       |
235c4762a1bSJed Brown    2---8---3--12---6
236c4762a1bSJed Brown 
237c4762a1bSJed Brown should become two quads separated by a zero-volume cell with 4 vertices
238c4762a1bSJed Brown 
239c4762a1bSJed Brown    6--13---5-20-10--17---8    5--10---4-14--7  4---7---2
240c4762a1bSJed Brown    |       |     |       |    |       |     |  |       |
241c4762a1bSJed Brown   14   0  12  2 18   1  16   11   0   9  1 12  8   0   6
242c4762a1bSJed Brown    |       |     |       |    |       |     |  |       |
243c4762a1bSJed Brown    3--11---4-19--9--15---7    2---8---3-13--6  3---5---1
244c4762a1bSJed Brown 
245c4762a1bSJed Brown Test 1:
246c4762a1bSJed Brown 
247c4762a1bSJed Brown Original mesh with 9 cells,
248c4762a1bSJed Brown 
2495b9dfbb6SMatthew G. Knepley   9-----10-----11-----12
2505b9dfbb6SMatthew G. Knepley   |      |     ||      |
2515b9dfbb6SMatthew G. Knepley   |      |     ||      |
2525b9dfbb6SMatthew G. Knepley   |   0  |  1  ||  2   |
2535b9dfbb6SMatthew G. Knepley   |      |     ||      |
2545b9dfbb6SMatthew G. Knepley  13-----14-----15-----16
2555b9dfbb6SMatthew G. Knepley   |      |     ||      |
2565b9dfbb6SMatthew G. Knepley   |      |     ||      |
2575b9dfbb6SMatthew G. Knepley   |  3   |  4  ||  5   |
2585b9dfbb6SMatthew G. Knepley   |      |     ||      |
2595b9dfbb6SMatthew G. Knepley  17-----18-----19=====20
260c4762a1bSJed Brown   |      |      |      |
261c4762a1bSJed Brown   |      |      |      |
2625b9dfbb6SMatthew G. Knepley   |  6   |  7   |  8   |
263c4762a1bSJed Brown   |      |      |      |
2645b9dfbb6SMatthew G. Knepley  21-----22-----23-----24
265c4762a1bSJed Brown 
266c4762a1bSJed Brown After first fault,
267c4762a1bSJed Brown 
268c4762a1bSJed Brown  12 ----13 ----14-28 ----15
269c4762a1bSJed Brown   |      |      |  |      |
270c4762a1bSJed Brown   |  0   |  1   | 9|  2   |
271c4762a1bSJed Brown   |      |      |  |      |
272c4762a1bSJed Brown   |      |      |  |      |
273c4762a1bSJed Brown  16 ----17 ----18-29 ----19
274c4762a1bSJed Brown   |      |      |  |      |
275c4762a1bSJed Brown   |  3   |  4   |10|  5   |
276c4762a1bSJed Brown   |      |      |  |      |
277c4762a1bSJed Brown   |      |      |  |      |
278c4762a1bSJed Brown  20 ----21-----22-30 ----23
279c4762a1bSJed Brown   |      |      |  \--11- |
280c4762a1bSJed Brown   |  6   |  7   |     8   |
281c4762a1bSJed Brown   |      |      |         |
282c4762a1bSJed Brown   |      |      |         |
283c4762a1bSJed Brown  24 ----25 ----26--------27
284c4762a1bSJed Brown 
285c4762a1bSJed Brown After second fault,
286c4762a1bSJed Brown 
287c4762a1bSJed Brown  14 ----15 ----16-30 ----17
288c4762a1bSJed Brown   |      |      |  |      |
289c4762a1bSJed Brown   |  0   |  1   | 9|  2   |
290c4762a1bSJed Brown   |      |      |  |      |
291c4762a1bSJed Brown   |      |      |  |      |
292c4762a1bSJed Brown  18 ----19 ----20-31 ----21
293c4762a1bSJed Brown   |      |      |  |      |
294c4762a1bSJed Brown   |  3   |  4   |10|  5   |
295c4762a1bSJed Brown   |      |      |  |      |
296c4762a1bSJed Brown   |      |      |  |      |
297c4762a1bSJed Brown  33 ----34-----24-32 ----25
298c4762a1bSJed Brown   |  12  | 13 / |  \-11-- |
299c4762a1bSJed Brown  22 ----23---/  |         |
3005b9dfbb6SMatthew G. Knepley   |      |      |         |
3015b9dfbb6SMatthew G. Knepley   |  6   |   7  |     8   |
302c4762a1bSJed Brown   |      |      |         |
303c4762a1bSJed Brown   |      |      |         |
304c4762a1bSJed Brown  26 ----27 ----28--------29
305c4762a1bSJed Brown 
3065b9dfbb6SMatthew G. Knepley  Test 2:
3075b9dfbb6SMatthew G. Knepley  Two quads sharing a face in parallel
3085b9dfbb6SMatthew G. Knepley 
3095b9dfbb6SMatthew G. Knepley     4---7---3  2---8---4
3105b9dfbb6SMatthew G. Knepley     |       |  |       |
3115b9dfbb6SMatthew G. Knepley     8   0   6  5   0   7
3125b9dfbb6SMatthew G. Knepley     |       |  |       |
3135b9dfbb6SMatthew G. Knepley     1---5---2  1---6---3
3145b9dfbb6SMatthew G. Knepley 
3155b9dfbb6SMatthew G. Knepley  should become two quads separated by a zero-volume cell with 4 vertices
3165b9dfbb6SMatthew G. Knepley 
3175b9dfbb6SMatthew G. Knepley      4---7---3  3-14--7--11---5
3185b9dfbb6SMatthew G. Knepley      |       |  |     |       |
3195b9dfbb6SMatthew G. Knepley      8   0   6  8  1  12  0   10
3205b9dfbb6SMatthew G. Knepley      |       |  |     |       |
3215b9dfbb6SMatthew G. Knepley      1---5---2  2-13--6---9---4
3225b9dfbb6SMatthew G. Knepley 
3235b9dfbb6SMatthew G. Knepley  Test 3:
3245b9dfbb6SMatthew G. Knepley  Like Test 2, but with different partition
3255b9dfbb6SMatthew G. Knepley 
3265b9dfbb6SMatthew G. Knepley      5--10---4-14--7   2---8---4
3275b9dfbb6SMatthew G. Knepley      |       |     |   |       |
3285b9dfbb6SMatthew G. Knepley     11   0   9  1  12  5   0   7
3295b9dfbb6SMatthew G. Knepley      |       |     |   |       |
3305b9dfbb6SMatthew G. Knepley      2---8---3-13--6   1---6---3
3315b9dfbb6SMatthew G. Knepley 
332c4762a1bSJed Brown Hexahedron
333c4762a1bSJed Brown ----------
334c4762a1bSJed Brown Test 0:
335c4762a1bSJed Brown Two hexes sharing a face
336c4762a1bSJed Brown 
337c4762a1bSJed Brown cell   9-----31------8-----42------13 cell
338c4762a1bSJed Brown 0     /|            /|            /|     1
339c4762a1bSJed Brown     32 |   15      30|   21      41|
340c4762a1bSJed Brown     /  |          /  |          /  |
341c4762a1bSJed Brown    6-----29------7-----40------12  |
342c4762a1bSJed Brown    |   |     18  |   |     24  |   |
343c4762a1bSJed Brown    |  36         |  35         |   44
344c4762a1bSJed Brown    |19 |         |17 |         |23 |
345c4762a1bSJed Brown   33   |  16    34   |   22   43   |
346c4762a1bSJed Brown    |   5-----27--|---4-----39--|---11
347c4762a1bSJed Brown    |  /          |  /          |  /
348c4762a1bSJed Brown    | 28   14     | 26    20    | 38
349c4762a1bSJed Brown    |/            |/            |/
350c4762a1bSJed Brown    2-----25------3-----37------10
351c4762a1bSJed Brown 
352c4762a1bSJed Brown should become two hexes separated by a zero-volume cell with 8 vertices
353c4762a1bSJed Brown 
354c4762a1bSJed Brown                          cell 2
355c4762a1bSJed Brown cell  10-----41------9-----62------18----52------14 cell
356c4762a1bSJed Brown 0     /|            /|            /|            /|     1
357c4762a1bSJed Brown     42 |   20      40|  32       56|   26      51|
358c4762a1bSJed Brown     /  |          /  |          /  |          /  |
359c4762a1bSJed Brown    7-----39------8-----61------17--|-50------13  |
360c4762a1bSJed Brown    |   |     23  |   |         |   |     29  |   |
361c4762a1bSJed Brown    |  46         |  45         |   58        |   54
362c4762a1bSJed Brown    |24 |         |22 |         |30 |         |28 |
363c4762a1bSJed Brown   43   |  21    44   |        57   |   27   53   |
364c4762a1bSJed Brown    |   6-----37--|---5-----60--|---16----49--|---12
365c4762a1bSJed Brown    |  /          |  /          |  /          |  /
366c4762a1bSJed Brown    | 38   19     | 36   31     | 55    25    | 48
367c4762a1bSJed Brown    |/            |/            |/            |/
368c4762a1bSJed Brown    3-----35------4-----59------15----47------11
369c4762a1bSJed Brown 
370c4762a1bSJed Brown In parallel,
371c4762a1bSJed Brown 
372c4762a1bSJed Brown                          cell 2
373c4762a1bSJed Brown cell   9-----31------8-----44------13     8----20------4  cell
374c4762a1bSJed Brown 0     /|            /|            /|     /|           /|     1
375c4762a1bSJed Brown     32 |   15      30|  22       38|   24 |  10      19|
376c4762a1bSJed Brown     /  |          /  |          /  |   /  |         /  |
377c4762a1bSJed Brown    6-----29------7-----43------12  |  7----18------3   |
378c4762a1bSJed Brown    |   |     18  |   |         |   |  |   |    13  |   |
379c4762a1bSJed Brown    |  36         |  35         |   40 |  26        |   22
380c4762a1bSJed Brown    |19 |         |17 |         |20 |  |14 |        |12 |
381c4762a1bSJed Brown   33   |  16    34   |        39   |  25  |  11   21   |
382c4762a1bSJed Brown    |   5-----27--|---4-----42--|---11 |   6----17--|---2
383c4762a1bSJed Brown    |  /          |  /          |  /   |  /         |  /
384c4762a1bSJed Brown    | 28   14     | 26   21     | 37   |23     9    | 16
385c4762a1bSJed Brown    |/            |/            |/     |/           |/
386c4762a1bSJed Brown    2-----25------3-----41------10     5----15------1
387c4762a1bSJed Brown 
388c4762a1bSJed Brown Test 1:
389c4762a1bSJed Brown 
390c4762a1bSJed Brown */
391c4762a1bSJed Brown 
392c4762a1bSJed Brown typedef struct {
393c4762a1bSJed Brown   PetscInt  debug;          /* The debugging level */
394c4762a1bSJed Brown   PetscInt  dim;            /* The topological mesh dimension */
395c4762a1bSJed Brown   PetscBool cellSimplex;    /* Use simplices or hexes */
396c4762a1bSJed Brown   PetscBool testPartition;  /* Use a fixed partitioning for testing */
397c4762a1bSJed Brown   PetscInt  testNum;        /* The particular mesh to test */
398b7519becSMatthew G. Knepley   PetscInt  cohesiveFields; /* The number of cohesive fields */
399c4762a1bSJed Brown } AppCtx;
400c4762a1bSJed Brown 
4019371c9d4SSatish Balay static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) {
402c4762a1bSJed Brown   PetscFunctionBegin;
403c4762a1bSJed Brown   options->debug          = 0;
404c4762a1bSJed Brown   options->dim            = 2;
405c4762a1bSJed Brown   options->cellSimplex    = PETSC_TRUE;
406c4762a1bSJed Brown   options->testPartition  = PETSC_TRUE;
407c4762a1bSJed Brown   options->testNum        = 0;
408b7519becSMatthew G. Knepley   options->cohesiveFields = 1;
409c4762a1bSJed Brown 
410d0609cedSBarry Smith   PetscOptionsBegin(comm, "", "Meshing Problem Options", "DMPLEX");
4119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-debug", "The debugging level", "ex5.c", options->debug, &options->debug, NULL, 0));
4129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsRangeInt("-dim", "The topological mesh dimension", "ex5.c", options->dim, &options->dim, NULL, 1, 3));
4139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-cell_simplex", "Use simplices if true, otherwise hexes", "ex5.c", options->cellSimplex, &options->cellSimplex, NULL));
4149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-test_partition", "Use a fixed partition for testing", "ex5.c", options->testPartition, &options->testPartition, NULL));
4159566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-test_num", "The particular mesh to test", "ex5.c", options->testNum, &options->testNum, NULL, 0));
4169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoundedInt("-cohesive_fields", "The number of cohesive fields", "ex5.c", options->cohesiveFields, &options->cohesiveFields, NULL, 0));
417d0609cedSBarry Smith   PetscOptionsEnd();
418c4762a1bSJed Brown   PetscFunctionReturn(0);
419c4762a1bSJed Brown }
420c4762a1bSJed Brown 
4219371c9d4SSatish Balay static PetscErrorCode CreateSimplex_2D(MPI_Comm comm, PetscInt testNum, DM *dm) {
422c4762a1bSJed Brown   DM          idm;
423c4762a1bSJed Brown   PetscInt    p;
424c4762a1bSJed Brown   PetscMPIInt rank;
425c4762a1bSJed Brown 
426c4762a1bSJed Brown   PetscFunctionBegin;
4279566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
428dd400576SPatrick Sanan   if (rank == 0) {
429c4762a1bSJed Brown     switch (testNum) {
4309371c9d4SSatish Balay     case 0: {
431c4762a1bSJed Brown       PetscInt    numPoints[2]        = {4, 2};
432c4762a1bSJed Brown       PetscInt    coneSize[6]         = {3, 3, 0, 0, 0, 0};
433c4762a1bSJed Brown       PetscInt    cones[6]            = {2, 3, 4, 5, 4, 3};
434c4762a1bSJed Brown       PetscInt    coneOrientations[6] = {0, 0, 0, 0, 0, 0};
435c4762a1bSJed Brown       PetscScalar vertexCoords[8]     = {-0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 0.5, 0.5};
436c4762a1bSJed Brown       PetscInt    markerPoints[8]     = {2, 1, 3, 1, 4, 1, 5, 1};
437c4762a1bSJed Brown       PetscInt    faultPoints[2]      = {3, 4};
438c4762a1bSJed Brown 
4399566063dSJacob Faibussowitsch       PetscCall(DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords));
4409566063dSJacob Faibussowitsch       for (p = 0; p < 4; ++p) PetscCall(DMSetLabelValue(*dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1]));
4419566063dSJacob Faibussowitsch       for (p = 0; p < 2; ++p) PetscCall(DMSetLabelValue(*dm, "fault", faultPoints[p], 1));
4429566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 0, 1));
4439566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 1, 2));
4449371c9d4SSatish Balay     } break;
4459371c9d4SSatish Balay     case 1: {
446c4762a1bSJed Brown       PetscInt    numPoints[2]         = {6, 4};
447c4762a1bSJed Brown       PetscInt    coneSize[10]         = {3, 3, 3, 3, 0, 0, 0, 0, 0, 0};
448c4762a1bSJed Brown       PetscInt    cones[12]            = {4, 6, 5, 5, 6, 7, 8, 5, 9, 8, 4, 5};
449c4762a1bSJed Brown       PetscInt    coneOrientations[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
450c4762a1bSJed Brown       PetscScalar vertexCoords[12]     = {-1.0, 0.0, 0.0, 1.0, 0.0, -1.0, 1.0, 0.0, -2.0, 1.0, -1.0, 2.0};
451c4762a1bSJed Brown       PetscInt    markerPoints[6]      = {4, 1, 6, 1, 8, 1};
452c4762a1bSJed Brown       PetscInt    faultPoints[3]       = {5, 6, 8};
453c4762a1bSJed Brown 
4549566063dSJacob Faibussowitsch       PetscCall(DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords));
4559566063dSJacob Faibussowitsch       for (p = 0; p < 3; ++p) PetscCall(DMSetLabelValue(*dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1]));
4569566063dSJacob Faibussowitsch       for (p = 0; p < 3; ++p) PetscCall(DMSetLabelValue(*dm, "fault", faultPoints[p], 1));
4579371c9d4SSatish Balay       PetscCall(DMSetLabelValue(*dm, "material", 0, 1));
4589371c9d4SSatish Balay       PetscCall(DMSetLabelValue(*dm, "material", 3, 1));
4599371c9d4SSatish Balay       PetscCall(DMSetLabelValue(*dm, "material", 1, 2));
4609371c9d4SSatish Balay       PetscCall(DMSetLabelValue(*dm, "material", 2, 2));
4619371c9d4SSatish Balay     } break;
4625b9dfbb6SMatthew G. Knepley     case 2:
4635b9dfbb6SMatthew G. Knepley     case 3:
4649371c9d4SSatish Balay     case 4: {
4655b9dfbb6SMatthew G. Knepley       PetscInt    numPoints[2]         = {8, 6};
4665b9dfbb6SMatthew G. Knepley       PetscInt    coneSize[14]         = {3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0};
4679371c9d4SSatish Balay       PetscInt    cones[18]            = {6, 7, 9, 9, 12, 11, 7, 12, 9, 7, 8, 10, 10, 13, 12, 7, 10, 12};
4685b9dfbb6SMatthew G. Knepley       PetscInt    coneOrientations[18] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
4699371c9d4SSatish Balay       PetscScalar vertexCoords[16]     = {
4709371c9d4SSatish Balay             -1., -1., 0., -1., 1., -1., -1., 0., 1., 0., -1., 1., 0., 1., 1., 1.,
4719371c9d4SSatish Balay       };
4725b9dfbb6SMatthew G. Knepley       PetscInt markerPoints[16] = {6, 1, 7, 1, 8, 1, 9, 1, 10, 1, 11, 1, 12, 1, 13, 1};
4735b9dfbb6SMatthew G. Knepley       PetscInt faultPoints[2]   = {7, 12};
4745b9dfbb6SMatthew G. Knepley 
4755b9dfbb6SMatthew G. Knepley       PetscCall(DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords));
4765b9dfbb6SMatthew G. Knepley       PetscCall(DMSetLabelValue(*dm, "material", 0, 1));
4775b9dfbb6SMatthew G. Knepley       PetscCall(DMSetLabelValue(*dm, "material", 1, 1));
4785b9dfbb6SMatthew G. Knepley       PetscCall(DMSetLabelValue(*dm, "material", 2, 1));
4795b9dfbb6SMatthew G. Knepley       PetscCall(DMSetLabelValue(*dm, "material", 3, 2));
4805b9dfbb6SMatthew G. Knepley       PetscCall(DMSetLabelValue(*dm, "material", 4, 2));
4815b9dfbb6SMatthew G. Knepley       PetscCall(DMSetLabelValue(*dm, "material", 5, 2));
4825b9dfbb6SMatthew G. Knepley       for (p = 0; p < 8; ++p) PetscCall(DMSetLabelValue(*dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1]));
4839371c9d4SSatish Balay       if (testNum == 2)
4849371c9d4SSatish Balay         for (p = 0; p < 2; ++p) PetscCall(DMSetLabelValue(*dm, "fault", faultPoints[p], 1));
4859371c9d4SSatish Balay       if (testNum == 3 || testNum == 4)
4869371c9d4SSatish Balay         for (p = 0; p < 2; ++p) PetscCall(DMSetLabelValue(*dm, "pfault", faultPoints[p], 1));
4879371c9d4SSatish Balay     } break;
4889371c9d4SSatish Balay     case 5: {
4893bdf08b3SMatthew G. Knepley       PetscInt    numPoints[2]         = {7, 6};
4903bdf08b3SMatthew G. Knepley       PetscInt    coneSize[13]         = {3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0};
4913bdf08b3SMatthew G. Knepley       PetscInt    cones[18]            = {6, 7, 8, 8, 9, 6, 7, 10, 8, 9, 8, 12, 8, 10, 11, 11, 12, 8};
4923bdf08b3SMatthew G. Knepley       PetscInt    coneOrientations[18] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
4933bdf08b3SMatthew G. Knepley       PetscScalar vertexCoords[14]     = {0.0, 2.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, -1.0, -1.0, 0.0, -2.0, 1.0, -1.0};
4943bdf08b3SMatthew G. Knepley       PetscInt    faultPoints[2]       = {8, 11};
4953bdf08b3SMatthew G. Knepley       PetscInt    faultBdPoints[1]     = {8};
4963bdf08b3SMatthew G. Knepley 
4973bdf08b3SMatthew G. Knepley       PetscCall(DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords));
4983bdf08b3SMatthew G. Knepley       for (p = 0; p < 2; ++p) PetscCall(DMSetLabelValue(*dm, "fault", faultPoints[p], 1));
4993bdf08b3SMatthew G. Knepley       for (p = 0; p < 1; ++p) PetscCall(DMSetLabelValue(*dm, "faultBd", faultBdPoints[p], 1));
5009371c9d4SSatish Balay       PetscCall(DMSetLabelValue(*dm, "material", 0, 0));
5019371c9d4SSatish Balay       PetscCall(DMSetLabelValue(*dm, "material", 2, 0));
5029371c9d4SSatish Balay       PetscCall(DMSetLabelValue(*dm, "material", 4, 0));
5039371c9d4SSatish Balay       PetscCall(DMSetLabelValue(*dm, "material", 1, 2));
5049371c9d4SSatish Balay       PetscCall(DMSetLabelValue(*dm, "material", 3, 2));
5059371c9d4SSatish Balay       PetscCall(DMSetLabelValue(*dm, "material", 5, 2));
5069371c9d4SSatish Balay     } break;
5079371c9d4SSatish Balay     default: SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %" PetscInt_FMT, testNum);
508c4762a1bSJed Brown     }
509c4762a1bSJed Brown   } else {
510c4762a1bSJed Brown     PetscInt numPoints[3] = {0, 0, 0};
511c4762a1bSJed Brown 
5129566063dSJacob Faibussowitsch     PetscCall(DMPlexCreateFromDAG(*dm, 1, numPoints, NULL, NULL, NULL, NULL));
5135b9dfbb6SMatthew G. Knepley     if (testNum == 3 || testNum == 4) PetscCall(DMCreateLabel(*dm, "pfault"));
5145b9dfbb6SMatthew G. Knepley     else PetscCall(DMCreateLabel(*dm, "fault"));
515c4762a1bSJed Brown   }
5169566063dSJacob Faibussowitsch   PetscCall(DMPlexInterpolate(*dm, &idm));
5179566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(idm, NULL, "-in_dm_view"));
5189566063dSJacob Faibussowitsch   PetscCall(DMDestroy(dm));
519c4762a1bSJed Brown   *dm = idm;
520c4762a1bSJed Brown   PetscFunctionReturn(0);
521c4762a1bSJed Brown }
522c4762a1bSJed Brown 
5239371c9d4SSatish Balay static PetscErrorCode CreateSimplex_3D(MPI_Comm comm, AppCtx *user, DM dm) {
524c4762a1bSJed Brown   PetscInt    depth = 3, testNum = user->testNum, p;
525c4762a1bSJed Brown   PetscMPIInt rank;
526c4762a1bSJed Brown 
527c4762a1bSJed Brown   PetscFunctionBegin;
5289566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
529dd400576SPatrick Sanan   if (rank == 0) {
530c4762a1bSJed Brown     switch (testNum) {
5319371c9d4SSatish Balay     case 0: {
532c4762a1bSJed Brown       PetscInt    numPoints[4]         = {5, 7, 9, 2};
533c4762a1bSJed Brown       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};
534c4762a1bSJed Brown       PetscInt    cones[47]            = {7, 8, 9, 10, 11, 10, 13, 12, 15, 17, 14, 16, 18, 15, 14, 19, 16, 17, 18, 19, 17, 21, 20, 18, 22, 21, 22, 19, 20, 2, 3, 2, 4, 2, 5, 3, 4, 4, 5, 5, 3, 3, 6, 4, 6, 5, 6};
535b5a892a1SMatthew G. Knepley       PetscInt    coneOrientations[47] = {0, 0, 0, 0, 0, -2, 2, 2, 0, -1, -1, 0, -1, -1, 0, -1, -1, 0, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
536c4762a1bSJed Brown       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};
537c4762a1bSJed Brown       PetscInt    markerPoints[20]     = {2, 1, 3, 1, 4, 1, 5, 1, 14, 1, 15, 1, 16, 1, 17, 1, 18, 1, 19, 1};
538c4762a1bSJed Brown       PetscInt    faultPoints[3]       = {3, 4, 5};
539c4762a1bSJed Brown 
5409566063dSJacob Faibussowitsch       PetscCall(DMPlexCreateFromDAG(dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords));
541*48a46eb9SPierre Jolivet       for (p = 0; p < 10; ++p) PetscCall(DMSetLabelValue(dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1]));
542*48a46eb9SPierre Jolivet       for (p = 0; p < 3; ++p) PetscCall(DMSetLabelValue(dm, "fault", faultPoints[p], 1));
5439566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(dm, "material", 0, 1));
5449566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(dm, "material", 1, 2));
5459371c9d4SSatish Balay     } break;
5469371c9d4SSatish Balay     case 1: {
547c4762a1bSJed Brown       PetscInt    numPoints[4]         = {6, 13, 12, 4};
548c4762a1bSJed Brown       PetscInt    coneSize[35]         = {4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
5499371c9d4SSatish Balay       PetscInt    cones[78]            = {10, 11, 12, 13, 10, 15, 16, 14, 17, 18, 14, 19, 20, 13, 19, 21, 22, 23, 24, 25, 26, 22, 24, 27, 25, 23, 26, 27, 28, 29, 23, 24, 30, 28, 22, 29, 30, 31, 32,
5509371c9d4SSatish Balay                                           28, 29, 33, 31, 32, 33, 23, 26, 34, 33, 34, 27, 32, 6,  5,  5,  7,  7,  6,  6,  4,  4,  5,  7,  4,  7,  9,  9,  5,  6,  9,  9,  8,  8,  7,  5,  8,  4,  8};
5519371c9d4SSatish Balay       PetscInt    coneOrientations[78] = {0, 0, 0, 0,  -2, 1,  0, 2,  0, 0,  -3, 0,  0,  -3, -1, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, -1, 0, -1, -1, 0, 0,
5529371c9d4SSatish Balay                                           0, 0, 0, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, 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};
553c4762a1bSJed Brown       PetscScalar vertexCoords[18]     = {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0};
554c4762a1bSJed Brown       PetscInt    markerPoints[14]     = {5, 1, 6, 1, 7, 1, 10, 1, 22, 1, 23, 1, 24, 1};
555c4762a1bSJed Brown       PetscInt    faultPoints[4]       = {5, 6, 7, 8};
556c4762a1bSJed Brown 
5579566063dSJacob Faibussowitsch       PetscCall(DMPlexCreateFromDAG(dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords));
558*48a46eb9SPierre Jolivet       for (p = 0; p < 7; ++p) PetscCall(DMSetLabelValue(dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1]));
559*48a46eb9SPierre Jolivet       for (p = 0; p < 4; ++p) PetscCall(DMSetLabelValue(dm, "fault", faultPoints[p], 1));
5609566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(dm, "material", 0, 1));
5619566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(dm, "material", 1, 2));
5629371c9d4SSatish Balay     } break;
5639371c9d4SSatish Balay     default: SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %" PetscInt_FMT, testNum);
564c4762a1bSJed Brown     }
565c4762a1bSJed Brown   } else {
566c4762a1bSJed Brown     PetscInt numPoints[4] = {0, 0, 0, 0};
567c4762a1bSJed Brown 
5689566063dSJacob Faibussowitsch     PetscCall(DMPlexCreateFromDAG(dm, depth, numPoints, NULL, NULL, NULL, NULL));
5699566063dSJacob Faibussowitsch     PetscCall(DMCreateLabel(dm, "fault"));
570c4762a1bSJed Brown   }
571c4762a1bSJed Brown   PetscFunctionReturn(0);
572c4762a1bSJed Brown }
573c4762a1bSJed Brown 
5749371c9d4SSatish Balay static PetscErrorCode CreateQuad_2D(MPI_Comm comm, PetscInt testNum, DM *dm) {
575c4762a1bSJed Brown   DM          idm;
576c4762a1bSJed Brown   PetscInt    p;
577c4762a1bSJed Brown   PetscMPIInt rank;
578c4762a1bSJed Brown 
579c4762a1bSJed Brown   PetscFunctionBegin;
5809566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
581dd400576SPatrick Sanan   if (rank == 0) {
582c4762a1bSJed Brown     switch (testNum) {
583c4762a1bSJed Brown     case 0:
584c4762a1bSJed Brown     case 2:
5859371c9d4SSatish Balay     case 3: {
586c4762a1bSJed Brown       PetscInt    numPoints[2]        = {6, 2};
587c4762a1bSJed Brown       PetscInt    coneSize[8]         = {4, 4, 0, 0, 0, 0, 0, 0};
588c4762a1bSJed Brown       PetscInt    cones[8]            = {2, 3, 4, 5, 3, 6, 7, 4};
589c4762a1bSJed Brown       PetscInt    coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0};
590c4762a1bSJed Brown       PetscScalar vertexCoords[12]    = {-0.5, 0.0, 0.0, 0.0, 0.0, 1.0, -0.5, 1.0, 0.5, 0.0, 0.5, 1.0};
591c4762a1bSJed Brown       PetscInt    markerPoints[12]    = {2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1};
592c4762a1bSJed Brown       PetscInt    faultPoints[2]      = {3, 4};
593c4762a1bSJed Brown 
5949566063dSJacob Faibussowitsch       PetscCall(DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords));
5959566063dSJacob Faibussowitsch       for (p = 0; p < 6; ++p) PetscCall(DMSetLabelValue(*dm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1]));
5969371c9d4SSatish Balay       if (testNum == 0)
5979371c9d4SSatish Balay         for (p = 0; p < 2; ++p) PetscCall(DMSetLabelValue(*dm, "fault", faultPoints[p], 1));
5989371c9d4SSatish Balay       if (testNum == 2 || testNum == 3)
5999371c9d4SSatish Balay         for (p = 0; p < 2; ++p) PetscCall(DMSetLabelValue(*dm, "pfault", faultPoints[p], 1));
6009566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 0, 1));
6019566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 1, 2));
6029371c9d4SSatish Balay     } break;
6039371c9d4SSatish Balay     case 1: {
604c4762a1bSJed Brown       PetscInt    numPoints[2]         = {16, 9};
605c4762a1bSJed Brown       PetscInt    coneSize[25]         = {4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
6069371c9d4SSatish Balay       PetscInt    cones[36]            = {9, 13, 14, 10, 10, 14, 15, 11, 11, 15, 16, 12, 13, 17, 18, 14, 14, 18, 19, 15, 15, 19, 20, 16, 17, 21, 22, 18, 18, 22, 23, 19, 19, 23, 24, 20};
607c4762a1bSJed Brown       PetscInt    coneOrientations[36] = {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};
6089371c9d4SSatish Balay       PetscScalar vertexCoords[32]     = {-3.0, 3.0, -1.0, 3.0, 1.0, 3.0, 3.0, 3.0, -3.0, 1.0, -1.0, 1.0, 1.0, 1.0, 3.0, 1.0, -3.0, -1.0, -1.0, -1.0, 1.0, -1.0, 3.0, -1.0, -3.0, -3.0, -1.0, -3.0, 1.0, -3.0, 3.0, -3.0};
6095b9dfbb6SMatthew G. Knepley       PetscInt    faultPoints[4]       = {11, 15, 19, 20};
610c4762a1bSJed Brown       PetscInt    fault2Points[2]      = {17, 18};
611c4762a1bSJed Brown 
6129566063dSJacob Faibussowitsch       PetscCall(DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords));
6135b9dfbb6SMatthew G. Knepley       for (p = 0; p < 4; ++p) PetscCall(DMSetLabelValue(*dm, "fault", faultPoints[p], 1));
6145b9dfbb6SMatthew G. Knepley       for (p = 3; p < 4; ++p) PetscCall(DMSetLabelValue(*dm, "faultBd", faultPoints[p], 1));
6159566063dSJacob Faibussowitsch       for (p = 0; p < 2; ++p) PetscCall(DMSetLabelValue(*dm, "fault2", fault2Points[p], 1));
6169566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 0, 1));
6179566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 1, 1));
6189566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 2, 1));
6199566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 3, 1));
6209566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 4, 1));
6219566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 5, 2));
6229566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 6, 2));
6239566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 7, 2));
6249566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 8, 2));
6259371c9d4SSatish Balay     } break;
6269371c9d4SSatish Balay     default: SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %" PetscInt_FMT, testNum);
627c4762a1bSJed Brown     }
628c4762a1bSJed Brown   } else {
629c4762a1bSJed Brown     PetscInt numPoints[3] = {0, 0, 0};
630c4762a1bSJed Brown 
6319566063dSJacob Faibussowitsch     PetscCall(DMPlexCreateFromDAG(*dm, 1, numPoints, NULL, NULL, NULL, NULL));
6325b9dfbb6SMatthew G. Knepley     if (testNum == 2 || testNum == 3) PetscCall(DMCreateLabel(*dm, "pfault"));
6339566063dSJacob Faibussowitsch     else PetscCall(DMCreateLabel(*dm, "fault"));
634c4762a1bSJed Brown   }
6359566063dSJacob Faibussowitsch   PetscCall(DMPlexInterpolate(*dm, &idm));
6369566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(idm, NULL, "-in_dm_view"));
6379566063dSJacob Faibussowitsch   PetscCall(DMDestroy(dm));
638c4762a1bSJed Brown   *dm = idm;
639c4762a1bSJed Brown   PetscFunctionReturn(0);
640c4762a1bSJed Brown }
641c4762a1bSJed Brown 
6429371c9d4SSatish Balay static PetscErrorCode CreateHex_3D(MPI_Comm comm, PetscInt testNum, DM *dm) {
643c4762a1bSJed Brown   DM          idm;
644c4762a1bSJed Brown   PetscInt    depth = 3, p;
645c4762a1bSJed Brown   PetscMPIInt rank;
646c4762a1bSJed Brown 
647c4762a1bSJed Brown   PetscFunctionBegin;
6489566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
649dd400576SPatrick Sanan   if (rank == 0) {
650c4762a1bSJed Brown     switch (testNum) {
6519371c9d4SSatish Balay     case 0: {
652c4762a1bSJed Brown       PetscInt    numPoints[2]         = {12, 2};
653c4762a1bSJed Brown       PetscInt    coneSize[14]         = {8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
654c4762a1bSJed Brown       PetscInt    cones[16]            = {2, 5, 4, 3, 6, 7, 8, 9, 3, 4, 11, 10, 7, 12, 13, 8};
655c4762a1bSJed Brown       PetscInt    coneOrientations[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
6569371c9d4SSatish Balay       PetscScalar vertexCoords[36]     = {-0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.5, 1.0, 0.0, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, -0.5, 1.0, 1.0, 0.5, 0.0, 0.0, 0.5, 1.0, 0.0, 0.5, 0.0, 1.0, 0.5, 1.0, 1.0};
657c4762a1bSJed Brown       PetscInt    markerPoints[52]     = {2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1};
658c4762a1bSJed Brown       PetscInt    faultPoints[4]       = {3, 4, 7, 8};
659c4762a1bSJed Brown 
6609566063dSJacob Faibussowitsch       PetscCall(DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords));
6619566063dSJacob Faibussowitsch       PetscCall(DMPlexInterpolate(*dm, &idm));
6629566063dSJacob Faibussowitsch       for (p = 0; p < 8; ++p) PetscCall(DMSetLabelValue(idm, "marker", markerPoints[p * 2], markerPoints[p * 2 + 1]));
6639566063dSJacob Faibussowitsch       for (p = 0; p < 4; ++p) PetscCall(DMSetLabelValue(idm, "fault", faultPoints[p], 1));
6649566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 0, 1));
6659566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 1, 2));
6669371c9d4SSatish Balay     } break;
6679371c9d4SSatish Balay     case 1: {
668c4762a1bSJed Brown       /* Cell Adjacency Graph:
669c4762a1bSJed Brown         0 -- { 8, 13, 21, 24} --> 1
670c4762a1bSJed Brown         0 -- {20, 21, 23, 24} --> 5 F
671c4762a1bSJed Brown         1 -- {10, 15, 21, 24} --> 2
672c4762a1bSJed Brown         1 -- {13, 14, 15, 24} --> 6
673c4762a1bSJed Brown         2 -- {21, 22, 24, 25} --> 4 F
674c4762a1bSJed Brown         3 -- {21, 24, 30, 35} --> 4
675c4762a1bSJed Brown         3 -- {21, 24, 28, 33} --> 5
676c4762a1bSJed Brown        */
677c4762a1bSJed Brown       PetscInt numPoints[2] = {30, 7};
678c4762a1bSJed Brown       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};
6799371c9d4SSatish Balay       PetscInt cones[56] = {8, 21, 20, 7, 13, 12, 23, 24, 14, 15, 10, 9, 13, 8, 21, 24, 15, 16, 11, 10, 24, 21, 22, 25, 30, 29, 28, 21, 35, 24, 33, 34, 24, 21, 30, 35, 25, 36, 31, 22, 27, 20, 21, 28, 32, 33, 24, 23, 15, 24, 13, 14, 19, 18, 17, 26};
680c4762a1bSJed Brown       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};
6819371c9d4SSatish Balay       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,  -2.0, -1.0, 0.0, -3.0, 0.0, 0.0, -2.0, 1.0, 0.0, -2.0, 2.0, 0.0,
6829371c9d4SSatish Balay                                        -2.0, -1.0, 2.0,  -3.0, 0.0,  2.0,  -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, 0.0,  2.0, 0.0, 0.0,  0.0, 2.0,
6839371c9d4SSatish Balay                                        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,  2.0,  -1.0, 0.0, 3.0,  0.0, 0.0, 2.0,  1.0, 0.0, 2.0,  2.0, 0.0};
684c4762a1bSJed Brown       PetscInt    faultPoints[6]    = {20, 21, 22, 23, 24, 25};
685c4762a1bSJed Brown 
6869566063dSJacob Faibussowitsch       PetscCall(DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords));
6879566063dSJacob Faibussowitsch       PetscCall(DMPlexInterpolate(*dm, &idm));
6889566063dSJacob Faibussowitsch       for (p = 0; p < 6; ++p) PetscCall(DMSetLabelValue(idm, "fault", faultPoints[p], 1));
6899566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 0, 1));
6909566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 1, 1));
6919566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 2, 1));
6929566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 3, 2));
6939566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 4, 2));
6949566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 5, 2));
6959566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 6, 2));
6969371c9d4SSatish Balay     } break;
6979371c9d4SSatish Balay     case 2: {
698c4762a1bSJed Brown       /* Buried fault edge */
699c4762a1bSJed Brown       PetscInt    numPoints[2]         = {18, 4};
700c4762a1bSJed Brown       PetscInt    coneSize[22]         = {8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
7019371c9d4SSatish Balay       PetscInt    cones[32]            = {4, 5, 8, 7, 13, 16, 17, 14, 5, 6, 9, 8, 14, 17, 18, 15, 7, 8, 11, 10, 16, 19, 20, 17, 8, 9, 12, 11, 17, 20, 21, 18};
702c4762a1bSJed Brown       PetscInt    coneOrientations[32] = {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};
7039371c9d4SSatish Balay       PetscScalar vertexCoords[54]     = {-2.0, -2.0, 0.0, -2.0, 0.0, 0.0, -2.0, 2.0, 0.0, 0.0, -2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, 2.0, -2.0, 0.0, 2.0, 0.0, 0.0, 2.0, 2.0, 0.0,
7049371c9d4SSatish Balay                                           -2.0, -2.0, 2.0, -2.0, 0.0, 2.0, -2.0, 2.0, 2.0, 0.0, -2.0, 2.0, 0.0, 0.0, 2.0, 0.0, 2.0, 2.0, 2.0, -2.0, 2.0, 2.0, 0.0, 2.0, 2.0, 2.0, 2.0};
705c4762a1bSJed Brown       PetscInt    faultPoints[4]       = {7, 8, 16, 17};
706c4762a1bSJed Brown 
7079566063dSJacob Faibussowitsch       PetscCall(DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords));
7089566063dSJacob Faibussowitsch       PetscCall(DMPlexInterpolate(*dm, &idm));
7099566063dSJacob Faibussowitsch       for (p = 0; p < 4; ++p) PetscCall(DMSetLabelValue(idm, "fault", faultPoints[p], 1));
7109566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 0, 1));
7119566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 1, 1));
7129566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 2, 2));
7139566063dSJacob Faibussowitsch       PetscCall(DMSetLabelValue(*dm, "material", 3, 2));
7149371c9d4SSatish Balay     } break;
71563a3b9bcSJacob Faibussowitsch     default: SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %" PetscInt_FMT, testNum);
716c4762a1bSJed Brown     }
717c4762a1bSJed Brown   } else {
718c4762a1bSJed Brown     PetscInt numPoints[4] = {0, 0, 0, 0};
719c4762a1bSJed Brown 
7209566063dSJacob Faibussowitsch     PetscCall(DMPlexCreateFromDAG(*dm, depth, numPoints, NULL, NULL, NULL, NULL));
7219566063dSJacob Faibussowitsch     PetscCall(DMPlexInterpolate(*dm, &idm));
7229566063dSJacob Faibussowitsch     PetscCall(DMCreateLabel(idm, "fault"));
723c4762a1bSJed Brown   }
7249566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(idm, NULL, "-in_dm_view"));
7259566063dSJacob Faibussowitsch   PetscCall(DMDestroy(dm));
726c4762a1bSJed Brown   *dm = idm;
727c4762a1bSJed Brown   PetscFunctionReturn(0);
728c4762a1bSJed Brown }
729c4762a1bSJed Brown 
7309371c9d4SSatish Balay static PetscErrorCode CreateFaultLabel(DM dm) {
731b253942bSMatthew G. Knepley   DMLabel  label;
732b253942bSMatthew G. Knepley   PetscInt dim, h, pStart, pEnd, pMax, p;
733b253942bSMatthew G. Knepley 
734b253942bSMatthew G. Knepley   PetscFunctionBegin;
7359566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
7369566063dSJacob Faibussowitsch   PetscCall(DMCreateLabel(dm, "cohesive"));
7379566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(dm, "cohesive", &label));
738b253942bSMatthew G. Knepley   for (h = 0; h <= dim; ++h) {
7399566063dSJacob Faibussowitsch     PetscCall(DMPlexGetSimplexOrBoxCells(dm, h, NULL, &pMax));
7409566063dSJacob Faibussowitsch     PetscCall(DMPlexGetHeightStratum(dm, h, &pStart, &pEnd));
7419566063dSJacob Faibussowitsch     for (p = pMax; p < pEnd; ++p) PetscCall(DMLabelSetValue(label, p, 1));
742b253942bSMatthew G. Knepley   }
743b253942bSMatthew G. Knepley   PetscFunctionReturn(0);
744b253942bSMatthew G. Knepley }
745b253942bSMatthew G. Knepley 
7469371c9d4SSatish Balay static PetscErrorCode CreateDiscretization(DM dm, AppCtx *user) {
747b253942bSMatthew G. Knepley   PetscFE  fe;
748b253942bSMatthew G. Knepley   DMLabel  fault;
749b7519becSMatthew G. Knepley   PetscInt dim, Ncf = user->cohesiveFields, f;
750b253942bSMatthew G. Knepley 
751b253942bSMatthew G. Knepley   PetscFunctionBegin;
7529566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
7539566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(dm, "cohesive", &fault));
7549566063dSJacob Faibussowitsch   PetscCall(DMLabelView(fault, PETSC_VIEWER_STDOUT_WORLD));
755b253942bSMatthew G. Knepley 
7569566063dSJacob Faibussowitsch   PetscCall(PetscFECreateDefault(PETSC_COMM_SELF, dim, dim, user->cellSimplex, "displacement_", PETSC_DETERMINE, &fe));
7579566063dSJacob Faibussowitsch   PetscCall(PetscFESetName(fe, "displacement"));
7589566063dSJacob Faibussowitsch   PetscCall(DMAddField(dm, NULL, (PetscObject)fe));
7599566063dSJacob Faibussowitsch   PetscCall(PetscFEDestroy(&fe));
760b253942bSMatthew G. Knepley 
761b7519becSMatthew G. Knepley   if (Ncf > 0) {
7629566063dSJacob Faibussowitsch     PetscCall(PetscFECreateDefault(PETSC_COMM_SELF, dim - 1, dim, user->cellSimplex, "faulttraction_", PETSC_DETERMINE, &fe));
7639566063dSJacob Faibussowitsch     PetscCall(PetscFESetName(fe, "fault traction"));
7649566063dSJacob Faibussowitsch     PetscCall(DMAddField(dm, fault, (PetscObject)fe));
7659566063dSJacob Faibussowitsch     PetscCall(PetscFEDestroy(&fe));
766b7519becSMatthew G. Knepley   }
767b7519becSMatthew G. Knepley   for (f = 1; f < Ncf; ++f) {
768b7519becSMatthew G. Knepley     char name[256], opt[256];
769b7519becSMatthew G. Knepley 
77063a3b9bcSJacob Faibussowitsch     PetscCall(PetscSNPrintf(name, 256, "fault field %" PetscInt_FMT, f));
77163a3b9bcSJacob Faibussowitsch     PetscCall(PetscSNPrintf(opt, 256, "faultfield_%" PetscInt_FMT "_", f));
7729566063dSJacob Faibussowitsch     PetscCall(PetscFECreateDefault(PETSC_COMM_SELF, dim - 1, dim, user->cellSimplex, opt, PETSC_DETERMINE, &fe));
7739566063dSJacob Faibussowitsch     PetscCall(PetscFESetName(fe, name));
7749566063dSJacob Faibussowitsch     PetscCall(DMAddField(dm, fault, (PetscObject)fe));
7759566063dSJacob Faibussowitsch     PetscCall(PetscFEDestroy(&fe));
776b7519becSMatthew G. Knepley   }
777b253942bSMatthew G. Knepley 
7789566063dSJacob Faibussowitsch   PetscCall(DMCreateDS(dm));
779b253942bSMatthew G. Knepley   PetscFunctionReturn(0);
780b253942bSMatthew G. Knepley }
781b253942bSMatthew G. Knepley 
7829371c9d4SSatish Balay static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) {
783c4762a1bSJed Brown   PetscInt    dim         = user->dim;
784c4762a1bSJed Brown   PetscBool   cellSimplex = user->cellSimplex, hasFault, hasFault2, hasParallelFault;
785c4762a1bSJed Brown   PetscMPIInt rank, size;
786dd96b1f9SToby Isaac   DMLabel     matLabel;
787c4762a1bSJed Brown 
788c4762a1bSJed Brown   PetscFunctionBegin;
7899566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
7909566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
7919566063dSJacob Faibussowitsch   PetscCall(DMCreate(comm, dm));
7929566063dSJacob Faibussowitsch   PetscCall(DMSetType(*dm, DMPLEX));
7939566063dSJacob Faibussowitsch   PetscCall(DMSetDimension(*dm, dim));
794c4762a1bSJed Brown   switch (dim) {
795c4762a1bSJed Brown   case 2:
796c4762a1bSJed Brown     if (cellSimplex) {
7979566063dSJacob Faibussowitsch       PetscCall(CreateSimplex_2D(comm, user->testNum, dm));
798c4762a1bSJed Brown     } else {
7999566063dSJacob Faibussowitsch       PetscCall(CreateQuad_2D(comm, user->testNum, dm));
800c4762a1bSJed Brown     }
801c4762a1bSJed Brown     break;
802c4762a1bSJed Brown   case 3:
803c4762a1bSJed Brown     if (cellSimplex) {
8049566063dSJacob Faibussowitsch       PetscCall(CreateSimplex_3D(comm, user, *dm));
805c4762a1bSJed Brown     } else {
8069566063dSJacob Faibussowitsch       PetscCall(CreateHex_3D(comm, user->testNum, dm));
807c4762a1bSJed Brown     }
808c4762a1bSJed Brown     break;
8099371c9d4SSatish Balay   default: SETERRQ(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make hybrid meshes for dimension %" PetscInt_FMT, dim);
810c4762a1bSJed Brown   }
8119566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*dm, "orig_"));
8129566063dSJacob Faibussowitsch   PetscCall(DMPlexDistributeSetDefault(*dm, PETSC_FALSE));
8139566063dSJacob Faibussowitsch   PetscCall(DMSetFromOptions(*dm));
8149566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(*dm, "material", &matLabel));
8151baa6e33SBarry Smith   if (matLabel) PetscCall(DMPlexLabelComplete(*dm, matLabel));
8169566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view"));
8179566063dSJacob Faibussowitsch   PetscCall(DMHasLabel(*dm, "fault", &hasFault));
818c4762a1bSJed Brown   if (hasFault) {
819b253942bSMatthew G. Knepley     DM      dmHybrid = NULL, dmInterface = NULL;
820b253942bSMatthew G. Knepley     DMLabel faultLabel, faultBdLabel, hybridLabel, splitLabel;
821c4762a1bSJed Brown 
8229566063dSJacob Faibussowitsch     PetscCall(DMGetLabel(*dm, "fault", &faultLabel));
8239566063dSJacob Faibussowitsch     PetscCall(DMGetLabel(*dm, "faultBd", &faultBdLabel));
824caf9e14dSMatthew G. Knepley     PetscCall(DMPlexCreateHybridMesh(*dm, faultLabel, faultBdLabel, 1, &hybridLabel, &splitLabel, &dmInterface, &dmHybrid));
8259566063dSJacob Faibussowitsch     PetscCall(DMLabelView(hybridLabel, PETSC_VIEWER_STDOUT_WORLD));
8269566063dSJacob Faibussowitsch     PetscCall(DMLabelDestroy(&hybridLabel));
8279566063dSJacob Faibussowitsch     PetscCall(DMLabelView(splitLabel, PETSC_VIEWER_STDOUT_WORLD));
8289566063dSJacob Faibussowitsch     PetscCall(DMLabelDestroy(&splitLabel));
8299566063dSJacob Faibussowitsch     PetscCall(DMViewFromOptions(dmInterface, NULL, "-dm_interface_view"));
8309566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&dmInterface));
8319566063dSJacob Faibussowitsch     PetscCall(DMDestroy(dm));
832c4762a1bSJed Brown     *dm = dmHybrid;
833c4762a1bSJed Brown   }
8349566063dSJacob Faibussowitsch   PetscCall(DMHasLabel(*dm, "fault2", &hasFault2));
835c4762a1bSJed Brown   if (hasFault2) {
836c4762a1bSJed Brown     DM      dmHybrid = NULL;
837c4762a1bSJed Brown     DMLabel faultLabel, faultBdLabel, hybridLabel;
838c4762a1bSJed Brown 
8399566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptionsPrefix((PetscObject)*dm, "faulted_"));
8409566063dSJacob Faibussowitsch     PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view_pre"));
8419566063dSJacob Faibussowitsch     PetscCall(DMPlexDistributeSetDefault(*dm, PETSC_FALSE));
8429566063dSJacob Faibussowitsch     PetscCall(DMSetFromOptions(*dm));
8439566063dSJacob Faibussowitsch     PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view"));
8449566063dSJacob Faibussowitsch     PetscCall(DMGetLabel(*dm, "fault2", &faultLabel));
8459566063dSJacob Faibussowitsch     PetscCall(DMGetLabel(*dm, "fault2Bd", &faultBdLabel));
846caf9e14dSMatthew G. Knepley     PetscCall(DMPlexCreateHybridMesh(*dm, faultLabel, faultBdLabel, 1, &hybridLabel, NULL, NULL, &dmHybrid));
8479566063dSJacob Faibussowitsch     PetscCall(DMLabelView(hybridLabel, PETSC_VIEWER_STDOUT_WORLD));
8489566063dSJacob Faibussowitsch     PetscCall(DMLabelDestroy(&hybridLabel));
8499566063dSJacob Faibussowitsch     PetscCall(DMDestroy(dm));
850c4762a1bSJed Brown     *dm = dmHybrid;
851c4762a1bSJed Brown   }
852c4762a1bSJed Brown   if (user->testPartition && size > 1) {
853c4762a1bSJed Brown     PetscPartitioner part;
854c4762a1bSJed Brown     PetscInt        *sizes  = NULL;
855c4762a1bSJed Brown     PetscInt        *points = NULL;
856c4762a1bSJed Brown 
857dd400576SPatrick Sanan     if (rank == 0) {
858c4762a1bSJed Brown       if (dim == 2 && cellSimplex && size == 2) {
859c4762a1bSJed Brown         switch (user->testNum) {
860c4762a1bSJed Brown         case 0: {
861c4762a1bSJed Brown           PetscInt triSizes_p2[2]  = {1, 2};
862c4762a1bSJed Brown           PetscInt triPoints_p2[3] = {0, 1, 2};
863c4762a1bSJed Brown 
8649566063dSJacob Faibussowitsch           PetscCall(PetscMalloc2(2, &sizes, 3, &points));
8659566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(sizes, triSizes_p2, 2));
8669371c9d4SSatish Balay           PetscCall(PetscArraycpy(points, triPoints_p2, 3));
8679371c9d4SSatish Balay           break;
8689371c9d4SSatish Balay         }
8695b9dfbb6SMatthew G. Knepley         case 3: {
8705b9dfbb6SMatthew G. Knepley           PetscInt triSizes_p2[2]  = {3, 3};
8715b9dfbb6SMatthew G. Knepley           PetscInt triPoints_p2[6] = {0, 1, 2, 3, 4, 5};
8725b9dfbb6SMatthew G. Knepley 
8735b9dfbb6SMatthew G. Knepley           PetscCall(PetscMalloc2(2, &sizes, 6, &points));
8745b9dfbb6SMatthew G. Knepley           PetscCall(PetscArraycpy(sizes, triSizes_p2, 2));
8759371c9d4SSatish Balay           PetscCall(PetscArraycpy(points, triPoints_p2, 6));
8769371c9d4SSatish Balay           break;
8779371c9d4SSatish Balay         }
8789371c9d4SSatish Balay         default: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %" PetscInt_FMT " for triangular mesh on 2 procs", user->testNum);
8795b9dfbb6SMatthew G. Knepley         }
8805b9dfbb6SMatthew G. Knepley       } else if (dim == 2 && cellSimplex && size == 6) {
8815b9dfbb6SMatthew G. Knepley         switch (user->testNum) {
8825b9dfbb6SMatthew G. Knepley         case 4: {
8835b9dfbb6SMatthew G. Knepley           PetscInt triSizes_p6[6]  = {1, 1, 1, 1, 1, 1};
8845b9dfbb6SMatthew G. Knepley           PetscInt triPoints_p6[6] = {0, 1, 2, 3, 4, 5};
8855b9dfbb6SMatthew G. Knepley 
8865b9dfbb6SMatthew G. Knepley           PetscCall(PetscMalloc2(6, &sizes, 6, &points));
8875b9dfbb6SMatthew G. Knepley           PetscCall(PetscArraycpy(sizes, triSizes_p6, 6));
8889371c9d4SSatish Balay           PetscCall(PetscArraycpy(points, triPoints_p6, 6));
8899371c9d4SSatish Balay           break;
8909371c9d4SSatish Balay         }
8919371c9d4SSatish Balay         default: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %" PetscInt_FMT " for triangular mesh on 6 procs", user->testNum);
892c4762a1bSJed Brown         }
893c4762a1bSJed Brown       } else if (dim == 2 && !cellSimplex && size == 2) {
894c4762a1bSJed Brown         switch (user->testNum) {
895c4762a1bSJed Brown         case 0: {
896c4762a1bSJed Brown           PetscInt quadSizes_p2[2]  = {1, 2};
897c4762a1bSJed Brown           PetscInt quadPoints_p2[3] = {0, 1, 2};
898c4762a1bSJed Brown 
8999566063dSJacob Faibussowitsch           PetscCall(PetscMalloc2(2, &sizes, 3, &points));
9009566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(sizes, quadSizes_p2, 2));
9019371c9d4SSatish Balay           PetscCall(PetscArraycpy(points, quadPoints_p2, 3));
9029371c9d4SSatish Balay           break;
9039371c9d4SSatish Balay         }
904c4762a1bSJed Brown         case 2: {
905c4762a1bSJed Brown           PetscInt quadSizes_p2[2]  = {1, 1};
906c4762a1bSJed Brown           PetscInt quadPoints_p2[2] = {0, 1};
907c4762a1bSJed Brown 
9089566063dSJacob Faibussowitsch           PetscCall(PetscMalloc2(2, &sizes, 2, &points));
9099566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(sizes, quadSizes_p2, 2));
9109371c9d4SSatish Balay           PetscCall(PetscArraycpy(points, quadPoints_p2, 2));
9119371c9d4SSatish Balay           break;
9129371c9d4SSatish Balay         }
9135b9dfbb6SMatthew G. Knepley         case 3: {
9145b9dfbb6SMatthew G. Knepley           PetscInt quadSizes_p2[2]  = {1, 1};
9155b9dfbb6SMatthew G. Knepley           PetscInt quadPoints_p2[2] = {1, 0};
9165b9dfbb6SMatthew G. Knepley 
9175b9dfbb6SMatthew G. Knepley           PetscCall(PetscMalloc2(2, &sizes, 2, &points));
9185b9dfbb6SMatthew G. Knepley           PetscCall(PetscArraycpy(sizes, quadSizes_p2, 2));
9199371c9d4SSatish Balay           PetscCall(PetscArraycpy(points, quadPoints_p2, 2));
9209371c9d4SSatish Balay           break;
9219371c9d4SSatish Balay         }
9229371c9d4SSatish Balay         default: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %" PetscInt_FMT " for quadrilateral mesh on 2 procs", user->testNum);
923c4762a1bSJed Brown         }
924c4762a1bSJed Brown       } else if (dim == 3 && cellSimplex && size == 2) {
925c4762a1bSJed Brown         switch (user->testNum) {
926c4762a1bSJed Brown         case 0: {
927c4762a1bSJed Brown           PetscInt tetSizes_p2[2]  = {1, 2};
928c4762a1bSJed Brown           PetscInt tetPoints_p2[3] = {0, 1, 2};
929c4762a1bSJed Brown 
9309566063dSJacob Faibussowitsch           PetscCall(PetscMalloc2(2, &sizes, 3, &points));
9319566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(sizes, tetSizes_p2, 2));
9329371c9d4SSatish Balay           PetscCall(PetscArraycpy(points, tetPoints_p2, 3));
9339371c9d4SSatish Balay           break;
9349371c9d4SSatish Balay         }
9359371c9d4SSatish Balay         default: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %" PetscInt_FMT " for teterehedral mesh on 2 procs", user->testNum);
936c4762a1bSJed Brown         }
937c4762a1bSJed Brown       } else if (dim == 3 && !cellSimplex && size == 2) {
938c4762a1bSJed Brown         switch (user->testNum) {
939c4762a1bSJed Brown         case 0: {
940c4762a1bSJed Brown           PetscInt hexSizes_p2[2]  = {1, 2};
941c4762a1bSJed Brown           PetscInt hexPoints_p2[3] = {0, 1, 2};
942c4762a1bSJed Brown 
9439566063dSJacob Faibussowitsch           PetscCall(PetscMalloc2(2, &sizes, 3, &points));
9449566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(sizes, hexSizes_p2, 2));
9459371c9d4SSatish Balay           PetscCall(PetscArraycpy(points, hexPoints_p2, 3));
9469371c9d4SSatish Balay           break;
9479371c9d4SSatish Balay         }
9489371c9d4SSatish Balay         default: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %" PetscInt_FMT " for hexahedral mesh on 2 procs", user->testNum);
949c4762a1bSJed Brown         }
950c4762a1bSJed Brown       } else SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test partition");
951c4762a1bSJed Brown     }
9529566063dSJacob Faibussowitsch     PetscCall(DMPlexGetPartitioner(*dm, &part));
9539566063dSJacob Faibussowitsch     PetscCall(PetscPartitionerSetType(part, PETSCPARTITIONERSHELL));
9549566063dSJacob Faibussowitsch     PetscCall(PetscPartitionerShellSetPartition(part, size, sizes, points));
9559566063dSJacob Faibussowitsch     PetscCall(PetscFree2(sizes, points));
956c4762a1bSJed Brown   }
957c4762a1bSJed Brown   {
958c4762a1bSJed Brown     DM pdm = NULL;
959c4762a1bSJed Brown 
960c4762a1bSJed Brown     /* Distribute mesh over processes */
9619566063dSJacob Faibussowitsch     PetscCall(DMPlexDistribute(*dm, 0, NULL, &pdm));
962c4762a1bSJed Brown     if (pdm) {
9639566063dSJacob Faibussowitsch       PetscCall(DMViewFromOptions(pdm, NULL, "-dm_view"));
9649566063dSJacob Faibussowitsch       PetscCall(DMDestroy(dm));
965c4762a1bSJed Brown       *dm = pdm;
966c4762a1bSJed Brown     }
967c4762a1bSJed Brown   }
9689566063dSJacob Faibussowitsch   PetscCall(DMHasLabel(*dm, "pfault", &hasParallelFault));
969c4762a1bSJed Brown   if (hasParallelFault) {
9705b9dfbb6SMatthew G. Knepley     DM      dmHybrid = NULL, dmInterface;
971c4762a1bSJed Brown     DMLabel faultLabel, faultBdLabel, hybridLabel;
972c4762a1bSJed Brown 
9739566063dSJacob Faibussowitsch     PetscCall(DMGetLabel(*dm, "pfault", &faultLabel));
9749566063dSJacob Faibussowitsch     PetscCall(DMGetLabel(*dm, "pfaultBd", &faultBdLabel));
975caf9e14dSMatthew G. Knepley     PetscCall(DMPlexCreateHybridMesh(*dm, faultLabel, faultBdLabel, 1, &hybridLabel, NULL, &dmInterface, &dmHybrid));
9765b9dfbb6SMatthew G. Knepley     PetscCall(DMViewFromOptions(dmInterface, NULL, "-dm_fault_view"));
9775b9dfbb6SMatthew G. Knepley     {
9785b9dfbb6SMatthew G. Knepley       PetscViewer viewer;
9795b9dfbb6SMatthew G. Knepley       PetscMPIInt rank;
9805b9dfbb6SMatthew G. Knepley 
9815b9dfbb6SMatthew G. Knepley       PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)*dm), &rank));
9825b9dfbb6SMatthew G. Knepley       PetscCall(PetscViewerGetSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &viewer));
9835b9dfbb6SMatthew G. Knepley       PetscCall(PetscViewerASCIIPrintf(viewer, "Rank %d\n", rank));
9845b9dfbb6SMatthew G. Knepley       PetscCall(DMLabelView(hybridLabel, viewer));
9855b9dfbb6SMatthew G. Knepley       PetscCall(PetscViewerRestoreSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &viewer));
9865b9dfbb6SMatthew G. Knepley       PetscCall(PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD));
9875b9dfbb6SMatthew G. Knepley     }
9889566063dSJacob Faibussowitsch     PetscCall(DMLabelDestroy(&hybridLabel));
9895b9dfbb6SMatthew G. Knepley     PetscCall(DMDestroy(&dmInterface));
9909566063dSJacob Faibussowitsch     PetscCall(DMDestroy(dm));
991c4762a1bSJed Brown     *dm = dmHybrid;
992c4762a1bSJed Brown   }
9939566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)*dm, "Hybrid Mesh"));
9949566063dSJacob Faibussowitsch   PetscCall(CreateFaultLabel(*dm));
9959566063dSJacob Faibussowitsch   PetscCall(CreateDiscretization(*dm, user));
9969566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view_pre"));
9979566063dSJacob Faibussowitsch   PetscCall(DMPlexDistributeSetDefault(*dm, PETSC_FALSE));
9989566063dSJacob Faibussowitsch   PetscCall(DMSetFromOptions(*dm));
9999566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view"));
1000c4762a1bSJed Brown   PetscFunctionReturn(0);
1001c4762a1bSJed Brown }
1002c4762a1bSJed Brown 
10039371c9d4SSatish Balay static PetscErrorCode TestMesh(DM dm, AppCtx *user) {
1004b253942bSMatthew G. Knepley   PetscFunctionBegin;
10059566063dSJacob Faibussowitsch   PetscCall(DMPlexCheckSymmetry(dm));
10069566063dSJacob Faibussowitsch   PetscCall(DMPlexCheckSkeleton(dm, 0));
10079566063dSJacob Faibussowitsch   PetscCall(DMPlexCheckFaces(dm, 0));
1008b253942bSMatthew G. Knepley   PetscFunctionReturn(0);
1009b253942bSMatthew G. Knepley }
1010b253942bSMatthew G. Knepley 
10119371c9d4SSatish Balay static PetscErrorCode TestDiscretization(DM dm, AppCtx *user) {
1012b253942bSMatthew G. Knepley   PetscSection s;
1013b253942bSMatthew G. Knepley 
1014b253942bSMatthew G. Knepley   PetscFunctionBegin;
10159566063dSJacob Faibussowitsch   PetscCall(DMGetSection(dm, &s));
10169566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)s, NULL, "-local_section_view"));
1017b253942bSMatthew G. Knepley   PetscFunctionReturn(0);
1018b253942bSMatthew G. Knepley }
1019b253942bSMatthew G. Knepley 
10209371c9d4SSatish Balay static PetscErrorCode r(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
1021b253942bSMatthew G. Knepley   PetscInt d;
1022b253942bSMatthew G. Knepley   for (d = 0; d < dim; ++d) u[d] = x[d];
1023b253942bSMatthew G. Knepley   return 0;
1024b253942bSMatthew G. Knepley }
1025b253942bSMatthew G. Knepley 
10269371c9d4SSatish Balay static PetscErrorCode rp1(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
1027b253942bSMatthew G. Knepley   PetscInt d;
1028b253942bSMatthew G. Knepley   for (d = 0; d < dim; ++d) u[d] = x[d] + (d > 0 ? 1.0 : 0.0);
1029b253942bSMatthew G. Knepley   return 0;
1030b253942bSMatthew G. Knepley }
1031b253942bSMatthew G. Knepley 
10329371c9d4SSatish Balay static PetscErrorCode phi(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
1033b253942bSMatthew G. Knepley   PetscInt d;
1034b253942bSMatthew G. Knepley   u[0] = -x[1];
1035b253942bSMatthew G. Knepley   u[1] = x[0];
1036b253942bSMatthew G. Knepley   for (d = 2; d < dim; ++d) u[d] = x[d];
1037b253942bSMatthew G. Knepley   return 0;
1038b253942bSMatthew G. Knepley }
1039b253942bSMatthew G. Knepley 
1040b253942bSMatthew G. Knepley /* \lambda \cdot (\psi_u^- - \psi_u^+) */
10419371c9d4SSatish Balay static void f0_bd_u(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) {
1042b253942bSMatthew G. Knepley   const PetscInt Nc = uOff[1] - uOff[0];
1043b253942bSMatthew G. Knepley   PetscInt       c;
1044b253942bSMatthew G. Knepley   for (c = 0; c < Nc; ++c) {
1045b253942bSMatthew G. Knepley     f0[c]      = u[Nc * 2 + c] + x[Nc - c - 1];
1046b253942bSMatthew G. Knepley     f0[Nc + c] = -(u[Nc * 2 + c] + x[Nc - c - 1]);
1047b253942bSMatthew G. Knepley   }
1048b253942bSMatthew G. Knepley }
1049b253942bSMatthew G. Knepley 
1050b253942bSMatthew G. Knepley /* (d - u^+ + u^-) \cdot \psi_\lambda */
10519371c9d4SSatish Balay static void f0_bd_l(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) {
1052b253942bSMatthew G. Knepley   const PetscInt Nc = uOff[2] - uOff[1];
1053b253942bSMatthew G. Knepley   PetscInt       c;
1054b253942bSMatthew G. Knepley 
1055b253942bSMatthew G. Knepley   for (c = 0; c < Nc; ++c) f0[c] = (c > 0 ? 1.0 : 0.0) + u[c] - u[Nc + c];
1056b253942bSMatthew G. Knepley }
1057b253942bSMatthew G. Knepley 
1058b253942bSMatthew G. Knepley /* \psi_lambda \cdot (\psi_u^- - \psi_u^+) */
10599371c9d4SSatish Balay static void g0_bd_ul(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) {
1060b253942bSMatthew G. Knepley   const PetscInt Nc = uOff[1] - uOff[0];
1061b253942bSMatthew G. Knepley   PetscInt       c;
1062b253942bSMatthew G. Knepley 
1063b253942bSMatthew G. Knepley   for (c = 0; c < Nc; ++c) {
1064b253942bSMatthew G. Knepley     g0[(0 + c) * Nc + c]  = 1.0;
1065b253942bSMatthew G. Knepley     g0[(Nc + c) * Nc + c] = -1.0;
1066b253942bSMatthew G. Knepley   }
1067b253942bSMatthew G. Knepley }
1068b253942bSMatthew G. Knepley 
1069b253942bSMatthew G. Knepley /* (-\psi_u^+ + \psi_u^-) \cdot \psi_\lambda */
10709371c9d4SSatish Balay static void g0_bd_lu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) {
1071b253942bSMatthew G. Knepley   const PetscInt Nc = uOff[2] - uOff[1];
1072b253942bSMatthew G. Knepley   PetscInt       c;
1073b253942bSMatthew G. Knepley 
1074b253942bSMatthew G. Knepley   for (c = 0; c < Nc; ++c) {
1075b253942bSMatthew G. Knepley     g0[c * Nc * 2 + c]      = 1.0;
1076b253942bSMatthew G. Knepley     g0[c * Nc * 2 + Nc + c] = -1.0;
1077b253942bSMatthew G. Knepley   }
1078b253942bSMatthew G. Knepley }
1079b253942bSMatthew G. Knepley 
10809371c9d4SSatish Balay static PetscErrorCode TestAssembly(DM dm, AppCtx *user) {
1081b253942bSMatthew G. Knepley   Mat           J;
1082b253942bSMatthew G. Knepley   Vec           locX, locF;
1083b253942bSMatthew G. Knepley   PetscDS       probh;
1084b253942bSMatthew G. Knepley   DMLabel       fault, material;
1085b253942bSMatthew G. Knepley   IS            cohesiveCells;
1086b7519becSMatthew G. Knepley   PetscWeakForm wf;
108706ad1575SMatthew G. Knepley   PetscFormKey  keys[3];
1088b253942bSMatthew G. Knepley   PetscErrorCode (*initialGuess[2])(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar u[], void *ctx);
1089b253942bSMatthew G. Knepley   PetscInt    dim, Nf, cMax, cEnd, id;
1090b7519becSMatthew G. Knepley   PetscMPIInt rank;
1091b253942bSMatthew G. Knepley 
1092b253942bSMatthew G. Knepley   PetscFunctionBegin;
10939566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank));
10949566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
10959566063dSJacob Faibussowitsch   PetscCall(DMPlexGetSimplexOrBoxCells(dm, 0, NULL, &cMax));
10969566063dSJacob Faibussowitsch   PetscCall(DMPlexGetHeightStratum(dm, 0, NULL, &cEnd));
10979566063dSJacob Faibussowitsch   PetscCall(ISCreateStride(PETSC_COMM_SELF, cEnd - cMax, cMax, 1, &cohesiveCells));
10989566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(dm, "cohesive", &fault));
10999566063dSJacob Faibussowitsch   PetscCall(DMGetLocalVector(dm, &locX));
11009566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)locX, "Local Solution"));
11019566063dSJacob Faibussowitsch   PetscCall(DMGetLocalVector(dm, &locF));
11029566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)locF, "Local Residual"));
11039566063dSJacob Faibussowitsch   PetscCall(DMCreateMatrix(dm, &J));
11049566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)J, "Jacobian"));
1105b253942bSMatthew G. Knepley 
1106b253942bSMatthew G. Knepley   /* The initial guess has displacement shifted by one unit in each fault parallel direction across the fault */
11079566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(dm, "material", &material));
1108b253942bSMatthew G. Knepley   id              = 1;
1109b253942bSMatthew G. Knepley   initialGuess[0] = r;
1110b253942bSMatthew G. Knepley   initialGuess[1] = NULL;
11119566063dSJacob Faibussowitsch   PetscCall(DMProjectFunctionLabelLocal(dm, 0.0, material, 1, &id, PETSC_DETERMINE, NULL, initialGuess, NULL, INSERT_VALUES, locX));
1112b253942bSMatthew G. Knepley   id              = 2;
1113b253942bSMatthew G. Knepley   initialGuess[0] = rp1;
1114b253942bSMatthew G. Knepley   initialGuess[1] = NULL;
11159566063dSJacob Faibussowitsch   PetscCall(DMProjectFunctionLabelLocal(dm, 0.0, material, 1, &id, PETSC_DETERMINE, NULL, initialGuess, NULL, INSERT_VALUES, locX));
1116b253942bSMatthew G. Knepley   id              = 1;
1117b253942bSMatthew G. Knepley   initialGuess[0] = NULL;
1118b253942bSMatthew G. Knepley   initialGuess[1] = phi;
11199566063dSJacob Faibussowitsch   PetscCall(DMProjectFunctionLabelLocal(dm, 0.0, fault, 1, &id, PETSC_DETERMINE, NULL, initialGuess, NULL, INSERT_VALUES, locX));
11209566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(locX, NULL, "-local_solution_view"));
1121b253942bSMatthew G. Knepley 
11229566063dSJacob Faibussowitsch   PetscCall(DMGetCellDS(dm, cMax, &probh));
11239566063dSJacob Faibussowitsch   PetscCall(PetscDSGetWeakForm(probh, &wf));
11249566063dSJacob Faibussowitsch   PetscCall(PetscDSGetNumFields(probh, &Nf));
11259566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(wf, material, 1, 0, 0, 0, f0_bd_u, 0, NULL));
11269566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(wf, material, 2, 0, 0, 0, f0_bd_u, 0, NULL));
11279566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(wf, material, 1, 0, 1, 0, 0, g0_bd_ul, 0, NULL, 0, NULL, 0, NULL));
11289566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdJacobian(wf, material, 2, 0, 1, 0, 0, g0_bd_ul, 0, NULL, 0, NULL, 0, NULL));
1129b7519becSMatthew G. Knepley   if (Nf > 1) {
11309566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormSetIndexBdResidual(wf, fault, 1, 1, 0, 0, f0_bd_l, 0, NULL));
11319566063dSJacob Faibussowitsch     PetscCall(PetscWeakFormSetIndexBdJacobian(wf, fault, 1, 1, 0, 0, 0, g0_bd_lu, 0, NULL, 0, NULL, 0, NULL));
1132b7519becSMatthew G. Knepley   }
1133c5853193SPierre Jolivet   if (rank == 0) PetscCall(PetscDSView(probh, NULL));
1134b253942bSMatthew G. Knepley 
1135dd96b1f9SToby Isaac   keys[0].label = NULL;
1136dd96b1f9SToby Isaac   keys[0].value = 0;
11376528b96dSMatthew G. Knepley   keys[0].field = 0;
1138dd96b1f9SToby Isaac   keys[0].part  = 0;
1139b7519becSMatthew G. Knepley   keys[1].label = material;
1140b7519becSMatthew G. Knepley   keys[1].value = 2;
11416528b96dSMatthew G. Knepley   keys[1].field = 0;
1142dd96b1f9SToby Isaac   keys[1].part  = 0;
1143b7519becSMatthew G. Knepley   keys[2].label = fault;
1144b7519becSMatthew G. Knepley   keys[2].value = 1;
1145b7519becSMatthew G. Knepley   keys[2].field = 1;
1146dd96b1f9SToby Isaac   keys[2].part  = 0;
11479566063dSJacob Faibussowitsch   PetscCall(VecSet(locF, 0.));
11489566063dSJacob Faibussowitsch   PetscCall(DMPlexComputeResidual_Hybrid_Internal(dm, keys, cohesiveCells, 0.0, locX, NULL, 0.0, locF, user));
11499566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(locF, NULL, "-local_residual_view"));
11509566063dSJacob Faibussowitsch   PetscCall(MatZeroEntries(J));
11519566063dSJacob Faibussowitsch   PetscCall(DMPlexComputeJacobian_Hybrid_Internal(dm, keys, cohesiveCells, 0.0, 0.0, locX, NULL, J, J, user));
115249664dceSMatthew G. Knepley   PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY));
115349664dceSMatthew G. Knepley   PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY));
11549566063dSJacob Faibussowitsch   PetscCall(MatViewFromOptions(J, NULL, "-local_jacobian_view"));
1155b253942bSMatthew G. Knepley 
11569566063dSJacob Faibussowitsch   PetscCall(DMRestoreLocalVector(dm, &locX));
11579566063dSJacob Faibussowitsch   PetscCall(DMRestoreLocalVector(dm, &locF));
11589566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&J));
11599566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&cohesiveCells));
1160b253942bSMatthew G. Knepley   PetscFunctionReturn(0);
1161b253942bSMatthew G. Knepley }
1162b253942bSMatthew G. Knepley 
11639371c9d4SSatish Balay int main(int argc, char **argv) {
1164c4762a1bSJed Brown   DM     dm;
1165c4762a1bSJed Brown   AppCtx user; /* user-defined work context */
1166c4762a1bSJed Brown 
1167327415f7SBarry Smith   PetscFunctionBeginUser;
11689566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
11699566063dSJacob Faibussowitsch   PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user));
11709566063dSJacob Faibussowitsch   PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &dm));
11719566063dSJacob Faibussowitsch   PetscCall(TestMesh(dm, &user));
11729566063dSJacob Faibussowitsch   PetscCall(TestDiscretization(dm, &user));
11739566063dSJacob Faibussowitsch   PetscCall(TestAssembly(dm, &user));
11749566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&dm));
11759566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
1176b122ec5aSJacob Faibussowitsch   return 0;
1177c4762a1bSJed Brown }
1178c4762a1bSJed Brown 
1179c4762a1bSJed Brown /*TEST
1180c4762a1bSJed Brown   testset:
1181b253942bSMatthew G. Knepley     args: -orig_dm_plex_check_all -dm_plex_check_all \
1182b7519becSMatthew G. Knepley           -displacement_petscspace_degree 1 -faulttraction_petscspace_degree 1 -local_section_view \
1183b253942bSMatthew G. Knepley           -local_solution_view -local_residual_view -local_jacobian_view
1184c4762a1bSJed Brown     test:
1185c4762a1bSJed Brown       suffix: tri_0
1186c4762a1bSJed Brown       args: -dim 2
11871c6715b8SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
1188c4762a1bSJed Brown     test:
1189c4762a1bSJed Brown       suffix: tri_t1_0
1190c4762a1bSJed Brown       args: -dim 2 -test_num 1
11911c6715b8SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
1192c4762a1bSJed Brown     test:
11935b9dfbb6SMatthew G. Knepley       suffix: tri_t2_0
11945b9dfbb6SMatthew G. Knepley       args: -dim 2 -test_num 2
11955b9dfbb6SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
11965b9dfbb6SMatthew G. Knepley     test:
11973bdf08b3SMatthew G. Knepley       suffix: tri_t5_0
11983bdf08b3SMatthew G. Knepley       args: -dim 2 -test_num 5
11993bdf08b3SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
12003bdf08b3SMatthew G. Knepley     test:
1201c4762a1bSJed Brown       suffix: tet_0
1202c4762a1bSJed Brown       args: -dim 3
12031c6715b8SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
1204c4762a1bSJed Brown     test:
1205b253942bSMatthew G. Knepley       suffix: tet_t1_0
1206b253942bSMatthew G. Knepley       args: -dim 3 -test_num 1
12071c6715b8SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
1208b253942bSMatthew G. Knepley 
1209b253942bSMatthew G. Knepley   testset:
1210b253942bSMatthew G. Knepley     args: -orig_dm_plex_check_all -dm_plex_check_all \
1211b7519becSMatthew G. Knepley           -displacement_petscspace_degree 1 -faulttraction_petscspace_degree 1
1212b253942bSMatthew G. Knepley     test:
1213c4762a1bSJed Brown       suffix: tet_1
1214c4762a1bSJed Brown       nsize: 2
1215c4762a1bSJed Brown       args: -dim 3
12161c6715b8SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
1217c4762a1bSJed Brown     test:
1218b253942bSMatthew G. Knepley       suffix: tri_1
1219b253942bSMatthew G. Knepley       nsize: 2
1220b253942bSMatthew G. Knepley       args: -dim 2
12211c6715b8SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
12225b9dfbb6SMatthew G. Knepley     test:
12235b9dfbb6SMatthew G. Knepley       suffix: tri_t3_0
12245b9dfbb6SMatthew G. Knepley       nsize: 2
12255b9dfbb6SMatthew G. Knepley       args: -dim 2 -test_num 3
12265b9dfbb6SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
12275b9dfbb6SMatthew G. Knepley     test:
12285b9dfbb6SMatthew G. Knepley       suffix: tri_t4_0
12295b9dfbb6SMatthew G. Knepley       nsize: 6
12305b9dfbb6SMatthew G. Knepley       args: -dim 2 -test_num 4
12315b9dfbb6SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
1232c4762a1bSJed Brown 
1233c4762a1bSJed Brown   testset:
1234ecfb78b5SMatthew G. Knepley     args: -orig_dm_plex_check_all -dm_plex_check_all \
1235b7519becSMatthew G. Knepley           -displacement_petscspace_degree 1 -faulttraction_petscspace_degree 1
1236c4762a1bSJed Brown     # 2D Quads
1237c4762a1bSJed Brown     test:
1238c4762a1bSJed Brown       suffix: quad_0
1239c4762a1bSJed Brown       args: -dim 2 -cell_simplex 0
12401c6715b8SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
1241c4762a1bSJed Brown     test:
1242c4762a1bSJed Brown       suffix: quad_1
1243c4762a1bSJed Brown       nsize: 2
1244c4762a1bSJed Brown       args: -dim 2 -cell_simplex 0
12451c6715b8SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
1246c4762a1bSJed Brown     test:
1247c4762a1bSJed Brown       suffix: quad_t1_0
124854fcfd0cSMatthew G. Knepley       args: -dim 2 -cell_simplex 0 -test_num 1 -faulted_dm_plex_check_all
12491c6715b8SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
12505b9dfbb6SMatthew G. Knepley     test:
12515b9dfbb6SMatthew G. Knepley       suffix: quad_t2_0
12525b9dfbb6SMatthew G. Knepley       nsize: 2
12535b9dfbb6SMatthew G. Knepley       args: -dim 2 -cell_simplex 0 -test_num 2
12545b9dfbb6SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
12555b9dfbb6SMatthew G. Knepley     test:
12565b9dfbb6SMatthew G. Knepley       # TODO: The PetscSF is wrong here (connects to wrong side of split)
12575b9dfbb6SMatthew G. Knepley       suffix: quad_t3_0
12585b9dfbb6SMatthew G. Knepley       nsize: 2
12595b9dfbb6SMatthew G. Knepley       args: -dim 2 -cell_simplex 0 -test_num 3
12605b9dfbb6SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
1261c4762a1bSJed Brown     # 3D Hex
1262c4762a1bSJed Brown     test:
1263c4762a1bSJed Brown       suffix: hex_0
1264c4762a1bSJed Brown       args: -dim 3 -cell_simplex 0
12651c6715b8SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
1266c4762a1bSJed Brown     test:
1267c4762a1bSJed Brown       suffix: hex_1
1268c4762a1bSJed Brown       nsize: 2
1269c4762a1bSJed Brown       args: -dim 3 -cell_simplex 0
12701c6715b8SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
1271c4762a1bSJed Brown     test:
1272c4762a1bSJed Brown       suffix: hex_t1_0
1273c4762a1bSJed Brown       args: -dim 3 -cell_simplex 0 -test_num 1
12741c6715b8SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
1275c4762a1bSJed Brown     test:
1276c4762a1bSJed Brown       suffix: hex_t2_0
1277c4762a1bSJed Brown       args: -dim 3 -cell_simplex 0 -test_num 2
12781c6715b8SMatthew G. Knepley       filter: sed -e "s/_start//g" -e "s/f0_bd_u//g" -e "s/f0_bd_l//g" -e "s/g0_bd_ul//g" -e "s/g0_bd_lu//g"
1279c4762a1bSJed Brown 
1280c4762a1bSJed Brown TEST*/
1281