xref: /petsc/src/dm/impls/plex/plexrefine.c (revision cf4091a3b8056603b0f079088752bd16877c3248)
1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h>   /*I      "petscdmplex.h"   I*/
2412e9a14SMatthew G. Knepley #include <petsc/private/petscfeimpl.h>  /* For PetscFEInterpolate_Static() */
375d3a19aSMatthew G. Knepley #include <petscsf.h>
475d3a19aSMatthew G. Knepley 
5*cf4091a3SMatthew G. Knepley const char * const DMPlexCellRefinerTypes[] = {"Regular", "ToBox", "ToSimplex", "Alfeld2D", "Alfeld3D", "PowellSabin", "BoundaryLayer", "DMPlexCellRefinerTypes", "DM_REFINER_", 0};
675d3a19aSMatthew G. Knepley 
709789c4cSMatthew G. Knepley /*
809789c4cSMatthew G. Knepley   Note that j and invj are non-square:
909789c4cSMatthew G. Knepley          v0 + j x_face = x_cell
1009789c4cSMatthew G. Knepley     invj (x_cell - v0) = x_face
1109789c4cSMatthew G. Knepley */
12412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[])
1309789c4cSMatthew G. Knepley {
1409789c4cSMatthew G. Knepley   /*
1509789c4cSMatthew G. Knepley    2
1609789c4cSMatthew G. Knepley    |\
1709789c4cSMatthew G. Knepley    | \
1809789c4cSMatthew G. Knepley    |  \
1909789c4cSMatthew G. Knepley    |   \
2009789c4cSMatthew G. Knepley    |    \
2109789c4cSMatthew G. Knepley    |     \
2209789c4cSMatthew G. Knepley    |      \
2309789c4cSMatthew G. Knepley    2       1
2409789c4cSMatthew G. Knepley    |        \
2509789c4cSMatthew G. Knepley    |         \
2609789c4cSMatthew G. Knepley    |          \
2709789c4cSMatthew G. Knepley    0---0-------1
28412e9a14SMatthew G. Knepley    v0[Nf][dc]:       3 x 2
29412e9a14SMatthew G. Knepley    J[Nf][df][dc]:    3 x 1 x 2
30412e9a14SMatthew G. Knepley    invJ[Nf][dc][df]: 3 x 2 x 1
31412e9a14SMatthew G. Knepley    detJ[Nf]:         3
3209789c4cSMatthew G. Knepley    */
33412e9a14SMatthew G. Knepley   static PetscReal tri_v0[]   = {0.0, -1.0,  0.0, 0.0,  -1.0,  0.0};
34412e9a14SMatthew G. Knepley   static PetscReal tri_J[]    = {1.0, 0.0,  -1.0, 1.0,   0.0, -1.0};
35412e9a14SMatthew G. Knepley   static PetscReal tri_invJ[] = {1.0, 0.0,  -0.5, 0.5,   0.0, -1.0};
36412e9a14SMatthew G. Knepley   static PetscReal tri_detJ[] = {1.0,  1.414213562373095,  1.0};
3709789c4cSMatthew G. Knepley   /*
3809789c4cSMatthew G. Knepley    3---------2---------2
3909789c4cSMatthew G. Knepley    |                   |
4009789c4cSMatthew G. Knepley    |                   |
4109789c4cSMatthew G. Knepley    |                   |
4209789c4cSMatthew G. Knepley    3                   1
4309789c4cSMatthew G. Knepley    |                   |
4409789c4cSMatthew G. Knepley    |                   |
4509789c4cSMatthew G. Knepley    |                   |
4609789c4cSMatthew G. Knepley    0---------0---------1
47412e9a14SMatthew G. Knepley 
48412e9a14SMatthew G. Knepley    v0[Nf][dc]:       4 x 2
49412e9a14SMatthew G. Knepley    J[Nf][df][dc]:    4 x 1 x 2
50412e9a14SMatthew G. Knepley    invJ[Nf][dc][df]: 4 x 2 x 1
51412e9a14SMatthew G. Knepley    detJ[Nf]:         4
5209789c4cSMatthew G. Knepley    */
53412e9a14SMatthew G. Knepley   static PetscReal quad_v0[]   = {0.0, -1.0,  1.0, 0.0,   0.0, 1.0  -1.0,  0.0};
54412e9a14SMatthew G. Knepley   static PetscReal quad_J[]    = {1.0, 0.0,   0.0, 1.0,  -1.0, 0.0,  0.0, -1.0};
55412e9a14SMatthew G. Knepley   static PetscReal quad_invJ[] = {1.0, 0.0,   0.0, 1.0,  -1.0, 0.0,  0.0, -1.0};
56412e9a14SMatthew G. Knepley   static PetscReal quad_detJ[] = {1.0,  1.0,  1.0,  1.0};
57412e9a14SMatthew G. Knepley 
58412e9a14SMatthew G. Knepley   PetscFunctionBegin;
59412e9a14SMatthew G. Knepley   switch (ct) {
60412e9a14SMatthew G. Knepley   case DM_POLYTOPE_TRIANGLE:      if (Nf) *Nf = 3; if (v0) *v0 = tri_v0;  if (J) *J = tri_J;  if (invJ) *invJ = tri_invJ;  if (detJ) *detJ = tri_detJ;  break;
61412e9a14SMatthew G. Knepley   case DM_POLYTOPE_QUADRILATERAL: if (Nf) *Nf = 4; if (v0) *v0 = quad_v0; if (J) *J = quad_J; if (invJ) *invJ = quad_invJ; if (detJ) *detJ = quad_detJ; break;
6209789c4cSMatthew G. Knepley   default:
63412e9a14SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]);
6409789c4cSMatthew G. Knepley   }
6509789c4cSMatthew G. Knepley   PetscFunctionReturn(0);
6609789c4cSMatthew G. Knepley }
6709789c4cSMatthew G. Knepley 
68bed052eaSMatthew G. Knepley /* Gets the affine map from the original cell to each subcell */
69412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetAffineTransforms_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[])
70bed052eaSMatthew G. Knepley {
71260b6d3fSMatthew G. Knepley   /*
72260b6d3fSMatthew G. Knepley    2
73260b6d3fSMatthew G. Knepley    |\
74260b6d3fSMatthew G. Knepley    | \
75260b6d3fSMatthew G. Knepley    |  \
76260b6d3fSMatthew G. Knepley    |   \
77260b6d3fSMatthew G. Knepley    | C  \
78260b6d3fSMatthew G. Knepley    |     \
79260b6d3fSMatthew G. Knepley    |      \
80260b6d3fSMatthew G. Knepley    2---1---1
81260b6d3fSMatthew G. Knepley    |\  D  / \
82260b6d3fSMatthew G. Knepley    | 2   0   \
83260b6d3fSMatthew G. Knepley    |A \ /  B  \
84260b6d3fSMatthew G. Knepley    0---0-------1
85260b6d3fSMatthew G. Knepley    */
86412e9a14SMatthew G. Knepley   static PetscReal tri_v0[]   = {-1.0, -1.0,  0.0, -1.0,  -1.0, 0.0,  0.0, -1.0};
87412e9a14SMatthew G. Knepley   static PetscReal tri_J[]    = {0.5, 0.0,
88412e9a14SMatthew G. Knepley                                  0.0, 0.5,
89412e9a14SMatthew G. Knepley 
90412e9a14SMatthew G. Knepley                                  0.5, 0.0,
91412e9a14SMatthew G. Knepley                                  0.0, 0.5,
92412e9a14SMatthew G. Knepley 
93412e9a14SMatthew G. Knepley                                  0.5, 0.0,
94412e9a14SMatthew G. Knepley                                  0.0, 0.5,
95412e9a14SMatthew G. Knepley 
96412e9a14SMatthew G. Knepley                                  0.0, -0.5,
97412e9a14SMatthew G. Knepley                                  0.5,  0.5};
98412e9a14SMatthew G. Knepley   static PetscReal tri_invJ[] = {2.0, 0.0,
99412e9a14SMatthew G. Knepley                                  0.0, 2.0,
100412e9a14SMatthew G. Knepley 
101412e9a14SMatthew G. Knepley                                  2.0, 0.0,
102412e9a14SMatthew G. Knepley                                  0.0, 2.0,
103412e9a14SMatthew G. Knepley 
104412e9a14SMatthew G. Knepley                                  2.0, 0.0,
105412e9a14SMatthew G. Knepley                                  0.0, 2.0,
106412e9a14SMatthew G. Knepley 
107412e9a14SMatthew G. Knepley                                  2.0,  2.0,
108412e9a14SMatthew G. Knepley                                 -2.0,  0.0};
109260b6d3fSMatthew G. Knepley     /*
110260b6d3fSMatthew G. Knepley      3---------2---------2
111260b6d3fSMatthew G. Knepley      |         |         |
112260b6d3fSMatthew G. Knepley      |    D    2    C    |
113260b6d3fSMatthew G. Knepley      |         |         |
114260b6d3fSMatthew G. Knepley      3----3----0----1----1
115260b6d3fSMatthew G. Knepley      |         |         |
116260b6d3fSMatthew G. Knepley      |    A    0    B    |
117260b6d3fSMatthew G. Knepley      |         |         |
118260b6d3fSMatthew G. Knepley      0---------0---------1
119260b6d3fSMatthew G. Knepley      */
120412e9a14SMatthew G. Knepley   static PetscReal quad_v0[]   = {-1.0, -1.0,  0.0, -1.0,  0.0, 0.0,  -1.0, 0.0};
121412e9a14SMatthew G. Knepley   static PetscReal quad_J[]    = {0.5, 0.0,
122412e9a14SMatthew G. Knepley                                   0.0, 0.5,
123412e9a14SMatthew G. Knepley 
124412e9a14SMatthew G. Knepley                                   0.5, 0.0,
125412e9a14SMatthew G. Knepley                                   0.0, 0.5,
126412e9a14SMatthew G. Knepley 
127412e9a14SMatthew G. Knepley                                   0.5, 0.0,
128412e9a14SMatthew G. Knepley                                   0.0, 0.5,
129412e9a14SMatthew G. Knepley 
130412e9a14SMatthew G. Knepley                                   0.5, 0.0,
131412e9a14SMatthew G. Knepley                                   0.0, 0.5};
132412e9a14SMatthew G. Knepley   static PetscReal quad_invJ[] = {2.0, 0.0,
133412e9a14SMatthew G. Knepley                                   0.0, 2.0,
134412e9a14SMatthew G. Knepley 
135412e9a14SMatthew G. Knepley                                   2.0, 0.0,
136412e9a14SMatthew G. Knepley                                   0.0, 2.0,
137412e9a14SMatthew G. Knepley 
138412e9a14SMatthew G. Knepley                                   2.0, 0.0,
139412e9a14SMatthew G. Knepley                                   0.0, 2.0,
140412e9a14SMatthew G. Knepley 
141412e9a14SMatthew G. Knepley                                   2.0, 0.0,
142412e9a14SMatthew G. Knepley                                   0.0, 2.0};
143c1879b55SMatthew G. Knepley     /*
144c1879b55SMatthew G. Knepley      Bottom (viewed from top)    Top
145c1879b55SMatthew G. Knepley      1---------2---------2       7---------2---------6
146c1879b55SMatthew G. Knepley      |         |         |       |         |         |
147c1879b55SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
148c1879b55SMatthew G. Knepley      |         |         |       |         |         |
149c1879b55SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
150c1879b55SMatthew G. Knepley      |         |         |       |         |         |
151c1879b55SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
152c1879b55SMatthew G. Knepley      |         |         |       |         |         |
153c1879b55SMatthew G. Knepley      0---------0---------3       4---------0---------5
154c1879b55SMatthew G. Knepley      */
155412e9a14SMatthew G. Knepley   static PetscReal hex_v0[]   = {-1.0, -1.0, -1.0,  -1.0,  0.0, -1.0,  0.0, 0.0, -1.0,   0.0, -1.0, -1.0,
156412e9a14SMatthew G. Knepley                                  -1.0, -1.0,  0.0,   0.0, -1.0,  0.0,  0.0, 0.0,  0.0,  -1.0,  0.0,  0.0};
157412e9a14SMatthew G. Knepley   static PetscReal hex_J[]    = {0.5, 0.0, 0.0,
158412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
159412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
160bed052eaSMatthew G. Knepley 
161412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
162412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
163412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
164412e9a14SMatthew G. Knepley 
165412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
166412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
167412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
168412e9a14SMatthew G. Knepley 
169412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
170412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
171412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
172412e9a14SMatthew G. Knepley 
173412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
174412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
175412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
176412e9a14SMatthew G. Knepley 
177412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
178412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
179412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
180412e9a14SMatthew G. Knepley 
181412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
182412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
183412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
184412e9a14SMatthew G. Knepley 
185412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
186412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
187412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5};
188412e9a14SMatthew G. Knepley   static PetscReal hex_invJ[] = {2.0, 0.0, 0.0,
189412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
190412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
191412e9a14SMatthew G. Knepley 
192412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
193412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
194412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
195412e9a14SMatthew G. Knepley 
196412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
197412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
198412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
199412e9a14SMatthew G. Knepley 
200412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
201412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
202412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
203412e9a14SMatthew G. Knepley 
204412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
205412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
206412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
207412e9a14SMatthew G. Knepley 
208412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
209412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
210412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
211412e9a14SMatthew G. Knepley 
212412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
213412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
214412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
215412e9a14SMatthew G. Knepley 
216412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
217412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
218412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0};
219bed052eaSMatthew G. Knepley 
220bed052eaSMatthew G. Knepley   PetscFunctionBegin;
221412e9a14SMatthew G. Knepley   switch (ct) {
222412e9a14SMatthew G. Knepley   case DM_POLYTOPE_TRIANGLE:      if (Nc) *Nc = 4; if (v0) *v0 = tri_v0;  if (J) *J = tri_J;  if (invJ) *invJ = tri_invJ;  break;
223412e9a14SMatthew G. Knepley   case DM_POLYTOPE_QUADRILATERAL: if (Nc) *Nc = 4; if (v0) *v0 = quad_v0; if (J) *J = quad_J; if (invJ) *invJ = quad_invJ; break;
224412e9a14SMatthew G. Knepley   case DM_POLYTOPE_HEXAHEDRON:    if (Nc) *Nc = 8; if (v0) *v0 = hex_v0;  if (J) *J = hex_J;  if (invJ) *invJ = hex_invJ;  break;
225412e9a14SMatthew G. Knepley   default:
226412e9a14SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]);
227412e9a14SMatthew G. Knepley   }
228bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
229bed052eaSMatthew G. Knepley }
230bed052eaSMatthew G. Knepley 
23180389061SMatthew G. Knepley /* Should this be here or in the DualSpace somehow? */
232412e9a14SMatthew G. Knepley PetscErrorCode CellRefinerInCellTest_Internal(DMPolytopeType ct, const PetscReal point[], PetscBool *inside)
23380389061SMatthew G. Knepley {
23480389061SMatthew G. Knepley   PetscReal sum = 0.0;
23580389061SMatthew G. Knepley   PetscInt  d;
23680389061SMatthew G. Knepley 
23780389061SMatthew G. Knepley   PetscFunctionBegin;
23880389061SMatthew G. Knepley   *inside = PETSC_TRUE;
239412e9a14SMatthew G. Knepley   switch (ct) {
240412e9a14SMatthew G. Knepley   case DM_POLYTOPE_TRIANGLE:
241412e9a14SMatthew G. Knepley   case DM_POLYTOPE_TETRAHEDRON:
242412e9a14SMatthew G. Knepley     for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) {
24380389061SMatthew G. Knepley       if (point[d] < -1.0) {*inside = PETSC_FALSE; break;}
24480389061SMatthew G. Knepley       sum += point[d];
24580389061SMatthew G. Knepley     }
246412e9a14SMatthew G. Knepley     if (sum > PETSC_SMALL) {*inside = PETSC_FALSE; break;}
24780389061SMatthew G. Knepley     break;
248412e9a14SMatthew G. Knepley   case DM_POLYTOPE_QUADRILATERAL:
249412e9a14SMatthew G. Knepley   case DM_POLYTOPE_HEXAHEDRON:
250412e9a14SMatthew G. Knepley     for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d)
251412e9a14SMatthew G. Knepley       if (PetscAbsReal(point[d]) > 1.+PETSC_SMALL) {*inside = PETSC_FALSE; break;}
25294339e62SJed Brown     break;
25380389061SMatthew G. Knepley   default:
254412e9a14SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]);
25580389061SMatthew G. Knepley   }
25680389061SMatthew G. Knepley   PetscFunctionReturn(0);
25780389061SMatthew G. Knepley }
25880389061SMatthew G. Knepley 
259412e9a14SMatthew G. Knepley /* Regular Refinment of Hybrid Meshes
26075d3a19aSMatthew G. Knepley 
261412e9a14SMatthew G. Knepley    We would like to express regular refinement as a small set of rules that can be applied on every point of the Plex
262412e9a14SMatthew G. Knepley    to automatically generate a refined Plex. In fact, we would like these rules to be general enough to encompass other
263412e9a14SMatthew G. Knepley    transformations, such as changing from one type of cell to another, as simplex to hex.
26475d3a19aSMatthew G. Knepley 
265412e9a14SMatthew G. Knepley    To start, we can create a function that takes an original cell type and returns the number of new cells replacing it
266412e9a14SMatthew G. Knepley    and the types of the new cells.
267518a8359SMatthew G. Knepley 
268412e9a14SMatthew G. Knepley    We need the group multiplication table for group actions from the dihedral group for each cell type.
26942525629SMatthew G. Knepley 
270412e9a14SMatthew G. Knepley    We need an operator which takes in a cell, and produces a new set of cells with new faces and correct orientations. I think
271412e9a14SMatthew G. Knepley    we can just write this operator for faces with identity, and then compose the face orientation actions to get the actual
272412e9a14SMatthew G. Knepley    (face, orient) pairs for each subcell.
273412e9a14SMatthew G. Knepley */
2740314a74cSLawrence Mitchell 
27575d3a19aSMatthew G. Knepley /*
276412e9a14SMatthew G. Knepley   Input Parameters:
277412e9a14SMatthew G. Knepley + ct - The type of the input cell
278412e9a14SMatthew G. Knepley . co - The orientation of this cell in it parent
279412e9a14SMatthew G. Knepley - cp - The requested cone point of this cell assuming orientation 0
280412e9a14SMatthew G. Knepley 
281412e9a14SMatthew G. Knepley   Output Parameters:
282412e9a14SMatthew G. Knepley . cpnew - The new cone point, taking inout account the orientation co
283412e9a14SMatthew G. Knepley */
284412e9a14SMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode DMPolytopeMapCell(DMPolytopeType ct, PetscInt co, PetscInt cp, PetscInt *cpnew)
285412e9a14SMatthew G. Knepley {
286412e9a14SMatthew G. Knepley   const PetscInt csize = DMPolytopeTypeGetConeSize(ct);
287412e9a14SMatthew G. Knepley 
288412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
289412e9a14SMatthew G. Knepley   if (ct == DM_POLYTOPE_POINT) {*cpnew = cp;}
290412e9a14SMatthew G. Knepley   else                         {*cpnew = (co < 0 ? -(co+1)-cp+csize : co+cp)%csize;}
291412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
292412e9a14SMatthew G. Knepley }
293412e9a14SMatthew G. Knepley 
294412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCellVertices_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[])
295412e9a14SMatthew G. Knepley {
296412e9a14SMatthew G. Knepley   static PetscReal seg_v[]  = {-1.0,  0.0,  1.0};
297412e9a14SMatthew G. Knepley   static PetscReal tri_v[]  = {-1.0, -1.0,  1.0, -1.0,  -1.0, 1.0,  0.0, -1.0,  0.0, 0.0,  -1.0, 0.0};
298412e9a14SMatthew G. Knepley   static PetscReal quad_v[] = {-1.0, -1.0,  1.0, -1.0,   1.0, 1.0,  -1.0, 1.0,  0.0, -1.0,  1.0, 0.0,   0.0, 1.0,  -1.0, 0.0,  0.0, 0.0};
299412e9a14SMatthew G. Knepley   static PetscReal tet_v[]  = {-1.0, -1.0, -1.0,   0.0, -1.0, -1.0,   1.0, -1.0, -1.0,
300412e9a14SMatthew G. Knepley                                -1.0,  0.0, -1.0,   0.0,  0.0, -1.0,  -1.0,  1.0, -1.0,
301412e9a14SMatthew G. Knepley                                -1.0, -1.0,  0.0,   0.0, -1.0,  0.0,  -1.0,  0.0,  0.0,  -1.0, -1.0,  1.0};
302412e9a14SMatthew G. Knepley   static PetscReal hex_v[]  = {-1.0, -1.0, -1.0,   0.0, -1.0, -1.0,   1.0, -1.0, -1.0,
303412e9a14SMatthew G. Knepley                                -1.0,  0.0, -1.0,   0.0,  0.0, -1.0,   1.0,  0.0, -1.0,
304412e9a14SMatthew G. Knepley                                -1.0,  1.0, -1.0,   0.0,  1.0, -1.0,   1.0,  1.0, -1.0,
305412e9a14SMatthew G. Knepley                                -1.0, -1.0,  0.0,   0.0, -1.0,  0.0,   1.0, -1.0,  0.0,
306412e9a14SMatthew G. Knepley                                -1.0,  0.0,  0.0,   0.0,  0.0,  0.0,   1.0,  0.0,  0.0,
307412e9a14SMatthew G. Knepley                                -1.0,  1.0,  0.0,   0.0,  1.0,  0.0,   1.0,  1.0,  0.0,
308412e9a14SMatthew G. Knepley                                -1.0, -1.0,  1.0,   0.0, -1.0,  1.0,   1.0, -1.0,  1.0,
309412e9a14SMatthew G. Knepley                                -1.0,  0.0,  1.0,   0.0,  0.0,  1.0,   1.0,  0.0,  1.0,
310412e9a14SMatthew G. Knepley                                -1.0,  1.0,  1.0,   0.0,  1.0,  1.0,   1.0,  1.0,  1.0};
311412e9a14SMatthew G. Knepley 
312412e9a14SMatthew G. Knepley   PetscFunctionBegin;
313412e9a14SMatthew G. Knepley   switch (ct) {
314412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:       *Nv =  3; *subcellV = seg_v;  break;
315412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:      *Nv =  6; *subcellV = tri_v;  break;
316412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL: *Nv =  9; *subcellV = quad_v; break;
317412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:   *Nv = 10; *subcellV = tet_v;  break;
318412e9a14SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:    *Nv = 27; *subcellV = hex_v;  break;
319412e9a14SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]);
320412e9a14SMatthew G. Knepley   }
321412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
322412e9a14SMatthew G. Knepley }
323412e9a14SMatthew G. Knepley 
32496ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerGetCellVertices_ToBox(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[])
325412e9a14SMatthew G. Knepley {
326412e9a14SMatthew G. Knepley   static PetscReal tri_v[] = {-1.0, -1.0,  1.0, -1.0,  -1.0, 1.0,  0.0, -1.0,  0.0, 0.0,  -1.0, 0.0,  -1.0/3.0, -1.0/3.0};
327412e9a14SMatthew G. Knepley   static PetscReal tet_v[] = {-1.0, -1.0, -1.0,   0.0, -1.0, -1.0,   1.0, -1.0, -1.0,
328412e9a14SMatthew G. Knepley                               -1.0,  0.0, -1.0,  -1.0/3.0, -1.0/3.0, -1.0,   0.0,  0.0, -1.0,  -1.0,  1.0, -1.0,
329412e9a14SMatthew G. Knepley                               -1.0, -1.0,  0.0,  -1.0/3.0, -1.0, -1.0/3.0,   0.0, -1.0,  0.0,
330412e9a14SMatthew G. Knepley                               -1.0, -1.0/3.0, -1.0/3.0,  -1.0/3.0, -1.0/3.0, -1.0/3.0,  -1.0,  0.0,  0.0,
331412e9a14SMatthew G. Knepley                               -1.0, -1.0,  1.0,  -0.5, -0.5, -0.5};
332412e9a14SMatthew G. Knepley   PetscErrorCode   ierr;
333412e9a14SMatthew G. Knepley 
334412e9a14SMatthew G. Knepley   PetscFunctionBegin;
335412e9a14SMatthew G. Knepley   switch (ct) {
336412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
337412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
338412e9a14SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:
339412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerGetCellVertices_Regular(cr, ct, Nv, subcellV);CHKERRQ(ierr);break;
340412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:    *Nv =  7; *subcellV = tri_v; break;
341412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON: *Nv = 15; *subcellV = tet_v;  break;
342412e9a14SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]);
343412e9a14SMatthew G. Knepley   }
344412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
345412e9a14SMatthew G. Knepley }
346412e9a14SMatthew G. Knepley 
347412e9a14SMatthew G. Knepley /*
348412e9a14SMatthew G. Knepley   DMPlexCellRefinerGetCellVertices - Get the set of refined vertices lying in the closure of a reference cell of given type
349412e9a14SMatthew G. Knepley 
350412e9a14SMatthew G. Knepley   Input Parameters:
351412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object
352412e9a14SMatthew G. Knepley - ct - The cell type
353412e9a14SMatthew G. Knepley 
354412e9a14SMatthew G. Knepley   Output Parameters:
355412e9a14SMatthew G. Knepley + Nv       - The number of refined vertices in the closure of the reference cell of given type
356412e9a14SMatthew G. Knepley - subcellV - The coordinates of these vertices in the reference cell
357412e9a14SMatthew G. Knepley 
358412e9a14SMatthew G. Knepley   Level: developer
359412e9a14SMatthew G. Knepley 
360412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetSubcellVertices()
361412e9a14SMatthew G. Knepley */
362412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCellVertices(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nv, PetscReal *subcellV[])
363412e9a14SMatthew G. Knepley {
364412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
365412e9a14SMatthew G. Knepley 
366412e9a14SMatthew G. Knepley   PetscFunctionBegin;
367412e9a14SMatthew G. Knepley   ierr = (*cr->ops->getcellvertices)(cr, ct, Nv, subcellV);CHKERRQ(ierr);
368412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
369412e9a14SMatthew G. Knepley }
370412e9a14SMatthew G. Knepley 
371412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[])
372412e9a14SMatthew G. Knepley {
373412e9a14SMatthew G. Knepley   static PetscInt seg_v[]  = {0, 1, 1, 2};
374412e9a14SMatthew G. Knepley   static PetscInt tri_v[]  = {0, 3, 5,  3, 1, 4,  5, 4, 2,  3, 4, 5};
375412e9a14SMatthew G. Knepley   static PetscInt quad_v[] = {0, 4, 8, 7,  4, 1, 5, 8,  8, 5, 2, 6,  7, 8, 6, 3};
376412e9a14SMatthew G. Knepley   static PetscInt tet_v[]  = {0, 3, 1, 6,  3, 2, 4, 8,  1, 4, 5, 7,  6, 8, 7, 9,
377412e9a14SMatthew G. Knepley                               1, 6, 3, 7,  8, 4, 3, 7,  7, 3, 1, 4,  7, 3, 8, 6};
378412e9a14SMatthew G. Knepley   static PetscInt hex_v[]  = {0,  3,  4,  1,  9, 10, 13, 12,   3,  6,  7,  4, 12, 13, 16, 15,   4,  7,  8,  5, 13, 14, 17, 16,   1,  4 , 5 , 2, 10, 11, 14, 13,
379412e9a14SMatthew G. Knepley                               9, 12, 13, 10, 18, 19, 22, 21,  10, 13, 14, 11, 19, 20, 23, 22,  13, 16, 17, 14, 22, 23, 26, 25,  12, 15, 16, 13, 21, 22, 25, 24};
380412e9a14SMatthew G. Knepley 
381412e9a14SMatthew G. Knepley   PetscFunctionBegin;
382412e9a14SMatthew G. Knepley   if (ct != rct) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]);
383412e9a14SMatthew G. Knepley   switch (ct) {
384412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:       *Nv = 2; *subcellV = &seg_v[r*(*Nv)];  break;
385412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:      *Nv = 3; *subcellV = &tri_v[r*(*Nv)];  break;
386412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL: *Nv = 4; *subcellV = &quad_v[r*(*Nv)]; break;
387412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:   *Nv = 4; *subcellV = &tet_v[r*(*Nv)];  break;
388412e9a14SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:    *Nv = 8; *subcellV = &hex_v[r*(*Nv)];  break;
389412e9a14SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]);
390412e9a14SMatthew G. Knepley   }
391412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
392412e9a14SMatthew G. Knepley }
393412e9a14SMatthew G. Knepley 
39496ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_ToBox(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[])
395412e9a14SMatthew G. Knepley {
396412e9a14SMatthew G. Knepley   static PetscInt tri_v[]  = {0, 3, 6, 5,  3, 1, 4, 6,  5, 6, 4, 2};
397412e9a14SMatthew G. Knepley   static PetscInt tet_v[]  = {0,  3,  4,  1,  7,  8, 14, 10,   6, 12, 11,  5,  3,  4, 14, 10,   2,  5, 11,  9,  1,  8, 14,  4,  13, 12 , 10,  7,  9,  8, 14, 11};
398412e9a14SMatthew G. Knepley   PetscErrorCode  ierr;
399412e9a14SMatthew G. Knepley 
400412e9a14SMatthew G. Knepley   PetscFunctionBegin;
401412e9a14SMatthew G. Knepley   switch (ct) {
402412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
403412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
404412e9a14SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:
405412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerGetSubcellVertices_Regular(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr);break;
406412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:
407412e9a14SMatthew G. Knepley       if (rct != DM_POLYTOPE_QUADRILATERAL) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]);
408412e9a14SMatthew G. Knepley       *Nv = 4; *subcellV = &tri_v[r*(*Nv)]; break;
409412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:
410412e9a14SMatthew G. Knepley       if (rct != DM_POLYTOPE_HEXAHEDRON) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]);
411412e9a14SMatthew G. Knepley       *Nv = 8; *subcellV = &tet_v[r*(*Nv)]; break;
412412e9a14SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]);
413412e9a14SMatthew G. Knepley   }
414412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
415412e9a14SMatthew G. Knepley }
416412e9a14SMatthew G. Knepley 
417412e9a14SMatthew G. Knepley /*
418412e9a14SMatthew G. Knepley   DMPlexCellRefinerGetSubcellVertices - Get the set of refined vertices defining a subcell in the reference cell of given type
419412e9a14SMatthew G. Knepley 
420412e9a14SMatthew G. Knepley   Input Parameters:
421412e9a14SMatthew G. Knepley + cr  - The DMPlexCellRefiner object
422412e9a14SMatthew G. Knepley . ct  - The cell type
423412e9a14SMatthew G. Knepley . rct - The type of subcell
424412e9a14SMatthew G. Knepley - r   - The subcell index
425412e9a14SMatthew G. Knepley 
426412e9a14SMatthew G. Knepley   Output Parameters:
427412e9a14SMatthew G. Knepley + Nv       - The number of refined vertices in the subcell
428412e9a14SMatthew G. Knepley - subcellV - The indices of these vertices in the set of vertices returned by DMPlexCellRefinerGetCellVertices()
429412e9a14SMatthew G. Knepley 
430412e9a14SMatthew G. Knepley   Level: developer
431412e9a14SMatthew G. Knepley 
432412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetCellVertices()
433412e9a14SMatthew G. Knepley */
434412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[])
435412e9a14SMatthew G. Knepley {
436412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
437412e9a14SMatthew G. Knepley 
438412e9a14SMatthew G. Knepley   PetscFunctionBegin;
439412e9a14SMatthew G. Knepley   ierr = (*cr->ops->getsubcellvertices)(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr);
440412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
441412e9a14SMatthew G. Knepley }
442412e9a14SMatthew G. Knepley 
443412e9a14SMatthew G. Knepley /*
444412e9a14SMatthew G. Knepley   Input Parameters:
445412e9a14SMatthew G. Knepley + cr  - The DMPlexCellRefiner
446412e9a14SMatthew G. Knepley . pct - The cell type of the parent, from whom the new cell is being produced
447412e9a14SMatthew G. Knepley . po  - The orientation of the parent cell in its enclosing parent
448412e9a14SMatthew G. Knepley . ct  - The type being produced
449412e9a14SMatthew G. Knepley . r   - The replica number requested for the produced cell type
450412e9a14SMatthew G. Knepley - o   - The relative orientation of the replica
451412e9a14SMatthew G. Knepley 
452412e9a14SMatthew G. Knepley   Output Parameters:
453412e9a14SMatthew G. Knepley + rnew - The replica number, given the orientation of of the parent
454412e9a14SMatthew G. Knepley - onew - The replica orientation, given the orientation of the parent
455412e9a14SMatthew G. Knepley */
456412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
457412e9a14SMatthew G. Knepley {
458412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
459412e9a14SMatthew G. Knepley 
460412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
461412e9a14SMatthew G. Knepley   ierr = (*cr->ops->mapsubcells)(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr);
462412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
463412e9a14SMatthew G. Knepley }
464412e9a14SMatthew G. Knepley 
465*cf4091a3SMatthew G. Knepley /*
466*cf4091a3SMatthew G. Knepley   This is the group multiplication table for the dihedral group of the cell.
467*cf4091a3SMatthew G. Knepley */
468*cf4091a3SMatthew G. Knepley static PetscErrorCode ComposeOrientation_Private(PetscInt n, PetscInt o1, PetscInt o2, PetscInt *o)
469*cf4091a3SMatthew G. Knepley {
470*cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
471*cf4091a3SMatthew G. Knepley   if (!n)                      {*o = 0;}
472*cf4091a3SMatthew G. Knepley   else if (o1 >= 0 && o2 >= 0) {*o = ( o1 + o2) % n;}
473*cf4091a3SMatthew G. Knepley   else if (o1 <  0 && o2 <  0) {*o = (-o1 - o2) % n;}
474*cf4091a3SMatthew G. Knepley   else if (o1 < 0)             {*o = -((-(o1+1) + o2) % n + 1);}
475*cf4091a3SMatthew G. Knepley   else if (o2 < 0)             {*o = -((-(o2+1) + o1) % n + 1);}
476*cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
477*cf4091a3SMatthew G. Knepley }
478*cf4091a3SMatthew G. Knepley 
479*cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_None(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
480*cf4091a3SMatthew G. Knepley {
481*cf4091a3SMatthew G. Knepley   PetscErrorCode ierr;
482*cf4091a3SMatthew G. Knepley 
483*cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
484*cf4091a3SMatthew G. Knepley   *rnew = r;
485*cf4091a3SMatthew G. Knepley   ierr  = ComposeOrientation_Private(DMPolytopeTypeGetConeSize(ct), po, o, onew);CHKERRQ(ierr);
486*cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
487*cf4091a3SMatthew G. Knepley }
488*cf4091a3SMatthew G. Knepley 
489412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_Regular(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
490412e9a14SMatthew G. Knepley {
491412e9a14SMatthew G. Knepley   /* We shift any input orientation in order to make it non-negative
492412e9a14SMatthew G. Knepley        The orientation array o[po][o] gives the orientation the new replica rnew has to have in order to reproduce the face sequence from (r, o)
493412e9a14SMatthew G. Knepley        The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po
494412e9a14SMatthew G. Knepley        Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po
495412e9a14SMatthew G. Knepley   */
496412e9a14SMatthew G. Knepley   PetscInt tri_seg_o[] = {-2, 0,
497412e9a14SMatthew G. Knepley                           -2, 0,
498412e9a14SMatthew G. Knepley                           -2, 0,
499412e9a14SMatthew G. Knepley                           0, -2,
500412e9a14SMatthew G. Knepley                           0, -2,
501412e9a14SMatthew G. Knepley                           0, -2};
502412e9a14SMatthew G. Knepley   PetscInt tri_seg_r[] = {1, 0, 2,
503412e9a14SMatthew G. Knepley                           0, 2, 1,
504412e9a14SMatthew G. Knepley                           2, 1, 0,
505412e9a14SMatthew G. Knepley                           0, 1, 2,
506412e9a14SMatthew G. Knepley                           1, 2, 0,
507412e9a14SMatthew G. Knepley                           2, 0, 1};
508412e9a14SMatthew G. Knepley   PetscInt tri_tri_o[] = {0,  1,  2, -3, -2, -1,
509412e9a14SMatthew G. Knepley                           2,  0,  1, -2, -1, -3,
510412e9a14SMatthew G. Knepley                           1,  2,  0, -1, -3, -2,
511412e9a14SMatthew G. Knepley                          -3, -2, -1,  0,  1,  2,
512412e9a14SMatthew G. Knepley                          -1, -3, -2,  1,  2,  0,
513412e9a14SMatthew G. Knepley                          -2, -1, -3,  2,  0,  1};
514412e9a14SMatthew G. Knepley   /* orientation if the replica is the center triangle */
515412e9a14SMatthew G. Knepley   PetscInt tri_tri_o_c[] = {2,  0,  1, -2, -1, -3,
516412e9a14SMatthew G. Knepley                             1,  2,  0, -1, -3, -2,
517412e9a14SMatthew G. Knepley                             0,  1,  2, -3, -2, -1,
518412e9a14SMatthew G. Knepley                            -3, -2, -1,  0,  1,  2,
519412e9a14SMatthew G. Knepley                            -1, -3, -2,  1,  2,  0,
520412e9a14SMatthew G. Knepley                            -2, -1, -3,  2,  0,  1};
521412e9a14SMatthew G. Knepley   PetscInt tri_tri_r[] = {0, 2, 1, 3,
522412e9a14SMatthew G. Knepley                           2, 1, 0, 3,
523412e9a14SMatthew G. Knepley                           1, 0, 2, 3,
524412e9a14SMatthew G. Knepley                           0, 1, 2, 3,
525412e9a14SMatthew G. Knepley                           1, 2, 0, 3,
526412e9a14SMatthew G. Knepley                           2, 0, 1, 3};
527412e9a14SMatthew G. Knepley   PetscInt quad_seg_r[] = {3, 2, 1, 0,
528412e9a14SMatthew G. Knepley                            2, 1, 0, 3,
529412e9a14SMatthew G. Knepley                            1, 0, 3, 2,
530412e9a14SMatthew G. Knepley                            0, 3, 2, 1,
531412e9a14SMatthew G. Knepley                            0, 1, 2, 3,
532412e9a14SMatthew G. Knepley                            1, 2, 3, 0,
533412e9a14SMatthew G. Knepley                            2, 3, 0, 1,
534412e9a14SMatthew G. Knepley                            3, 0, 1, 2};
535412e9a14SMatthew G. Knepley   PetscInt quad_quad_o[] = { 0,  1,  2,  3, -4, -3, -2, -1,
536412e9a14SMatthew G. Knepley                              4,  0,  1,  2, -3, -2, -1, -4,
537412e9a14SMatthew G. Knepley                              3,  4,  0,  1, -2, -1, -4, -3,
538412e9a14SMatthew G. Knepley                              2,  3,  4,  0, -1, -4, -3, -2,
539412e9a14SMatthew G. Knepley                             -4, -3, -2, -1,  0,  1,  2,  3,
540412e9a14SMatthew G. Knepley                             -1, -4, -3, -2,  1,  2,  3,  0,
541412e9a14SMatthew G. Knepley                             -2, -1, -4, -3,  2,  3,  0,  1,
542412e9a14SMatthew G. Knepley                             -3, -2, -1, -4,  3,  0,  1,  2};
543412e9a14SMatthew G. Knepley   PetscInt quad_quad_r[] = {0, 3, 2, 1,
544412e9a14SMatthew G. Knepley                             3, 2, 1, 0,
545412e9a14SMatthew G. Knepley                             2, 1, 0, 3,
546412e9a14SMatthew G. Knepley                             1, 0, 3, 2,
547412e9a14SMatthew G. Knepley                             0, 1, 2, 3,
548412e9a14SMatthew G. Knepley                             1, 2, 3, 0,
549412e9a14SMatthew G. Knepley                             2, 3, 0, 1,
550412e9a14SMatthew G. Knepley                             3, 0, 1, 2};
551412e9a14SMatthew G. Knepley   PetscInt tquad_tquad_o[] = { 0,  1, -2, -1,
552412e9a14SMatthew G. Knepley                                1,  0, -1, -2,
553412e9a14SMatthew G. Knepley                               -2, -1,  0,  1,
554412e9a14SMatthew G. Knepley                               -1, -2,  1,  0};
555412e9a14SMatthew G. Knepley   PetscInt tquad_tquad_r[] = {1, 0,
556412e9a14SMatthew G. Knepley                               1, 0,
557412e9a14SMatthew G. Knepley                               0, 1,
558412e9a14SMatthew G. Knepley                               0, 1};
559412e9a14SMatthew G. Knepley 
560412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
561412e9a14SMatthew G. Knepley   /* The default is no transformation */
562412e9a14SMatthew G. Knepley   *rnew = r;
563412e9a14SMatthew G. Knepley   *onew = o;
564412e9a14SMatthew G. Knepley   switch (pct) {
565412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
566412e9a14SMatthew G. Knepley       if (ct == DM_POLYTOPE_SEGMENT) {
567412e9a14SMatthew G. Knepley         if      (po == 0 || po == -1) {*rnew = r;       *onew = o;}
568412e9a14SMatthew G. Knepley         else if (po == 1 || po == -2) {*rnew = (r+1)%2; *onew = (o == 0 || o == -1) ? -2 : 0;}
569412e9a14SMatthew G. Knepley         else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for segment", po);
570412e9a14SMatthew G. Knepley       }
571412e9a14SMatthew G. Knepley       break;
572412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:
573412e9a14SMatthew G. Knepley       switch (ct) {
574412e9a14SMatthew G. Knepley         case DM_POLYTOPE_SEGMENT:
575412e9a14SMatthew G. Knepley           if (o == -1) o = 0;
576412e9a14SMatthew G. Knepley           if (o == -2) o = 1;
577412e9a14SMatthew G. Knepley           *onew = tri_seg_o[(po+3)*2+o];
578412e9a14SMatthew G. Knepley           *rnew = tri_seg_r[(po+3)*3+r];
579412e9a14SMatthew G. Knepley           break;
580412e9a14SMatthew G. Knepley         case DM_POLYTOPE_TRIANGLE:
581412e9a14SMatthew G. Knepley           *onew = r == 3 && po < 0 ? tri_tri_o_c[((po+3)%3)*6+o+3] : tri_tri_o[(po+3)*6+o+3];
582412e9a14SMatthew G. Knepley           *rnew = tri_tri_r[(po+3)*4+r];
583412e9a14SMatthew G. Knepley           break;
584412e9a14SMatthew G. Knepley         default: break;
585412e9a14SMatthew G. Knepley       }
586412e9a14SMatthew G. Knepley       break;
587412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
588412e9a14SMatthew G. Knepley       switch (ct) {
589412e9a14SMatthew G. Knepley         case DM_POLYTOPE_SEGMENT:
590412e9a14SMatthew G. Knepley           *onew = o;
591412e9a14SMatthew G. Knepley           *rnew = quad_seg_r[(po+4)*4+r];
592412e9a14SMatthew G. Knepley           break;
593412e9a14SMatthew G. Knepley         case DM_POLYTOPE_QUADRILATERAL:
594412e9a14SMatthew G. Knepley           *onew = quad_quad_o[(po+4)*8+o+4];
595412e9a14SMatthew G. Knepley           *rnew = quad_quad_r[(po+4)*4+r];
596412e9a14SMatthew G. Knepley           break;
597412e9a14SMatthew G. Knepley         default: break;
598412e9a14SMatthew G. Knepley       }
599412e9a14SMatthew G. Knepley       break;
600412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
601412e9a14SMatthew G. Knepley       switch (ct) {
602412e9a14SMatthew G. Knepley         /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */
603412e9a14SMatthew G. Knepley         case DM_POLYTOPE_SEG_PRISM_TENSOR:
604412e9a14SMatthew G. Knepley           *onew = tquad_tquad_o[(po+2)*4+o+2];
605412e9a14SMatthew G. Knepley           *rnew = tquad_tquad_r[(po+2)*2+r];
606412e9a14SMatthew G. Knepley           break;
607412e9a14SMatthew G. Knepley         default: break;
608412e9a14SMatthew G. Knepley       }
609412e9a14SMatthew G. Knepley       break;
610412e9a14SMatthew G. Knepley     default: break;
611412e9a14SMatthew G. Knepley   }
612412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
613412e9a14SMatthew G. Knepley }
614412e9a14SMatthew G. Knepley 
61596ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerMapSubcells_ToBox(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
616412e9a14SMatthew G. Knepley {
617412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
618412e9a14SMatthew G. Knepley   /* We shift any input orientation in order to make it non-negative
619412e9a14SMatthew G. Knepley        The orientation array o[po][o] gives the orientation the new replica rnew has to have in order to reproduce the face sequence from (r, o)
620412e9a14SMatthew G. Knepley        The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po
621412e9a14SMatthew G. Knepley        Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po
622412e9a14SMatthew G. Knepley   */
623412e9a14SMatthew G. Knepley   PetscInt tri_seg_o[] = {0, -2,
624412e9a14SMatthew G. Knepley                           0, -2,
625412e9a14SMatthew G. Knepley                           0, -2,
626412e9a14SMatthew G. Knepley                           0, -2,
627412e9a14SMatthew G. Knepley                           0, -2,
628412e9a14SMatthew G. Knepley                           0, -2};
629412e9a14SMatthew G. Knepley   PetscInt tri_seg_r[] = {2, 1, 0,
630412e9a14SMatthew G. Knepley                           1, 0, 2,
631412e9a14SMatthew G. Knepley                           0, 2, 1,
632412e9a14SMatthew G. Knepley                           0, 1, 2,
633412e9a14SMatthew G. Knepley                           1, 2, 0,
634412e9a14SMatthew G. Knepley                           2, 0, 1};
635412e9a14SMatthew G. Knepley   PetscInt tri_tri_o[] = {0,  1,  2,  3, -4, -3, -2, -1,
636412e9a14SMatthew G. Knepley                           3,  0,  1,  2, -3, -2, -1, -4,
637412e9a14SMatthew G. Knepley                           1,  2,  3,  0, -1, -4, -3, -2,
638412e9a14SMatthew G. Knepley                          -4, -3, -2, -1,  0,  1,  2,  3,
639412e9a14SMatthew G. Knepley                          -1, -4, -3, -2,  1,  2,  3,  0,
640412e9a14SMatthew G. Knepley                          -3, -2, -1, -4,  3,  0,  1,  2};
641412e9a14SMatthew G. Knepley   PetscInt tri_tri_r[] = {0, 2, 1,
642412e9a14SMatthew G. Knepley                           2, 1, 0,
643412e9a14SMatthew G. Knepley                           1, 0, 2,
644412e9a14SMatthew G. Knepley                           0, 1, 2,
645412e9a14SMatthew G. Knepley                           1, 2, 0,
646412e9a14SMatthew G. Knepley                           2, 0, 1};
647412e9a14SMatthew G. Knepley   PetscInt tquad_tquad_o[] = { 0,  1, -2, -1,
648412e9a14SMatthew G. Knepley                                1,  0, -1, -2,
649412e9a14SMatthew G. Knepley                               -2, -1,  0,  1,
650412e9a14SMatthew G. Knepley                               -1, -2,  1,  0};
651412e9a14SMatthew G. Knepley   PetscInt tquad_tquad_r[] = {1, 0,
652412e9a14SMatthew G. Knepley                               1, 0,
653412e9a14SMatthew G. Knepley                               0, 1,
654412e9a14SMatthew G. Knepley                               0, 1};
655412e9a14SMatthew G. Knepley   PetscInt tquad_quad_o[] = {-2, -1, -4, -3,  2,  3,  0,  1,
656412e9a14SMatthew G. Knepley                               1,  2,  3,  0, -1, -4, -3, -2,
657412e9a14SMatthew G. Knepley                              -4, -3, -2, -1,  0,  1,  2,  3,
658412e9a14SMatthew G. Knepley                               1,  0,  3,  2, -3, -4, -1, -2};
659412e9a14SMatthew G. Knepley 
660412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
661412e9a14SMatthew G. Knepley   *rnew = r;
662412e9a14SMatthew G. Knepley   *onew = o;
663412e9a14SMatthew G. Knepley   switch (pct) {
664412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:
665412e9a14SMatthew G. Knepley       switch (ct) {
666412e9a14SMatthew G. Knepley         case DM_POLYTOPE_SEGMENT:
667412e9a14SMatthew G. Knepley           if (o == -1) o = 0;
668412e9a14SMatthew G. Knepley           if (o == -2) o = 1;
669412e9a14SMatthew G. Knepley           *onew = tri_seg_o[(po+3)*2+o];
670412e9a14SMatthew G. Knepley           *rnew = tri_seg_r[(po+3)*3+r];
671412e9a14SMatthew G. Knepley           break;
672412e9a14SMatthew G. Knepley         case DM_POLYTOPE_QUADRILATERAL:
673412e9a14SMatthew G. Knepley           *onew = tri_tri_o[(po+3)*8+o+4];
674412e9a14SMatthew G. Knepley           /* TODO See sheet, for fixing po == 1 and 2 */
675412e9a14SMatthew G. Knepley           if (po ==  2 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4];
676412e9a14SMatthew G. Knepley           if (po ==  2 && r == 2 && o <  0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)];
677412e9a14SMatthew G. Knepley           if (po ==  1 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4];
678412e9a14SMatthew G. Knepley           if (po ==  1 && r == 1 && o <  0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)];
679412e9a14SMatthew G. Knepley           if (po == -1 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4];
680412e9a14SMatthew G. Knepley           if (po == -1 && r == 2 && o <  0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)];
681412e9a14SMatthew G. Knepley           if (po == -2 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4];
682412e9a14SMatthew G. Knepley           if (po == -2 && r == 1 && o <  0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)];
683412e9a14SMatthew G. Knepley           *rnew = tri_tri_r[(po+3)*3+r];
684412e9a14SMatthew G. Knepley           break;
685412e9a14SMatthew G. Knepley         default: break;
686412e9a14SMatthew G. Knepley       }
687412e9a14SMatthew G. Knepley       break;
688412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
689412e9a14SMatthew G. Knepley       switch (ct) {
690412e9a14SMatthew G. Knepley         /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */
691412e9a14SMatthew G. Knepley         case DM_POLYTOPE_SEG_PRISM_TENSOR:
692412e9a14SMatthew G. Knepley           *onew = tquad_tquad_o[(po+2)*4+o+2];
693412e9a14SMatthew G. Knepley           *rnew = tquad_tquad_r[(po+2)*2+r];
694412e9a14SMatthew G. Knepley           break;
695412e9a14SMatthew G. Knepley         case DM_POLYTOPE_QUADRILATERAL:
696412e9a14SMatthew G. Knepley           *onew = tquad_quad_o[(po+2)*8+o+4];
697412e9a14SMatthew G. Knepley           *rnew = tquad_tquad_r[(po+2)*2+r];
698412e9a14SMatthew G. Knepley           break;
699412e9a14SMatthew G. Knepley         default: break;
700412e9a14SMatthew G. Knepley       }
701412e9a14SMatthew G. Knepley       break;
702412e9a14SMatthew G. Knepley     default:
703412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerMapSubcells_Regular(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr);
704412e9a14SMatthew G. Knepley   }
705412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
706412e9a14SMatthew G. Knepley }
707412e9a14SMatthew G. Knepley 
708412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
709412e9a14SMatthew G. Knepley {
710412e9a14SMatthew G. Knepley   return DMPlexCellRefinerMapSubcells_Regular(cr, pct, po, ct, r, o, rnew, onew);
711412e9a14SMatthew G. Knepley }
712412e9a14SMatthew G. Knepley 
713*cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_BL(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
714*cf4091a3SMatthew G. Knepley {
715*cf4091a3SMatthew G. Knepley   /* We shift any input orientation in order to make it non-negative
716*cf4091a3SMatthew G. Knepley        The orientation array o[po][o] gives the orientation the new replica rnew has to have in order to reproduce the face sequence from (r, o)
717*cf4091a3SMatthew G. Knepley        The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po
718*cf4091a3SMatthew G. Knepley        Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po
719*cf4091a3SMatthew G. Knepley   */
720*cf4091a3SMatthew G. Knepley   PetscInt tquad_seg_o[]   = { 0,  1, -2, -1,
721*cf4091a3SMatthew G. Knepley                                0,  1, -2, -1,
722*cf4091a3SMatthew G. Knepley                               -2, -1,  0,  1,
723*cf4091a3SMatthew G. Knepley                               -2, -1,  0,  1};
724*cf4091a3SMatthew G. Knepley   PetscInt tquad_tquad_o[] = { 0,  1, -2, -1,
725*cf4091a3SMatthew G. Knepley                                1,  0, -1, -2,
726*cf4091a3SMatthew G. Knepley                               -2, -1,  0,  1,
727*cf4091a3SMatthew G. Knepley                               -1, -2,  1,  0};
728*cf4091a3SMatthew G. Knepley   PetscInt tquad_tquad_r[] = {1, 0,
729*cf4091a3SMatthew G. Knepley                               0, 1,
730*cf4091a3SMatthew G. Knepley                               0, 1,
731*cf4091a3SMatthew G. Knepley                               1, 0};
732*cf4091a3SMatthew G. Knepley   PetscErrorCode ierr;
733*cf4091a3SMatthew G. Knepley 
734*cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
735*cf4091a3SMatthew G. Knepley   *rnew = r;
736*cf4091a3SMatthew G. Knepley   *onew = o;
737*cf4091a3SMatthew G. Knepley   switch (pct) {
738*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR:
739*cf4091a3SMatthew G. Knepley       if (ct == DM_POLYTOPE_POINT_PRISM_TENSOR) {
740*cf4091a3SMatthew G. Knepley         if      (po == 0 || po == -1) {*rnew = r;       *onew = o;}
741*cf4091a3SMatthew G. Knepley         else if (po == 1 || po == -2) {*rnew = (r+1)%2; *onew = (o == 0 || o == -1) ? -2 : 0;}
742*cf4091a3SMatthew G. Knepley         else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for tensor segment", po);
743*cf4091a3SMatthew G. Knepley       }
744*cf4091a3SMatthew G. Knepley       break;
745*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
746*cf4091a3SMatthew G. Knepley       switch (ct) {
747*cf4091a3SMatthew G. Knepley         case DM_POLYTOPE_SEGMENT:
748*cf4091a3SMatthew G. Knepley           *onew = tquad_seg_o[(po+2)*4+o+2];
749*cf4091a3SMatthew G. Knepley           break;
750*cf4091a3SMatthew G. Knepley         case DM_POLYTOPE_SEG_PRISM_TENSOR:
751*cf4091a3SMatthew G. Knepley           *onew = tquad_tquad_o[(po+2)*4+o+2];
752*cf4091a3SMatthew G. Knepley           *rnew = tquad_tquad_r[(po+2)*2+r];
753*cf4091a3SMatthew G. Knepley           break;
754*cf4091a3SMatthew G. Knepley         default: break;
755*cf4091a3SMatthew G. Knepley       }
756*cf4091a3SMatthew G. Knepley       break;
757*cf4091a3SMatthew G. Knepley     default:
758*cf4091a3SMatthew G. Knepley       ierr = DMPlexCellRefinerMapSubcells_None(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr);
759*cf4091a3SMatthew G. Knepley   }
760*cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
761*cf4091a3SMatthew G. Knepley }
762*cf4091a3SMatthew G. Knepley 
763412e9a14SMatthew G. Knepley /*@
764412e9a14SMatthew G. Knepley   DMPlexCellRefinerRefine - Return a description of the refinement for a given cell type
765412e9a14SMatthew G. Knepley 
766412e9a14SMatthew G. Knepley   Input Parameter:
767412e9a14SMatthew G. Knepley . source - The cell type for a source point
768412e9a14SMatthew G. Knepley 
769412e9a14SMatthew G. Knepley   Output Parameter:
770412e9a14SMatthew G. Knepley + Nt     - The number of cell types generated by refinement
771412e9a14SMatthew G. Knepley . target - The cell types generated
772412e9a14SMatthew G. Knepley . size   - The number of subcells of each type, ordered by dimension
773412e9a14SMatthew G. Knepley . cone   - A list of the faces for each subcell of the same type as source
774412e9a14SMatthew G. Knepley - ornt   - A list of the face orientations for each subcell of the same type as source
775412e9a14SMatthew G. Knepley 
776412e9a14SMatthew G. Knepley   Note: The cone array gives the cone of each subcell listed by the first three outputs. For the each cone point, we
777412e9a14SMatthew G. Knepley   need the cell type, point identifier, and orientation within the subcell. The orientation is with respect to the canonical
778412e9a14SMatthew G. Knepley   division (described in these outputs) of the cell in the original mesh. The point identifier is given by
779412e9a14SMatthew G. Knepley $   the number of cones to be taken, or 0 for the current cell
780412e9a14SMatthew G. Knepley $   the cell cone point number at each level from which it is subdivided
781412e9a14SMatthew G. Knepley $   the replica number r of the subdivision.
782412e9a14SMatthew G. Knepley   The orientation is with respect to the canonical cone orientation. For example, the prescription for edge division is
783412e9a14SMatthew G. Knepley $   Nt     = 2
784412e9a14SMatthew G. Knepley $   target = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT}
785412e9a14SMatthew G. Knepley $   size   = {1, 2}
786412e9a14SMatthew G. Knepley $   cone   = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,  DM_POLYTOPE_POINT, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0}
787412e9a14SMatthew G. Knepley $   ornt   = {                         0,                       0,                        0,                          0}
788412e9a14SMatthew G. Knepley 
789412e9a14SMatthew G. Knepley   Level: developer
790412e9a14SMatthew G. Knepley 
79196ca5757SLisandro Dalcin .seealso: DMPlexCellRefinerCreate(), DMPlexRefineUniform()
792412e9a14SMatthew G. Knepley @*/
793412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerRefine(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
794412e9a14SMatthew G. Knepley {
795412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
796412e9a14SMatthew G. Knepley 
797412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
798412e9a14SMatthew G. Knepley   ierr = (*cr->ops->refine)(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
799412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
800412e9a14SMatthew G. Knepley }
801412e9a14SMatthew G. Knepley 
802*cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_None(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
803*cf4091a3SMatthew G. Knepley {
804*cf4091a3SMatthew G. Knepley   static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT};
805*cf4091a3SMatthew G. Knepley   static PetscInt       vertexS[] = {1};
806*cf4091a3SMatthew G. Knepley   static PetscInt       vertexC[] = {0};
807*cf4091a3SMatthew G. Knepley   static PetscInt       vertexO[] = {0};
808*cf4091a3SMatthew G. Knepley   static DMPolytopeType edgeT[]   = {DM_POLYTOPE_SEGMENT};
809*cf4091a3SMatthew G. Knepley   static PetscInt       edgeS[]   = {1};
810*cf4091a3SMatthew G. Knepley   static PetscInt       edgeC[]   = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
811*cf4091a3SMatthew G. Knepley   static PetscInt       edgeO[]   = {0, 0};
812*cf4091a3SMatthew G. Knepley   static DMPolytopeType tedgeT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR};
813*cf4091a3SMatthew G. Knepley   static PetscInt       tedgeS[]  = {1};
814*cf4091a3SMatthew G. Knepley   static PetscInt       tedgeC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
815*cf4091a3SMatthew G. Knepley   static PetscInt       tedgeO[]  = {0, 0};
816*cf4091a3SMatthew G. Knepley   static DMPolytopeType triT[]    = {DM_POLYTOPE_TRIANGLE};
817*cf4091a3SMatthew G. Knepley   static PetscInt       triS[]    = {1};
818*cf4091a3SMatthew G. Knepley   static PetscInt       triC[]    = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0};
819*cf4091a3SMatthew G. Knepley   static PetscInt       triO[]    = {0, 0, 0};
820*cf4091a3SMatthew G. Knepley   static DMPolytopeType quadT[]   = {DM_POLYTOPE_QUADRILATERAL};
821*cf4091a3SMatthew G. Knepley   static PetscInt       quadS[]   = {1};
822*cf4091a3SMatthew G. Knepley   static PetscInt       quadC[]   = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0};
823*cf4091a3SMatthew G. Knepley   static PetscInt       quadO[]   = {0, 0, 0, 0};
824*cf4091a3SMatthew G. Knepley   static DMPolytopeType tquadT[]  = {DM_POLYTOPE_SEG_PRISM_TENSOR};
825*cf4091a3SMatthew G. Knepley   static PetscInt       tquadS[]  = {1};
826*cf4091a3SMatthew G. Knepley   static PetscInt       tquadC[]  = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0};
827*cf4091a3SMatthew G. Knepley   static PetscInt       tquadO[]  = {0, 0, 0, 0};
828*cf4091a3SMatthew G. Knepley   static DMPolytopeType tetT[]    = {DM_POLYTOPE_TETRAHEDRON};
829*cf4091a3SMatthew G. Knepley   static PetscInt       tetS[]    = {1};
830*cf4091a3SMatthew G. Knepley   static PetscInt       tetC[]    = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 1, 3, 0};
831*cf4091a3SMatthew G. Knepley   static PetscInt       tetO[]    = {0, 0, 0, 0};
832*cf4091a3SMatthew G. Knepley   static DMPolytopeType hexT[]    = {DM_POLYTOPE_HEXAHEDRON};
833*cf4091a3SMatthew G. Knepley   static PetscInt       hexS[]    = {1};
834*cf4091a3SMatthew G. Knepley   static PetscInt       hexC[]    = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0,
835*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0, DM_POLYTOPE_QUADRILATERAL, 1, 5, 0};
836*cf4091a3SMatthew G. Knepley   static PetscInt       hexO[]    = {0, 0, 0, 0, 0, 0};
837*cf4091a3SMatthew G. Knepley   static DMPolytopeType tripT[]   = {DM_POLYTOPE_TRI_PRISM};
838*cf4091a3SMatthew G. Knepley   static PetscInt       tripS[]   = {1};
839*cf4091a3SMatthew G. Knepley   static PetscInt       tripC[]   = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0,
840*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0};
841*cf4091a3SMatthew G. Knepley   static PetscInt       tripO[]   = {0, 0, 0, 0, 0};
842*cf4091a3SMatthew G. Knepley   static DMPolytopeType ttripT[]  = {DM_POLYTOPE_TRI_PRISM_TENSOR};
843*cf4091a3SMatthew G. Knepley   static PetscInt       ttripS[]  = {1};
844*cf4091a3SMatthew G. Knepley   static PetscInt       ttripC[]  = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0,
845*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0};
846*cf4091a3SMatthew G. Knepley   static PetscInt       ttripO[]  = {0, 0, 0, 0, 0};
847*cf4091a3SMatthew G. Knepley   static DMPolytopeType tquadpT[] = {DM_POLYTOPE_QUAD_PRISM_TENSOR};
848*cf4091a3SMatthew G. Knepley   static PetscInt       tquadpS[] = {1};
849*cf4091a3SMatthew G. Knepley   static PetscInt       tquadpC[] = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0,
850*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 0};
851*cf4091a3SMatthew G. Knepley   static PetscInt       tquadpO[] = {0, 0, 0, 0, 0, 0};
852*cf4091a3SMatthew G. Knepley 
853*cf4091a3SMatthew G. Knepley   PetscFunctionBegin;
854*cf4091a3SMatthew G. Knepley   switch (source) {
855*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT:              *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break;
856*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:            *Nt = 1; *target = edgeT;   *size = edgeS;   *cone = edgeC;   *ornt = edgeO;   break;
857*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT;  *size = tedgeS;  *cone = tedgeC;  *ornt = tedgeO;  break;
858*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:           *Nt = 1; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
859*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:      *Nt = 1; *target = quadT;   *size = quadS;   *cone = quadC;   *ornt = quadO;   break;
860*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:   *Nt = 1; *target = tquadT;  *size = tquadS;  *cone = tquadC;  *ornt = tquadO;  break;
861*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:        *Nt = 1; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
862*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:         *Nt = 1; *target = hexT;    *size = hexS;    *cone = hexC;    *ornt = hexO;    break;
863*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:          *Nt = 1; *target = tripT;   *size = tripS;   *cone = tripC;   *ornt = tripO;   break;
864*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:   *Nt = 1; *target = ttripT;  *size = ttripS;  *cone = ttripC;  *ornt = ttripO;  break;
865*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  *Nt = 1; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break;
866*cf4091a3SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
867*cf4091a3SMatthew G. Knepley   }
868*cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
869*cf4091a3SMatthew G. Knepley }
870*cf4091a3SMatthew G. Knepley 
871412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Regular(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
872412e9a14SMatthew G. Knepley {
873412e9a14SMatthew G. Knepley   /* All vertices remain in the refined mesh */
874412e9a14SMatthew G. Knepley   static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT};
875412e9a14SMatthew G. Knepley   static PetscInt       vertexS[] = {1};
876412e9a14SMatthew G. Knepley   static PetscInt       vertexC[] = {0};
877412e9a14SMatthew G. Knepley   static PetscInt       vertexO[] = {0};
878412e9a14SMatthew G. Knepley   /* Split all edges with a new vertex, making two new 2 edges
879412e9a14SMatthew G. Knepley      0--0--0--1--1
880412e9a14SMatthew G. Knepley   */
881412e9a14SMatthew G. Knepley   static DMPolytopeType edgeT[]   = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT};
882412e9a14SMatthew G. Knepley   static PetscInt       edgeS[]   = {1, 2};
883412e9a14SMatthew G. Knepley   static PetscInt       edgeC[]   = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,  DM_POLYTOPE_POINT, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
884412e9a14SMatthew G. Knepley   static PetscInt       edgeO[]   = {                         0,                       0,                        0,                          0};
885412e9a14SMatthew G. Knepley   /* Do not split tensor edges */
886412e9a14SMatthew G. Knepley   static DMPolytopeType tedgeT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR};
887412e9a14SMatthew G. Knepley   static PetscInt       tedgeS[]  = {1};
888412e9a14SMatthew G. Knepley   static PetscInt       tedgeC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
889412e9a14SMatthew G. Knepley   static PetscInt       tedgeO[]  = {                         0,                          0};
890412e9a14SMatthew G. Knepley   /* Add 3 edges inside every triangle, making 4 new triangles.
89175d3a19aSMatthew G. Knepley    2
89275d3a19aSMatthew G. Knepley    |\
89375d3a19aSMatthew G. Knepley    | \
89475d3a19aSMatthew G. Knepley    |  \
895412e9a14SMatthew G. Knepley    0   1
89675d3a19aSMatthew G. Knepley    | C  \
89775d3a19aSMatthew G. Knepley    |     \
89875d3a19aSMatthew G. Knepley    |      \
89975d3a19aSMatthew G. Knepley    2---1---1
90075d3a19aSMatthew G. Knepley    |\  D  / \
901412e9a14SMatthew G. Knepley    1 2   0   0
90275d3a19aSMatthew G. Knepley    |A \ /  B  \
903412e9a14SMatthew G. Knepley    0-0-0---1---1
90475d3a19aSMatthew G. Knepley   */
905412e9a14SMatthew G. Knepley   static DMPolytopeType triT[]    = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE};
906412e9a14SMatthew G. Knepley   static PetscInt       triS[]    = {3, 4};
907412e9a14SMatthew G. Knepley   static PetscInt       triC[]    = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
908412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 1, 2, 0,
909412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 0, 0,
910412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 1,
911412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    0,
912412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0,
913412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    2};
914412e9a14SMatthew G. Knepley   static PetscInt       triO[]    = {0, 0,
915412e9a14SMatthew G. Knepley                                      0, 0,
916412e9a14SMatthew G. Knepley                                      0, 0,
917412e9a14SMatthew G. Knepley                                      0, -2,  0,
918412e9a14SMatthew G. Knepley                                      0,  0, -2,
919412e9a14SMatthew G. Knepley                                     -2,  0,  0,
920412e9a14SMatthew G. Knepley                                      0,  0,  0};
921412e9a14SMatthew G. Knepley   /* Add a vertex in the center of each quadrilateral, and 4 edges inside, making 4 new quads.
922412e9a14SMatthew G. Knepley      3----1----2----0----2
923412e9a14SMatthew G. Knepley      |         |         |
924412e9a14SMatthew G. Knepley      0    D    2    C    1
925412e9a14SMatthew G. Knepley      |         |         |
926412e9a14SMatthew G. Knepley      3----3----0----1----1
927412e9a14SMatthew G. Knepley      |         |         |
928412e9a14SMatthew G. Knepley      1    A    0    B    0
929412e9a14SMatthew G. Knepley      |         |         |
930412e9a14SMatthew G. Knepley      0----0----0----1----1
931412e9a14SMatthew G. Knepley   */
932412e9a14SMatthew G. Knepley   static DMPolytopeType quadT[]   = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL};
933412e9a14SMatthew G. Knepley   static PetscInt       quadS[]   = {1, 4, 4};
934412e9a14SMatthew G. Knepley   static PetscInt       quadC[]   = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
935412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0,
936412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0,
937412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0,
938412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 1,
939412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    0,
940412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0,    2,
941412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0};
942412e9a14SMatthew G. Knepley   static PetscInt       quadO[]   = {0, 0,
943412e9a14SMatthew G. Knepley                                      0, 0,
944412e9a14SMatthew G. Knepley                                      0, 0,
945412e9a14SMatthew G. Knepley                                      0, 0,
946412e9a14SMatthew G. Knepley                                      0,  0, -2,  0,
947412e9a14SMatthew G. Knepley                                      0,  0,  0, -2,
948412e9a14SMatthew G. Knepley                                     -2,  0,  0,  0,
949412e9a14SMatthew G. Knepley                                      0, -2,  0,  0};
950412e9a14SMatthew G. Knepley   /* Add 1 edge inside every tensor quad, making 2 new tensor quads
951412e9a14SMatthew G. Knepley      2----2----1----3----3
952412e9a14SMatthew G. Knepley      |         |         |
953412e9a14SMatthew G. Knepley      |         |         |
954412e9a14SMatthew G. Knepley      |         |         |
955412e9a14SMatthew G. Knepley      4    A    6    B    5
956412e9a14SMatthew G. Knepley      |         |         |
957412e9a14SMatthew G. Knepley      |         |         |
958412e9a14SMatthew G. Knepley      |         |         |
959412e9a14SMatthew G. Knepley      0----0----0----1----1
960412e9a14SMatthew G. Knepley   */
961412e9a14SMatthew G. Knepley   static DMPolytopeType tquadT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR};
962412e9a14SMatthew G. Knepley   static PetscInt       tquadS[]  = {1, 2};
963412e9a14SMatthew G. Knepley   static PetscInt       tquadC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
964412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0,   0,
965412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_POINT_PRISM_TENSOR, 0,    0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0};
966412e9a14SMatthew G. Knepley   static PetscInt       tquadO[]  = {0, 0,
967412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
968412e9a14SMatthew G. Knepley                                      0, 0, 0, 0};
969412e9a14SMatthew G. Knepley   /* Add 1 edge and 8 triangles inside every cell, making 8 new tets
970412e9a14SMatthew G. Knepley      The vertices of our reference tet are [(-1, -1, -1), (-1, 1, -1), (1, -1, -1), (-1, -1, 1)], which we call [v0, v1, v2, v3]. The first
971412e9a14SMatthew G. Knepley      three edges are [v0, v1], [v1, v2], [v2, v0] called e0, e1, and e2, and then three edges to the top point [v0, v3], [v1, v3], [v2, v3]
972412e9a14SMatthew G. Knepley      called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are
973412e9a14SMatthew G. Knepley        [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3]
974412e9a14SMatthew G. Knepley      The first four tets just cut off the corners, using the replica notation for new vertices,
975412e9a14SMatthew G. Knepley        [v0,      (e0, 0), (e2, 0), (e3, 0)]
976412e9a14SMatthew G. Knepley        [(e0, 0), v1,      (e1, 0), (e4, 0)]
977412e9a14SMatthew G. Knepley        [(e2, 0), (e1, 0), v2,      (e5, 0)]
978412e9a14SMatthew G. Knepley        [(e3, 0), (e4, 0), (e5, 0), v3     ]
979412e9a14SMatthew G. Knepley      The next four tets match a vertex to the newly created faces from cutting off those first tets.
980412e9a14SMatthew G. Knepley        [(e2, 0), (e3, 0), (e0, 0), (e5, 0)]
981412e9a14SMatthew G. Knepley        [(e4, 0), (e1, 0), (e0, 0), (e5, 0)]
982412e9a14SMatthew G. Knepley        [(e5, 0), (e0, 0), (e2, 0), (e1, 0)]
983412e9a14SMatthew G. Knepley        [(e5, 0), (e0, 0), (e4, 0), (e3, 0)]
984412e9a14SMatthew G. Knepley      We can see that a new edge is introduced in the cell [(e0, 0), (e5, 0)] which we call (-1, 0). The first four faces created are
985412e9a14SMatthew G. Knepley        [(e2, 0), (e0, 0), (e3, 0)]
986412e9a14SMatthew G. Knepley        [(e0, 0), (e1, 0), (e4, 0)]
987412e9a14SMatthew G. Knepley        [(e2, 0), (e5, 0), (e1, 0)]
988412e9a14SMatthew G. Knepley        [(e3, 0), (e4, 0), (e5, 0)]
989412e9a14SMatthew G. Knepley      The next four, from the second group of tets, are
990412e9a14SMatthew G. Knepley        [(e2, 0), (e0, 0), (e5, 0)]
991412e9a14SMatthew G. Knepley        [(e4, 0), (e0, 0), (e5, 0)]
992412e9a14SMatthew G. Knepley        [(e0, 0), (e1, 0), (e5, 0)]
993412e9a14SMatthew G. Knepley        [(e5, 0), (e3, 0), (e0, 0)]
994412e9a14SMatthew G. Knepley      I could write a program to generate these orientations by comparing the faces from GetRawFaces() with my existing table.
995412e9a14SMatthew G. Knepley    */
996412e9a14SMatthew G. Knepley   static DMPolytopeType tetT[]    = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON};
997412e9a14SMatthew G. Knepley   static PetscInt       tetS[]    = {1, 8, 8};
998412e9a14SMatthew G. Knepley   static PetscInt       tetC[]    = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 2, 2, 1, 0,
999412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 2, 2,
1000412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 1, 1,
1001412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 1, 0, 1,
1002412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 2, 1,
1003412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 2, 0,
1004412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 3, 1,
1005412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0,    0,
1006412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0,    0,
1007412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 0,    0,
1008412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 1, DM_POLYTOPE_TRIANGLE, 1, 1, 2, DM_POLYTOPE_TRIANGLE, 0,    1, DM_POLYTOPE_TRIANGLE, 1, 3, 1,
1009412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 2, DM_POLYTOPE_TRIANGLE, 0,    2, DM_POLYTOPE_TRIANGLE, 1, 2, 1, DM_POLYTOPE_TRIANGLE, 1, 3, 0,
1010412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    3, DM_POLYTOPE_TRIANGLE, 1, 1, 1, DM_POLYTOPE_TRIANGLE, 1, 2, 2, DM_POLYTOPE_TRIANGLE, 1, 3, 2,
1011412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    0, DM_POLYTOPE_TRIANGLE, 1, 2, 3, DM_POLYTOPE_TRIANGLE, 0,    4, DM_POLYTOPE_TRIANGLE, 0,    7,
1012412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    1, DM_POLYTOPE_TRIANGLE, 1, 3, 3, DM_POLYTOPE_TRIANGLE, 0,    5, DM_POLYTOPE_TRIANGLE, 0,    6,
1013412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    4, DM_POLYTOPE_TRIANGLE, 0,    6, DM_POLYTOPE_TRIANGLE, 0,    2, DM_POLYTOPE_TRIANGLE, 1, 0, 3,
1014412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    5, DM_POLYTOPE_TRIANGLE, 0,    7, DM_POLYTOPE_TRIANGLE, 0,    3, DM_POLYTOPE_TRIANGLE, 1, 1, 3};
1015412e9a14SMatthew G. Knepley   static PetscInt       tetO[]    = {0, 0,
1016412e9a14SMatthew G. Knepley                                      0,  0,  0,
1017412e9a14SMatthew G. Knepley                                      0,  0,  0,
1018412e9a14SMatthew G. Knepley                                      0,  0,  0,
1019412e9a14SMatthew G. Knepley                                      0,  0,  0,
1020412e9a14SMatthew G. Knepley                                      0,  0, -2,
1021412e9a14SMatthew G. Knepley                                      0,  0, -2,
1022412e9a14SMatthew G. Knepley                                      0, -2, -2,
1023412e9a14SMatthew G. Knepley                                      0, -2,  0,
1024412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,
1025412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,
1026412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,
1027412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,
1028412e9a14SMatthew G. Knepley                                     -3,  0,  0, -2,
1029412e9a14SMatthew G. Knepley                                     -2,  1,  0,  0,
1030412e9a14SMatthew G. Knepley                                     -2, -2, -1,  2,
1031412e9a14SMatthew G. Knepley                                     -2,  0, -2,  1};
1032412e9a14SMatthew G. Knepley   /* Add a vertex in the center of each cell, add 6 edges and 12 quads inside every cell, making 8 new hexes
1033412e9a14SMatthew G. Knepley      The vertices of our reference hex are (-1, -1, -1), (-1, 1, -1), (1, 1, -1), (1, -1, -1), (-1, -1, 1), (1, -1, 1), (1, 1, 1), (-1, 1, 1) which we call [v0, v1, v2, v3, v4, v5, v6, v7]. The fours edges around the bottom [v0, v1], [v1, v2], [v2, v3], [v3, v0] are [e0, e1, e2, e3], and likewise around the top [v4, v5], [v5, v6], [v6, v7], [v7, v4] are [e4, e5, e6, e7]. Finally [v0, v4], [v1, v7], [v2, v6], [v3, v5] are [e9, e10, e11, e8]. The faces of a hex, given in DMPlexGetRawFaces_Internal(), oriented with outward normals, are
1034412e9a14SMatthew G. Knepley        [v0, v1, v2, v3] f0 bottom
1035412e9a14SMatthew G. Knepley        [v4, v5, v6, v7] f1 top
1036412e9a14SMatthew G. Knepley        [v0, v3, v5, v4] f2 front
1037412e9a14SMatthew G. Knepley        [v2, v1, v7, v6] f3 back
1038412e9a14SMatthew G. Knepley        [v3, v2, v6, v5] f4 right
1039412e9a14SMatthew G. Knepley        [v0, v4, v7, v1] f5 left
1040412e9a14SMatthew G. Knepley      The eight hexes are divided into four on the bottom, and four on the top,
1041412e9a14SMatthew G. Knepley        [v0,      (e0, 0),  (f0, 0),  (e3, 0),  (e9, 0), (f2, 0),  (c0, 0),  (f5, 0)]
1042412e9a14SMatthew G. Knepley        [(e0, 0), v1,       (e1, 0),  (f0, 0),  (f5, 0), (c0, 0),  (f3, 0),  (e10, 0)]
1043412e9a14SMatthew G. Knepley        [(f0, 0), (e1, 0),  v2,       (e2, 0),  (c0, 0), (f4, 0),  (e11, 0), (f3, 0)]
1044412e9a14SMatthew G. Knepley        [(e3, 0), (f0, 0),  (e2, 0),  v3,       (f2, 0), (e8, 0),  (f4, 0),  (c0, 0)]
1045412e9a14SMatthew G. Knepley        [(e9, 0), (f5, 0),  (c0, 0),  (f2, 0),  v4,      (e4, 0),  (f1, 0),  (e7, 0)]
1046412e9a14SMatthew G. Knepley        [(f2, 0), (c0, 0),  (f4, 0),  (e8, 0),  (e4, 0), v5,       (e5, 0),  (f1, 0)]
1047412e9a14SMatthew G. Knepley        [(c0, 0), (f3, 0),  (e11, 0), (f4, 0),  (f1, 0), (e5, 0),  v6,       (e6, 0)]
1048412e9a14SMatthew G. Knepley        [(f5, 0), (e10, 0), (f3, 0),  (c0, 0),  (e7, 0), (f1, 0),  (e6, 0),  v7]
1049412e9a14SMatthew G. Knepley      The 6 internal edges will go from the faces to the central vertex. The 12 internal faces can be divided into groups of 4 by the plane on which they sit. First the faces on the x-y plane are,
1050412e9a14SMatthew G. Knepley        [(e9, 0), (f2, 0),  (c0, 0),  (f5, 0)]
1051412e9a14SMatthew G. Knepley        [(f5, 0), (c0, 0),  (f3, 0),  (e10, 0)]
1052412e9a14SMatthew G. Knepley        [(c0, 0), (f4, 0),  (e11, 0), (f3, 0)]
1053412e9a14SMatthew G. Knepley        [(f2, 0), (e8, 0),  (f4, 0),  (c0, 0)]
1054412e9a14SMatthew G. Knepley      and on the x-z plane,
1055412e9a14SMatthew G. Knepley        [(f0, 0), (e0, 0), (f5, 0), (c0, 0)]
1056412e9a14SMatthew G. Knepley        [(c0, 0), (f5, 0), (e7, 0), (f1, 0)]
1057412e9a14SMatthew G. Knepley        [(f4, 0), (c0, 0), (f1, 0), (e5, 0)]
1058412e9a14SMatthew G. Knepley        [(e2, 0), (f0, 0), (c0, 0), (f4, 0)]
1059412e9a14SMatthew G. Knepley      and on the y-z plane,
1060412e9a14SMatthew G. Knepley        [(e3, 0), (f2, 0), (c0, 0), (f0, 0)]
1061412e9a14SMatthew G. Knepley        [(f2, 0), (e4, 0), (f1, 0), (c0, 0)]
1062412e9a14SMatthew G. Knepley        [(c0, 0), (f1, 0), (e6, 0), (f3, 0)]
1063412e9a14SMatthew G. Knepley        [(f0, 0), (c0, 0), (f3, 0), (e1, 0)]
1064412e9a14SMatthew G. Knepley   */
1065412e9a14SMatthew G. Knepley   static DMPolytopeType hexT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON};
1066412e9a14SMatthew G. Knepley   static PetscInt       hexS[]    = {1, 6, 12, 8};
1067412e9a14SMatthew G. Knepley   static PetscInt       hexC[]    = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1068412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0,
1069412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0,
1070412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0,
1071412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0,
1072412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 5, 0, DM_POLYTOPE_POINT, 0, 0,
1073412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    5, DM_POLYTOPE_SEGMENT, 1, 5, 0,
1074412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    5, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 5, 2,
1075412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 1, 4, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0,    3,
1076412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 0,    2,
1077412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 5, 3, DM_POLYTOPE_SEGMENT, 0,    5, DM_POLYTOPE_SEGMENT, 0,    0,
1078412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    5, DM_POLYTOPE_SEGMENT, 1, 5, 1, DM_POLYTOPE_SEGMENT, 1, 1, 3, DM_POLYTOPE_SEGMENT, 0,    1,
1079412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 4, 2,
1080412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 1, 4, 0,
1081412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 0, 3,
1082412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    2,
1083412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0,    3,
1084412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1,
1085412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 0,    0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 0,    4, DM_POLYTOPE_QUADRILATERAL, 0,    8, DM_POLYTOPE_QUADRILATERAL, 1, 5, 0,
1086412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 0,    1, DM_POLYTOPE_QUADRILATERAL, 0,    4, DM_POLYTOPE_QUADRILATERAL, 1, 3, 1, DM_POLYTOPE_QUADRILATERAL, 0,   11, DM_POLYTOPE_QUADRILATERAL, 1, 5, 3,
1087412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 2, DM_POLYTOPE_QUADRILATERAL, 0,    2, DM_POLYTOPE_QUADRILATERAL, 0,    7, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 1, DM_POLYTOPE_QUADRILATERAL, 0,   11,
1088412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 3, DM_POLYTOPE_QUADRILATERAL, 0,    3, DM_POLYTOPE_QUADRILATERAL, 1, 2, 1, DM_POLYTOPE_QUADRILATERAL, 0,    7, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0, DM_POLYTOPE_QUADRILATERAL, 0,    8,
1089412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 0,    0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 3, DM_POLYTOPE_QUADRILATERAL, 0,    5, DM_POLYTOPE_QUADRILATERAL, 0,    9, DM_POLYTOPE_QUADRILATERAL, 1, 5, 1,
1090412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 0,    3, DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_QUADRILATERAL, 1, 2, 2, DM_POLYTOPE_QUADRILATERAL, 0,    6, DM_POLYTOPE_QUADRILATERAL, 1, 4, 3, DM_POLYTOPE_QUADRILATERAL, 0,    9,
1091412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 0,    2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2, DM_POLYTOPE_QUADRILATERAL, 0,    6, DM_POLYTOPE_QUADRILATERAL, 1, 3, 3, DM_POLYTOPE_QUADRILATERAL, 1, 4, 2, DM_POLYTOPE_QUADRILATERAL, 0,   10,
1092412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 0,    1, DM_POLYTOPE_QUADRILATERAL, 1, 1, 3, DM_POLYTOPE_QUADRILATERAL, 0,    5, DM_POLYTOPE_QUADRILATERAL, 1, 3, 2, DM_POLYTOPE_QUADRILATERAL, 0,   10, DM_POLYTOPE_QUADRILATERAL, 1, 5, 2};
1093412e9a14SMatthew G. Knepley   static PetscInt       hexO[]    = {0, 0,
1094412e9a14SMatthew G. Knepley                                      0, 0,
1095412e9a14SMatthew G. Knepley                                      0, 0,
1096412e9a14SMatthew G. Knepley                                      0, 0,
1097412e9a14SMatthew G. Knepley                                      0, 0,
1098412e9a14SMatthew G. Knepley                                      0, 0,
1099412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1100412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1101412e9a14SMatthew G. Knepley                                     -2, -2,  0,  0,
1102412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1103412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1104412e9a14SMatthew G. Knepley                                     -2, -2,  0,  0,
1105412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1106412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1107412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1108412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1109412e9a14SMatthew G. Knepley                                     -2, -2,  0,  0,
1110412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1111412e9a14SMatthew G. Knepley                                      0, 0,  0, 0, -4, 0,
1112412e9a14SMatthew G. Knepley                                      0, 0, -1, 0, -4, 0,
1113412e9a14SMatthew G. Knepley                                      0, 0, -1, 0,  0, 0,
1114412e9a14SMatthew G. Knepley                                      0, 0,  0, 0,  0, 0,
1115412e9a14SMatthew G. Knepley                                     -4, 0,  0, 0, -4, 0,
1116412e9a14SMatthew G. Knepley                                     -4, 0,  0, 0,  0, 0,
1117412e9a14SMatthew G. Knepley                                     -4, 0, -1, 0,  0, 0,
1118412e9a14SMatthew G. Knepley                                     -4, 0, -1, 0, -4, 0};
1119412e9a14SMatthew G. Knepley   /* Add 3 quads inside every triangular prism, making 4 new prisms. */
1120412e9a14SMatthew G. Knepley   static DMPolytopeType tripT[]   = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_TRI_PRISM};
1121412e9a14SMatthew G. Knepley   static PetscInt       tripS[]   = {3, 4, 6, 8};
1122412e9a14SMatthew G. Knepley   static PetscInt       tripC[]   = {DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 3, 0,
1123412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 1, 4, 0,
1124412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 1, 2, 0,
1125412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 4, 1,
1126412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0,    0,
1127412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3,
1128412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    2,
1129412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 2, 0,
1130412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 4, 0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 3, 0,
1131412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 4, 0,
1132412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 2,
1133412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 4, 2, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 3, 2,
1134412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 4, 2,
1135412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 0,    0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 0,    2, DM_POLYTOPE_QUADRILATERAL, 1, 4, 1,
1136412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 2, DM_POLYTOPE_TRIANGLE, 0,    1, DM_POLYTOPE_QUADRILATERAL, 1, 2, 1, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 0,    0,
1137412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 1, DM_POLYTOPE_TRIANGLE, 0,    2, DM_POLYTOPE_QUADRILATERAL, 0,    1, DM_POLYTOPE_QUADRILATERAL, 1, 3, 1, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0,
1138412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 3, DM_POLYTOPE_TRIANGLE, 0,    3, DM_POLYTOPE_QUADRILATERAL, 0,    0, DM_POLYTOPE_QUADRILATERAL, 0,    1, DM_POLYTOPE_QUADRILATERAL, 0,    2,
1139412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 3, DM_POLYTOPE_QUADRILATERAL, 0,    5, DM_POLYTOPE_QUADRILATERAL, 1, 4, 2,
1140412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    1, DM_POLYTOPE_TRIANGLE, 1, 1, 1, DM_POLYTOPE_QUADRILATERAL, 1, 2, 2, DM_POLYTOPE_QUADRILATERAL, 1, 3, 3, DM_POLYTOPE_QUADRILATERAL, 0,    3,
1141412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    2, DM_POLYTOPE_TRIANGLE, 1, 1, 2, DM_POLYTOPE_QUADRILATERAL, 0,    4, DM_POLYTOPE_QUADRILATERAL, 1, 3, 2, DM_POLYTOPE_QUADRILATERAL, 1, 4, 3,
1142412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    3, DM_POLYTOPE_TRIANGLE, 1, 1, 3, DM_POLYTOPE_QUADRILATERAL, 0,    3, DM_POLYTOPE_QUADRILATERAL, 0,    4, DM_POLYTOPE_QUADRILATERAL, 0,    5};
1143412e9a14SMatthew G. Knepley   static PetscInt       tripO[]   = {0, 0,
1144412e9a14SMatthew G. Knepley                                      0, 0,
1145412e9a14SMatthew G. Knepley                                      0, 0,
1146412e9a14SMatthew G. Knepley                                      0, -2, -2,
1147412e9a14SMatthew G. Knepley                                     -2,  0, -2,
1148412e9a14SMatthew G. Knepley                                     -2, -2,  0,
1149412e9a14SMatthew G. Knepley                                      0,  0,  0,
1150412e9a14SMatthew G. Knepley                                     -2,  0, -2, -2,
1151412e9a14SMatthew G. Knepley                                     -2,  0, -2, -2,
1152412e9a14SMatthew G. Knepley                                     -2,  0, -2, -2,
1153412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1154412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1155412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1156412e9a14SMatthew G. Knepley                                      0,  0,  0, -1,  0,
1157412e9a14SMatthew G. Knepley                                      0,  0,  0,  0, -1,
1158412e9a14SMatthew G. Knepley                                      0,  0, -1,  0,  0,
1159412e9a14SMatthew G. Knepley                                      2,  0,  0,  0,  0,
1160412e9a14SMatthew G. Knepley                                     -3,  0,  0, -1,  0,
1161412e9a14SMatthew G. Knepley                                     -3,  0,  0,  0, -1,
1162412e9a14SMatthew G. Knepley                                     -3,  0, -1,  0,  0,
1163412e9a14SMatthew G. Knepley                                     -3,  0,  0,  0,  0};
1164412e9a14SMatthew G. Knepley   /* Add 3 tensor quads inside every tensor triangular prism, making 4 new prisms.
1165412e9a14SMatthew G. Knepley       2
1166412e9a14SMatthew G. Knepley       |\
1167412e9a14SMatthew G. Knepley       | \
1168412e9a14SMatthew G. Knepley       |  \
1169412e9a14SMatthew G. Knepley       0---1
117075d3a19aSMatthew G. Knepley 
1171412e9a14SMatthew G. Knepley       2
117275d3a19aSMatthew G. Knepley 
1173412e9a14SMatthew G. Knepley       0   1
117475d3a19aSMatthew G. Knepley 
1175412e9a14SMatthew G. Knepley       2
1176412e9a14SMatthew G. Knepley       |\
1177412e9a14SMatthew G. Knepley       | \
1178412e9a14SMatthew G. Knepley       |  \
1179412e9a14SMatthew G. Knepley       0---1
1180412e9a14SMatthew G. Knepley   */
1181412e9a14SMatthew G. Knepley   static DMPolytopeType ttripT[]  = {DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_TRI_PRISM_TENSOR};
1182412e9a14SMatthew G. Knepley   static PetscInt       ttripS[]  = {3, 4};
1183412e9a14SMatthew G. Knepley   static PetscInt       ttripC[]  = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0,
1184412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 4, 0,
1185412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0,
1186412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    2, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 1,
1187412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 1, DM_POLYTOPE_TRIANGLE, 1, 1, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    0,
1188412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 2, DM_POLYTOPE_TRIANGLE, 1, 1, 2, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0,
1189412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 3, DM_POLYTOPE_TRIANGLE, 1, 1, 3, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,     1, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    2};
1190412e9a14SMatthew G. Knepley   static PetscInt       ttripO[]  = {0, 0, 0, 0,
1191412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1192412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1193412e9a14SMatthew G. Knepley                                      0, 0,  0, -1,  0,
1194412e9a14SMatthew G. Knepley                                      0, 0,  0,  0, -1,
1195412e9a14SMatthew G. Knepley                                      0, 0, -1,  0,  0,
1196412e9a14SMatthew G. Knepley                                      0, 0,  0,  0,  0};
1197412e9a14SMatthew G. Knepley   /* Add 1 edge and 4 tensor quads inside every tensor quad prism, making 4 new prisms. */
1198412e9a14SMatthew G. Knepley   static DMPolytopeType tquadpT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR};
1199412e9a14SMatthew G. Knepley   static PetscInt       tquadpS[]  = {1, 4, 4};
1200412e9a14SMatthew G. Knepley   static PetscInt       tquadpC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1201412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0,
1202412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0,
1203412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0,
1204412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_SEGMENT, 1, 0, 3, DM_POLYTOPE_SEGMENT, 1, 1, 3, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 5, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0,
1205412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    3, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 1,
1206412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    1, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    0,
1207412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_QUADRILATERAL, 1, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    2,
1208412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_QUADRILATERAL, 1, 0, 3, DM_POLYTOPE_QUADRILATERAL, 1, 1, 3, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    3, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    2, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 0};
1209412e9a14SMatthew G. Knepley   static PetscInt       tquadpO[]  = {0, 0,
1210412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1211412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1212412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1213412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1214412e9a14SMatthew G. Knepley                                       0, 0,  0,  0, -1,  0,
1215412e9a14SMatthew G. Knepley                                       0, 0,  0,  0,  0, -1,
1216412e9a14SMatthew G. Knepley                                       0, 0, -1,  0,  0,  0,
1217412e9a14SMatthew G. Knepley                                       0, 0,  0, -1,  0,  0};
121875d3a19aSMatthew G. Knepley 
1219412e9a14SMatthew G. Knepley   PetscFunctionBegin;
1220412e9a14SMatthew G. Knepley   switch (source) {
1221412e9a14SMatthew G. Knepley     case DM_POLYTOPE_POINT:              *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break;
1222412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:            *Nt = 2; *target = edgeT;   *size = edgeS;   *cone = edgeC;   *ornt = edgeO;   break;
1223412e9a14SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT;  *size = tedgeS;  *cone = tedgeC;  *ornt = tedgeO;  break;
1224412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:           *Nt = 2; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
1225412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:      *Nt = 3; *target = quadT;   *size = quadS;   *cone = quadC;   *ornt = quadO;   break;
1226412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:   *Nt = 2; *target = tquadT;  *size = tquadS;  *cone = tquadC;  *ornt = tquadO;  break;
1227412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:        *Nt = 3; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
1228412e9a14SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:         *Nt = 4; *target = hexT;    *size = hexS;    *cone = hexC;    *ornt = hexO;    break;
1229412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:          *Nt = 4; *target = tripT;   *size = tripS;   *cone = tripC;   *ornt = tripO;   break;
1230412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:   *Nt = 2; *target = ttripT;  *size = ttripS;  *cone = ttripC;  *ornt = ttripO;  break;
1231412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break;
1232412e9a14SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1233412e9a14SMatthew G. Knepley   }
1234412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1235412e9a14SMatthew G. Knepley }
123675d3a19aSMatthew G. Knepley 
123796ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerRefine_ToBox(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
1238412e9a14SMatthew G. Knepley {
1239412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
1240412e9a14SMatthew G. Knepley   /* Change tensor edges to segments */
1241412e9a14SMatthew G. Knepley   static DMPolytopeType tedgeT[]  = {DM_POLYTOPE_SEGMENT};
1242412e9a14SMatthew G. Knepley   static PetscInt       tedgeS[]  = {1};
1243412e9a14SMatthew G. Knepley   static PetscInt       tedgeC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
1244412e9a14SMatthew G. Knepley   static PetscInt       tedgeO[]  = {                         0,                          0};
1245412e9a14SMatthew G. Knepley   /* Add 1 vertex, 3 edges inside every triangle, making 3 new quadrilaterals.
1246e5337592SStefano Zampini    2
1247e5337592SStefano Zampini    |\
1248e5337592SStefano Zampini    | \
1249e5337592SStefano Zampini    |  \
1250e5337592SStefano Zampini    |   \
1251412e9a14SMatthew G. Knepley    0    1
1252412e9a14SMatthew G. Knepley    |     \
1253e5337592SStefano Zampini    |      \
1254e5337592SStefano Zampini    2       1
1255e5337592SStefano Zampini    |\     / \
1256e5337592SStefano Zampini    | 2   1   \
1257e5337592SStefano Zampini    |  \ /     \
1258412e9a14SMatthew G. Knepley    1   |       0
1259e5337592SStefano Zampini    |   0        \
1260e5337592SStefano Zampini    |   |         \
1261412e9a14SMatthew G. Knepley    |   |          \
1262412e9a14SMatthew G. Knepley    0-0-0-----1-----1
1263e5337592SStefano Zampini   */
1264412e9a14SMatthew G. Knepley   static DMPolytopeType triT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL};
1265412e9a14SMatthew G. Knepley   static PetscInt       triS[]    = {1, 3, 3};
1266412e9a14SMatthew G. Knepley   static PetscInt       triC[]    = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0,    0,
1267412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0,    0,
1268412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0,    0,
1269412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 1,
1270412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    0,
1271412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0};
1272412e9a14SMatthew G. Knepley   static PetscInt       triO[]    = {0, 0,
1273412e9a14SMatthew G. Knepley                                      0, 0,
1274412e9a14SMatthew G. Knepley                                      0, 0,
1275412e9a14SMatthew G. Knepley                                      0,  0, -2,  0,
1276412e9a14SMatthew G. Knepley                                      0,  0,  0, -2,
1277412e9a14SMatthew G. Knepley                                      0, -2,  0,  0};
1278412e9a14SMatthew G. Knepley   /* Add 1 edge inside every tensor quad, making 2 new quadrilaterals
1279412e9a14SMatthew G. Knepley      2----2----1----3----3
12804330a3fcSStefano Zampini      |         |         |
12814330a3fcSStefano Zampini      |         |         |
12824330a3fcSStefano Zampini      |         |         |
1283412e9a14SMatthew G. Knepley      4    A    6    B    5
12844330a3fcSStefano Zampini      |         |         |
1285412e9a14SMatthew G. Knepley      |         |         |
1286412e9a14SMatthew G. Knepley      |         |         |
1287412e9a14SMatthew G. Knepley      0----0----0----1----1
12884330a3fcSStefano Zampini   */
1289412e9a14SMatthew G. Knepley   static DMPolytopeType tquadT[]  = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL};
1290412e9a14SMatthew G. Knepley   static PetscInt       tquadS[]  = {1, 2};
1291412e9a14SMatthew G. Knepley   static PetscInt       tquadC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1292412e9a14SMatthew G. Knepley                                      /* TODO  Fix these */
1293412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0,
1294412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0,    0};
1295412e9a14SMatthew G. Knepley   static PetscInt       tquadO[]  = {0, 0,
1296412e9a14SMatthew G. Knepley                                      0, 0, -2, -2,
1297412e9a14SMatthew G. Knepley                                      0, 0, -2, -2};
1298412e9a14SMatthew G. Knepley   /* Add 6 triangles inside every cell, making 4 new hexs
1299412e9a14SMatthew G. Knepley      TODO: Need different SubcellMap(). Need to make a struct with the function pointers in it
1300412e9a14SMatthew G. Knepley      The vertices of our reference tet are [(-1, -1, -1), (-1, 1, -1), (1, -1, -1), (-1, -1, 1)], which we call [v0, v1, v2, v3]. The first
1301412e9a14SMatthew G. Knepley      three edges are [v0, v1], [v1, v2], [v2, v0] called e0, e1, and e2, and then three edges to the top point [v0, v3], [v1, v3], [v2, v3]
1302412e9a14SMatthew G. Knepley      called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are
1303412e9a14SMatthew G. Knepley        [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3]
1304412e9a14SMatthew G. Knepley      We make a new hex in each corner
1305412e9a14SMatthew G. Knepley        [v0, (e0, 0), (f0, 0), (e2, 0), (e3, 0), (f2, 0), (c0, 0), (f1, 0)]
1306412e9a14SMatthew G. Knepley        [v1, (e4, 0), (f3, 0), (e1, 0), (e0, 0), (f0, 0), (c0, 0), (f1, 0)]
1307412e9a14SMatthew G. Knepley        [v2, (e1, 0), (f3, 0), (e5, 0), (e2, 0), (f2, 0), (c0, 0), (f0, 0)]
1308412e9a14SMatthew G. Knepley        [v3, (e4, 0), (f1, 0), (e3, 0), (e5, 0), (f2, 0), (c0, 0), (f3, 0)]
1309412e9a14SMatthew G. Knepley      We create a new face for each edge
1310412e9a14SMatthew G. Knepley        [(e3, 0), (f2, 0), (c0, 0), (f1, 0)]
1311412e9a14SMatthew G. Knepley        [(f0, 0), (e0, 0), (f1, 0), (c0, 0)]
1312412e9a14SMatthew G. Knepley        [(e2, 0), (f0, 0), (c0, 0), (f2, 0)]
1313412e9a14SMatthew G. Knepley        [(f3, 0), (e4, 0), (f1, 0), (c0, 0)]
1314412e9a14SMatthew G. Knepley        [(e1, 0), (f3, 0), (c0, 0), (f0, 0)]
1315412e9a14SMatthew G. Knepley        [(e5, 0), (f3, 0), (c0, 0), (f2, 0)]
1316412e9a14SMatthew G. Knepley      I could write a program to generate these from the first hex by acting with the symmetry group to take one subcell into another.
131775d3a19aSMatthew G. Knepley    */
1318412e9a14SMatthew G. Knepley   static DMPolytopeType tetT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON};
1319412e9a14SMatthew G. Knepley   static PetscInt       tetS[]    = {1, 4, 6, 4};
1320412e9a14SMatthew G. Knepley   static PetscInt       tetC[]    = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1321412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0,
1322412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0,
1323412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0,
1324412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 0,
1325412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    0,
1326412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 0,
1327412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    3,
1328412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 0, 1,
1329412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 1,
1330412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 0,    0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 0,    1, DM_POLYTOPE_QUADRILATERAL, 0,    2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0,
1331412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 3, 1, DM_POLYTOPE_QUADRILATERAL, 0,    1, DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 0,    3, DM_POLYTOPE_QUADRILATERAL, 0,    4, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2,
1332412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 0,    2, DM_POLYTOPE_QUADRILATERAL, 1, 2, 1, DM_POLYTOPE_QUADRILATERAL, 0,    4, DM_POLYTOPE_QUADRILATERAL, 0,    5, DM_POLYTOPE_QUADRILATERAL, 1, 0, 2,
1333412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_QUADRILATERAL, 0,    5, DM_POLYTOPE_QUADRILATERAL, 1, 2, 2, DM_POLYTOPE_QUADRILATERAL, 0,    3, DM_POLYTOPE_QUADRILATERAL, 0,    0, DM_POLYTOPE_QUADRILATERAL, 1, 3, 2};
1334412e9a14SMatthew G. Knepley   static PetscInt       tetO[]    = {0, 0,
1335412e9a14SMatthew G. Knepley                                      0, 0,
1336412e9a14SMatthew G. Knepley                                      0, 0,
1337412e9a14SMatthew G. Knepley                                      0, 0,
1338412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1339412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1340412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1341412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1342412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1343412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1344412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,  0,  0,
1345412e9a14SMatthew G. Knepley                                      1, -1,  1,  0,  0,  3,
1346412e9a14SMatthew G. Knepley                                      0, -4,  1, -1,  0,  3,
1347412e9a14SMatthew G. Knepley                                      1, -4,  3, -2, -4,  3};
1348412e9a14SMatthew G. Knepley   /* Add 3 quads inside every triangular prism, making 4 new prisms. */
1349412e9a14SMatthew G. Knepley   static DMPolytopeType tripT[]   = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON};
1350412e9a14SMatthew G. Knepley   static PetscInt       tripS[]   = {1, 5, 9, 6};
1351412e9a14SMatthew G. Knepley   static PetscInt       tripC[]   = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1352412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0,
1353412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0,
1354412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0,
1355412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0,
1356412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 1, 4, 1,
1357412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    2,
1358412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3,
1359412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 0,
1360412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 0,
1361412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 1, 4, 0,
1362412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 2,
1363412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 3, 2,
1364412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 4, 2,
1365412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 0,    0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 0,    5, DM_POLYTOPE_QUADRILATERAL, 0,    3, DM_POLYTOPE_QUADRILATERAL, 1, 4, 1,
1366412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 2, DM_POLYTOPE_QUADRILATERAL, 0,    1, DM_POLYTOPE_QUADRILATERAL, 1, 2, 1, DM_POLYTOPE_QUADRILATERAL, 0,    4, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 0,    3,
1367412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 0,    2, DM_POLYTOPE_QUADRILATERAL, 0,    5, DM_POLYTOPE_QUADRILATERAL, 1, 3, 1, DM_POLYTOPE_QUADRILATERAL, 0,    4, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0,
1368412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 0,    0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 3, DM_POLYTOPE_QUADRILATERAL, 0,    8, DM_POLYTOPE_QUADRILATERAL, 0,    6, DM_POLYTOPE_QUADRILATERAL, 1, 4, 2,
1369412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 0,    1, DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_QUADRILATERAL, 1, 2, 2, DM_POLYTOPE_QUADRILATERAL, 0,    7, DM_POLYTOPE_QUADRILATERAL, 1, 3, 3, DM_POLYTOPE_QUADRILATERAL, 0,    6,
1370412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 0,    2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2, DM_POLYTOPE_QUADRILATERAL, 0,    8, DM_POLYTOPE_QUADRILATERAL, 1, 3, 2, DM_POLYTOPE_QUADRILATERAL, 0,    7, DM_POLYTOPE_QUADRILATERAL, 1, 4, 3};
1371412e9a14SMatthew G. Knepley   static PetscInt       tripO[]   = {0, 0,
1372412e9a14SMatthew G. Knepley                                      0, 0,
1373412e9a14SMatthew G. Knepley                                      0, 0,
1374412e9a14SMatthew G. Knepley                                      0, 0,
1375412e9a14SMatthew G. Knepley                                      0, 0,
1376412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1377412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1378412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1379412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1380412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1381412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1382412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1383412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1384412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1385412e9a14SMatthew G. Knepley                                      0,  0,  0, -1,  0,  1,
1386412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,  0, -4,
1387412e9a14SMatthew G. Knepley                                      0,  0,  0,  0, -1,  1,
1388412e9a14SMatthew G. Knepley                                     -4,  0,  0, -1,  0,  1,
1389412e9a14SMatthew G. Knepley                                     -4,  0,  0,  0,  0, -4,
1390412e9a14SMatthew G. Knepley                                     -4,  0,  0,  0, -1,  1};
1391412e9a14SMatthew G. Knepley   /* Add 3 tensor quads inside every tensor triangular prism, making 4 new tensor triangular prisms.
1392412e9a14SMatthew G. Knepley       2
1393412e9a14SMatthew G. Knepley       |\
1394412e9a14SMatthew G. Knepley       | \
1395412e9a14SMatthew G. Knepley       |  \
1396412e9a14SMatthew G. Knepley       0---1
139775d3a19aSMatthew G. Knepley 
1398412e9a14SMatthew G. Knepley       2
139975d3a19aSMatthew G. Knepley 
1400412e9a14SMatthew G. Knepley       0   1
140175d3a19aSMatthew G. Knepley 
1402412e9a14SMatthew G. Knepley       2
1403412e9a14SMatthew G. Knepley       |\
1404412e9a14SMatthew G. Knepley       | \
1405412e9a14SMatthew G. Knepley       |  \
1406412e9a14SMatthew G. Knepley       0---1
140775d3a19aSMatthew G. Knepley   */
1408412e9a14SMatthew G. Knepley   static DMPolytopeType ttripT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR};
1409412e9a14SMatthew G. Knepley   static PetscInt       ttripS[]  = {1, 3, 3};
1410412e9a14SMatthew G. Knepley   static PetscInt       ttripC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1411412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0,
1412412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0,
1413412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0,
1414412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    2, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 1,
1415412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    1, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    0,
1416412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    2, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0};
1417412e9a14SMatthew G. Knepley   static PetscInt       ttripO[]  = {0, 0,
1418412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1419412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1420412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1421412e9a14SMatthew G. Knepley                                      0, 0, 0,  0, -1, 0,
1422412e9a14SMatthew G. Knepley                                      0, 0, 0,  0,  0, -1,
1423412e9a14SMatthew G. Knepley                                      0, 0, 0, -1,  0, 0};
1424412e9a14SMatthew G. Knepley   /* TODO Add 3 quads inside every tensor triangular prism, making 4 new triangular prisms.
1425412e9a14SMatthew G. Knepley       2
1426412e9a14SMatthew G. Knepley       |\
1427412e9a14SMatthew G. Knepley       | \
1428412e9a14SMatthew G. Knepley       |  \
1429412e9a14SMatthew G. Knepley       0---1
143075d3a19aSMatthew G. Knepley 
1431412e9a14SMatthew G. Knepley       2
143275d3a19aSMatthew G. Knepley 
1433412e9a14SMatthew G. Knepley       0   1
143475d3a19aSMatthew G. Knepley 
1435412e9a14SMatthew G. Knepley       2
1436412e9a14SMatthew G. Knepley       |\
1437412e9a14SMatthew G. Knepley       | \
1438412e9a14SMatthew G. Knepley       |  \
1439412e9a14SMatthew G. Knepley       0---1
1440a97b51b8SMatthew G. Knepley   */
1441412e9a14SMatthew G. Knepley   static DMPolytopeType ctripT[]  = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON};
1442412e9a14SMatthew G. Knepley   static PetscInt       ctripS[]  = {1, 3, 3};
1443412e9a14SMatthew G. Knepley   static PetscInt       ctripC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1444412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0,
1445412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0,
1446412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 4, 0,
1447412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 0,    2, DM_POLYTOPE_QUADRILATERAL, 0,    0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 1,
1448412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_QUADRILATERAL, 1, 2, 1, DM_POLYTOPE_QUADRILATERAL, 0,    1, DM_POLYTOPE_QUADRILATERAL, 1,  3, 0, DM_POLYTOPE_QUADRILATERAL, 0,    0,
1449412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2, DM_POLYTOPE_QUADRILATERAL, 0,    2, DM_POLYTOPE_QUADRILATERAL, 1, 3, 1, DM_POLYTOPE_QUADRILATERAL, 0,    1, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0};
1450412e9a14SMatthew G. Knepley   static PetscInt       ctripO[]  = {0, 0,
1451412e9a14SMatthew G. Knepley                                      0, 0, -2, -2,
1452412e9a14SMatthew G. Knepley                                      0, 0, -2, -2,
1453412e9a14SMatthew G. Knepley                                      0, 0, -2, -2,
1454412e9a14SMatthew G. Knepley                                     -4, 0, 0, -1,  0,  1,
1455412e9a14SMatthew G. Knepley                                     -4, 0, 0,  0,  0, -4,
1456412e9a14SMatthew G. Knepley                                     -4, 0, 0,  0, -1,  1};
1457412e9a14SMatthew G. Knepley   /* Add 1 edge and 4 quads inside every tensor quad prism, making 4 new hexahedra. */
1458412e9a14SMatthew G. Knepley   static DMPolytopeType tquadpT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR};
1459412e9a14SMatthew G. Knepley   static PetscInt       tquadpS[]  = {1, 4, 4};
1460412e9a14SMatthew G. Knepley   static PetscInt       tquadpC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1461412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0,
1462412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0,
1463412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0,
1464412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_SEGMENT, 1, 0, 3, DM_POLYTOPE_SEGMENT, 1, 1, 3, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 5, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 0, 0,
1465412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    3, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 1,
1466412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_QUADRILATERAL, 1, 0, 1, DM_POLYTOPE_QUADRILATERAL, 1, 1, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    1, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    0,
1467412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_QUADRILATERAL, 1, 0, 2, DM_POLYTOPE_QUADRILATERAL, 1, 1, 2, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    2,
1468412e9a14SMatthew G. Knepley                                       DM_POLYTOPE_QUADRILATERAL, 1, 0, 3, DM_POLYTOPE_QUADRILATERAL, 1, 1, 3, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    3, DM_POLYTOPE_SEG_PRISM_TENSOR, 0,    2, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 0};
1469412e9a14SMatthew G. Knepley   static PetscInt       tquadpO[]  = {0, 0,
1470412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1471412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1472412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1473412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1474412e9a14SMatthew G. Knepley                                       0, 0,  0,  0, -1,  0,
1475412e9a14SMatthew G. Knepley                                       0, 0,  0,  0,  0, -1,
1476412e9a14SMatthew G. Knepley                                       0, 0, -1,  0,  0,  0,
1477412e9a14SMatthew G. Knepley                                       0, 0,  0, -1,  0,  0};
1478412e9a14SMatthew G. Knepley   PetscBool convertTensor = PETSC_TRUE;
1479a97b51b8SMatthew G. Knepley 
1480412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
1481412e9a14SMatthew G. Knepley   if (convertTensor) {
1482412e9a14SMatthew G. Knepley     switch (source) {
1483412e9a14SMatthew G. Knepley       case DM_POLYTOPE_POINT:
1484412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEGMENT:
1485412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUADRILATERAL:
1486412e9a14SMatthew G. Knepley       case DM_POLYTOPE_HEXAHEDRON:
1487412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1488a97b51b8SMatthew G. Knepley         break;
1489412e9a14SMatthew G. Knepley       case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT;  *size = tedgeS;  *cone = tedgeC;  *ornt = tedgeO;  break;
1490412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEG_PRISM_TENSOR:   *Nt = 2; *target = tquadT;  *size = tquadS;  *cone = tquadC;  *ornt = tquadO;  break;
1491412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRI_PRISM_TENSOR:   *Nt = 3; *target = ctripT;  *size = ctripS;  *cone = ctripC;  *ornt = ctripO;  break;
1492412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUAD_PRISM_TENSOR:  *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break;
1493412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRIANGLE:           *Nt = 3; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
1494412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TETRAHEDRON:        *Nt = 4; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
1495412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRI_PRISM:          *Nt = 4; *target = tripT;   *size = tripS;   *cone = tripC;   *ornt = tripO;   break;
1496412e9a14SMatthew G. Knepley       default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1497b5da9499SMatthew G. Knepley     }
1498b5da9499SMatthew G. Knepley   } else {
1499412e9a14SMatthew G. Knepley     switch (source) {
1500412e9a14SMatthew G. Knepley       case DM_POLYTOPE_POINT:
1501412e9a14SMatthew G. Knepley       case DM_POLYTOPE_POINT_PRISM_TENSOR:
1502412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEGMENT:
1503412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUADRILATERAL:
1504412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEG_PRISM_TENSOR:
1505412e9a14SMatthew G. Knepley       case DM_POLYTOPE_HEXAHEDRON:
1506412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUAD_PRISM_TENSOR:
1507412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1508b5da9499SMatthew G. Knepley         break;
1509412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRIANGLE:           *Nt = 3; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
1510412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TETRAHEDRON:        *Nt = 4; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
1511412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRI_PRISM:          *Nt = 4; *target = tripT;   *size = tripS;   *cone = tripC;   *ornt = tripO;   break;
1512412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRI_PRISM_TENSOR:   *Nt = 3; *target = ttripT;  *size = ttripS;  *cone = ttripC;  *ornt = ttripO;  break;
1513412e9a14SMatthew G. Knepley       default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
151427fcede3SMatthew G. Knepley     }
151575d3a19aSMatthew G. Knepley   }
151675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
151775d3a19aSMatthew G. Knepley }
151875d3a19aSMatthew G. Knepley 
1519412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
152075d3a19aSMatthew G. Knepley {
1521412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
1522412e9a14SMatthew G. Knepley 
1523412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
1524412e9a14SMatthew G. Knepley   switch (source) {
1525412e9a14SMatthew G. Knepley     case DM_POLYTOPE_POINT:
1526412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
1527412e9a14SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR:
1528412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:
1529412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:
1530412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:
1531412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:
1532412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
1533412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
1534412e9a14SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:
1535412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:
1536412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1537412e9a14SMatthew G. Knepley       break;
1538412e9a14SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1539412e9a14SMatthew G. Knepley   }
1540412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1541412e9a14SMatthew G. Knepley }
1542412e9a14SMatthew G. Knepley 
1543*cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld2D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
1544*cf4091a3SMatthew G. Knepley {
1545*cf4091a3SMatthew G. Knepley   PetscErrorCode ierr;
1546*cf4091a3SMatthew G. Knepley   /* Add 1 vertex, 3 edges inside every triangle, making 3 new triangles.
1547*cf4091a3SMatthew G. Knepley    2
1548*cf4091a3SMatthew G. Knepley    |\
1549*cf4091a3SMatthew G. Knepley    |\\
1550*cf4091a3SMatthew G. Knepley    | |\
1551*cf4091a3SMatthew G. Knepley    | \ \
1552*cf4091a3SMatthew G. Knepley    | |  \
1553*cf4091a3SMatthew G. Knepley    |  \  \
1554*cf4091a3SMatthew G. Knepley    |   |  \
1555*cf4091a3SMatthew G. Knepley    2   \   \
1556*cf4091a3SMatthew G. Knepley    |   |    1
1557*cf4091a3SMatthew G. Knepley    |   2    \
1558*cf4091a3SMatthew G. Knepley    |   |    \
1559*cf4091a3SMatthew G. Knepley    |   /\   \
1560*cf4091a3SMatthew G. Knepley    |  0  1  |
1561*cf4091a3SMatthew G. Knepley    | /    \ |
1562*cf4091a3SMatthew G. Knepley    |/      \|
1563*cf4091a3SMatthew G. Knepley    0---0----1
1564*cf4091a3SMatthew G. Knepley   */
1565*cf4091a3SMatthew G. Knepley   static DMPolytopeType triT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE};
1566*cf4091a3SMatthew G. Knepley   static PetscInt       triS[]    = {1, 3, 3};
1567*cf4091a3SMatthew G. Knepley   static PetscInt       triC[]    = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1568*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 2, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1569*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 2, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1570*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0,
1571*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1,
1572*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2};
1573*cf4091a3SMatthew G. Knepley   static PetscInt       triO[]    = {0, 0,
1574*cf4091a3SMatthew G. Knepley                                      0, 0,
1575*cf4091a3SMatthew G. Knepley                                      0, 0,
1576*cf4091a3SMatthew G. Knepley                                      0,  0, -2,
1577*cf4091a3SMatthew G. Knepley                                      0,  0, -2,
1578*cf4091a3SMatthew G. Knepley                                      0,  0, -2};
1579*cf4091a3SMatthew G. Knepley 
1580*cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
1581*cf4091a3SMatthew G. Knepley   switch (source) {
1582*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT:
1583*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
1584*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR:
1585*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
1586*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
1587*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:
1588*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:
1589*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:
1590*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:
1591*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:
1592*cf4091a3SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1593*cf4091a3SMatthew G. Knepley       break;
1594*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:           *Nt = 3; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
1595*cf4091a3SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1596*cf4091a3SMatthew G. Knepley   }
1597*cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
1598*cf4091a3SMatthew G. Knepley }
1599*cf4091a3SMatthew G. Knepley 
1600*cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld3D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
1601*cf4091a3SMatthew G. Knepley {
1602*cf4091a3SMatthew G. Knepley   PetscErrorCode ierr;
1603*cf4091a3SMatthew G. Knepley   /* Add 6 triangles inside every cell, making 4 new tets
1604*cf4091a3SMatthew G. Knepley      The vertices of our reference tet are [(-1, -1, -1), (-1, 1, -1), (1, -1, -1), (-1, -1, 1)], which we call [v0, v1, v2, v3]. The first
1605*cf4091a3SMatthew G. Knepley      three edges are [v0, v1], [v1, v2], [v2, v0] called e0, e1, and e2, and then three edges to the top point [v0, v3], [v1, v3], [v2, v3]
1606*cf4091a3SMatthew G. Knepley      called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are
1607*cf4091a3SMatthew G. Knepley        [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3]
1608*cf4091a3SMatthew G. Knepley      We make a new tet on each face
1609*cf4091a3SMatthew G. Knepley        [v0, v1, v2, (c0, 0)]
1610*cf4091a3SMatthew G. Knepley        [v0, v3, v1, (c0, 0)]
1611*cf4091a3SMatthew G. Knepley        [v0, v2, v3, (c0, 0)]
1612*cf4091a3SMatthew G. Knepley        [v2, v1, v3, (c0, 0)]
1613*cf4091a3SMatthew G. Knepley      We create a new face for each edge
1614*cf4091a3SMatthew G. Knepley        [v0, (c0, 0), v1     ]
1615*cf4091a3SMatthew G. Knepley        [v0, v2,      (c0, 0)]
1616*cf4091a3SMatthew G. Knepley        [v2, v1,      (c0, 0)]
1617*cf4091a3SMatthew G. Knepley        [v0, (c0, 0), v3     ]
1618*cf4091a3SMatthew G. Knepley        [v1, v3,      (c0, 0)]
1619*cf4091a3SMatthew G. Knepley        [v3, v2,      (c0, 0)]
1620*cf4091a3SMatthew G. Knepley    */
1621*cf4091a3SMatthew G. Knepley   static DMPolytopeType tetT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON};
1622*cf4091a3SMatthew G. Knepley   static PetscInt       tetS[]    = {1, 4, 6, 4};
1623*cf4091a3SMatthew G. Knepley   static PetscInt       tetC[]    = {DM_POLYTOPE_POINT, 3, 0, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1624*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 3, 0, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1625*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 3, 0, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1626*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 3, 1, 0, 1, 0, DM_POLYTOPE_POINT, 0, 0,
1627*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,       0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 2, 0, 0, 0,
1628*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 2, 0, 2, 0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,       0,
1629*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 2, 0, 1, 0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,       2,
1630*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,       0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 2, 1, 0, 0,
1631*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 2, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,       1,
1632*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 2, 2, 1, 0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,       3,
1633*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 2,
1634*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 4,
1635*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 5,
1636*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 3, 0, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 4};
1637*cf4091a3SMatthew G. Knepley   static PetscInt       tetO[]    = {0, 0,
1638*cf4091a3SMatthew G. Knepley                                      0, 0,
1639*cf4091a3SMatthew G. Knepley                                      0, 0,
1640*cf4091a3SMatthew G. Knepley                                      0, 0,
1641*cf4091a3SMatthew G. Knepley                                      0, -2, -2,
1642*cf4091a3SMatthew G. Knepley                                     -2,  0, -2,
1643*cf4091a3SMatthew G. Knepley                                     -2,  0, -2,
1644*cf4091a3SMatthew G. Knepley                                      0, -2, -2,
1645*cf4091a3SMatthew G. Knepley                                     -2,  0, -2,
1646*cf4091a3SMatthew G. Knepley                                     -2,  0, -2,
1647*cf4091a3SMatthew G. Knepley                                      0,  0,  0,  0,
1648*cf4091a3SMatthew G. Knepley                                      0,  0, -3,  0,
1649*cf4091a3SMatthew G. Knepley                                      0, -3, -3,  0,
1650*cf4091a3SMatthew G. Knepley                                      0, -3, -1, -1};
1651*cf4091a3SMatthew G. Knepley 
1652*cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
1653*cf4091a3SMatthew G. Knepley   switch (source) {
1654*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT:
1655*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
1656*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR:
1657*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:
1658*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
1659*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
1660*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:
1661*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:
1662*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:
1663*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:
1664*cf4091a3SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1665*cf4091a3SMatthew G. Knepley       break;
1666*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:        *Nt = 4; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
1667*cf4091a3SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1668*cf4091a3SMatthew G. Knepley   }
1669*cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
1670*cf4091a3SMatthew G. Knepley }
1671*cf4091a3SMatthew G. Knepley 
1672*cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_BL(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
1673*cf4091a3SMatthew G. Knepley {
1674*cf4091a3SMatthew G. Knepley   PetscErrorCode ierr;
1675*cf4091a3SMatthew G. Knepley   /* Split all tensor edges with a new vertex, making two new 2 tensor edges
1676*cf4091a3SMatthew G. Knepley      0--0--0--1--1
1677*cf4091a3SMatthew G. Knepley   */
1678*cf4091a3SMatthew G. Knepley   static DMPolytopeType tedgeT[]   = {DM_POLYTOPE_POINT, DM_POLYTOPE_POINT_PRISM_TENSOR};
1679*cf4091a3SMatthew G. Knepley   static PetscInt       tedgeS[]   = {1, 2};
1680*cf4091a3SMatthew G. Knepley   static PetscInt       tedgeC[]   = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,  DM_POLYTOPE_POINT, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
1681*cf4091a3SMatthew G. Knepley   static PetscInt       tedgeO[]   = {                         0,                       0,                        0,                          0};
1682*cf4091a3SMatthew G. Knepley   /* Add 1 segment inside every tensor quad, making 2 new tensor quads
1683*cf4091a3SMatthew G. Knepley      2---------1---------3
1684*cf4091a3SMatthew G. Knepley      |                   |
1685*cf4091a3SMatthew G. Knepley      |         B         |
1686*cf4091a3SMatthew G. Knepley      |                   |
1687*cf4091a3SMatthew G. Knepley      2---------2---------3
1688*cf4091a3SMatthew G. Knepley      |                   |
1689*cf4091a3SMatthew G. Knepley      |         A         |
1690*cf4091a3SMatthew G. Knepley      |                   |
1691*cf4091a3SMatthew G. Knepley      0---------0---------1
1692*cf4091a3SMatthew G. Knepley   */
1693*cf4091a3SMatthew G. Knepley   static DMPolytopeType tquadT[]  = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_SEG_PRISM_TENSOR};
1694*cf4091a3SMatthew G. Knepley   static PetscInt       tquadS[]  = {1, 2};
1695*cf4091a3SMatthew G. Knepley   static PetscInt       tquadC[]  = {DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 3, 0,
1696*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 0,
1697*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_POINT_PRISM_TENSOR, 1, 3, 1};
1698*cf4091a3SMatthew G. Knepley   static PetscInt       tquadO[]  = {0, 0,
1699*cf4091a3SMatthew G. Knepley                                      0, 0, 0, 0,
1700*cf4091a3SMatthew G. Knepley                                      0, 0, 0, 0};
1701*cf4091a3SMatthew G. Knepley   /* Add 1 triangle and make 2 new tensor triangular prisms */
1702*cf4091a3SMatthew G. Knepley   static DMPolytopeType ttripT[]  = {DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TRI_PRISM_TENSOR};
1703*cf4091a3SMatthew G. Knepley   static PetscInt       ttripS[]  = {1, 2};
1704*cf4091a3SMatthew G. Knepley   static PetscInt       ttripC[]  = {DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 4, 0,
1705*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 0,    0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0,
1706*cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    0, DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 1};
1707*cf4091a3SMatthew G. Knepley   static PetscInt       ttripO[]  = {0, 0, 0,
1708*cf4091a3SMatthew G. Knepley                                      0, 0, 0, 0, 0,
1709*cf4091a3SMatthew G. Knepley                                      0, 0, 0, 0, 0,
1710*cf4091a3SMatthew G. Knepley                                      0, 0, 0, 0, 0,
1711*cf4091a3SMatthew G. Knepley                                      0, 0, 0, 0, 0};
1712*cf4091a3SMatthew G. Knepley   /* Add 1 quad and make 2 new tensor quad prisms */
1713*cf4091a3SMatthew G. Knepley   static DMPolytopeType tquadpT[]  = {DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_QUAD_PRISM_TENSOR};
1714*cf4091a3SMatthew G. Knepley   static PetscInt       tquadpS[]  = {1, 2};
1715*cf4091a3SMatthew G. Knepley   static PetscInt       tquadpC[]  = {DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 4, 0, DM_POLYTOPE_SEGMENT, 1, 5, 0,
1716*cf4091a3SMatthew G. Knepley                                       DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 0,    0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 0,
1717*cf4091a3SMatthew G. Knepley                                       DM_POLYTOPE_QUADRILATERAL, 0,    0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 2, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 3, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 4, 1, DM_POLYTOPE_SEG_PRISM_TENSOR, 1, 5, 1};
1718*cf4091a3SMatthew G. Knepley   static PetscInt       tquadpO[]  = {0, 0, 0, 0,
1719*cf4091a3SMatthew G. Knepley                                       0, 0, 0, 0, 0, 0,
1720*cf4091a3SMatthew G. Knepley                                       0, 0, 0, 0, 0, 0,
1721*cf4091a3SMatthew G. Knepley                                       0, 0, 0, 0, 0, 0,
1722*cf4091a3SMatthew G. Knepley                                       0, 0, 0, 0, 0, 0};
1723*cf4091a3SMatthew G. Knepley 
1724*cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
1725*cf4091a3SMatthew G. Knepley   switch (source) {
1726*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT:
1727*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
1728*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:
1729*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
1730*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:
1731*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:
1732*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:
1733*cf4091a3SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1734*cf4091a3SMatthew G. Knepley       break;
1735*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 2; *target = tedgeT;  *size = tedgeS;  *cone = tedgeC;  *ornt = tedgeO;  break;
1736*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:   *Nt = 2; *target = tquadT;  *size = tquadS;  *cone = tquadC;  *ornt = tquadO;  break;
1737*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:   *Nt = 2; *target = ttripT;  *size = ttripS;  *cone = ttripC;  *ornt = ttripO;  break;
1738*cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  *Nt = 2; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break;
1739*cf4091a3SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1740*cf4091a3SMatthew G. Knepley   }
1741*cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
1742*cf4091a3SMatthew G. Knepley }
1743*cf4091a3SMatthew G. Knepley 
1744412e9a14SMatthew G. Knepley static PetscErrorCode CellRefinerCreateOffset_Internal(DMPlexCellRefiner cr, PetscInt ctOrder[], PetscInt ctStart[], PetscInt **offset)
1745412e9a14SMatthew G. Knepley {
1746412e9a14SMatthew G. Knepley   PetscInt       c, cN, *off;
174775d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
174875d3a19aSMatthew G. Knepley 
174975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
1750412e9a14SMatthew G. Knepley   ierr = PetscCalloc1(DM_NUM_POLYTOPES*DM_NUM_POLYTOPES, &off);CHKERRQ(ierr);
1751412e9a14SMatthew G. Knepley   for (c = DM_POLYTOPE_POINT; c < DM_NUM_POLYTOPES; ++c) {
1752412e9a14SMatthew G. Knepley     const DMPolytopeType ct = (DMPolytopeType) c;
1753412e9a14SMatthew G. Knepley     for (cN = DM_POLYTOPE_POINT; cN < DM_NUM_POLYTOPES; ++cN) {
1754412e9a14SMatthew G. Knepley       const DMPolytopeType ctNew = (DMPolytopeType) cN;
1755412e9a14SMatthew G. Knepley       DMPolytopeType      *rct;
1756412e9a14SMatthew G. Knepley       PetscInt            *rsize, *cone, *ornt;
1757412e9a14SMatthew G. Knepley       PetscInt             Nct, n, i;
1758412e9a14SMatthew G. Knepley 
1759412e9a14SMatthew G. Knepley       if (DMPolytopeTypeGetDim(ct) < 0 || DMPolytopeTypeGetDim(ctNew) < 0) {off[ct*DM_NUM_POLYTOPES+ctNew] = -1; break;}
1760412e9a14SMatthew G. Knepley       off[ct*DM_NUM_POLYTOPES+ctNew] = 0;
1761412e9a14SMatthew G. Knepley       for (i = DM_POLYTOPE_POINT; i < DM_NUM_POLYTOPES; ++i) {
1762412e9a14SMatthew G. Knepley         const DMPolytopeType ict  = (DMPolytopeType) ctOrder[i];
1763412e9a14SMatthew G. Knepley         const DMPolytopeType ictn = (DMPolytopeType) ctOrder[i+1];
1764412e9a14SMatthew G. Knepley 
1765412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine(cr, ict, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr);
1766412e9a14SMatthew G. Knepley         if (ict == ct) {
1767412e9a14SMatthew G. Knepley           for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) break;
1768412e9a14SMatthew G. Knepley           if (n == Nct) off[ct*DM_NUM_POLYTOPES+ctNew] = -1;
1769412e9a14SMatthew G. Knepley           break;
1770412e9a14SMatthew G. Knepley         }
1771412e9a14SMatthew G. Knepley         for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) off[ct*DM_NUM_POLYTOPES+ctNew] += (ctStart[ictn]-ctStart[ict]) * rsize[n];
1772412e9a14SMatthew G. Knepley       }
1773412e9a14SMatthew G. Knepley     }
1774412e9a14SMatthew G. Knepley   }
1775412e9a14SMatthew G. Knepley   *offset = off;
1776412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1777412e9a14SMatthew G. Knepley }
1778412e9a14SMatthew G. Knepley 
1779412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetStarts(DMPlexCellRefiner cr, const PetscInt ctStart[], const PetscInt ctStartNew[])
1780412e9a14SMatthew G. Knepley {
1781412e9a14SMatthew G. Knepley   const PetscInt ctSize = DM_NUM_POLYTOPES+1;
1782412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
1783412e9a14SMatthew G. Knepley 
1784412e9a14SMatthew G. Knepley   PetscFunctionBegin;
1785412e9a14SMatthew G. Knepley   if (cr->setupcalled) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_ARG_WRONGSTATE, "Must call this function before DMPlexCellRefinerSetUp()");
1786412e9a14SMatthew G. Knepley   ierr = PetscCalloc2(ctSize, &cr->ctStart, ctSize, &cr->ctStartNew);CHKERRQ(ierr);
1787412e9a14SMatthew G. Knepley   ierr = PetscArraycpy(cr->ctStart,    ctStart,    ctSize);CHKERRQ(ierr);
1788412e9a14SMatthew G. Knepley   ierr = PetscArraycpy(cr->ctStartNew, ctStartNew, ctSize);CHKERRQ(ierr);
1789412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1790412e9a14SMatthew G. Knepley }
1791412e9a14SMatthew G. Knepley 
1792412e9a14SMatthew G. Knepley /* Construct cell type order since we must loop over cell types in depth order */
1793412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCreateCellTypeOrder_Internal(DMPolytopeType ctCell, PetscInt *ctOrder[], PetscInt *ctOrderInv[])
1794412e9a14SMatthew G. Knepley {
1795412e9a14SMatthew G. Knepley   PetscInt      *ctO, *ctOInv;
1796412e9a14SMatthew G. Knepley   PetscInt       c, d, off = 0;
1797412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
1798412e9a14SMatthew G. Knepley 
1799412e9a14SMatthew G. Knepley   PetscFunctionBegin;
1800412e9a14SMatthew G. Knepley   ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctO, DM_NUM_POLYTOPES+1, &ctOInv);CHKERRQ(ierr);
1801412e9a14SMatthew G. Knepley   for (d = 3; d >= DMPolytopeTypeGetDim(ctCell); --d) {
1802412e9a14SMatthew G. Knepley     for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
1803412e9a14SMatthew G. Knepley       if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue;
1804412e9a14SMatthew G. Knepley       ctO[off++] = c;
1805412e9a14SMatthew G. Knepley     }
1806412e9a14SMatthew G. Knepley   }
1807412e9a14SMatthew G. Knepley   if (DMPolytopeTypeGetDim(ctCell) != 0) {
1808412e9a14SMatthew G. Knepley     for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
1809412e9a14SMatthew G. Knepley       if (DMPolytopeTypeGetDim((DMPolytopeType) c) != 0) continue;
1810412e9a14SMatthew G. Knepley       ctO[off++] = c;
1811412e9a14SMatthew G. Knepley     }
1812412e9a14SMatthew G. Knepley   }
1813412e9a14SMatthew G. Knepley   for (d = DMPolytopeTypeGetDim(ctCell)-1; d > 0; --d) {
1814412e9a14SMatthew G. Knepley     for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
1815412e9a14SMatthew G. Knepley       if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue;
1816412e9a14SMatthew G. Knepley       ctO[off++] = c;
1817412e9a14SMatthew G. Knepley     }
1818412e9a14SMatthew G. Knepley   }
1819412e9a14SMatthew G. Knepley   for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
1820412e9a14SMatthew G. Knepley     if (DMPolytopeTypeGetDim((DMPolytopeType) c) >= 0) continue;
1821412e9a14SMatthew G. Knepley     ctO[off++] = c;
1822412e9a14SMatthew G. Knepley   }
1823412e9a14SMatthew G. Knepley   if (off != DM_NUM_POLYTOPES+1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid offset %D for cell type order", off);
1824412e9a14SMatthew G. Knepley   for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
1825412e9a14SMatthew G. Knepley     ctOInv[ctO[c]] = c;
1826412e9a14SMatthew G. Knepley   }
1827412e9a14SMatthew G. Knepley   *ctOrder    = ctO;
1828412e9a14SMatthew G. Knepley   *ctOrderInv = ctOInv;
1829412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1830412e9a14SMatthew G. Knepley }
1831412e9a14SMatthew G. Knepley 
1832412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerSetUp(DMPlexCellRefiner cr)
1833412e9a14SMatthew G. Knepley {
1834412e9a14SMatthew G. Knepley   DM             dm = cr->dm;
1835412e9a14SMatthew G. Knepley   DMPolytopeType ctCell;
1836412e9a14SMatthew G. Knepley   PetscInt       pStart, pEnd, p, c;
1837412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
1838412e9a14SMatthew G. Knepley 
1839412e9a14SMatthew G. Knepley   PetscFunctionBegin;
1840412e9a14SMatthew G. Knepley   PetscValidHeader(cr, 1);
1841412e9a14SMatthew G. Knepley   if (cr->setupcalled) PetscFunctionReturn(0);
1842412e9a14SMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
1843412e9a14SMatthew G. Knepley   if (pEnd > pStart) {ierr = DMPlexGetCellType(dm, 0, &ctCell);CHKERRQ(ierr);}
1844412e9a14SMatthew G. Knepley   else               {
1845412e9a14SMatthew G. Knepley     PetscInt dim;
1846a57030b0SMatthew G. Knepley     ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
1847412e9a14SMatthew G. Knepley     switch (dim) {
1848412e9a14SMatthew G. Knepley       case 0: ctCell = DM_POLYTOPE_POINT;break;
1849412e9a14SMatthew G. Knepley       case 1: ctCell = DM_POLYTOPE_SEGMENT;break;
1850412e9a14SMatthew G. Knepley       case 2: ctCell = DM_POLYTOPE_TRIANGLE;break;
1851412e9a14SMatthew G. Knepley       case 3: ctCell = DM_POLYTOPE_TETRAHEDRON;break;
1852412e9a14SMatthew G. Knepley       default: ctCell = DM_POLYTOPE_TETRAHEDRON;
1853412e9a14SMatthew G. Knepley     }
1854412e9a14SMatthew G. Knepley   }
1855412e9a14SMatthew G. Knepley   ierr = DMPlexCreateCellTypeOrder_Internal(ctCell, &cr->ctOrder, &cr->ctOrderInv);CHKERRQ(ierr);
1856412e9a14SMatthew G. Knepley   /* Construct sizes and offsets for each cell type */
1857412e9a14SMatthew G. Knepley   if (!cr->ctStart) {
1858412e9a14SMatthew G. Knepley     PetscInt *ctS, *ctSN, *ctC, *ctCN;
1859412e9a14SMatthew G. Knepley 
1860412e9a14SMatthew G. Knepley     ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctS, DM_NUM_POLYTOPES+1, &ctSN);CHKERRQ(ierr);
1861412e9a14SMatthew G. Knepley     ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctC, DM_NUM_POLYTOPES+1, &ctCN);CHKERRQ(ierr);
1862412e9a14SMatthew G. Knepley     for (p = pStart; p < pEnd; ++p) {
1863412e9a14SMatthew G. Knepley       DMPolytopeType  ct;
1864412e9a14SMatthew G. Knepley       DMPolytopeType *rct;
1865412e9a14SMatthew G. Knepley       PetscInt       *rsize, *cone, *ornt;
1866412e9a14SMatthew G. Knepley       PetscInt        Nct, n;
1867412e9a14SMatthew G. Knepley 
1868412e9a14SMatthew G. Knepley       ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
1869412e9a14SMatthew G. Knepley       if ((PetscInt) ct < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell type for point %D", p);
1870412e9a14SMatthew G. Knepley       ++ctC[ct];
1871412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr);
1872412e9a14SMatthew G. Knepley       for (n = 0; n < Nct; ++n) ctCN[rct[n]] += rsize[n];
1873412e9a14SMatthew G. Knepley     }
1874412e9a14SMatthew G. Knepley     for (c = 0; c < DM_NUM_POLYTOPES; ++c) {
1875412e9a14SMatthew G. Knepley       const PetscInt ct  = cr->ctOrder[c];
1876412e9a14SMatthew G. Knepley       const PetscInt ctn = cr->ctOrder[c+1];
1877412e9a14SMatthew G. Knepley 
1878412e9a14SMatthew G. Knepley       ctS[ctn]  = ctS[ct]  + ctC[ct];
1879412e9a14SMatthew G. Knepley       ctSN[ctn] = ctSN[ct] + ctCN[ct];
1880412e9a14SMatthew G. Knepley     }
1881412e9a14SMatthew G. Knepley     ierr = PetscFree2(ctC, ctCN);CHKERRQ(ierr);
1882412e9a14SMatthew G. Knepley     cr->ctStart    = ctS;
1883412e9a14SMatthew G. Knepley     cr->ctStartNew = ctSN;
1884412e9a14SMatthew G. Knepley   }
1885412e9a14SMatthew G. Knepley   ierr = CellRefinerCreateOffset_Internal(cr, cr->ctOrder, cr->ctStart, &cr->offset);CHKERRQ(ierr);
1886412e9a14SMatthew G. Knepley   cr->setupcalled = PETSC_TRUE;
1887412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1888412e9a14SMatthew G. Knepley }
1889412e9a14SMatthew G. Knepley 
1890412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView_Ascii(DMPlexCellRefiner cr, PetscViewer v)
1891412e9a14SMatthew G. Knepley {
1892412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
1893412e9a14SMatthew G. Knepley 
1894412e9a14SMatthew G. Knepley   PetscFunctionBegin;
1895412e9a14SMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(v, "Cell Refiner: %s\n", DMPlexCellRefinerTypes[cr->type]);CHKERRQ(ierr);
1896412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1897412e9a14SMatthew G. Knepley }
1898412e9a14SMatthew G. Knepley 
1899412e9a14SMatthew G. Knepley /*
1900412e9a14SMatthew G. Knepley   DMPlexCellRefinerView - Views a DMPlexCellRefiner object
1901412e9a14SMatthew G. Knepley 
1902412e9a14SMatthew G. Knepley   Collective on cr
1903412e9a14SMatthew G. Knepley 
1904412e9a14SMatthew G. Knepley   Input Parameters:
1905412e9a14SMatthew G. Knepley + cr     - The DMPlexCellRefiner object
1906412e9a14SMatthew G. Knepley - viewer - The PetscViewer object
1907412e9a14SMatthew G. Knepley 
1908412e9a14SMatthew G. Knepley   Level: beginner
1909412e9a14SMatthew G. Knepley 
1910412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerCreate()
1911412e9a14SMatthew G. Knepley */
1912412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView(DMPlexCellRefiner cr, PetscViewer viewer)
1913412e9a14SMatthew G. Knepley {
1914412e9a14SMatthew G. Knepley   PetscBool      iascii;
1915412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
1916412e9a14SMatthew G. Knepley 
1917412e9a14SMatthew G. Knepley   PetscFunctionBegin;
1918412e9a14SMatthew G. Knepley   PetscValidHeader(cr, 1);
1919412e9a14SMatthew G. Knepley   if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1920412e9a14SMatthew G. Knepley   if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) cr), &viewer);CHKERRQ(ierr);}
1921412e9a14SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
1922412e9a14SMatthew G. Knepley   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
1923412e9a14SMatthew G. Knepley   if (iascii) {ierr = DMPlexCellRefinerView_Ascii(cr, viewer);CHKERRQ(ierr);}
1924412e9a14SMatthew G. Knepley   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1925412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1926412e9a14SMatthew G. Knepley }
1927412e9a14SMatthew G. Knepley 
1928412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerDestroy(DMPlexCellRefiner *cr)
1929412e9a14SMatthew G. Knepley {
1930412e9a14SMatthew G. Knepley   PetscInt       c;
1931412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
1932412e9a14SMatthew G. Knepley 
1933412e9a14SMatthew G. Knepley   PetscFunctionBegin;
1934412e9a14SMatthew G. Knepley   if (!*cr) PetscFunctionReturn(0);
1935412e9a14SMatthew G. Knepley   PetscValidHeaderSpecific(*cr, DM_CLASSID, 1);
1936412e9a14SMatthew G. Knepley   ierr = PetscObjectDereference((PetscObject) (*cr)->dm);CHKERRQ(ierr);
1937412e9a14SMatthew G. Knepley   ierr = PetscFree2((*cr)->ctOrder, (*cr)->ctOrderInv);CHKERRQ(ierr);
1938412e9a14SMatthew G. Knepley   ierr = PetscFree2((*cr)->ctStart, (*cr)->ctStartNew);CHKERRQ(ierr);
1939412e9a14SMatthew G. Knepley   ierr = PetscFree((*cr)->offset);CHKERRQ(ierr);
1940412e9a14SMatthew G. Knepley   for (c = 0; c < DM_NUM_POLYTOPES; ++c) {
1941412e9a14SMatthew G. Knepley     ierr = PetscFEDestroy(&(*cr)->coordFE[c]);CHKERRQ(ierr);
1942412e9a14SMatthew G. Knepley     ierr = PetscFEGeomDestroy(&(*cr)->refGeom[c]);CHKERRQ(ierr);
1943412e9a14SMatthew G. Knepley   }
1944412e9a14SMatthew G. Knepley   ierr = PetscFree2((*cr)->coordFE, (*cr)->refGeom);CHKERRQ(ierr);
1945412e9a14SMatthew G. Knepley   ierr = PetscHeaderDestroy(cr);CHKERRQ(ierr);
1946412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1947412e9a14SMatthew G. Knepley }
1948412e9a14SMatthew G. Knepley 
1949412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerCreate(DM dm, DMPlexCellRefiner *cr)
1950412e9a14SMatthew G. Knepley {
1951412e9a14SMatthew G. Knepley   DMPlexCellRefiner tmp;
1952412e9a14SMatthew G. Knepley   PetscErrorCode    ierr;
1953412e9a14SMatthew G. Knepley 
1954412e9a14SMatthew G. Knepley   PetscFunctionBegin;
1955412e9a14SMatthew G. Knepley   PetscValidPointer(cr, 2);
1956412e9a14SMatthew G. Knepley   *cr  = NULL;
1957412e9a14SMatthew G. Knepley   ierr = PetscHeaderCreate(tmp, DM_CLASSID, "DMPlexCellRefiner", "Cell Refiner", "DMPlexCellRefiner", PETSC_COMM_SELF, DMPlexCellRefinerDestroy, DMPlexCellRefinerView);CHKERRQ(ierr);
1958412e9a14SMatthew G. Knepley   tmp->setupcalled = PETSC_FALSE;
1959412e9a14SMatthew G. Knepley 
1960412e9a14SMatthew G. Knepley   tmp->dm = dm;
1961412e9a14SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr);
1962412e9a14SMatthew G. Knepley   ierr = DMPlexGetCellRefinerType(dm, &tmp->type);CHKERRQ(ierr);
1963412e9a14SMatthew G. Knepley   switch (tmp->type) {
196496ca5757SLisandro Dalcin     case DM_REFINER_REGULAR:
1965412e9a14SMatthew G. Knepley       tmp->ops->refine                  = DMPlexCellRefinerRefine_Regular;
1966412e9a14SMatthew G. Knepley       tmp->ops->mapsubcells             = DMPlexCellRefinerMapSubcells_Regular;
1967412e9a14SMatthew G. Knepley       tmp->ops->getcellvertices         = DMPlexCellRefinerGetCellVertices_Regular;
1968412e9a14SMatthew G. Knepley       tmp->ops->getsubcellvertices      = DMPlexCellRefinerGetSubcellVertices_Regular;
1969412e9a14SMatthew G. Knepley       tmp->ops->getaffinetransforms     = DMPlexCellRefinerGetAffineTransforms_Regular;
1970412e9a14SMatthew G. Knepley       tmp->ops->getaffinefacetransforms = DMPlexCellRefinerGetAffineFaceTransforms_Regular;
1971412e9a14SMatthew G. Knepley       break;
197296ca5757SLisandro Dalcin     case DM_REFINER_TO_BOX:
197396ca5757SLisandro Dalcin       tmp->ops->refine             = DMPlexCellRefinerRefine_ToBox;
197496ca5757SLisandro Dalcin       tmp->ops->mapsubcells        = DMPlexCellRefinerMapSubcells_ToBox;
197596ca5757SLisandro Dalcin       tmp->ops->getcellvertices    = DMPlexCellRefinerGetCellVertices_ToBox;
197696ca5757SLisandro Dalcin       tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_ToBox;
1977412e9a14SMatthew G. Knepley       break;
197896ca5757SLisandro Dalcin     case DM_REFINER_TO_SIMPLEX:
1979412e9a14SMatthew G. Knepley       tmp->ops->refine      = DMPlexCellRefinerRefine_ToSimplex;
1980412e9a14SMatthew G. Knepley       tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToSimplex;
1981412e9a14SMatthew G. Knepley       break;
1982*cf4091a3SMatthew G. Knepley     case DM_REFINER_ALFELD2D:
1983*cf4091a3SMatthew G. Knepley       tmp->ops->refine      = DMPlexCellRefinerRefine_Alfeld2D;
1984*cf4091a3SMatthew G. Knepley       tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None;
1985*cf4091a3SMatthew G. Knepley       break;
1986*cf4091a3SMatthew G. Knepley     case DM_REFINER_ALFELD3D:
1987*cf4091a3SMatthew G. Knepley       tmp->ops->refine      = DMPlexCellRefinerRefine_Alfeld3D;
1988*cf4091a3SMatthew G. Knepley       tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None;
1989*cf4091a3SMatthew G. Knepley       break;
1990*cf4091a3SMatthew G. Knepley     case DM_REFINER_BL:
1991*cf4091a3SMatthew G. Knepley       tmp->ops->refine      = DMPlexCellRefinerRefine_BL;
1992*cf4091a3SMatthew G. Knepley       tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_BL;
1993*cf4091a3SMatthew G. Knepley       break;
1994412e9a14SMatthew G. Knepley     default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Invalid cell refiner type %s", DMPlexCellRefinerTypes[tmp->type]);
1995412e9a14SMatthew G. Knepley   }
1996412e9a14SMatthew G. Knepley   ierr = PetscCalloc2(DM_NUM_POLYTOPES, &tmp->coordFE, DM_NUM_POLYTOPES, &tmp->refGeom);CHKERRQ(ierr);
1997412e9a14SMatthew G. Knepley   *cr = tmp;
1998412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1999412e9a14SMatthew G. Knepley }
2000412e9a14SMatthew G. Knepley 
2001412e9a14SMatthew G. Knepley /*@
2002412e9a14SMatthew G. Knepley   DMPlexCellRefinerGetAffineTransforms - Gets the affine map from the reference cell to each subcell
2003412e9a14SMatthew G. Knepley 
2004412e9a14SMatthew G. Knepley   Input Parameters:
2005412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object
2006412e9a14SMatthew G. Knepley - ct - The cell type
2007412e9a14SMatthew G. Knepley 
2008412e9a14SMatthew G. Knepley   Output Parameters:
2009412e9a14SMatthew G. Knepley + Nc   - The number of subcells produced from this cell type
2010412e9a14SMatthew G. Knepley . v0   - The translation of the first vertex for each subcell
2011412e9a14SMatthew G. Knepley . J    - The Jacobian for each subcell (map from reference cell to subcell)
2012412e9a14SMatthew G. Knepley - invJ - The inverse Jacobian for each subcell
2013412e9a14SMatthew G. Knepley 
2014412e9a14SMatthew G. Knepley   Level: developer
2015412e9a14SMatthew G. Knepley 
2016412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineFaceTransforms(), Create()
2017412e9a14SMatthew G. Knepley @*/
2018412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[])
2019412e9a14SMatthew G. Knepley {
2020412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2021412e9a14SMatthew G. Knepley 
2022412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2023412e9a14SMatthew G. Knepley   if (!cr->ops->getaffinetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine transforms from this refiner");
2024412e9a14SMatthew G. Knepley   ierr = (*cr->ops->getaffinetransforms)(cr, ct, Nc, v0, J, invJ);CHKERRQ(ierr);
2025412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2026412e9a14SMatthew G. Knepley }
2027412e9a14SMatthew G. Knepley 
2028412e9a14SMatthew G. Knepley /*@
2029412e9a14SMatthew G. Knepley   DMPlexCellRefinerGetAffineFaceTransforms - Gets the affine map from the reference face cell to each face in the given cell
2030412e9a14SMatthew G. Knepley 
2031412e9a14SMatthew G. Knepley   Input Parameters:
2032412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object
2033412e9a14SMatthew G. Knepley - ct - The cell type
2034412e9a14SMatthew G. Knepley 
2035412e9a14SMatthew G. Knepley   Output Parameters:
2036412e9a14SMatthew G. Knepley + Nf   - The number of faces for this cell type
2037412e9a14SMatthew G. Knepley . v0   - The translation of the first vertex for each face
2038412e9a14SMatthew G. Knepley . J    - The Jacobian for each face (map from original cell to subcell)
2039412e9a14SMatthew G. Knepley . invJ - The inverse Jacobian for each face
2040412e9a14SMatthew G. Knepley - detJ - The determinant of the Jacobian for each face
2041412e9a14SMatthew G. Knepley 
2042412e9a14SMatthew G. Knepley   Note: The Jacobian and inverse Jacboian will be rectangular, and the inverse is really a generalized inverse.
2043412e9a14SMatthew G. Knepley 
2044412e9a14SMatthew G. Knepley   Level: developer
2045412e9a14SMatthew G. Knepley 
2046412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineTransforms(), Create()
2047412e9a14SMatthew G. Knepley @*/
2048412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[])
2049412e9a14SMatthew G. Knepley {
2050412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2051412e9a14SMatthew G. Knepley 
2052412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2053412e9a14SMatthew G. Knepley   if (!cr->ops->getaffinefacetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine face transforms from this refiner");
2054412e9a14SMatthew G. Knepley   ierr = (*cr->ops->getaffinefacetransforms)(cr, ct, Nf, v0, J, invJ, detJ);CHKERRQ(ierr);
2055412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2056412e9a14SMatthew G. Knepley }
2057412e9a14SMatthew G. Knepley 
2058412e9a14SMatthew G. Knepley /* Numbering regularly refined meshes
2059412e9a14SMatthew G. Knepley 
2060412e9a14SMatthew G. Knepley    We want the numbering of the new mesh to respect the same depth stratification as the old mesh. We first compute
2061412e9a14SMatthew G. Knepley    the number of new points at each depth. This means that offsets for each depth can be computed, making no assumptions
2062412e9a14SMatthew G. Knepley    about the order of different cell types.
2063412e9a14SMatthew G. Knepley 
2064412e9a14SMatthew G. Knepley    However, when we want to order different depth strata, it will be very useful to make assumptions about contiguous
2065412e9a14SMatthew G. Knepley    numbering of different cell types, especially if we want to compute new numberings without communication. Therefore, we
2066412e9a14SMatthew G. Knepley    will require that cells are numbering contiguously for each cell type, and that those blocks come in the same order as
2067412e9a14SMatthew G. Knepley    the cell type enumeration within a given depth stratum.
2068412e9a14SMatthew G. Knepley 
2069412e9a14SMatthew G. Knepley    Thus, at each depth, each cell type will add a certain number of points at that depth. To get the new point number, we
2070412e9a14SMatthew G. Knepley    start at the new depth offset, run through all prior cell types incrementing by the total addition from that type, then
2071412e9a14SMatthew G. Knepley    offset by the old cell type number and replica number for the insertion.
2072412e9a14SMatthew G. Knepley */
2073412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetNewPoint(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType ctNew, PetscInt p, PetscInt r, PetscInt *pNew)
2074412e9a14SMatthew G. Knepley {
2075412e9a14SMatthew G. Knepley   DMPolytopeType  *rct;
2076412e9a14SMatthew G. Knepley   PetscInt        *rsize, *cone, *ornt;
2077412e9a14SMatthew G. Knepley   PetscInt         Nct, n;
2078412e9a14SMatthew G. Knepley   PetscInt         off  = cr->offset[ct*DM_NUM_POLYTOPES+ctNew];
2079412e9a14SMatthew G. Knepley   PetscInt         ctS  = cr->ctStart[ct],       ctE  = cr->ctStart[cr->ctOrder[cr->ctOrderInv[ct]+1]];
2080412e9a14SMatthew G. Knepley   PetscInt         ctSN = cr->ctStartNew[ctNew], ctEN = cr->ctStartNew[cr->ctOrder[cr->ctOrderInv[ctNew]+1]];
2081412e9a14SMatthew G. Knepley   PetscInt         newp = ctSN;
2082412e9a14SMatthew G. Knepley   PetscErrorCode   ierr;
2083412e9a14SMatthew G. Knepley 
2084412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
2085412e9a14SMatthew G. Knepley   if ((p < ctS) || (p >= ctE)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a %s [%D, %D)", p, DMPolytopeTypes[ct], ctS, ctE);
2086412e9a14SMatthew G. Knepley   if (off < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Cell type %s does not produce type %s", DMPolytopeTypes[ct], DMPolytopeTypes[ctNew]);
2087412e9a14SMatthew G. Knepley 
2088412e9a14SMatthew G. Knepley   newp += off;
2089412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr);
2090412e9a14SMatthew G. Knepley   for (n = 0; n < Nct; ++n) {
2091412e9a14SMatthew G. Knepley     if (rct[n] == ctNew) {
2092412e9a14SMatthew G. Knepley       if (rsize[n] && r >= rsize[n])
2093412e9a14SMatthew G. Knepley         SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Replica number %D should be in [0, %D) for subcell type %s in cell type %s", r, rsize[n], DMPolytopeTypes[rct[n]], DMPolytopeTypes[ct]);
2094412e9a14SMatthew G. Knepley       newp += (p - ctS) * rsize[n] + r;
2095412e9a14SMatthew G. Knepley       break;
2096412e9a14SMatthew G. Knepley     }
2097412e9a14SMatthew G. Knepley   }
2098412e9a14SMatthew G. Knepley 
2099412e9a14SMatthew G. Knepley   if ((newp < ctSN) || (newp >= ctEN)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "New point %D is not a %s [%D, %D)", newp, DMPolytopeTypes[ctNew], ctSN, ctEN);
2100412e9a14SMatthew G. Knepley   *pNew = newp;
2101412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2102412e9a14SMatthew G. Knepley }
2103412e9a14SMatthew G. Knepley 
2104412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetConeSizes(DMPlexCellRefiner cr, DM rdm)
2105412e9a14SMatthew G. Knepley {
2106412e9a14SMatthew G. Knepley   DM              dm = cr->dm;
2107412e9a14SMatthew G. Knepley   PetscInt        pStart, pEnd, p, pNew;
2108412e9a14SMatthew G. Knepley   PetscErrorCode  ierr;
2109412e9a14SMatthew G. Knepley 
2110412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2111412e9a14SMatthew G. Knepley   /* Must create the celltype label here so that we do not automatically try to compute the types */
2112412e9a14SMatthew G. Knepley   ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr);
2113412e9a14SMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
2114412e9a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2115412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
2116412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2117412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2118412e9a14SMatthew G. Knepley     PetscInt        Nct, n, r;
2119412e9a14SMatthew G. Knepley 
2120412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2121412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2122412e9a14SMatthew G. Knepley     for (n = 0; n < Nct; ++n) {
2123412e9a14SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r) {
2124412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr);
2125412e9a14SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, pNew, DMPolytopeTypeGetConeSize(rct[n]));CHKERRQ(ierr);
2126412e9a14SMatthew G. Knepley         ierr = DMPlexSetCellType(rdm, pNew, rct[n]);CHKERRQ(ierr);
2127412e9a14SMatthew G. Knepley       }
2128412e9a14SMatthew G. Knepley     }
2129412e9a14SMatthew G. Knepley   }
2130412e9a14SMatthew G. Knepley   {
2131412e9a14SMatthew G. Knepley     DMLabel  ctLabel;
2132412e9a14SMatthew G. Knepley     DM_Plex *plex = (DM_Plex *) rdm->data;
2133412e9a14SMatthew G. Knepley 
2134412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellTypeLabel(rdm, &ctLabel);CHKERRQ(ierr);
2135412e9a14SMatthew G. Knepley     ierr = PetscObjectStateGet((PetscObject) ctLabel, &plex->celltypeState);CHKERRQ(ierr);
2136412e9a14SMatthew G. Knepley   }
2137412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2138412e9a14SMatthew G. Knepley }
2139412e9a14SMatthew G. Knepley 
2140412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCones(DMPlexCellRefiner cr, DM rdm)
2141412e9a14SMatthew G. Knepley {
2142412e9a14SMatthew G. Knepley   DM             dm = cr->dm;
2143412e9a14SMatthew G. Knepley   DMPolytopeType ct;
2144412e9a14SMatthew G. Knepley   PetscInt      *coneNew, *orntNew;
2145412e9a14SMatthew G. Knepley   PetscInt       maxConeSize = 0, pStart, pEnd, p, pNew;
2146412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2147412e9a14SMatthew G. Knepley 
2148412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2149412e9a14SMatthew G. Knepley   for (p = 0; p < DM_NUM_POLYTOPES; ++p) maxConeSize = PetscMax(maxConeSize, DMPolytopeTypeGetConeSize((DMPolytopeType) p));
2150412e9a14SMatthew G. Knepley   ierr = PetscMalloc2(maxConeSize, &coneNew, maxConeSize, &orntNew);CHKERRQ(ierr);
2151412e9a14SMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
2152412e9a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2153412e9a14SMatthew G. Knepley     const PetscInt *cone, *ornt;
2154412e9a14SMatthew G. Knepley     PetscInt        coff, ooff, c;
2155412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2156412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2157412e9a14SMatthew G. Knepley     PetscInt        Nct, n, r;
2158412e9a14SMatthew G. Knepley 
2159412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2160412e9a14SMatthew G. Knepley     ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr);
2161412e9a14SMatthew G. Knepley     ierr = DMPlexGetConeOrientation(dm, p, &ornt);CHKERRQ(ierr);
2162412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2163412e9a14SMatthew G. Knepley     for (n = 0, coff = 0, ooff = 0; n < Nct; ++n) {
2164412e9a14SMatthew G. Knepley       const DMPolytopeType ctNew    = rct[n];
2165412e9a14SMatthew G. Knepley       const PetscInt       csizeNew = DMPolytopeTypeGetConeSize(ctNew);
2166412e9a14SMatthew G. Knepley 
2167412e9a14SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r) {
2168412e9a14SMatthew G. Knepley         /* pNew is a subcell produced by subdividing p */
2169412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr);
2170412e9a14SMatthew G. Knepley         for (c = 0; c < csizeNew; ++c) {
2171412e9a14SMatthew G. Knepley           PetscInt             ppp   = -1;                             /* Parent Parent point: Parent of point pp */
2172412e9a14SMatthew G. Knepley           PetscInt             pp    = p;                              /* Parent point: Point in the original mesh producing new cone point */
2173412e9a14SMatthew G. Knepley           PetscInt             po    = 0;                              /* Orientation of parent point pp in parent parent point ppp */
2174412e9a14SMatthew G. Knepley           DMPolytopeType       pct   = ct;                             /* Parent type:  Cell type for parent of new cone point */
2175412e9a14SMatthew G. Knepley           const PetscInt      *pcone = cone;                           /* Parent cone: Cone of parent point pp */
2176412e9a14SMatthew G. Knepley           PetscInt             pr    = -1;                             /* Replica number of pp that produces new cone point  */
2177412e9a14SMatthew G. Knepley           const DMPolytopeType ft    = (DMPolytopeType) rcone[coff++]; /* Cell type for new cone point of pNew */
2178412e9a14SMatthew G. Knepley           const PetscInt       fn    = rcone[coff++];                  /* Number of cones of p that need to be taken when producing new cone point */
2179412e9a14SMatthew G. Knepley           PetscInt             fo    = rornt[ooff++];                  /* Orientation of new cone point in pNew */
2180412e9a14SMatthew G. Knepley           PetscInt             lc;
2181412e9a14SMatthew G. Knepley 
2182412e9a14SMatthew G. Knepley           /* Get the type (pct) and point number (pp) of the parent point in the original mesh which produces this cone point */
2183412e9a14SMatthew G. Knepley           for (lc = 0; lc < fn; ++lc) {
2184412e9a14SMatthew G. Knepley             const PetscInt *ppornt;
2185412e9a14SMatthew G. Knepley             PetscInt        pcp;
2186412e9a14SMatthew G. Knepley 
2187412e9a14SMatthew G. Knepley             ierr = DMPolytopeMapCell(pct, po, rcone[coff++], &pcp);CHKERRQ(ierr);
2188412e9a14SMatthew G. Knepley             ppp  = pp;
2189412e9a14SMatthew G. Knepley             pp   = pcone[pcp];
2190412e9a14SMatthew G. Knepley             ierr = DMPlexGetCellType(dm, pp, &pct);CHKERRQ(ierr);
2191412e9a14SMatthew G. Knepley             ierr = DMPlexGetCone(dm, pp, &pcone);CHKERRQ(ierr);
2192412e9a14SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, ppp, &ppornt);CHKERRQ(ierr);
2193*cf4091a3SMatthew G. Knepley             if (po <  0 && pct != DM_POLYTOPE_POINT) {
2194*cf4091a3SMatthew G. Knepley               const PetscInt pornt   = ppornt[pcp];
2195*cf4091a3SMatthew G. Knepley               const PetscInt pcsize  = DMPolytopeTypeGetConeSize(pct);
2196*cf4091a3SMatthew G. Knepley               const PetscInt pcstart = pornt < 0 ? -(pornt+1) : pornt;
2197*cf4091a3SMatthew G. Knepley               const PetscInt rcstart = (pcstart+pcsize-1)%pcsize;
2198*cf4091a3SMatthew G. Knepley               po = pornt < 0 ? -(rcstart+1) : rcstart;
2199*cf4091a3SMatthew G. Knepley             } else {
2200412e9a14SMatthew G. Knepley               po = ppornt[pcp];
2201412e9a14SMatthew G. Knepley             }
2202*cf4091a3SMatthew G. Knepley           }
2203412e9a14SMatthew G. Knepley           pr = rcone[coff++];
2204412e9a14SMatthew G. Knepley           /* Orientation po of pp maps (pr, fo) -> (pr', fo') */
2205412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerMapSubcells(cr, pct, po, ft, pr, fo, &pr, &fo);CHKERRQ(ierr);
2206412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerGetNewPoint(cr, pct, ft, pp, pr, &coneNew[c]);CHKERRQ(ierr);
2207412e9a14SMatthew G. Knepley           orntNew[c] = fo;
2208412e9a14SMatthew G. Knepley         }
2209412e9a14SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, pNew, coneNew);CHKERRQ(ierr);
2210412e9a14SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, pNew, orntNew);CHKERRQ(ierr);
2211412e9a14SMatthew G. Knepley       }
2212412e9a14SMatthew G. Knepley     }
2213412e9a14SMatthew G. Knepley   }
2214412e9a14SMatthew G. Knepley   ierr = PetscFree2(coneNew, orntNew);CHKERRQ(ierr);
2215412e9a14SMatthew G. Knepley   ierr = DMPlexSymmetrize(rdm);CHKERRQ(ierr);
2216412e9a14SMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
2217412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2218412e9a14SMatthew G. Knepley }
2219412e9a14SMatthew G. Knepley 
2220412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCoordinateFE(DMPlexCellRefiner cr, DMPolytopeType ct, PetscFE *fe)
2221412e9a14SMatthew G. Knepley {
2222412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2223412e9a14SMatthew G. Knepley 
2224412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2225412e9a14SMatthew G. Knepley   if (!cr->coordFE[ct]) {
2226412e9a14SMatthew G. Knepley     PetscInt  dim, cdim;
2227412e9a14SMatthew G. Knepley     PetscBool isSimplex;
2228412e9a14SMatthew G. Knepley 
2229412e9a14SMatthew G. Knepley     switch (ct) {
2230412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEGMENT:       dim = 1; isSimplex = PETSC_TRUE;  break;
2231412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRIANGLE:      dim = 2; isSimplex = PETSC_TRUE;  break;
2232412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUADRILATERAL: dim = 2; isSimplex = PETSC_FALSE; break;
2233412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TETRAHEDRON:   dim = 3; isSimplex = PETSC_TRUE;  break;
2234412e9a14SMatthew G. Knepley       case DM_POLYTOPE_HEXAHEDRON:    dim = 3; isSimplex = PETSC_FALSE; break;
2235412e9a14SMatthew G. Knepley       default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No coordinate FE for cell type %s", DMPolytopeTypes[ct]);
2236412e9a14SMatthew G. Knepley     }
2237412e9a14SMatthew G. Knepley     ierr = DMGetCoordinateDim(cr->dm, &cdim);CHKERRQ(ierr);
2238412e9a14SMatthew G. Knepley     ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, cdim, isSimplex, 1, PETSC_DETERMINE, &cr->coordFE[ct]);CHKERRQ(ierr);
2239412e9a14SMatthew G. Knepley     {
2240412e9a14SMatthew G. Knepley       PetscDualSpace  dsp;
2241412e9a14SMatthew G. Knepley       PetscQuadrature quad;
2242412e9a14SMatthew G. Knepley       DM              K;
2243412e9a14SMatthew G. Knepley       PetscFEGeom    *cg;
2244412e9a14SMatthew G. Knepley       PetscReal      *Xq, *xq, *wq;
2245412e9a14SMatthew G. Knepley       PetscInt        Nq, q;
2246412e9a14SMatthew G. Knepley 
2247412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerGetCellVertices(cr, ct, &Nq, &Xq);CHKERRQ(ierr);
2248412e9a14SMatthew G. Knepley       ierr = PetscMalloc1(Nq*cdim, &xq);CHKERRQ(ierr);
2249412e9a14SMatthew G. Knepley       for (q = 0; q < Nq*cdim; ++q) xq[q] = Xq[q];
2250412e9a14SMatthew G. Knepley       ierr = PetscMalloc1(Nq, &wq);CHKERRQ(ierr);
2251412e9a14SMatthew G. Knepley       for (q = 0; q < Nq; ++q) wq[q] = 1.0;
2252412e9a14SMatthew G. Knepley       ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &quad);CHKERRQ(ierr);
2253412e9a14SMatthew G. Knepley       ierr = PetscQuadratureSetData(quad, dim, 1, Nq, xq, wq);CHKERRQ(ierr);
2254412e9a14SMatthew G. Knepley       ierr = PetscFESetQuadrature(cr->coordFE[ct], quad);CHKERRQ(ierr);
2255412e9a14SMatthew G. Knepley 
2256412e9a14SMatthew G. Knepley       ierr = PetscFEGetDualSpace(cr->coordFE[ct], &dsp);CHKERRQ(ierr);
2257412e9a14SMatthew G. Knepley       ierr = PetscDualSpaceGetDM(dsp, &K);CHKERRQ(ierr);
2258412e9a14SMatthew G. Knepley       ierr = PetscFEGeomCreate(quad, 1, cdim, PETSC_FALSE, &cr->refGeom[ct]);CHKERRQ(ierr);
2259412e9a14SMatthew G. Knepley       cg   = cr->refGeom[ct];
2260412e9a14SMatthew G. Knepley       ierr = DMPlexComputeCellGeometryFEM(K, 0, NULL, cg->v, cg->J, cg->invJ, cg->detJ);CHKERRQ(ierr);
2261412e9a14SMatthew G. Knepley       ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr);
2262412e9a14SMatthew G. Knepley     }
2263412e9a14SMatthew G. Knepley   }
2264412e9a14SMatthew G. Knepley   *fe = cr->coordFE[ct];
2265412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2266412e9a14SMatthew G. Knepley }
2267412e9a14SMatthew G. Knepley 
2268412e9a14SMatthew G. Knepley /*
2269412e9a14SMatthew G. Knepley   DMPlexCellRefinerMapLocalizedCoordinates - Given a cell of type ct with localized coordinates x, we generate localized coordinates xr for subcell r of type rct.
2270412e9a14SMatthew G. Knepley 
2271412e9a14SMatthew G. Knepley   Not collective
2272412e9a14SMatthew G. Knepley 
2273412e9a14SMatthew G. Knepley   Input Parameters:
2274412e9a14SMatthew G. Knepley + cr  - The DMPlexCellRefiner
2275412e9a14SMatthew G. Knepley . ct  - The type of the parent cell
2276412e9a14SMatthew G. Knepley . rct - The type of the produced cell
2277412e9a14SMatthew G. Knepley . r   - The index of the produced cell
2278412e9a14SMatthew G. Knepley - x   - The localized coordinates for the parent cell
2279412e9a14SMatthew G. Knepley 
2280412e9a14SMatthew G. Knepley   Output Parameter:
2281412e9a14SMatthew G. Knepley . xr  - The localized coordinates for the produced cell
2282412e9a14SMatthew G. Knepley 
2283412e9a14SMatthew G. Knepley   Level: developer
2284412e9a14SMatthew G. Knepley 
2285412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerSetCoordinates()
2286412e9a14SMatthew G. Knepley */
2287412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapLocalizedCoordinates(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, const PetscScalar x[], PetscScalar xr[])
2288412e9a14SMatthew G. Knepley {
2289412e9a14SMatthew G. Knepley   PetscFE        fe = NULL;
2290412e9a14SMatthew G. Knepley   PetscInt       cdim, Nv, v, *subcellV;
2291412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2292412e9a14SMatthew G. Knepley 
2293412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2294412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerGetCoordinateFE(cr, ct, &fe);CHKERRQ(ierr);
2295412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerGetSubcellVertices(cr, ct, rct, r, &Nv, &subcellV);CHKERRQ(ierr);
2296412e9a14SMatthew G. Knepley   ierr = PetscFEGetNumComponents(fe, &cdim);CHKERRQ(ierr);
2297412e9a14SMatthew G. Knepley   for (v = 0; v < Nv; ++v) {
2298412e9a14SMatthew G. Knepley     ierr = PetscFEInterpolate_Static(fe, x, cr->refGeom[ct], subcellV[v], &xr[v*cdim]);CHKERRQ(ierr);
2299412e9a14SMatthew G. Knepley   }
2300412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2301412e9a14SMatthew G. Knepley }
2302412e9a14SMatthew G. Knepley 
2303412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCoordinates(DMPlexCellRefiner cr, DM rdm)
2304412e9a14SMatthew G. Knepley {
2305412e9a14SMatthew G. Knepley   DM                    dm = cr->dm, cdm;
2306412e9a14SMatthew G. Knepley   PetscSection          coordSection, coordSectionNew;
2307412e9a14SMatthew G. Knepley   Vec                   coordsLocal, coordsLocalNew;
2308412e9a14SMatthew G. Knepley   const PetscScalar    *coords;
2309412e9a14SMatthew G. Knepley   PetscScalar          *coordsNew;
2310412e9a14SMatthew G. Knepley   const DMBoundaryType *bd;
2311412e9a14SMatthew G. Knepley   const PetscReal      *maxCell, *L;
2312412e9a14SMatthew G. Knepley   PetscBool             isperiodic, localizeVertices = PETSC_FALSE, localizeCells = PETSC_FALSE;
2313412e9a14SMatthew G. Knepley   PetscInt              dE, d, cStart, cEnd, c, vStartNew, vEndNew, v, pStart, pEnd, p, ocStart, ocEnd;
2314412e9a14SMatthew G. Knepley   PetscErrorCode        ierr;
2315412e9a14SMatthew G. Knepley 
2316412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2317412e9a14SMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
231890b157c4SStefano Zampini   ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr);
231990b157c4SStefano Zampini   /* Determine if we need to localize coordinates when generating them */
2320b9ccc978SStefano Zampini   if (isperiodic) {
2321412e9a14SMatthew G. Knepley     localizeVertices = PETSC_TRUE;
2322412e9a14SMatthew G. Knepley     if (!maxCell) {
2323412e9a14SMatthew G. Knepley       PetscBool localized;
2324412e9a14SMatthew G. Knepley       ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
2325412e9a14SMatthew G. Knepley       if (!localized) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Cannot refine a periodic mesh if coordinates have not been localized");
2326412e9a14SMatthew G. Knepley       localizeCells = PETSC_TRUE;
2327b9ccc978SStefano Zampini     }
2328b9ccc978SStefano Zampini   }
2329b9ccc978SStefano Zampini 
2330b9ccc978SStefano Zampini   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
2331412e9a14SMatthew G. Knepley   ierr = PetscSectionGetFieldComponents(coordSection, 0, &dE);CHKERRQ(ierr);
2332412e9a14SMatthew G. Knepley   if (maxCell) {
2333412e9a14SMatthew G. Knepley     PetscReal maxCellNew[3];
2334412e9a14SMatthew G. Knepley 
2335412e9a14SMatthew G. Knepley     for (d = 0; d < dE; ++d) maxCellNew[d] = maxCell[d]/2.0;
2336412e9a14SMatthew G. Knepley     ierr = DMSetPeriodicity(rdm, isperiodic, maxCellNew, L, bd);CHKERRQ(ierr);
2337412e9a14SMatthew G. Knepley   } else {
2338412e9a14SMatthew G. Knepley     ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr);
2339412e9a14SMatthew G. Knepley   }
2340b9ccc978SStefano Zampini   ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &coordSectionNew);CHKERRQ(ierr);
2341b9ccc978SStefano Zampini   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
2342412e9a14SMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dE);CHKERRQ(ierr);
2343412e9a14SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(rdm, 0, &vStartNew, &vEndNew);CHKERRQ(ierr);
2344412e9a14SMatthew G. Knepley   if (localizeCells) {ierr = PetscSectionSetChart(coordSectionNew, 0,         vEndNew);CHKERRQ(ierr);}
2345412e9a14SMatthew G. Knepley   else               {ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vEndNew);CHKERRQ(ierr);}
2346b9ccc978SStefano Zampini 
2347412e9a14SMatthew G. Knepley   /* Localization should be inherited */
2348412e9a14SMatthew G. Knepley   /*   Stefano calculates parent cells for each new cell for localization */
2349412e9a14SMatthew G. Knepley   /*   Localized cells need coordinates of closure */
2350412e9a14SMatthew G. Knepley   for (v = vStartNew; v < vEndNew; ++v) {
2351412e9a14SMatthew G. Knepley     ierr = PetscSectionSetDof(coordSectionNew, v, dE);CHKERRQ(ierr);
2352412e9a14SMatthew G. Knepley     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dE);CHKERRQ(ierr);
2353412e9a14SMatthew G. Knepley   }
2354412e9a14SMatthew G. Knepley   if (localizeCells) {
2355412e9a14SMatthew G. Knepley     ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
2356412e9a14SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2357412e9a14SMatthew G. Knepley       PetscInt dof;
235890b157c4SStefano Zampini 
2359412e9a14SMatthew G. Knepley       ierr = PetscSectionGetDof(coordSection, c, &dof); CHKERRQ(ierr);
2360412e9a14SMatthew G. Knepley       if (dof) {
2361412e9a14SMatthew G. Knepley         DMPolytopeType  ct;
2362412e9a14SMatthew G. Knepley         DMPolytopeType *rct;
2363412e9a14SMatthew G. Knepley         PetscInt       *rsize, *rcone, *rornt;
2364412e9a14SMatthew G. Knepley         PetscInt        dim, cNew, Nct, n, r;
236590b157c4SStefano Zampini 
2366412e9a14SMatthew G. Knepley         ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr);
2367412e9a14SMatthew G. Knepley         dim  = DMPolytopeTypeGetDim(ct);
2368412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2369412e9a14SMatthew G. Knepley         /* This allows for different cell types */
2370412e9a14SMatthew G. Knepley         for (n = 0; n < Nct; ++n) {
2371412e9a14SMatthew G. Knepley           if (dim != DMPolytopeTypeGetDim(rct[n])) continue;
2372412e9a14SMatthew G. Knepley           for (r = 0; r < rsize[n]; ++r) {
2373412e9a14SMatthew G. Knepley             PetscInt *closure = NULL;
2374412e9a14SMatthew G. Knepley             PetscInt  clSize, cl, Nv = 0;
237590b157c4SStefano Zampini 
2376412e9a14SMatthew G. Knepley             ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], c, r, &cNew);CHKERRQ(ierr);
2377412e9a14SMatthew G. Knepley             ierr = DMPlexGetTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr);
2378412e9a14SMatthew G. Knepley             for (cl = 0; cl < clSize*2; cl += 2) {if ((closure[cl] >= vStartNew) && (closure[cl] < vEndNew)) ++Nv;}
2379412e9a14SMatthew G. Knepley             ierr = DMPlexRestoreTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr);
2380412e9a14SMatthew G. Knepley             ierr = PetscSectionSetDof(coordSectionNew, cNew, Nv * dE);CHKERRQ(ierr);
2381412e9a14SMatthew G. Knepley             ierr = PetscSectionSetFieldDof(coordSectionNew, cNew, 0, Nv * dE);CHKERRQ(ierr);
23829fc2a3f3SStefano Zampini           }
238390b157c4SStefano Zampini         }
238490b157c4SStefano Zampini       }
2385412e9a14SMatthew G. Knepley     }
238675d3a19aSMatthew G. Knepley   }
238775d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
2388412e9a14SMatthew G. Knepley   ierr = DMViewFromOptions(dm, NULL, "-coarse_dm_view");CHKERRQ(ierr);
238946e270d4SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr);
2390412e9a14SMatthew G. Knepley   {
2391412e9a14SMatthew G. Knepley     VecType     vtype;
2392412e9a14SMatthew G. Knepley     PetscInt    coordSizeNew, bs;
2393412e9a14SMatthew G. Knepley     const char *name;
2394412e9a14SMatthew G. Knepley 
2395412e9a14SMatthew G. Knepley     ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr);
2396412e9a14SMatthew G. Knepley     ierr = VecCreate(PETSC_COMM_SELF, &coordsLocalNew);CHKERRQ(ierr);
239775d3a19aSMatthew G. Knepley     ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
2398412e9a14SMatthew G. Knepley     ierr = VecSetSizes(coordsLocalNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
2399412e9a14SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) coordsLocal, &name);CHKERRQ(ierr);
2400412e9a14SMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) coordsLocalNew, name);CHKERRQ(ierr);
2401412e9a14SMatthew G. Knepley     ierr = VecGetBlockSize(coordsLocal, &bs);CHKERRQ(ierr);
2402412e9a14SMatthew G. Knepley     ierr = VecSetBlockSize(coordsLocalNew, bs);CHKERRQ(ierr);
2403412e9a14SMatthew G. Knepley     ierr = VecGetType(coordsLocal, &vtype);CHKERRQ(ierr);
2404412e9a14SMatthew G. Knepley     ierr = VecSetType(coordsLocalNew, vtype);CHKERRQ(ierr);
2405b5da9499SMatthew G. Knepley   }
2406412e9a14SMatthew G. Knepley   ierr = VecGetArrayRead(coordsLocal, &coords);CHKERRQ(ierr);
2407412e9a14SMatthew G. Knepley   ierr = VecGetArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr);
2408412e9a14SMatthew G. Knepley   ierr = PetscSectionGetChart(coordSection, &ocStart, &ocEnd);CHKERRQ(ierr);
2409412e9a14SMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
2410412e9a14SMatthew G. Knepley   /* First set coordinates for vertices*/
2411412e9a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2412412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
2413412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2414412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2415412e9a14SMatthew G. Knepley     PetscInt        Nct, n, r;
2416412e9a14SMatthew G. Knepley     PetscBool       hasVertex = PETSC_FALSE, isLocalized = PETSC_FALSE;
241790b157c4SStefano Zampini 
2418412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2419412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2420412e9a14SMatthew G. Knepley     for (n = 0; n < Nct; ++n) {
2421412e9a14SMatthew G. Knepley       if (rct[n] == DM_POLYTOPE_POINT) {hasVertex = PETSC_TRUE; break;}
2422412e9a14SMatthew G. Knepley     }
2423412e9a14SMatthew G. Knepley     if (localizeVertices && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) {
2424412e9a14SMatthew G. Knepley       PetscInt dof;
2425412e9a14SMatthew G. Knepley       ierr = PetscSectionGetDof(coordSection, p, &dof); CHKERRQ(ierr);
2426412e9a14SMatthew G. Knepley       if (dof) isLocalized = PETSC_TRUE;
2427412e9a14SMatthew G. Knepley     }
2428412e9a14SMatthew G. Knepley     if (hasVertex) {
2429412e9a14SMatthew G. Knepley       PetscScalar *pcoords = NULL;
2430412e9a14SMatthew G. Knepley       PetscScalar  vcoords[3] = {0., 0., 0.};
2431412e9a14SMatthew G. Knepley       PetscInt     Nc, Nv, v, d;
243290b157c4SStefano Zampini 
2433412e9a14SMatthew G. Knepley       ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr);
2434412e9a14SMatthew G. Knepley       if (ct == DM_POLYTOPE_POINT) {
2435412e9a14SMatthew G. Knepley         for (d = 0; d < dE; ++d) vcoords[d] = pcoords[d];
24369fc2a3f3SStefano Zampini       } else {
2437412e9a14SMatthew G. Knepley         if (localizeVertices) {
2438412e9a14SMatthew G. Knepley           PetscScalar anchor[3];
243990b157c4SStefano Zampini 
2440412e9a14SMatthew G. Knepley           for (d = 0; d < dE; ++d) anchor[d] = pcoords[d];
2441412e9a14SMatthew G. Knepley           if (!isLocalized) {
2442412e9a14SMatthew G. Knepley             Nv = Nc/dE;
2443412e9a14SMatthew G. Knepley             for (v = 0; v < Nv; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], vcoords);CHKERRQ(ierr);}
2444412e9a14SMatthew G. Knepley           } else {
2445412e9a14SMatthew G. Knepley             Nv = Nc/(2*dE);
2446412e9a14SMatthew G. Knepley             for (v = Nv; v < Nv*2; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], vcoords);CHKERRQ(ierr);}
244790b157c4SStefano Zampini           }
244890b157c4SStefano Zampini         } else {
2449412e9a14SMatthew G. Knepley           Nv = Nc/dE;
2450412e9a14SMatthew G. Knepley           for (v = 0; v < Nv; ++v) for (d = 0; d < dE; ++d) vcoords[d] += pcoords[v*dE+d];
2451b5da9499SMatthew G. Knepley         }
2452412e9a14SMatthew G. Knepley         for (d = 0; d < dE; ++d) vcoords[d] /= Nv;
245390b157c4SStefano Zampini       }
2454412e9a14SMatthew G. Knepley       ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr);
2455412e9a14SMatthew G. Knepley       for (n = 0; n < Nct; ++n) {
2456412e9a14SMatthew G. Knepley         if (rct[n] != DM_POLYTOPE_POINT) continue;
2457eac51794SMatthew G. Knepley         if (rsize[n] > 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Only support creating a single vertex in cell refinement, not %D", rsize[n]);
2458412e9a14SMatthew G. Knepley         for (r = 0; r < rsize[n]; ++r) {
2459412e9a14SMatthew G. Knepley           PetscInt vNew, off;
2460b5da9499SMatthew G. Knepley 
2461412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &vNew);CHKERRQ(ierr);
2462412e9a14SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSectionNew, vNew, &off);CHKERRQ(ierr);
2463eac51794SMatthew G. Knepley           ierr = DMPlexSnapToGeomModel(dm, p, vcoords, &coordsNew[off]);CHKERRQ(ierr);
2464b5da9499SMatthew G. Knepley         }
24659fc2a3f3SStefano Zampini       }
2466412e9a14SMatthew G. Knepley     }
2467412e9a14SMatthew G. Knepley   }
2468412e9a14SMatthew G. Knepley   /* Then set coordinates for cells by localizing */
2469412e9a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2470412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
2471412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2472412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2473412e9a14SMatthew G. Knepley     PetscInt        Nct, n, r;
2474412e9a14SMatthew G. Knepley     PetscBool       isLocalized = PETSC_FALSE;
247590b157c4SStefano Zampini 
2476412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2477412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2478412e9a14SMatthew G. Knepley     if (localizeCells && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) {
2479412e9a14SMatthew G. Knepley       PetscInt dof;
2480412e9a14SMatthew G. Knepley       ierr = PetscSectionGetDof(coordSection, p, &dof); CHKERRQ(ierr);
2481412e9a14SMatthew G. Knepley       if (dof) isLocalized = PETSC_TRUE;
2482b5da9499SMatthew G. Knepley     }
2483412e9a14SMatthew G. Knepley     if (isLocalized) {
2484412e9a14SMatthew G. Knepley       const PetscScalar *pcoords;
24859fc2a3f3SStefano Zampini 
2486412e9a14SMatthew G. Knepley       ierr = DMPlexPointLocalRead(cdm, p, coords, &pcoords);CHKERRQ(ierr);
2487412e9a14SMatthew G. Knepley       for (n = 0; n < Nct; ++n) {
2488412e9a14SMatthew G. Knepley         const PetscInt Nr = rsize[n];
248990b157c4SStefano Zampini 
2490412e9a14SMatthew G. Knepley         if (DMPolytopeTypeGetDim(ct) != DMPolytopeTypeGetDim(rct[n])) continue;
2491412e9a14SMatthew G. Knepley         for (r = 0; r < Nr; ++r) {
2492412e9a14SMatthew G. Knepley           PetscInt pNew, offNew;
249390b157c4SStefano Zampini 
2494412e9a14SMatthew G. Knepley           /* It looks like Stefano and Lisandro are allowing localized coordinates without defining the periodic boundary, which means that
2495412e9a14SMatthew G. Knepley              DMLocalizeCoordinate_Internal() will not work. Localized coordinates will have to have obtained by the affine map of the larger
2496412e9a14SMatthew G. Knepley              cell to the ones it produces. */
2497412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr);
2498412e9a14SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSectionNew, pNew, &offNew);CHKERRQ(ierr);
2499412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerMapLocalizedCoordinates(cr, ct, rct[n], r, pcoords, &coordsNew[offNew]);CHKERRQ(ierr);
250090b157c4SStefano Zampini         }
250190b157c4SStefano Zampini       }
250290b157c4SStefano Zampini     }
250390b157c4SStefano Zampini   }
2504412e9a14SMatthew G. Knepley   ierr = VecRestoreArrayRead(coordsLocal, &coords);CHKERRQ(ierr);
2505412e9a14SMatthew G. Knepley   ierr = VecRestoreArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr);
2506412e9a14SMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordsLocalNew);CHKERRQ(ierr);
2507412e9a14SMatthew G. Knepley   /* TODO Stefano has a final reduction if some hybrid coordinates cannot be found. (needcoords) Should not be needed. */
2508412e9a14SMatthew G. Knepley   ierr = VecDestroy(&coordsLocalNew);CHKERRQ(ierr);
250975d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
2510412e9a14SMatthew G. Knepley   if (!localizeCells) {ierr = DMLocalizeCoordinates(rdm);CHKERRQ(ierr);}
251175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
251275d3a19aSMatthew G. Knepley }
251375d3a19aSMatthew G. Knepley 
2514963fc26aSMatthew G. Knepley /*@
2515963fc26aSMatthew G. Knepley   DMPlexCreateProcessSF - Create an SF which just has process connectivity
2516963fc26aSMatthew G. Knepley 
2517d083f849SBarry Smith   Collective on dm
2518963fc26aSMatthew G. Knepley 
2519963fc26aSMatthew G. Knepley   Input Parameters:
2520963fc26aSMatthew G. Knepley + dm      - The DM
2521963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity
2522963fc26aSMatthew G. Knepley 
2523963fc26aSMatthew G. Knepley   Output Parameters:
2524963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL
2525963fc26aSMatthew G. Knepley - sfProcess    - An SF encoding the process connectivity, or NULL
2526963fc26aSMatthew G. Knepley 
2527963fc26aSMatthew G. Knepley   Level: developer
2528963fc26aSMatthew G. Knepley 
2529963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF()
2530963fc26aSMatthew G. Knepley @*/
2531963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
253275d3a19aSMatthew G. Knepley {
253375d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
253475d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
253575d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
253675d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
253775d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
253875d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
25399852e123SBarry Smith   PetscMPIInt        size;
254075d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
254175d3a19aSMatthew G. Knepley 
254275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
2543963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2544963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2);
2545963fc26aSMatthew G. Knepley   if (processRanks) {PetscValidPointer(processRanks, 3);}
2546963fc26aSMatthew G. Knepley   if (sfProcess)    {PetscValidPointer(sfProcess, 4);}
25479852e123SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr);
254875d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
2549785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
255075d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
255175d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
255275d3a19aSMatthew G. Knepley   }
255375d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
2554785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr);
2555785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr);
2556785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
255775d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
255875d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
255975d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
256075d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
256175d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
256275d3a19aSMatthew G. Knepley   }
256375d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
2564963fc26aSMatthew G. Knepley   if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);}
2565963fc26aSMatthew G. Knepley   else              {ierr = PetscFree(ranksNew);CHKERRQ(ierr);}
2566963fc26aSMatthew G. Knepley   if (sfProcess) {
256775d3a19aSMatthew G. Knepley     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
2568963fc26aSMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr);
256975d3a19aSMatthew G. Knepley     ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
25709852e123SBarry Smith     ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
2571963fc26aSMatthew G. Knepley   }
257275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
257375d3a19aSMatthew G. Knepley }
257475d3a19aSMatthew G. Knepley 
2575412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateSF(DMPlexCellRefiner cr, DM rdm)
257675d3a19aSMatthew G. Knepley {
2577412e9a14SMatthew G. Knepley   DM                 dm = cr->dm;
2578412e9a14SMatthew G. Knepley   DMPlexCellRefiner *crRem;
257975d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
258075d3a19aSMatthew G. Knepley   IS                 processRanks;
2581412e9a14SMatthew G. Knepley   MPI_Datatype       ctType;
258275d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
258375d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
258475d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
258575d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
258675d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
2587412e9a14SMatthew G. Knepley   PetscInt          *ctStartRem, *ctStartNewRem;
2588412e9a14SMatthew G. Knepley   PetscInt           ctSize = DM_NUM_POLYTOPES+1, numNeighbors, n, pStartNew, pEndNew, pNew, pNewRem;
258975d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
259075d3a19aSMatthew G. Knepley 
259175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
259275d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
259375d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
259475d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
2595add09238SMatthew G. Knepley   /* Calculate size of new SF */
259675d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
259775d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
259875d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
259975d3a19aSMatthew G. Knepley     const PetscInt  p = localPoints[l];
2600412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
2601412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2602412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2603412e9a14SMatthew G. Knepley     PetscInt        Nct, n;
260475d3a19aSMatthew G. Knepley 
2605412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2606412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2607412e9a14SMatthew G. Knepley     for (n = 0; n < Nct; ++n) numLeavesNew += rsize[n];
26080314a74cSLawrence Mitchell   }
2609412e9a14SMatthew G. Knepley   /* Communicate ctStart and cStartNew for each remote rank */
261075d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
261175d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
2612412e9a14SMatthew G. Knepley   ierr = PetscMalloc2(ctSize*numNeighbors, &ctStartRem, ctSize*numNeighbors, &ctStartNewRem);CHKERRQ(ierr);
2613412e9a14SMatthew G. Knepley   ierr = MPI_Type_contiguous(ctSize, MPIU_INT, &ctType);CHKERRQ(ierr);
2614412e9a14SMatthew G. Knepley   ierr = MPI_Type_commit(&ctType);CHKERRQ(ierr);
2615412e9a14SMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr);
2616412e9a14SMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr);
2617412e9a14SMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr);
2618412e9a14SMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr);
2619412e9a14SMatthew G. Knepley   ierr = MPI_Type_free(&ctType);CHKERRQ(ierr);
262075d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
2621412e9a14SMatthew G. Knepley   ierr = PetscMalloc1(numNeighbors, &crRem);CHKERRQ(ierr);
2622412e9a14SMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
2623412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerCreate(dm, &crRem[n]);CHKERRQ(ierr);
2624412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerSetStarts(crRem[n], &ctStartRem[n*ctSize], &ctStartNewRem[n*ctSize]);
2625412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerSetUp(crRem[n]);CHKERRQ(ierr);
2626412e9a14SMatthew G. Knepley   }
2627412e9a14SMatthew G. Knepley   ierr = PetscFree2(ctStartRem, ctStartNewRem);CHKERRQ(ierr);
262875d3a19aSMatthew G. Knepley   /* Calculate new point SF */
2629785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr);
2630785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
263175d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
263275d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
263375d3a19aSMatthew G. Knepley     PetscInt        p       = localPoints[l];
2634412e9a14SMatthew G. Knepley     PetscInt        pRem    = remotePoints[l].index;
2635412e9a14SMatthew G. Knepley     PetscMPIInt     rankRem = remotePoints[l].rank;
2636412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
2637412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2638412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2639412e9a14SMatthew G. Knepley     PetscInt        neighbor, Nct, n, r;
264075d3a19aSMatthew G. Knepley 
2641412e9a14SMatthew G. Knepley     ierr = PetscFindInt(rankRem, numNeighbors, neighbors, &neighbor);CHKERRQ(ierr);
2642412e9a14SMatthew G. Knepley     if (neighbor < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rankRem);
2643412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2644412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2645412e9a14SMatthew G. Knepley     for (n = 0; n < Nct; ++n) {
2646412e9a14SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r) {
2647412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr);
2648412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerGetNewPoint(crRem[neighbor], ct, rct[n], pRem, r, &pNewRem);CHKERRQ(ierr);
2649412e9a14SMatthew G. Knepley         localPointsNew[m]        = pNew;
2650412e9a14SMatthew G. Knepley         remotePointsNew[m].index = pNewRem;
2651412e9a14SMatthew G. Knepley         remotePointsNew[m].rank  = rankRem;
26520314a74cSLawrence Mitchell         ++m;
26530314a74cSLawrence Mitchell       }
26546ce3c06aSMatthew G. Knepley     }
26556ce3c06aSMatthew G. Knepley   }
2656412e9a14SMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {ierr = DMPlexCellRefinerDestroy(&crRem[n]);CHKERRQ(ierr);}
2657412e9a14SMatthew G. Knepley   ierr = PetscFree(crRem);CHKERRQ(ierr);
2658d7eabd03SStefano Zampini   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew);
265975d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
266075d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
2661ba3c3d50SMatthew G. Knepley   {
2662ba3c3d50SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
2663ba3c3d50SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
2664ba3c3d50SMatthew G. Knepley 
2665ba3c3d50SMatthew G. Knepley     /* SF needs sorted leaves to correct calculate Gather */
2666ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &idx);CHKERRQ(ierr);
2667ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr);
2668ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr);
2669c7c54c77SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
2670d7eabd03SStefano Zampini       if ((localPointsNew[i] < pStartNew) || (localPointsNew[i] >= pEndNew)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local SF point %D (%D) not in [%D, %D)", localPointsNew[i], i, pStartNew, pEndNew);
2671c7c54c77SMatthew G. Knepley       idx[i] = i;
2672c7c54c77SMatthew G. Knepley     }
2673ba3c3d50SMatthew G. Knepley     ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr);
2674ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
2675ba3c3d50SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
2676ba3c3d50SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
2677ba3c3d50SMatthew G. Knepley     }
2678ba3c3d50SMatthew G. Knepley     ltmp            = localPointsNew;
2679ba3c3d50SMatthew G. Knepley     localPointsNew  = lp;
2680ba3c3d50SMatthew G. Knepley     rtmp            = remotePointsNew;
2681ba3c3d50SMatthew G. Knepley     remotePointsNew = rp;
2682ba3c3d50SMatthew G. Knepley     ierr = PetscFree(idx);CHKERRQ(ierr);
2683ba3c3d50SMatthew G. Knepley     ierr = PetscFree(ltmp);CHKERRQ(ierr);
2684ba3c3d50SMatthew G. Knepley     ierr = PetscFree(rtmp);CHKERRQ(ierr);
2685ba3c3d50SMatthew G. Knepley   }
268675d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
268775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
268875d3a19aSMatthew G. Knepley }
268975d3a19aSMatthew G. Knepley 
2690e7887635SMatthew G. Knepley static PetscErrorCode RefineLabel_Internal(DMPlexCellRefiner cr, DMLabel label, DMLabel labelNew)
269175d3a19aSMatthew G. Knepley {
2692412e9a14SMatthew G. Knepley   DM              dm = cr->dm;
2693e7887635SMatthew G. Knepley   IS              valueIS;
2694e7887635SMatthew G. Knepley   const PetscInt *values;
2695e7887635SMatthew G. Knepley   PetscInt        defVal, Nv, val;
269675d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
269775d3a19aSMatthew G. Knepley 
269875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
26995aa44df4SToby Isaac   ierr = DMLabelGetDefaultValue(label, &defVal);CHKERRQ(ierr);
27005aa44df4SToby Isaac   ierr = DMLabelSetDefaultValue(labelNew, defVal);CHKERRQ(ierr);
270175d3a19aSMatthew G. Knepley   ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
2702e7887635SMatthew G. Knepley   ierr = ISGetLocalSize(valueIS, &Nv);CHKERRQ(ierr);
270375d3a19aSMatthew G. Knepley   ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
2704e7887635SMatthew G. Knepley   for (val = 0; val < Nv; ++val) {
270575d3a19aSMatthew G. Knepley     IS              pointIS;
270675d3a19aSMatthew G. Knepley     const PetscInt *points;
2707412e9a14SMatthew G. Knepley     PetscInt        numPoints, p;
270875d3a19aSMatthew G. Knepley 
27092bc5314cSMichael Lange     /* Ensure refined label is created with same number of strata as
27102bc5314cSMichael Lange      * original (even if no entries here). */
2711ad8374ffSToby Isaac     ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr);
2712412e9a14SMatthew G. Knepley     ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
2713412e9a14SMatthew G. Knepley     ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
2714412e9a14SMatthew G. Knepley     ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
2715412e9a14SMatthew G. Knepley     for (p = 0; p < numPoints; ++p) {
2716412e9a14SMatthew G. Knepley       const PetscInt  point = points[p];
2717412e9a14SMatthew G. Knepley       DMPolytopeType  ct;
2718412e9a14SMatthew G. Knepley       DMPolytopeType *rct;
2719412e9a14SMatthew G. Knepley       PetscInt       *rsize, *rcone, *rornt;
2720e7887635SMatthew G. Knepley       PetscInt        Nct, n, r, pNew;
2721412e9a14SMatthew G. Knepley 
2722412e9a14SMatthew G. Knepley       ierr = DMPlexGetCellType(dm, point, &ct);CHKERRQ(ierr);
2723412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2724412e9a14SMatthew G. Knepley       for (n = 0; n < Nct; ++n) {
2725412e9a14SMatthew G. Knepley         for (r = 0; r < rsize[n]; ++r) {
2726412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], point, r, &pNew);CHKERRQ(ierr);
2727412e9a14SMatthew G. Knepley           ierr = DMLabelSetValue(labelNew, pNew, values[val]);CHKERRQ(ierr);
272827fcede3SMatthew G. Knepley         }
272975d3a19aSMatthew G. Knepley       }
273075d3a19aSMatthew G. Knepley     }
273175d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
273275d3a19aSMatthew G. Knepley     ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
273375d3a19aSMatthew G. Knepley   }
273475d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
273575d3a19aSMatthew G. Knepley   ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
2736e7887635SMatthew G. Knepley   PetscFunctionReturn(0);
2737e7887635SMatthew G. Knepley }
2738e7887635SMatthew G. Knepley 
2739e7887635SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateLabels(DMPlexCellRefiner cr, DM rdm)
2740e7887635SMatthew G. Knepley {
2741e7887635SMatthew G. Knepley   DM             dm = cr->dm;
2742e7887635SMatthew G. Knepley   PetscInt       numLabels, l;
2743e7887635SMatthew G. Knepley   PetscErrorCode ierr;
2744e7887635SMatthew G. Knepley 
2745e7887635SMatthew G. Knepley   PetscFunctionBegin;
2746e7887635SMatthew G. Knepley   ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
2747e7887635SMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
2748e7887635SMatthew G. Knepley     DMLabel         label, labelNew;
2749e7887635SMatthew G. Knepley     const char     *lname;
2750e7887635SMatthew G. Knepley     PetscBool       isDepth, isCellType;
2751e7887635SMatthew G. Knepley 
2752e7887635SMatthew G. Knepley     ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr);
2753e7887635SMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
2754e7887635SMatthew G. Knepley     if (isDepth) continue;
2755e7887635SMatthew G. Knepley     ierr = PetscStrcmp(lname, "celltype", &isCellType);CHKERRQ(ierr);
2756e7887635SMatthew G. Knepley     if (isCellType) continue;
2757e7887635SMatthew G. Knepley     ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr);
2758e7887635SMatthew G. Knepley     ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr);
2759e7887635SMatthew G. Knepley     ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
2760e7887635SMatthew G. Knepley     ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr);
276175d3a19aSMatthew G. Knepley   }
276275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
276375d3a19aSMatthew G. Knepley }
276475d3a19aSMatthew G. Knepley 
276575d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
2766412e9a14SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform(DM dm, DMPlexCellRefiner cr, DM *dmRefined)
276775d3a19aSMatthew G. Knepley {
276875d3a19aSMatthew G. Knepley   DM              rdm;
2769412e9a14SMatthew G. Knepley   PetscInt        dim, embedDim, depth;
277075d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
277175d3a19aSMatthew G. Knepley 
277275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
2773412e9a14SMatthew G. Knepley   PetscValidHeader(cr, 1);
277475d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
277575d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
2776c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
2777c73cfb54SMatthew G. Knepley   ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr);
27786dcbd917SStefano Zampini   ierr = DMGetCoordinateDim(dm, &embedDim);CHKERRQ(ierr);
27796dcbd917SStefano Zampini   ierr = DMSetCoordinateDim(rdm, embedDim);CHKERRQ(ierr);
278075d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
278175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
27821e573d11SMatthew G. Knepley   if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement");
278375d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
2784412e9a14SMatthew G. Knepley   ierr = DMPlexSetChart(rdm, 0, cr->ctStartNew[cr->ctOrder[DM_NUM_POLYTOPES]]);CHKERRQ(ierr);
27856d7373e8SToby Isaac   /* Step 2: Set cone/support sizes (automatically stratifies) */
2786412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerSetConeSizes(cr, rdm);CHKERRQ(ierr);
278775d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
278875d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
27896d7373e8SToby Isaac   /* Step 4: Set cones and supports (automatically symmetrizes) */
2790412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerSetCones(cr, rdm);CHKERRQ(ierr);
27916d7373e8SToby Isaac   /* Step 5: Create pointSF */
2792412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerCreateSF(cr, rdm);CHKERRQ(ierr);
27936d7373e8SToby Isaac   /* Step 6: Create labels */
2794412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerCreateLabels(cr, rdm);CHKERRQ(ierr);
27956d7373e8SToby Isaac   /* Step 7: Set coordinates */
2796412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerSetCoordinates(cr, rdm);CHKERRQ(ierr);
279775d3a19aSMatthew G. Knepley   *dmRefined = rdm;
279875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
279975d3a19aSMatthew G. Knepley }
280075d3a19aSMatthew G. Knepley 
28012389894bSMatthew G. Knepley /*@
28022389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
28032389894bSMatthew G. Knepley 
28042389894bSMatthew G. Knepley   Input Parameter:
28052389894bSMatthew G. Knepley . dm - The coarse DM
28062389894bSMatthew G. Knepley 
28072389894bSMatthew G. Knepley   Output Parameter:
28082389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
28092389894bSMatthew G. Knepley 
28102389894bSMatthew G. Knepley   Level: developer
28112389894bSMatthew G. Knepley 
281297d8846cSMatthew Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetSubpointIS()
28132389894bSMatthew G. Knepley @*/
28142389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
28152389894bSMatthew G. Knepley {
2816412e9a14SMatthew G. Knepley   DMPlexCellRefiner cr;
2817412e9a14SMatthew G. Knepley   PetscInt         *fpoints;
2818412e9a14SMatthew G. Knepley   PetscInt          pStart, pEnd, p, vStart, vEnd, v, vNew;
28192389894bSMatthew G. Knepley   PetscErrorCode    ierr;
28202389894bSMatthew G. Knepley 
28212389894bSMatthew G. Knepley   PetscFunctionBegin;
28222389894bSMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
28232389894bSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
2824412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr);
2825412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr);
28262389894bSMatthew G. Knepley   ierr = PetscMalloc1(pEnd-pStart, &fpoints);CHKERRQ(ierr);
28272389894bSMatthew G. Knepley   for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
2828412e9a14SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
2829412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerGetNewPoint(cr, DM_POLYTOPE_POINT, DM_POLYTOPE_POINT, p, 0, &vNew);CHKERRQ(ierr);
2830412e9a14SMatthew G. Knepley     fpoints[v-pStart] = vNew;
28312389894bSMatthew G. Knepley   }
2832412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr);
28332389894bSMatthew G. Knepley   ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr);
28342389894bSMatthew G. Knepley   PetscFunctionReturn(0);
28352389894bSMatthew G. Knepley }
28362389894bSMatthew G. Knepley 
28370e2b6761SMatthew G. Knepley /*@
28380e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
28390e2b6761SMatthew G. Knepley 
28400e2b6761SMatthew G. Knepley   Input Parameters:
28410e2b6761SMatthew G. Knepley + dm - The DM
28420e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
28430e2b6761SMatthew G. Knepley 
28440e2b6761SMatthew G. Knepley   Level: developer
28450e2b6761SMatthew G. Knepley 
28460e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
28470e2b6761SMatthew G. Knepley @*/
284875d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
284975d3a19aSMatthew G. Knepley {
285075d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
285175d3a19aSMatthew G. Knepley 
285275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
285375d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
285475d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
285575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
285675d3a19aSMatthew G. Knepley }
285775d3a19aSMatthew G. Knepley 
28580e2b6761SMatthew G. Knepley /*@
28590e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
28600e2b6761SMatthew G. Knepley 
28610e2b6761SMatthew G. Knepley   Input Parameter:
28620e2b6761SMatthew G. Knepley . dm - The DM
28630e2b6761SMatthew G. Knepley 
28640e2b6761SMatthew G. Knepley   Output Parameter:
28650e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
28660e2b6761SMatthew G. Knepley 
28670e2b6761SMatthew G. Knepley   Level: developer
28680e2b6761SMatthew G. Knepley 
28690e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
28700e2b6761SMatthew G. Knepley @*/
287175d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
287275d3a19aSMatthew G. Knepley {
287375d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
287475d3a19aSMatthew G. Knepley 
287575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
287675d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
287775d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
287875d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
287975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
288075d3a19aSMatthew G. Knepley }
288175d3a19aSMatthew G. Knepley 
28820e2b6761SMatthew G. Knepley /*@
28830e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
28840e2b6761SMatthew G. Knepley 
28850e2b6761SMatthew G. Knepley   Input Parameters:
28860e2b6761SMatthew G. Knepley + dm - The DM
28870e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
28880e2b6761SMatthew G. Knepley 
28890e2b6761SMatthew G. Knepley   Level: developer
28900e2b6761SMatthew G. Knepley 
28910e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
28920e2b6761SMatthew G. Knepley @*/
289375d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
289475d3a19aSMatthew G. Knepley {
289575d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
289675d3a19aSMatthew G. Knepley 
289775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
289875d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
289975d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
290075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
290175d3a19aSMatthew G. Knepley }
290275d3a19aSMatthew G. Knepley 
29030e2b6761SMatthew G. Knepley /*@
29040e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
29050e2b6761SMatthew G. Knepley 
29060e2b6761SMatthew G. Knepley   Input Parameter:
29070e2b6761SMatthew G. Knepley . dm - The DM
29080e2b6761SMatthew G. Knepley 
29090e2b6761SMatthew G. Knepley   Output Parameter:
29100e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
29110e2b6761SMatthew G. Knepley 
29120e2b6761SMatthew G. Knepley   Level: developer
29130e2b6761SMatthew G. Knepley 
29140e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
29150e2b6761SMatthew G. Knepley @*/
291675d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
291775d3a19aSMatthew G. Knepley {
291875d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
291975d3a19aSMatthew G. Knepley 
292075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
292175d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
292275d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
292375d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
292475d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
292575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
292675d3a19aSMatthew G. Knepley }
292775d3a19aSMatthew G. Knepley 
2928b28003e6SMatthew G. Knepley /*@
2929b28003e6SMatthew G. Knepley   DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
2930b28003e6SMatthew G. Knepley 
2931b28003e6SMatthew G. Knepley   Input Parameters:
2932b28003e6SMatthew G. Knepley + dm - The DM
2933b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh
2934b28003e6SMatthew G. Knepley 
2935b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
2936b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
2937b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
2938b28003e6SMatthew G. Knepley 
2939b28003e6SMatthew G. Knepley   Level: developer
2940b28003e6SMatthew G. Knepley 
2941b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
2942b28003e6SMatthew G. Knepley @*/
2943b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *))
2944b28003e6SMatthew G. Knepley {
2945b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
2946b28003e6SMatthew G. Knepley 
2947b28003e6SMatthew G. Knepley   PetscFunctionBegin;
2948b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2949b28003e6SMatthew G. Knepley   mesh->refinementFunc = refinementFunc;
2950b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
2951b28003e6SMatthew G. Knepley }
2952b28003e6SMatthew G. Knepley 
2953b28003e6SMatthew G. Knepley /*@
2954b28003e6SMatthew G. Knepley   DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
2955b28003e6SMatthew G. Knepley 
2956b28003e6SMatthew G. Knepley   Input Parameter:
2957b28003e6SMatthew G. Knepley . dm - The DM
2958b28003e6SMatthew G. Knepley 
2959b28003e6SMatthew G. Knepley   Output Parameter:
2960b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh
2961b28003e6SMatthew G. Knepley 
2962b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
2963b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
2964b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
2965b28003e6SMatthew G. Knepley 
2966b28003e6SMatthew G. Knepley   Level: developer
2967b28003e6SMatthew G. Knepley 
2968b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
2969b28003e6SMatthew G. Knepley @*/
2970b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *))
2971b28003e6SMatthew G. Knepley {
2972b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
2973b28003e6SMatthew G. Knepley 
2974b28003e6SMatthew G. Knepley   PetscFunctionBegin;
2975b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2976b28003e6SMatthew G. Knepley   PetscValidPointer(refinementFunc,  2);
2977b28003e6SMatthew G. Knepley   *refinementFunc = mesh->refinementFunc;
2978b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
2979b28003e6SMatthew G. Knepley }
2980b28003e6SMatthew G. Knepley 
2981e7887635SMatthew G. Knepley static PetscErrorCode RefineDiscLabels_Internal(DMPlexCellRefiner cr, DM rdm)
2982e7887635SMatthew G. Knepley {
2983e7887635SMatthew G. Knepley   DM             dm = cr->dm;
2984e7887635SMatthew G. Knepley   PetscInt       Nf, f, Nds, s;
2985e7887635SMatthew G. Knepley   PetscErrorCode ierr;
2986e7887635SMatthew G. Knepley 
2987e7887635SMatthew G. Knepley   PetscFunctionBegin;
2988e7887635SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
2989e7887635SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
2990e7887635SMatthew G. Knepley     DMLabel     label, labelNew;
2991e7887635SMatthew G. Knepley     PetscObject obj;
2992e7887635SMatthew G. Knepley     const char *lname;
2993e7887635SMatthew G. Knepley 
2994e7887635SMatthew G. Knepley     ierr = DMGetField(rdm, f, &label, &obj);CHKERRQ(ierr);
2995e7887635SMatthew G. Knepley     if (!label) continue;
2996e7887635SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
2997e7887635SMatthew G. Knepley     ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr);
2998e7887635SMatthew G. Knepley     ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr);
2999e7887635SMatthew G. Knepley     ierr = DMSetField_Internal(rdm, f, labelNew, obj);CHKERRQ(ierr);
3000e7887635SMatthew G. Knepley     ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr);
3001e7887635SMatthew G. Knepley   }
3002e7887635SMatthew G. Knepley   ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
3003e7887635SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
3004e7887635SMatthew G. Knepley     DMLabel     label, labelNew;
3005e7887635SMatthew G. Knepley     const char *lname;
3006e7887635SMatthew G. Knepley 
3007e7887635SMatthew G. Knepley     ierr = DMGetRegionNumDS(rdm, s, &label, NULL, NULL);CHKERRQ(ierr);
3008e7887635SMatthew G. Knepley     if (!label) continue;
3009e7887635SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
3010e7887635SMatthew G. Knepley     ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr);
3011e7887635SMatthew G. Knepley     ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr);
3012e7887635SMatthew G. Knepley     ierr = DMSetRegionNumDS(rdm, s, labelNew, NULL, NULL);CHKERRQ(ierr);
3013e7887635SMatthew G. Knepley     ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr);
3014e7887635SMatthew G. Knepley   }
3015e7887635SMatthew G. Knepley   PetscFunctionReturn(0);
3016e7887635SMatthew G. Knepley }
3017e7887635SMatthew G. Knepley 
30180d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined)
30190d1cd5e0SMatthew G. Knepley {
3020492b8470SStefano Zampini   PetscBool         isUniform;
3021412e9a14SMatthew G. Knepley   DMPlexCellRefiner cr;
30220d1cd5e0SMatthew G. Knepley   PetscErrorCode    ierr;
30230d1cd5e0SMatthew G. Knepley 
30240d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
30250d1cd5e0SMatthew G. Knepley   ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr);
3026412e9a14SMatthew G. Knepley   ierr = DMViewFromOptions(dm, NULL, "-initref_dm_view");CHKERRQ(ierr);
30270d1cd5e0SMatthew G. Knepley   if (isUniform) {
3028492b8470SStefano Zampini     PetscBool localized;
30290d1cd5e0SMatthew G. Knepley 
3030412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr);
3031412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr);
3032492b8470SStefano Zampini     ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
3033412e9a14SMatthew G. Knepley     ierr = DMPlexRefineUniform(dm, cr, dmRefined);CHKERRQ(ierr);
30349a7e3c0aSMatthew G. Knepley     ierr = DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);CHKERRQ(ierr);
3035e7887635SMatthew G. Knepley     ierr = DMCopyDisc(dm, *dmRefined);CHKERRQ(ierr);
3036e7887635SMatthew G. Knepley     ierr = RefineDiscLabels_Internal(cr, *dmRefined);CHKERRQ(ierr);
30370d1cd5e0SMatthew G. Knepley     ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr);
3038412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr);
30390d1cd5e0SMatthew G. Knepley   } else {
30400d1cd5e0SMatthew G. Knepley     ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr);
30410d1cd5e0SMatthew G. Knepley   }
30420d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
30430d1cd5e0SMatthew G. Knepley }
30440d1cd5e0SMatthew G. Knepley 
30450d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[])
30460d1cd5e0SMatthew G. Knepley {
30470d1cd5e0SMatthew G. Knepley   DM             cdm = dm;
30480d1cd5e0SMatthew G. Knepley   PetscInt       r;
30490d1cd5e0SMatthew G. Knepley   PetscBool      isUniform, localized;
30500d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
30510d1cd5e0SMatthew G. Knepley 
30520d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
30530d1cd5e0SMatthew G. Knepley   ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr);
30540d1cd5e0SMatthew G. Knepley   ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
30550d1cd5e0SMatthew G. Knepley   if (isUniform) {
30560d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
3057412e9a14SMatthew G. Knepley       DMPlexCellRefiner cr;
30580d1cd5e0SMatthew G. Knepley 
3059412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerCreate(cdm, &cr);CHKERRQ(ierr);
3060412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr);
3061412e9a14SMatthew G. Knepley       ierr = DMPlexRefineUniform(cdm, cr, &dmRefined[r]);CHKERRQ(ierr);
30629a7e3c0aSMatthew G. Knepley       ierr = DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);CHKERRQ(ierr);
30639a7e3c0aSMatthew G. Knepley       ierr = DMSetRefineLevel(dmRefined[r], cdm->levelup+1);CHKERRQ(ierr);
3064e7887635SMatthew G. Knepley       ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr);
3065e7887635SMatthew G. Knepley       ierr = RefineDiscLabels_Internal(cr, dmRefined[r]);CHKERRQ(ierr);
30660d1cd5e0SMatthew G. Knepley       ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr);
30670d1cd5e0SMatthew G. Knepley       ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr);
30680d1cd5e0SMatthew G. Knepley       ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr);
30690d1cd5e0SMatthew G. Knepley       cdm  = dmRefined[r];
3070412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr);
30710d1cd5e0SMatthew G. Knepley     }
30720d1cd5e0SMatthew G. Knepley   } else {
30730d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
30740d1cd5e0SMatthew G. Knepley       ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr);
3075e7887635SMatthew G. Knepley       ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr);
30760d1cd5e0SMatthew G. Knepley       ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr);
30770d1cd5e0SMatthew G. Knepley       if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);}
30780d1cd5e0SMatthew G. Knepley       ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr);
30790d1cd5e0SMatthew G. Knepley       cdm  = dmRefined[r];
30800d1cd5e0SMatthew G. Knepley     }
30810d1cd5e0SMatthew G. Knepley   }
30820d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
30830d1cd5e0SMatthew G. Knepley }
3084