xref: /petsc/src/dm/impls/plex/plexrefine.c (revision da9060c4ebf05b549ae65df4db64c7bee7b2b8a9)
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 
5ea78f98cSLisandro Dalcin const char * const DMPlexCellRefinerTypes[] = {"Regular", "ToBox", "ToSimplex", "Alfeld2D", "Alfeld3D", "PowellSabin", "BoundaryLayer", "DMPlexCellRefinerTypes", "DM_REFINER_", NULL};
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
278a5801f52SStefano Zampini . co - The orientation of this cell in its parent
279412e9a14SMatthew G. Knepley - cp - The requested cone point of this cell assuming orientation 0
280412e9a14SMatthew G. Knepley 
281412e9a14SMatthew G. Knepley   Output Parameters:
282a5801f52SStefano Zampini . cpnew - The new cone point, taking into 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;
367a5801f52SStefano Zampini   if (!cr->ops->getcellvertices) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]);
368412e9a14SMatthew G. Knepley   ierr = (*cr->ops->getcellvertices)(cr, ct, Nv, subcellV);CHKERRQ(ierr);
369412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
370412e9a14SMatthew G. Knepley }
371412e9a14SMatthew G. Knepley 
372412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[])
373412e9a14SMatthew G. Knepley {
374412e9a14SMatthew G. Knepley   static PetscInt seg_v[]  = {0, 1, 1, 2};
375412e9a14SMatthew G. Knepley   static PetscInt tri_v[]  = {0, 3, 5,  3, 1, 4,  5, 4, 2,  3, 4, 5};
376412e9a14SMatthew G. Knepley   static PetscInt quad_v[] = {0, 4, 8, 7,  4, 1, 5, 8,  8, 5, 2, 6,  7, 8, 6, 3};
377412e9a14SMatthew G. Knepley   static PetscInt tet_v[]  = {0, 3, 1, 6,  3, 2, 4, 8,  1, 4, 5, 7,  6, 8, 7, 9,
378412e9a14SMatthew G. Knepley                               1, 6, 3, 7,  8, 4, 3, 7,  7, 3, 1, 4,  7, 3, 8, 6};
379412e9a14SMatthew 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,
380412e9a14SMatthew 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};
381412e9a14SMatthew G. Knepley 
382412e9a14SMatthew G. Knepley   PetscFunctionBegin;
383412e9a14SMatthew G. Knepley   if (ct != rct) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Cell type %s does not produce %s", DMPolytopeTypes[ct], DMPolytopeTypes[rct]);
384412e9a14SMatthew G. Knepley   switch (ct) {
385412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:       *Nv = 2; *subcellV = &seg_v[r*(*Nv)];  break;
386412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:      *Nv = 3; *subcellV = &tri_v[r*(*Nv)];  break;
387412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL: *Nv = 4; *subcellV = &quad_v[r*(*Nv)]; break;
388412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:   *Nv = 4; *subcellV = &tet_v[r*(*Nv)];  break;
389412e9a14SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:    *Nv = 8; *subcellV = &hex_v[r*(*Nv)];  break;
390412e9a14SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]);
391412e9a14SMatthew G. Knepley   }
392412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
393412e9a14SMatthew G. Knepley }
394412e9a14SMatthew G. Knepley 
39596ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerGetSubcellVertices_ToBox(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[])
396412e9a14SMatthew G. Knepley {
397412e9a14SMatthew G. Knepley   static PetscInt tri_v[]  = {0, 3, 6, 5,  3, 1, 4, 6,  5, 6, 4, 2};
398412e9a14SMatthew 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};
399412e9a14SMatthew G. Knepley   PetscErrorCode  ierr;
400412e9a14SMatthew G. Knepley 
401412e9a14SMatthew G. Knepley   PetscFunctionBegin;
402412e9a14SMatthew G. Knepley   switch (ct) {
403412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
404412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
405412e9a14SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:
406412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerGetSubcellVertices_Regular(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr);break;
407412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:
408412e9a14SMatthew 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]);
409412e9a14SMatthew G. Knepley       *Nv = 4; *subcellV = &tri_v[r*(*Nv)]; break;
410412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:
411412e9a14SMatthew 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]);
412412e9a14SMatthew G. Knepley       *Nv = 8; *subcellV = &tet_v[r*(*Nv)]; break;
413412e9a14SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No subcell vertices for cell type %s", DMPolytopeTypes[ct]);
414412e9a14SMatthew G. Knepley   }
415412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
416412e9a14SMatthew G. Knepley }
417412e9a14SMatthew G. Knepley 
418412e9a14SMatthew G. Knepley /*
419412e9a14SMatthew G. Knepley   DMPlexCellRefinerGetSubcellVertices - Get the set of refined vertices defining a subcell in the reference cell of given type
420412e9a14SMatthew G. Knepley 
421412e9a14SMatthew G. Knepley   Input Parameters:
422412e9a14SMatthew G. Knepley + cr  - The DMPlexCellRefiner object
423412e9a14SMatthew G. Knepley . ct  - The cell type
424412e9a14SMatthew G. Knepley . rct - The type of subcell
425412e9a14SMatthew G. Knepley - r   - The subcell index
426412e9a14SMatthew G. Knepley 
427412e9a14SMatthew G. Knepley   Output Parameters:
428412e9a14SMatthew G. Knepley + Nv       - The number of refined vertices in the subcell
429412e9a14SMatthew G. Knepley - subcellV - The indices of these vertices in the set of vertices returned by DMPlexCellRefinerGetCellVertices()
430412e9a14SMatthew G. Knepley 
431412e9a14SMatthew G. Knepley   Level: developer
432412e9a14SMatthew G. Knepley 
433412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetCellVertices()
434412e9a14SMatthew G. Knepley */
435412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetSubcellVertices(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, PetscInt *Nv, PetscInt *subcellV[])
436412e9a14SMatthew G. Knepley {
437412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
438412e9a14SMatthew G. Knepley 
439412e9a14SMatthew G. Knepley   PetscFunctionBegin;
440a5801f52SStefano Zampini   if (!cr->ops->getsubcellvertices) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]);
441412e9a14SMatthew G. Knepley   ierr = (*cr->ops->getsubcellvertices)(cr, ct, rct, r, Nv, subcellV);CHKERRQ(ierr);
442412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
443412e9a14SMatthew G. Knepley }
444412e9a14SMatthew G. Knepley 
445412e9a14SMatthew G. Knepley /*
446412e9a14SMatthew G. Knepley   Input Parameters:
447412e9a14SMatthew G. Knepley + cr   - The DMPlexCellRefiner
448412e9a14SMatthew G. Knepley . pct  - The cell type of the parent, from whom the new cell is being produced
449a5801f52SStefano Zampini . ct   - The type being produced
450a5801f52SStefano Zampini . r    - The replica number requested for the produced cell type
451a5801f52SStefano Zampini . Nv   - Number of vertices in the closure of the parent cell
452a5801f52SStefano Zampini . dE   - Spatial dimension
453a5801f52SStefano Zampini - in   - array of size Nv*dE, holding coordinates of the vertices in the closure of the parent cell
454a5801f52SStefano Zampini 
455a5801f52SStefano Zampini   Output Parameters:
456a5801f52SStefano Zampini . out - The coordinates of the new vertices
457a5801f52SStefano Zampini */
458a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapCoordinates(DMPlexCellRefiner cr, DMPolytopeType pct, DMPolytopeType ct, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[])
459a5801f52SStefano Zampini {
460a5801f52SStefano Zampini   PetscErrorCode ierr;
461a5801f52SStefano Zampini 
462a5801f52SStefano Zampini   PetscFunctionBeginHot;
463a5801f52SStefano Zampini   if (!cr->ops->mapcoords) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]);
464a5801f52SStefano Zampini   ierr = (*cr->ops->mapcoords)(cr, pct, ct, r, Nv, dE, in, out);CHKERRQ(ierr);
465a5801f52SStefano Zampini   PetscFunctionReturn(0);
466a5801f52SStefano Zampini }
467a5801f52SStefano Zampini 
468a5801f52SStefano Zampini /* Computes new vertex as the barycenter */
469a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapCoordinates_Barycenter(DMPlexCellRefiner cr, DMPolytopeType pct, DMPolytopeType ct, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[])
470a5801f52SStefano Zampini {
471a5801f52SStefano Zampini   PetscInt v,d;
472a5801f52SStefano Zampini 
473a5801f52SStefano Zampini   PetscFunctionBeginHot;
474a5801f52SStefano Zampini   if (ct != DM_POLYTOPE_POINT) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for refined point type %s",DMPolytopeTypes[ct]);
475a5801f52SStefano Zampini   for (d = 0; d < dE; ++d) out[d] = 0.0;
476a5801f52SStefano Zampini   for (v = 0; v < Nv; ++v) for (d = 0; d < dE; ++d) out[d] += in[v*dE+d];
477a5801f52SStefano Zampini   for (d = 0; d < dE; ++d) out[d] /= Nv;
478a5801f52SStefano Zampini   PetscFunctionReturn(0);
479a5801f52SStefano Zampini }
480a5801f52SStefano Zampini 
481a5801f52SStefano Zampini /*
482a5801f52SStefano Zampini   Input Parameters:
483a5801f52SStefano Zampini + cr  - The DMPlexCellRefiner
484a5801f52SStefano Zampini . pct - The cell type of the parent, from whom the new cell is being produced
485412e9a14SMatthew G. Knepley . po  - The orientation of the parent cell in its enclosing parent
486412e9a14SMatthew G. Knepley . ct  - The type being produced
487412e9a14SMatthew G. Knepley . r   - The replica number requested for the produced cell type
488412e9a14SMatthew G. Knepley - o   - The relative orientation of the replica
489412e9a14SMatthew G. Knepley 
490412e9a14SMatthew G. Knepley   Output Parameters:
491a5801f52SStefano Zampini + rnew - The replica number, given the orientation of the parent
492412e9a14SMatthew G. Knepley - onew - The replica orientation, given the orientation of the parent
493412e9a14SMatthew G. Knepley */
494412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
495412e9a14SMatthew G. Knepley {
496412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
497412e9a14SMatthew G. Knepley 
498412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
499a5801f52SStefano Zampini   if (!cr->ops->mapsubcells) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]);
500412e9a14SMatthew G. Knepley   ierr = (*cr->ops->mapsubcells)(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr);
501412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
502412e9a14SMatthew G. Knepley }
503412e9a14SMatthew G. Knepley 
504cf4091a3SMatthew G. Knepley /*
505cf4091a3SMatthew G. Knepley   This is the group multiplication table for the dihedral group of the cell.
506cf4091a3SMatthew G. Knepley */
507cf4091a3SMatthew G. Knepley static PetscErrorCode ComposeOrientation_Private(PetscInt n, PetscInt o1, PetscInt o2, PetscInt *o)
508cf4091a3SMatthew G. Knepley {
509cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
510cf4091a3SMatthew G. Knepley   if (!n)                      {*o = 0;}
511cf4091a3SMatthew G. Knepley   else if (o1 >= 0 && o2 >= 0) {*o = ( o1 + o2) % n;}
512cf4091a3SMatthew G. Knepley   else if (o1 <  0 && o2 <  0) {*o = (-o1 - o2) % n;}
513cf4091a3SMatthew G. Knepley   else if (o1 < 0)             {*o = -((-(o1+1) + o2) % n + 1);}
514cf4091a3SMatthew G. Knepley   else if (o2 < 0)             {*o = -((-(o2+1) + o1) % n + 1);}
515cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
516cf4091a3SMatthew G. Knepley }
517cf4091a3SMatthew G. Knepley 
518cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_None(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
519cf4091a3SMatthew G. Knepley {
520cf4091a3SMatthew G. Knepley   PetscErrorCode ierr;
521cf4091a3SMatthew G. Knepley 
522cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
523cf4091a3SMatthew G. Knepley   *rnew = r;
524cf4091a3SMatthew G. Knepley   ierr  = ComposeOrientation_Private(DMPolytopeTypeGetConeSize(ct), po, o, onew);CHKERRQ(ierr);
525cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
526cf4091a3SMatthew G. Knepley }
527cf4091a3SMatthew G. Knepley 
528412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_Regular(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
529412e9a14SMatthew G. Knepley {
530412e9a14SMatthew G. Knepley   /* We shift any input orientation in order to make it non-negative
531412e9a14SMatthew 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)
532412e9a14SMatthew G. Knepley        The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po
533412e9a14SMatthew G. Knepley        Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po
534412e9a14SMatthew G. Knepley   */
535412e9a14SMatthew G. Knepley   PetscInt tri_seg_o[] = {-2, 0,
536412e9a14SMatthew G. Knepley                           -2, 0,
537412e9a14SMatthew G. Knepley                           -2, 0,
538412e9a14SMatthew G. Knepley                           0, -2,
539412e9a14SMatthew G. Knepley                           0, -2,
540412e9a14SMatthew G. Knepley                           0, -2};
541412e9a14SMatthew G. Knepley   PetscInt tri_seg_r[] = {1, 0, 2,
542412e9a14SMatthew G. Knepley                           0, 2, 1,
543412e9a14SMatthew G. Knepley                           2, 1, 0,
544412e9a14SMatthew G. Knepley                           0, 1, 2,
545412e9a14SMatthew G. Knepley                           1, 2, 0,
546412e9a14SMatthew G. Knepley                           2, 0, 1};
547412e9a14SMatthew G. Knepley   PetscInt tri_tri_o[] = {0,  1,  2, -3, -2, -1,
548412e9a14SMatthew G. Knepley                           2,  0,  1, -2, -1, -3,
549412e9a14SMatthew G. Knepley                           1,  2,  0, -1, -3, -2,
550412e9a14SMatthew G. Knepley                          -3, -2, -1,  0,  1,  2,
551412e9a14SMatthew G. Knepley                          -1, -3, -2,  1,  2,  0,
552412e9a14SMatthew G. Knepley                          -2, -1, -3,  2,  0,  1};
553412e9a14SMatthew G. Knepley   /* orientation if the replica is the center triangle */
554412e9a14SMatthew G. Knepley   PetscInt tri_tri_o_c[] = {2,  0,  1, -2, -1, -3,
555412e9a14SMatthew G. Knepley                             1,  2,  0, -1, -3, -2,
556412e9a14SMatthew G. Knepley                             0,  1,  2, -3, -2, -1,
557412e9a14SMatthew G. Knepley                            -3, -2, -1,  0,  1,  2,
558412e9a14SMatthew G. Knepley                            -1, -3, -2,  1,  2,  0,
559412e9a14SMatthew G. Knepley                            -2, -1, -3,  2,  0,  1};
560412e9a14SMatthew G. Knepley   PetscInt tri_tri_r[] = {0, 2, 1, 3,
561412e9a14SMatthew G. Knepley                           2, 1, 0, 3,
562412e9a14SMatthew G. Knepley                           1, 0, 2, 3,
563412e9a14SMatthew G. Knepley                           0, 1, 2, 3,
564412e9a14SMatthew G. Knepley                           1, 2, 0, 3,
565412e9a14SMatthew G. Knepley                           2, 0, 1, 3};
566412e9a14SMatthew G. Knepley   PetscInt quad_seg_r[] = {3, 2, 1, 0,
567412e9a14SMatthew G. Knepley                            2, 1, 0, 3,
568412e9a14SMatthew G. Knepley                            1, 0, 3, 2,
569412e9a14SMatthew G. Knepley                            0, 3, 2, 1,
570412e9a14SMatthew G. Knepley                            0, 1, 2, 3,
571412e9a14SMatthew G. Knepley                            1, 2, 3, 0,
572412e9a14SMatthew G. Knepley                            2, 3, 0, 1,
573412e9a14SMatthew G. Knepley                            3, 0, 1, 2};
574412e9a14SMatthew G. Knepley   PetscInt quad_quad_o[] = { 0,  1,  2,  3, -4, -3, -2, -1,
575412e9a14SMatthew G. Knepley                              4,  0,  1,  2, -3, -2, -1, -4,
576412e9a14SMatthew G. Knepley                              3,  4,  0,  1, -2, -1, -4, -3,
577412e9a14SMatthew G. Knepley                              2,  3,  4,  0, -1, -4, -3, -2,
578412e9a14SMatthew G. Knepley                             -4, -3, -2, -1,  0,  1,  2,  3,
579412e9a14SMatthew G. Knepley                             -1, -4, -3, -2,  1,  2,  3,  0,
580412e9a14SMatthew G. Knepley                             -2, -1, -4, -3,  2,  3,  0,  1,
581412e9a14SMatthew G. Knepley                             -3, -2, -1, -4,  3,  0,  1,  2};
582412e9a14SMatthew G. Knepley   PetscInt quad_quad_r[] = {0, 3, 2, 1,
583412e9a14SMatthew G. Knepley                             3, 2, 1, 0,
584412e9a14SMatthew G. Knepley                             2, 1, 0, 3,
585412e9a14SMatthew G. Knepley                             1, 0, 3, 2,
586412e9a14SMatthew G. Knepley                             0, 1, 2, 3,
587412e9a14SMatthew G. Knepley                             1, 2, 3, 0,
588412e9a14SMatthew G. Knepley                             2, 3, 0, 1,
589412e9a14SMatthew G. Knepley                             3, 0, 1, 2};
590412e9a14SMatthew G. Knepley   PetscInt tquad_tquad_o[] = { 0,  1, -2, -1,
591412e9a14SMatthew G. Knepley                                1,  0, -1, -2,
592412e9a14SMatthew G. Knepley                               -2, -1,  0,  1,
593412e9a14SMatthew G. Knepley                               -1, -2,  1,  0};
594412e9a14SMatthew G. Knepley   PetscInt tquad_tquad_r[] = {1, 0,
595412e9a14SMatthew G. Knepley                               1, 0,
596412e9a14SMatthew G. Knepley                               0, 1,
597412e9a14SMatthew G. Knepley                               0, 1};
598412e9a14SMatthew G. Knepley 
599412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
600412e9a14SMatthew G. Knepley   /* The default is no transformation */
601412e9a14SMatthew G. Knepley   *rnew = r;
602412e9a14SMatthew G. Knepley   *onew = o;
603412e9a14SMatthew G. Knepley   switch (pct) {
604412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
605412e9a14SMatthew G. Knepley       if (ct == DM_POLYTOPE_SEGMENT) {
606412e9a14SMatthew G. Knepley         if      (po == 0 || po == -1) {*rnew = r;       *onew = o;}
607412e9a14SMatthew G. Knepley         else if (po == 1 || po == -2) {*rnew = (r+1)%2; *onew = (o == 0 || o == -1) ? -2 : 0;}
608412e9a14SMatthew G. Knepley         else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for segment", po);
609412e9a14SMatthew G. Knepley       }
610412e9a14SMatthew G. Knepley       break;
611412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:
612412e9a14SMatthew G. Knepley       switch (ct) {
613412e9a14SMatthew G. Knepley         case DM_POLYTOPE_SEGMENT:
614412e9a14SMatthew G. Knepley           if (o == -1) o = 0;
615412e9a14SMatthew G. Knepley           if (o == -2) o = 1;
616412e9a14SMatthew G. Knepley           *onew = tri_seg_o[(po+3)*2+o];
617412e9a14SMatthew G. Knepley           *rnew = tri_seg_r[(po+3)*3+r];
618412e9a14SMatthew G. Knepley           break;
619412e9a14SMatthew G. Knepley         case DM_POLYTOPE_TRIANGLE:
620412e9a14SMatthew 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];
621412e9a14SMatthew G. Knepley           *rnew = tri_tri_r[(po+3)*4+r];
622412e9a14SMatthew G. Knepley           break;
623412e9a14SMatthew G. Knepley         default: break;
624412e9a14SMatthew G. Knepley       }
625412e9a14SMatthew G. Knepley       break;
626412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
627412e9a14SMatthew G. Knepley       switch (ct) {
628412e9a14SMatthew G. Knepley         case DM_POLYTOPE_SEGMENT:
629412e9a14SMatthew G. Knepley           *onew = o;
630412e9a14SMatthew G. Knepley           *rnew = quad_seg_r[(po+4)*4+r];
631412e9a14SMatthew G. Knepley           break;
632412e9a14SMatthew G. Knepley         case DM_POLYTOPE_QUADRILATERAL:
633412e9a14SMatthew G. Knepley           *onew = quad_quad_o[(po+4)*8+o+4];
634412e9a14SMatthew G. Knepley           *rnew = quad_quad_r[(po+4)*4+r];
635412e9a14SMatthew G. Knepley           break;
636412e9a14SMatthew G. Knepley         default: break;
637412e9a14SMatthew G. Knepley       }
638412e9a14SMatthew G. Knepley       break;
639412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
640412e9a14SMatthew G. Knepley       switch (ct) {
641412e9a14SMatthew G. Knepley         /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */
642412e9a14SMatthew G. Knepley         case DM_POLYTOPE_SEG_PRISM_TENSOR:
643412e9a14SMatthew G. Knepley           *onew = tquad_tquad_o[(po+2)*4+o+2];
644412e9a14SMatthew G. Knepley           *rnew = tquad_tquad_r[(po+2)*2+r];
645412e9a14SMatthew G. Knepley           break;
646412e9a14SMatthew G. Knepley         default: break;
647412e9a14SMatthew G. Knepley       }
648412e9a14SMatthew G. Knepley       break;
649412e9a14SMatthew G. Knepley     default: break;
650412e9a14SMatthew G. Knepley   }
651412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
652412e9a14SMatthew G. Knepley }
653412e9a14SMatthew G. Knepley 
65496ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerMapSubcells_ToBox(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
655412e9a14SMatthew G. Knepley {
656412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
657412e9a14SMatthew G. Knepley   /* We shift any input orientation in order to make it non-negative
658412e9a14SMatthew 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)
659412e9a14SMatthew G. Knepley        The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po
660412e9a14SMatthew G. Knepley        Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po
661412e9a14SMatthew G. Knepley   */
662412e9a14SMatthew G. Knepley   PetscInt tri_seg_o[] = {0, -2,
663412e9a14SMatthew G. Knepley                           0, -2,
664412e9a14SMatthew G. Knepley                           0, -2,
665412e9a14SMatthew G. Knepley                           0, -2,
666412e9a14SMatthew G. Knepley                           0, -2,
667412e9a14SMatthew G. Knepley                           0, -2};
668412e9a14SMatthew G. Knepley   PetscInt tri_seg_r[] = {2, 1, 0,
669412e9a14SMatthew G. Knepley                           1, 0, 2,
670412e9a14SMatthew G. Knepley                           0, 2, 1,
671412e9a14SMatthew G. Knepley                           0, 1, 2,
672412e9a14SMatthew G. Knepley                           1, 2, 0,
673412e9a14SMatthew G. Knepley                           2, 0, 1};
674412e9a14SMatthew G. Knepley   PetscInt tri_tri_o[] = {0,  1,  2,  3, -4, -3, -2, -1,
675412e9a14SMatthew G. Knepley                           3,  0,  1,  2, -3, -2, -1, -4,
676412e9a14SMatthew G. Knepley                           1,  2,  3,  0, -1, -4, -3, -2,
677412e9a14SMatthew G. Knepley                          -4, -3, -2, -1,  0,  1,  2,  3,
678412e9a14SMatthew G. Knepley                          -1, -4, -3, -2,  1,  2,  3,  0,
679412e9a14SMatthew G. Knepley                          -3, -2, -1, -4,  3,  0,  1,  2};
680412e9a14SMatthew G. Knepley   PetscInt tri_tri_r[] = {0, 2, 1,
681412e9a14SMatthew G. Knepley                           2, 1, 0,
682412e9a14SMatthew G. Knepley                           1, 0, 2,
683412e9a14SMatthew G. Knepley                           0, 1, 2,
684412e9a14SMatthew G. Knepley                           1, 2, 0,
685412e9a14SMatthew G. Knepley                           2, 0, 1};
686412e9a14SMatthew G. Knepley   PetscInt tquad_tquad_o[] = { 0,  1, -2, -1,
687412e9a14SMatthew G. Knepley                                1,  0, -1, -2,
688412e9a14SMatthew G. Knepley                               -2, -1,  0,  1,
689412e9a14SMatthew G. Knepley                               -1, -2,  1,  0};
690412e9a14SMatthew G. Knepley   PetscInt tquad_tquad_r[] = {1, 0,
691412e9a14SMatthew G. Knepley                               1, 0,
692412e9a14SMatthew G. Knepley                               0, 1,
693412e9a14SMatthew G. Knepley                               0, 1};
694412e9a14SMatthew G. Knepley   PetscInt tquad_quad_o[] = {-2, -1, -4, -3,  2,  3,  0,  1,
695412e9a14SMatthew G. Knepley                               1,  2,  3,  0, -1, -4, -3, -2,
696412e9a14SMatthew G. Knepley                              -4, -3, -2, -1,  0,  1,  2,  3,
697412e9a14SMatthew G. Knepley                               1,  0,  3,  2, -3, -4, -1, -2};
698412e9a14SMatthew G. Knepley 
699412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
700412e9a14SMatthew G. Knepley   *rnew = r;
701412e9a14SMatthew G. Knepley   *onew = o;
702412e9a14SMatthew G. Knepley   switch (pct) {
703412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:
704412e9a14SMatthew G. Knepley       switch (ct) {
705412e9a14SMatthew G. Knepley         case DM_POLYTOPE_SEGMENT:
706412e9a14SMatthew G. Knepley           if (o == -1) o = 0;
707412e9a14SMatthew G. Knepley           if (o == -2) o = 1;
708412e9a14SMatthew G. Knepley           *onew = tri_seg_o[(po+3)*2+o];
709412e9a14SMatthew G. Knepley           *rnew = tri_seg_r[(po+3)*3+r];
710412e9a14SMatthew G. Knepley           break;
711412e9a14SMatthew G. Knepley         case DM_POLYTOPE_QUADRILATERAL:
712412e9a14SMatthew G. Knepley           *onew = tri_tri_o[(po+3)*8+o+4];
713412e9a14SMatthew G. Knepley           /* TODO See sheet, for fixing po == 1 and 2 */
714412e9a14SMatthew G. Knepley           if (po ==  2 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4];
715412e9a14SMatthew G. Knepley           if (po ==  2 && r == 2 && o <  0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)];
716412e9a14SMatthew G. Knepley           if (po ==  1 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4];
717412e9a14SMatthew G. Knepley           if (po ==  1 && r == 1 && o <  0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)];
718412e9a14SMatthew G. Knepley           if (po == -1 && r == 2 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+3)%4)+4];
719412e9a14SMatthew G. Knepley           if (po == -1 && r == 2 && o <  0) *onew = tri_tri_o[(po+3)*8+((o+5)%4)];
720412e9a14SMatthew G. Knepley           if (po == -2 && r == 1 && o >= 0) *onew = tri_tri_o[(po+3)*8+((o+1)%4)+4];
721412e9a14SMatthew G. Knepley           if (po == -2 && r == 1 && o <  0) *onew = tri_tri_o[(po+3)*8+((o+7)%4)];
722412e9a14SMatthew G. Knepley           *rnew = tri_tri_r[(po+3)*3+r];
723412e9a14SMatthew G. Knepley           break;
724412e9a14SMatthew G. Knepley         default: break;
725412e9a14SMatthew G. Knepley       }
726412e9a14SMatthew G. Knepley       break;
727412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
728412e9a14SMatthew G. Knepley       switch (ct) {
729412e9a14SMatthew G. Knepley         /* DM_POLYTOPE_POINT_PRISM_TENSOR does not change */
730412e9a14SMatthew G. Knepley         case DM_POLYTOPE_SEG_PRISM_TENSOR:
731412e9a14SMatthew G. Knepley           *onew = tquad_tquad_o[(po+2)*4+o+2];
732412e9a14SMatthew G. Knepley           *rnew = tquad_tquad_r[(po+2)*2+r];
733412e9a14SMatthew G. Knepley           break;
734412e9a14SMatthew G. Knepley         case DM_POLYTOPE_QUADRILATERAL:
735412e9a14SMatthew G. Knepley           *onew = tquad_quad_o[(po+2)*8+o+4];
736412e9a14SMatthew G. Knepley           *rnew = tquad_tquad_r[(po+2)*2+r];
737412e9a14SMatthew G. Knepley           break;
738412e9a14SMatthew G. Knepley         default: break;
739412e9a14SMatthew G. Knepley       }
740412e9a14SMatthew G. Knepley       break;
741412e9a14SMatthew G. Knepley     default:
742412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerMapSubcells_Regular(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr);
743412e9a14SMatthew G. Knepley   }
744412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
745412e9a14SMatthew G. Knepley }
746412e9a14SMatthew G. Knepley 
747412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapSubcells_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
748412e9a14SMatthew G. Knepley {
749412e9a14SMatthew G. Knepley   return DMPlexCellRefinerMapSubcells_Regular(cr, pct, po, ct, r, o, rnew, onew);
750412e9a14SMatthew G. Knepley }
751412e9a14SMatthew G. Knepley 
752412e9a14SMatthew G. Knepley /*@
753412e9a14SMatthew G. Knepley   DMPlexCellRefinerRefine - Return a description of the refinement for a given cell type
754412e9a14SMatthew G. Knepley 
755412e9a14SMatthew G. Knepley   Input Parameter:
756412e9a14SMatthew G. Knepley . source - The cell type for a source point
757412e9a14SMatthew G. Knepley 
758412e9a14SMatthew G. Knepley   Output Parameter:
759412e9a14SMatthew G. Knepley + Nt     - The number of cell types generated by refinement
760412e9a14SMatthew G. Knepley . target - The cell types generated
761412e9a14SMatthew G. Knepley . size   - The number of subcells of each type, ordered by dimension
762412e9a14SMatthew G. Knepley . cone   - A list of the faces for each subcell of the same type as source
763412e9a14SMatthew G. Knepley - ornt   - A list of the face orientations for each subcell of the same type as source
764412e9a14SMatthew G. Knepley 
765a5801f52SStefano Zampini   Note: The cone array gives the cone of each subcell listed by the first three outputs. For each cone point, we
766412e9a14SMatthew G. Knepley   need the cell type, point identifier, and orientation within the subcell. The orientation is with respect to the canonical
767412e9a14SMatthew G. Knepley   division (described in these outputs) of the cell in the original mesh. The point identifier is given by
768412e9a14SMatthew G. Knepley $   the number of cones to be taken, or 0 for the current cell
769412e9a14SMatthew G. Knepley $   the cell cone point number at each level from which it is subdivided
770412e9a14SMatthew G. Knepley $   the replica number r of the subdivision.
771412e9a14SMatthew G. Knepley   The orientation is with respect to the canonical cone orientation. For example, the prescription for edge division is
772412e9a14SMatthew G. Knepley $   Nt     = 2
773412e9a14SMatthew G. Knepley $   target = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT}
774412e9a14SMatthew G. Knepley $   size   = {1, 2}
775412e9a14SMatthew 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}
776412e9a14SMatthew G. Knepley $   ornt   = {                         0,                       0,                        0,                          0}
777412e9a14SMatthew G. Knepley 
778412e9a14SMatthew G. Knepley   Level: developer
779412e9a14SMatthew G. Knepley 
78096ca5757SLisandro Dalcin .seealso: DMPlexCellRefinerCreate(), DMPlexRefineUniform()
781412e9a14SMatthew G. Knepley @*/
782412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerRefine(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
783412e9a14SMatthew G. Knepley {
784412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
785412e9a14SMatthew G. Knepley 
786412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
787a5801f52SStefano Zampini   if (!cr->ops->refine) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Not for refiner type %s",DMPlexCellRefinerTypes[cr->type]);
788412e9a14SMatthew G. Knepley   ierr = (*cr->ops->refine)(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
789412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
790412e9a14SMatthew G. Knepley }
791412e9a14SMatthew G. Knepley 
792cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_None(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
793cf4091a3SMatthew G. Knepley {
794cf4091a3SMatthew G. Knepley   static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT};
795cf4091a3SMatthew G. Knepley   static PetscInt       vertexS[] = {1};
796cf4091a3SMatthew G. Knepley   static PetscInt       vertexC[] = {0};
797cf4091a3SMatthew G. Knepley   static PetscInt       vertexO[] = {0};
798cf4091a3SMatthew G. Knepley   static DMPolytopeType edgeT[]   = {DM_POLYTOPE_SEGMENT};
799cf4091a3SMatthew G. Knepley   static PetscInt       edgeS[]   = {1};
800cf4091a3SMatthew G. Knepley   static PetscInt       edgeC[]   = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
801cf4091a3SMatthew G. Knepley   static PetscInt       edgeO[]   = {0, 0};
802cf4091a3SMatthew G. Knepley   static DMPolytopeType tedgeT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR};
803cf4091a3SMatthew G. Knepley   static PetscInt       tedgeS[]  = {1};
804cf4091a3SMatthew G. Knepley   static PetscInt       tedgeC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
805cf4091a3SMatthew G. Knepley   static PetscInt       tedgeO[]  = {0, 0};
806cf4091a3SMatthew G. Knepley   static DMPolytopeType triT[]    = {DM_POLYTOPE_TRIANGLE};
807cf4091a3SMatthew G. Knepley   static PetscInt       triS[]    = {1};
808cf4091a3SMatthew G. Knepley   static PetscInt       triC[]    = {DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 0};
809cf4091a3SMatthew G. Knepley   static PetscInt       triO[]    = {0, 0, 0};
810cf4091a3SMatthew G. Knepley   static DMPolytopeType quadT[]   = {DM_POLYTOPE_QUADRILATERAL};
811cf4091a3SMatthew G. Knepley   static PetscInt       quadS[]   = {1};
812cf4091a3SMatthew 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};
813cf4091a3SMatthew G. Knepley   static PetscInt       quadO[]   = {0, 0, 0, 0};
814cf4091a3SMatthew G. Knepley   static DMPolytopeType tquadT[]  = {DM_POLYTOPE_SEG_PRISM_TENSOR};
815cf4091a3SMatthew G. Knepley   static PetscInt       tquadS[]  = {1};
816cf4091a3SMatthew 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};
817cf4091a3SMatthew G. Knepley   static PetscInt       tquadO[]  = {0, 0, 0, 0};
818cf4091a3SMatthew G. Knepley   static DMPolytopeType tetT[]    = {DM_POLYTOPE_TETRAHEDRON};
819cf4091a3SMatthew G. Knepley   static PetscInt       tetS[]    = {1};
820cf4091a3SMatthew 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};
821cf4091a3SMatthew G. Knepley   static PetscInt       tetO[]    = {0, 0, 0, 0};
822cf4091a3SMatthew G. Knepley   static DMPolytopeType hexT[]    = {DM_POLYTOPE_HEXAHEDRON};
823cf4091a3SMatthew G. Knepley   static PetscInt       hexS[]    = {1};
824cf4091a3SMatthew G. Knepley   static PetscInt       hexC[]    = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0, DM_POLYTOPE_QUADRILATERAL, 1, 2, 0,
825cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0, DM_POLYTOPE_QUADRILATERAL, 1, 5, 0};
826cf4091a3SMatthew G. Knepley   static PetscInt       hexO[]    = {0, 0, 0, 0, 0, 0};
827cf4091a3SMatthew G. Knepley   static DMPolytopeType tripT[]   = {DM_POLYTOPE_TRI_PRISM};
828cf4091a3SMatthew G. Knepley   static PetscInt       tripS[]   = {1};
829cf4091a3SMatthew G. Knepley   static PetscInt       tripC[]   = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0,
830cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_QUADRILATERAL, 1, 2, 0, DM_POLYTOPE_QUADRILATERAL, 1, 3, 0, DM_POLYTOPE_QUADRILATERAL, 1, 4, 0};
831cf4091a3SMatthew G. Knepley   static PetscInt       tripO[]   = {0, 0, 0, 0, 0};
832cf4091a3SMatthew G. Knepley   static DMPolytopeType ttripT[]  = {DM_POLYTOPE_TRI_PRISM_TENSOR};
833cf4091a3SMatthew G. Knepley   static PetscInt       ttripS[]  = {1};
834cf4091a3SMatthew G. Knepley   static PetscInt       ttripC[]  = {DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0,
835cf4091a3SMatthew 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};
836cf4091a3SMatthew G. Knepley   static PetscInt       ttripO[]  = {0, 0, 0, 0, 0};
837cf4091a3SMatthew G. Knepley   static DMPolytopeType tquadpT[] = {DM_POLYTOPE_QUAD_PRISM_TENSOR};
838cf4091a3SMatthew G. Knepley   static PetscInt       tquadpS[] = {1};
839cf4091a3SMatthew G. Knepley   static PetscInt       tquadpC[] = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_QUADRILATERAL, 1, 1, 0,
840cf4091a3SMatthew 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};
841cf4091a3SMatthew G. Knepley   static PetscInt       tquadpO[] = {0, 0, 0, 0, 0, 0};
842*da9060c4SMatthew G. Knepley   static DMPolytopeType pyrT[]    = {DM_POLYTOPE_PYRAMID};
843*da9060c4SMatthew G. Knepley   static PetscInt       pyrS[]    = {1};
844*da9060c4SMatthew G. Knepley   static PetscInt       pyrC[]    = {DM_POLYTOPE_QUADRILATERAL, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 1, 1, 0,
845*da9060c4SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 1, 3, 0, DM_POLYTOPE_TRIANGLE, 1, 4, 0};
846*da9060c4SMatthew G. Knepley   static PetscInt       pyrO[]    = {0, 0, 0, 0, 0};
847cf4091a3SMatthew G. Knepley 
848cf4091a3SMatthew G. Knepley   PetscFunctionBegin;
849cf4091a3SMatthew G. Knepley   switch (source) {
850cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT:              *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break;
851cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:            *Nt = 1; *target = edgeT;   *size = edgeS;   *cone = edgeC;   *ornt = edgeO;   break;
852cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT;  *size = tedgeS;  *cone = tedgeC;  *ornt = tedgeO;  break;
853cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:           *Nt = 1; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
854cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:      *Nt = 1; *target = quadT;   *size = quadS;   *cone = quadC;   *ornt = quadO;   break;
855cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:   *Nt = 1; *target = tquadT;  *size = tquadS;  *cone = tquadC;  *ornt = tquadO;  break;
856cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:        *Nt = 1; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
857cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:         *Nt = 1; *target = hexT;    *size = hexS;    *cone = hexC;    *ornt = hexO;    break;
858cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:          *Nt = 1; *target = tripT;   *size = tripS;   *cone = tripC;   *ornt = tripO;   break;
859cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:   *Nt = 1; *target = ttripT;  *size = ttripS;  *cone = ttripC;  *ornt = ttripO;  break;
860cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  *Nt = 1; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break;
861*da9060c4SMatthew G. Knepley     case DM_POLYTOPE_PYRAMID:            *Nt = 1; *target = pyrT;    *size = pyrS;    *cone = pyrC;    *ornt = pyrO;    break;
862cf4091a3SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
863cf4091a3SMatthew G. Knepley   }
864cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
865cf4091a3SMatthew G. Knepley }
866cf4091a3SMatthew G. Knepley 
867412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Regular(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
868412e9a14SMatthew G. Knepley {
869412e9a14SMatthew G. Knepley   /* All vertices remain in the refined mesh */
870412e9a14SMatthew G. Knepley   static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT};
871412e9a14SMatthew G. Knepley   static PetscInt       vertexS[] = {1};
872412e9a14SMatthew G. Knepley   static PetscInt       vertexC[] = {0};
873412e9a14SMatthew G. Knepley   static PetscInt       vertexO[] = {0};
874412e9a14SMatthew G. Knepley   /* Split all edges with a new vertex, making two new 2 edges
875412e9a14SMatthew G. Knepley      0--0--0--1--1
876412e9a14SMatthew G. Knepley   */
877412e9a14SMatthew G. Knepley   static DMPolytopeType edgeT[]   = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT};
878412e9a14SMatthew G. Knepley   static PetscInt       edgeS[]   = {1, 2};
879412e9a14SMatthew 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};
880412e9a14SMatthew G. Knepley   static PetscInt       edgeO[]   = {                         0,                       0,                        0,                          0};
881412e9a14SMatthew G. Knepley   /* Do not split tensor edges */
882412e9a14SMatthew G. Knepley   static DMPolytopeType tedgeT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR};
883412e9a14SMatthew G. Knepley   static PetscInt       tedgeS[]  = {1};
884412e9a14SMatthew G. Knepley   static PetscInt       tedgeC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
885412e9a14SMatthew G. Knepley   static PetscInt       tedgeO[]  = {                         0,                          0};
886412e9a14SMatthew G. Knepley   /* Add 3 edges inside every triangle, making 4 new triangles.
88775d3a19aSMatthew G. Knepley    2
88875d3a19aSMatthew G. Knepley    |\
88975d3a19aSMatthew G. Knepley    | \
89075d3a19aSMatthew G. Knepley    |  \
891412e9a14SMatthew G. Knepley    0   1
89275d3a19aSMatthew G. Knepley    | C  \
89375d3a19aSMatthew G. Knepley    |     \
89475d3a19aSMatthew G. Knepley    |      \
89575d3a19aSMatthew G. Knepley    2---1---1
89675d3a19aSMatthew G. Knepley    |\  D  / \
897412e9a14SMatthew G. Knepley    1 2   0   0
89875d3a19aSMatthew G. Knepley    |A \ /  B  \
899412e9a14SMatthew G. Knepley    0-0-0---1---1
90075d3a19aSMatthew G. Knepley   */
901412e9a14SMatthew G. Knepley   static DMPolytopeType triT[]    = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE};
902412e9a14SMatthew G. Knepley   static PetscInt       triS[]    = {3, 4};
903412e9a14SMatthew G. Knepley   static PetscInt       triC[]    = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
904412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 1, 2, 0,
905412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 0, 0,
906412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 1,
907412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    0,
908412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0,
909412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    2};
910412e9a14SMatthew G. Knepley   static PetscInt       triO[]    = {0, 0,
911412e9a14SMatthew G. Knepley                                      0, 0,
912412e9a14SMatthew G. Knepley                                      0, 0,
913412e9a14SMatthew G. Knepley                                      0, -2,  0,
914412e9a14SMatthew G. Knepley                                      0,  0, -2,
915412e9a14SMatthew G. Knepley                                     -2,  0,  0,
916412e9a14SMatthew G. Knepley                                      0,  0,  0};
917412e9a14SMatthew G. Knepley   /* Add a vertex in the center of each quadrilateral, and 4 edges inside, making 4 new quads.
918412e9a14SMatthew G. Knepley      3----1----2----0----2
919412e9a14SMatthew G. Knepley      |         |         |
920412e9a14SMatthew G. Knepley      0    D    2    C    1
921412e9a14SMatthew G. Knepley      |         |         |
922412e9a14SMatthew G. Knepley      3----3----0----1----1
923412e9a14SMatthew G. Knepley      |         |         |
924412e9a14SMatthew G. Knepley      1    A    0    B    0
925412e9a14SMatthew G. Knepley      |         |         |
926412e9a14SMatthew G. Knepley      0----0----0----1----1
927412e9a14SMatthew G. Knepley   */
928412e9a14SMatthew G. Knepley   static DMPolytopeType quadT[]   = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL};
929412e9a14SMatthew G. Knepley   static PetscInt       quadS[]   = {1, 4, 4};
930412e9a14SMatthew G. Knepley   static PetscInt       quadC[]   = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
931412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0,
932412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0,
933412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0,
934412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 1,
935412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    0,
936412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0,    2,
937412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0};
938412e9a14SMatthew G. Knepley   static PetscInt       quadO[]   = {0, 0,
939412e9a14SMatthew G. Knepley                                      0, 0,
940412e9a14SMatthew G. Knepley                                      0, 0,
941412e9a14SMatthew G. Knepley                                      0, 0,
942412e9a14SMatthew G. Knepley                                      0,  0, -2,  0,
943412e9a14SMatthew G. Knepley                                      0,  0,  0, -2,
944412e9a14SMatthew G. Knepley                                     -2,  0,  0,  0,
945412e9a14SMatthew G. Knepley                                      0, -2,  0,  0};
946412e9a14SMatthew G. Knepley   /* Add 1 edge inside every tensor quad, making 2 new tensor quads
947412e9a14SMatthew G. Knepley      2----2----1----3----3
948412e9a14SMatthew G. Knepley      |         |         |
949412e9a14SMatthew G. Knepley      |         |         |
950412e9a14SMatthew G. Knepley      |         |         |
951412e9a14SMatthew G. Knepley      4    A    6    B    5
952412e9a14SMatthew G. Knepley      |         |         |
953412e9a14SMatthew G. Knepley      |         |         |
954412e9a14SMatthew G. Knepley      |         |         |
955412e9a14SMatthew G. Knepley      0----0----0----1----1
956412e9a14SMatthew G. Knepley   */
957412e9a14SMatthew G. Knepley   static DMPolytopeType tquadT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR};
958412e9a14SMatthew G. Knepley   static PetscInt       tquadS[]  = {1, 2};
959412e9a14SMatthew G. Knepley   static PetscInt       tquadC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
960412e9a14SMatthew 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,
961412e9a14SMatthew 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};
962412e9a14SMatthew G. Knepley   static PetscInt       tquadO[]  = {0, 0,
963412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
964412e9a14SMatthew G. Knepley                                      0, 0, 0, 0};
965412e9a14SMatthew G. Knepley   /* Add 1 edge and 8 triangles inside every cell, making 8 new tets
966412e9a14SMatthew 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
967412e9a14SMatthew 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]
968412e9a14SMatthew G. Knepley      called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are
969412e9a14SMatthew G. Knepley        [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3]
970412e9a14SMatthew G. Knepley      The first four tets just cut off the corners, using the replica notation for new vertices,
971412e9a14SMatthew G. Knepley        [v0,      (e0, 0), (e2, 0), (e3, 0)]
972412e9a14SMatthew G. Knepley        [(e0, 0), v1,      (e1, 0), (e4, 0)]
973412e9a14SMatthew G. Knepley        [(e2, 0), (e1, 0), v2,      (e5, 0)]
974412e9a14SMatthew G. Knepley        [(e3, 0), (e4, 0), (e5, 0), v3     ]
975412e9a14SMatthew G. Knepley      The next four tets match a vertex to the newly created faces from cutting off those first tets.
976412e9a14SMatthew G. Knepley        [(e2, 0), (e3, 0), (e0, 0), (e5, 0)]
977412e9a14SMatthew G. Knepley        [(e4, 0), (e1, 0), (e0, 0), (e5, 0)]
978412e9a14SMatthew G. Knepley        [(e5, 0), (e0, 0), (e2, 0), (e1, 0)]
979412e9a14SMatthew G. Knepley        [(e5, 0), (e0, 0), (e4, 0), (e3, 0)]
980412e9a14SMatthew 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
981412e9a14SMatthew G. Knepley        [(e2, 0), (e0, 0), (e3, 0)]
982412e9a14SMatthew G. Knepley        [(e0, 0), (e1, 0), (e4, 0)]
983412e9a14SMatthew G. Knepley        [(e2, 0), (e5, 0), (e1, 0)]
984412e9a14SMatthew G. Knepley        [(e3, 0), (e4, 0), (e5, 0)]
985412e9a14SMatthew G. Knepley      The next four, from the second group of tets, are
986412e9a14SMatthew G. Knepley        [(e2, 0), (e0, 0), (e5, 0)]
987412e9a14SMatthew G. Knepley        [(e4, 0), (e0, 0), (e5, 0)]
988412e9a14SMatthew G. Knepley        [(e0, 0), (e1, 0), (e5, 0)]
989412e9a14SMatthew G. Knepley        [(e5, 0), (e3, 0), (e0, 0)]
990412e9a14SMatthew G. Knepley      I could write a program to generate these orientations by comparing the faces from GetRawFaces() with my existing table.
991412e9a14SMatthew G. Knepley    */
992412e9a14SMatthew G. Knepley   static DMPolytopeType tetT[]    = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON};
993412e9a14SMatthew G. Knepley   static PetscInt       tetS[]    = {1, 8, 8};
994412e9a14SMatthew G. Knepley   static PetscInt       tetC[]    = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 2, 2, 1, 0,
995412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 2, 2,
996412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 1, 1,
997412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 1, 0, 1,
998412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 2, 1,
999412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 2, 0,
1000412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 3, 1,
1001412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0,    0,
1002412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0,    0,
1003412e9a14SMatthew 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,
1004412e9a14SMatthew 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,
1005412e9a14SMatthew 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,
1006412e9a14SMatthew 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,
1007412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    0, DM_POLYTOPE_TRIANGLE, 1, 2, 3, DM_POLYTOPE_TRIANGLE, 0,    4, DM_POLYTOPE_TRIANGLE, 0,    7,
1008412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    1, DM_POLYTOPE_TRIANGLE, 1, 3, 3, DM_POLYTOPE_TRIANGLE, 0,    5, DM_POLYTOPE_TRIANGLE, 0,    6,
1009412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    4, DM_POLYTOPE_TRIANGLE, 0,    6, DM_POLYTOPE_TRIANGLE, 0,    2, DM_POLYTOPE_TRIANGLE, 1, 0, 3,
1010412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    5, DM_POLYTOPE_TRIANGLE, 0,    7, DM_POLYTOPE_TRIANGLE, 0,    3, DM_POLYTOPE_TRIANGLE, 1, 1, 3};
1011412e9a14SMatthew G. Knepley   static PetscInt       tetO[]    = {0, 0,
1012412e9a14SMatthew G. Knepley                                      0,  0,  0,
1013412e9a14SMatthew G. Knepley                                      0,  0,  0,
1014412e9a14SMatthew G. Knepley                                      0,  0,  0,
1015412e9a14SMatthew G. Knepley                                      0,  0,  0,
1016412e9a14SMatthew G. Knepley                                      0,  0, -2,
1017412e9a14SMatthew G. Knepley                                      0,  0, -2,
1018412e9a14SMatthew G. Knepley                                      0, -2, -2,
1019412e9a14SMatthew G. Knepley                                      0, -2,  0,
1020412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,
1021412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,
1022412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,
1023412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,
1024412e9a14SMatthew G. Knepley                                     -3,  0,  0, -2,
1025412e9a14SMatthew G. Knepley                                     -2,  1,  0,  0,
1026412e9a14SMatthew G. Knepley                                     -2, -2, -1,  2,
1027412e9a14SMatthew G. Knepley                                     -2,  0, -2,  1};
1028412e9a14SMatthew G. Knepley   /* Add a vertex in the center of each cell, add 6 edges and 12 quads inside every cell, making 8 new hexes
1029412e9a14SMatthew 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
1030412e9a14SMatthew G. Knepley        [v0, v1, v2, v3] f0 bottom
1031412e9a14SMatthew G. Knepley        [v4, v5, v6, v7] f1 top
1032412e9a14SMatthew G. Knepley        [v0, v3, v5, v4] f2 front
1033412e9a14SMatthew G. Knepley        [v2, v1, v7, v6] f3 back
1034412e9a14SMatthew G. Knepley        [v3, v2, v6, v5] f4 right
1035412e9a14SMatthew G. Knepley        [v0, v4, v7, v1] f5 left
1036412e9a14SMatthew G. Knepley      The eight hexes are divided into four on the bottom, and four on the top,
1037412e9a14SMatthew G. Knepley        [v0,      (e0, 0),  (f0, 0),  (e3, 0),  (e9, 0), (f2, 0),  (c0, 0),  (f5, 0)]
1038412e9a14SMatthew G. Knepley        [(e0, 0), v1,       (e1, 0),  (f0, 0),  (f5, 0), (c0, 0),  (f3, 0),  (e10, 0)]
1039412e9a14SMatthew G. Knepley        [(f0, 0), (e1, 0),  v2,       (e2, 0),  (c0, 0), (f4, 0),  (e11, 0), (f3, 0)]
1040412e9a14SMatthew G. Knepley        [(e3, 0), (f0, 0),  (e2, 0),  v3,       (f2, 0), (e8, 0),  (f4, 0),  (c0, 0)]
1041412e9a14SMatthew G. Knepley        [(e9, 0), (f5, 0),  (c0, 0),  (f2, 0),  v4,      (e4, 0),  (f1, 0),  (e7, 0)]
1042412e9a14SMatthew G. Knepley        [(f2, 0), (c0, 0),  (f4, 0),  (e8, 0),  (e4, 0), v5,       (e5, 0),  (f1, 0)]
1043412e9a14SMatthew G. Knepley        [(c0, 0), (f3, 0),  (e11, 0), (f4, 0),  (f1, 0), (e5, 0),  v6,       (e6, 0)]
1044412e9a14SMatthew G. Knepley        [(f5, 0), (e10, 0), (f3, 0),  (c0, 0),  (e7, 0), (f1, 0),  (e6, 0),  v7]
1045412e9a14SMatthew 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,
1046412e9a14SMatthew G. Knepley        [(e9, 0), (f2, 0),  (c0, 0),  (f5, 0)]
1047412e9a14SMatthew G. Knepley        [(f5, 0), (c0, 0),  (f3, 0),  (e10, 0)]
1048412e9a14SMatthew G. Knepley        [(c0, 0), (f4, 0),  (e11, 0), (f3, 0)]
1049412e9a14SMatthew G. Knepley        [(f2, 0), (e8, 0),  (f4, 0),  (c0, 0)]
1050412e9a14SMatthew G. Knepley      and on the x-z plane,
1051412e9a14SMatthew G. Knepley        [(f0, 0), (e0, 0), (f5, 0), (c0, 0)]
1052412e9a14SMatthew G. Knepley        [(c0, 0), (f5, 0), (e7, 0), (f1, 0)]
1053412e9a14SMatthew G. Knepley        [(f4, 0), (c0, 0), (f1, 0), (e5, 0)]
1054412e9a14SMatthew G. Knepley        [(e2, 0), (f0, 0), (c0, 0), (f4, 0)]
1055412e9a14SMatthew G. Knepley      and on the y-z plane,
1056412e9a14SMatthew G. Knepley        [(e3, 0), (f2, 0), (c0, 0), (f0, 0)]
1057412e9a14SMatthew G. Knepley        [(f2, 0), (e4, 0), (f1, 0), (c0, 0)]
1058412e9a14SMatthew G. Knepley        [(c0, 0), (f1, 0), (e6, 0), (f3, 0)]
1059412e9a14SMatthew G. Knepley        [(f0, 0), (c0, 0), (f3, 0), (e1, 0)]
1060412e9a14SMatthew G. Knepley   */
1061412e9a14SMatthew G. Knepley   static DMPolytopeType hexT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON};
1062412e9a14SMatthew G. Knepley   static PetscInt       hexS[]    = {1, 6, 12, 8};
1063412e9a14SMatthew G. Knepley   static PetscInt       hexC[]    = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1064412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0,
1065412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0,
1066412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0,
1067412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0,
1068412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 5, 0, DM_POLYTOPE_POINT, 0, 0,
1069412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    5, DM_POLYTOPE_SEGMENT, 1, 5, 0,
1070412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    5, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 5, 2,
1071412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 1, 4, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0,    3,
1072412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 0,    2,
1073412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 5, 3, DM_POLYTOPE_SEGMENT, 0,    5, DM_POLYTOPE_SEGMENT, 0,    0,
1074412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    5, DM_POLYTOPE_SEGMENT, 1, 5, 1, DM_POLYTOPE_SEGMENT, 1, 1, 3, DM_POLYTOPE_SEGMENT, 0,    1,
1075412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 4, 2,
1076412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 1, 4, 0,
1077412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 0, 3,
1078412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    2,
1079412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0,    3,
1080412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1,
1081412e9a14SMatthew 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,
1082412e9a14SMatthew 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,
1083412e9a14SMatthew 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,
1084412e9a14SMatthew 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,
1085412e9a14SMatthew 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,
1086412e9a14SMatthew 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,
1087412e9a14SMatthew 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,
1088412e9a14SMatthew 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};
1089412e9a14SMatthew G. Knepley   static PetscInt       hexO[]    = {0, 0,
1090412e9a14SMatthew G. Knepley                                      0, 0,
1091412e9a14SMatthew G. Knepley                                      0, 0,
1092412e9a14SMatthew G. Knepley                                      0, 0,
1093412e9a14SMatthew G. Knepley                                      0, 0,
1094412e9a14SMatthew G. Knepley                                      0, 0,
1095412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1096412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1097412e9a14SMatthew G. Knepley                                     -2, -2,  0,  0,
1098412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1099412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1100412e9a14SMatthew G. Knepley                                     -2, -2,  0,  0,
1101412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1102412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1103412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1104412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1105412e9a14SMatthew G. Knepley                                     -2, -2,  0,  0,
1106412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1107412e9a14SMatthew G. Knepley                                      0, 0,  0, 0, -4, 0,
1108412e9a14SMatthew G. Knepley                                      0, 0, -1, 0, -4, 0,
1109412e9a14SMatthew G. Knepley                                      0, 0, -1, 0,  0, 0,
1110412e9a14SMatthew G. Knepley                                      0, 0,  0, 0,  0, 0,
1111412e9a14SMatthew G. Knepley                                     -4, 0,  0, 0, -4, 0,
1112412e9a14SMatthew G. Knepley                                     -4, 0,  0, 0,  0, 0,
1113412e9a14SMatthew G. Knepley                                     -4, 0, -1, 0,  0, 0,
1114412e9a14SMatthew G. Knepley                                     -4, 0, -1, 0, -4, 0};
1115412e9a14SMatthew G. Knepley   /* Add 3 quads inside every triangular prism, making 4 new prisms. */
1116412e9a14SMatthew G. Knepley   static DMPolytopeType tripT[]   = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_TRI_PRISM};
1117412e9a14SMatthew G. Knepley   static PetscInt       tripS[]   = {3, 4, 6, 8};
1118412e9a14SMatthew G. Knepley   static PetscInt       tripC[]   = {DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 3, 0,
1119412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 1, 4, 0,
1120412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 1, 2, 0,
1121412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 4, 1,
1122412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0,    0,
1123412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3,
1124412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    2,
1125412e9a14SMatthew 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,
1126412e9a14SMatthew 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,
1127412e9a14SMatthew 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,
1128412e9a14SMatthew 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,
1129412e9a14SMatthew 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,
1130412e9a14SMatthew 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,
1131412e9a14SMatthew 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,
1132412e9a14SMatthew 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,
1133412e9a14SMatthew 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,
1134412e9a14SMatthew 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,
1135412e9a14SMatthew 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,
1136412e9a14SMatthew 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,
1137412e9a14SMatthew 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,
1138412e9a14SMatthew 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};
1139412e9a14SMatthew G. Knepley   static PetscInt       tripO[]   = {0, 0,
1140412e9a14SMatthew G. Knepley                                      0, 0,
1141412e9a14SMatthew G. Knepley                                      0, 0,
1142412e9a14SMatthew G. Knepley                                      0, -2, -2,
1143412e9a14SMatthew G. Knepley                                     -2,  0, -2,
1144412e9a14SMatthew G. Knepley                                     -2, -2,  0,
1145412e9a14SMatthew G. Knepley                                      0,  0,  0,
1146412e9a14SMatthew G. Knepley                                     -2,  0, -2, -2,
1147412e9a14SMatthew G. Knepley                                     -2,  0, -2, -2,
1148412e9a14SMatthew G. Knepley                                     -2,  0, -2, -2,
1149412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1150412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1151412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1152412e9a14SMatthew G. Knepley                                      0,  0,  0, -1,  0,
1153412e9a14SMatthew G. Knepley                                      0,  0,  0,  0, -1,
1154412e9a14SMatthew G. Knepley                                      0,  0, -1,  0,  0,
1155412e9a14SMatthew G. Knepley                                      2,  0,  0,  0,  0,
1156412e9a14SMatthew G. Knepley                                     -3,  0,  0, -1,  0,
1157412e9a14SMatthew G. Knepley                                     -3,  0,  0,  0, -1,
1158412e9a14SMatthew G. Knepley                                     -3,  0, -1,  0,  0,
1159412e9a14SMatthew G. Knepley                                     -3,  0,  0,  0,  0};
1160412e9a14SMatthew G. Knepley   /* Add 3 tensor quads inside every tensor triangular prism, making 4 new prisms.
1161412e9a14SMatthew G. Knepley       2
1162412e9a14SMatthew G. Knepley       |\
1163412e9a14SMatthew G. Knepley       | \
1164412e9a14SMatthew G. Knepley       |  \
1165412e9a14SMatthew G. Knepley       0---1
116675d3a19aSMatthew G. Knepley 
1167412e9a14SMatthew G. Knepley       2
116875d3a19aSMatthew G. Knepley 
1169412e9a14SMatthew G. Knepley       0   1
117075d3a19aSMatthew G. Knepley 
1171412e9a14SMatthew G. Knepley       2
1172412e9a14SMatthew G. Knepley       |\
1173412e9a14SMatthew G. Knepley       | \
1174412e9a14SMatthew G. Knepley       |  \
1175412e9a14SMatthew G. Knepley       0---1
1176412e9a14SMatthew G. Knepley   */
1177412e9a14SMatthew G. Knepley   static DMPolytopeType ttripT[]  = {DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_TRI_PRISM_TENSOR};
1178412e9a14SMatthew G. Knepley   static PetscInt       ttripS[]  = {3, 4};
1179412e9a14SMatthew 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,
1180412e9a14SMatthew 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,
1181412e9a14SMatthew 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,
1182412e9a14SMatthew 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,
1183412e9a14SMatthew 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,
1184412e9a14SMatthew 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,
1185412e9a14SMatthew 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};
1186412e9a14SMatthew G. Knepley   static PetscInt       ttripO[]  = {0, 0, 0, 0,
1187412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1188412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1189412e9a14SMatthew G. Knepley                                      0, 0,  0, -1,  0,
1190412e9a14SMatthew G. Knepley                                      0, 0,  0,  0, -1,
1191412e9a14SMatthew G. Knepley                                      0, 0, -1,  0,  0,
1192412e9a14SMatthew G. Knepley                                      0, 0,  0,  0,  0};
1193412e9a14SMatthew G. Knepley   /* Add 1 edge and 4 tensor quads inside every tensor quad prism, making 4 new prisms. */
1194412e9a14SMatthew G. Knepley   static DMPolytopeType tquadpT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR};
1195412e9a14SMatthew G. Knepley   static PetscInt       tquadpS[]  = {1, 4, 4};
1196412e9a14SMatthew G. Knepley   static PetscInt       tquadpC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1197412e9a14SMatthew 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,
1198412e9a14SMatthew 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,
1199412e9a14SMatthew 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,
1200412e9a14SMatthew 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,
1201412e9a14SMatthew 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,
1202412e9a14SMatthew 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,
1203412e9a14SMatthew 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,
1204412e9a14SMatthew 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};
1205412e9a14SMatthew G. Knepley   static PetscInt       tquadpO[]  = {0, 0,
1206412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1207412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1208412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1209412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1210412e9a14SMatthew G. Knepley                                       0, 0,  0,  0, -1,  0,
1211412e9a14SMatthew G. Knepley                                       0, 0,  0,  0,  0, -1,
1212412e9a14SMatthew G. Knepley                                       0, 0, -1,  0,  0,  0,
1213412e9a14SMatthew G. Knepley                                       0, 0,  0, -1,  0,  0};
1214*da9060c4SMatthew G. Knepley   PetscErrorCode ierr;
121575d3a19aSMatthew G. Knepley 
1216412e9a14SMatthew G. Knepley   PetscFunctionBegin;
1217412e9a14SMatthew G. Knepley   switch (source) {
1218412e9a14SMatthew G. Knepley     case DM_POLYTOPE_POINT:              *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break;
1219412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:            *Nt = 2; *target = edgeT;   *size = edgeS;   *cone = edgeC;   *ornt = edgeO;   break;
1220412e9a14SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT;  *size = tedgeS;  *cone = tedgeC;  *ornt = tedgeO;  break;
1221412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:           *Nt = 2; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
1222412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:      *Nt = 3; *target = quadT;   *size = quadS;   *cone = quadC;   *ornt = quadO;   break;
1223412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:   *Nt = 2; *target = tquadT;  *size = tquadS;  *cone = tquadC;  *ornt = tquadO;  break;
1224412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:        *Nt = 3; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
1225412e9a14SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:         *Nt = 4; *target = hexT;    *size = hexS;    *cone = hexC;    *ornt = hexO;    break;
1226412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:          *Nt = 4; *target = tripT;   *size = tripS;   *cone = tripC;   *ornt = tripO;   break;
1227412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:   *Nt = 2; *target = ttripT;  *size = ttripS;  *cone = ttripC;  *ornt = ttripO;  break;
1228412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break;
1229*da9060c4SMatthew G. Knepley     /* TODO Fix pyramids: For now, we just ignore them */
1230*da9060c4SMatthew G. Knepley     case DM_POLYTOPE_PYRAMID:
1231*da9060c4SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1232*da9060c4SMatthew G. Knepley       break;
1233412e9a14SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1234412e9a14SMatthew G. Knepley   }
1235412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1236412e9a14SMatthew G. Knepley }
123775d3a19aSMatthew G. Knepley 
123896ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerRefine_ToBox(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
1239412e9a14SMatthew G. Knepley {
1240412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
1241412e9a14SMatthew G. Knepley   /* Change tensor edges to segments */
1242412e9a14SMatthew G. Knepley   static DMPolytopeType tedgeT[]  = {DM_POLYTOPE_SEGMENT};
1243412e9a14SMatthew G. Knepley   static PetscInt       tedgeS[]  = {1};
1244412e9a14SMatthew G. Knepley   static PetscInt       tedgeC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
1245412e9a14SMatthew G. Knepley   static PetscInt       tedgeO[]  = {                         0,                          0};
1246412e9a14SMatthew G. Knepley   /* Add 1 vertex, 3 edges inside every triangle, making 3 new quadrilaterals.
1247e5337592SStefano Zampini    2
1248e5337592SStefano Zampini    |\
1249e5337592SStefano Zampini    | \
1250e5337592SStefano Zampini    |  \
1251e5337592SStefano Zampini    |   \
1252412e9a14SMatthew G. Knepley    0    1
1253412e9a14SMatthew G. Knepley    |     \
1254e5337592SStefano Zampini    |      \
1255e5337592SStefano Zampini    2       1
1256e5337592SStefano Zampini    |\     / \
1257e5337592SStefano Zampini    | 2   1   \
1258e5337592SStefano Zampini    |  \ /     \
1259412e9a14SMatthew G. Knepley    1   |       0
1260e5337592SStefano Zampini    |   0        \
1261e5337592SStefano Zampini    |   |         \
1262412e9a14SMatthew G. Knepley    |   |          \
1263412e9a14SMatthew G. Knepley    0-0-0-----1-----1
1264e5337592SStefano Zampini   */
1265412e9a14SMatthew G. Knepley   static DMPolytopeType triT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL};
1266412e9a14SMatthew G. Knepley   static PetscInt       triS[]    = {1, 3, 3};
1267412e9a14SMatthew G. Knepley   static PetscInt       triC[]    = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0,    0,
1268412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0,    0,
1269412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0,    0,
1270412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 1,
1271412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    0,
1272412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0};
1273412e9a14SMatthew G. Knepley   static PetscInt       triO[]    = {0, 0,
1274412e9a14SMatthew G. Knepley                                      0, 0,
1275412e9a14SMatthew G. Knepley                                      0, 0,
1276412e9a14SMatthew G. Knepley                                      0,  0, -2,  0,
1277412e9a14SMatthew G. Knepley                                      0,  0,  0, -2,
1278412e9a14SMatthew G. Knepley                                      0, -2,  0,  0};
1279412e9a14SMatthew G. Knepley   /* Add 1 edge inside every tensor quad, making 2 new quadrilaterals
1280412e9a14SMatthew G. Knepley      2----2----1----3----3
12814330a3fcSStefano Zampini      |         |         |
12824330a3fcSStefano Zampini      |         |         |
12834330a3fcSStefano Zampini      |         |         |
1284412e9a14SMatthew G. Knepley      4    A    6    B    5
12854330a3fcSStefano Zampini      |         |         |
1286412e9a14SMatthew G. Knepley      |         |         |
1287412e9a14SMatthew G. Knepley      |         |         |
1288412e9a14SMatthew G. Knepley      0----0----0----1----1
12894330a3fcSStefano Zampini   */
1290412e9a14SMatthew G. Knepley   static DMPolytopeType tquadT[]  = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL};
1291412e9a14SMatthew G. Knepley   static PetscInt       tquadS[]  = {1, 2};
1292412e9a14SMatthew G. Knepley   static PetscInt       tquadC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1293412e9a14SMatthew G. Knepley                                      /* TODO  Fix these */
1294412e9a14SMatthew 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,
1295412e9a14SMatthew 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};
1296412e9a14SMatthew G. Knepley   static PetscInt       tquadO[]  = {0, 0,
1297412e9a14SMatthew G. Knepley                                      0, 0, -2, -2,
1298412e9a14SMatthew G. Knepley                                      0, 0, -2, -2};
1299412e9a14SMatthew G. Knepley   /* Add 6 triangles inside every cell, making 4 new hexs
1300412e9a14SMatthew G. Knepley      TODO: Need different SubcellMap(). Need to make a struct with the function pointers in it
1301412e9a14SMatthew 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
1302412e9a14SMatthew 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]
1303412e9a14SMatthew G. Knepley      called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are
1304412e9a14SMatthew G. Knepley        [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3]
1305412e9a14SMatthew G. Knepley      We make a new hex in each corner
1306412e9a14SMatthew G. Knepley        [v0, (e0, 0), (f0, 0), (e2, 0), (e3, 0), (f2, 0), (c0, 0), (f1, 0)]
1307412e9a14SMatthew G. Knepley        [v1, (e4, 0), (f3, 0), (e1, 0), (e0, 0), (f0, 0), (c0, 0), (f1, 0)]
1308412e9a14SMatthew G. Knepley        [v2, (e1, 0), (f3, 0), (e5, 0), (e2, 0), (f2, 0), (c0, 0), (f0, 0)]
1309412e9a14SMatthew G. Knepley        [v3, (e4, 0), (f1, 0), (e3, 0), (e5, 0), (f2, 0), (c0, 0), (f3, 0)]
1310412e9a14SMatthew G. Knepley      We create a new face for each edge
1311412e9a14SMatthew G. Knepley        [(e3, 0), (f2, 0), (c0, 0), (f1, 0)]
1312412e9a14SMatthew G. Knepley        [(f0, 0), (e0, 0), (f1, 0), (c0, 0)]
1313412e9a14SMatthew G. Knepley        [(e2, 0), (f0, 0), (c0, 0), (f2, 0)]
1314412e9a14SMatthew G. Knepley        [(f3, 0), (e4, 0), (f1, 0), (c0, 0)]
1315412e9a14SMatthew G. Knepley        [(e1, 0), (f3, 0), (c0, 0), (f0, 0)]
1316412e9a14SMatthew G. Knepley        [(e5, 0), (f3, 0), (c0, 0), (f2, 0)]
1317412e9a14SMatthew 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.
131875d3a19aSMatthew G. Knepley    */
1319412e9a14SMatthew G. Knepley   static DMPolytopeType tetT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON};
1320412e9a14SMatthew G. Knepley   static PetscInt       tetS[]    = {1, 4, 6, 4};
1321412e9a14SMatthew G. Knepley   static PetscInt       tetC[]    = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1322412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0,
1323412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0,
1324412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0,
1325412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 0,
1326412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    0,
1327412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 0,
1328412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    3,
1329412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 0, 1,
1330412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 1,
1331412e9a14SMatthew 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,
1332412e9a14SMatthew 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,
1333412e9a14SMatthew 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,
1334412e9a14SMatthew 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};
1335412e9a14SMatthew G. Knepley   static PetscInt       tetO[]    = {0, 0,
1336412e9a14SMatthew G. Knepley                                      0, 0,
1337412e9a14SMatthew G. Knepley                                      0, 0,
1338412e9a14SMatthew G. Knepley                                      0, 0,
1339412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1340412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1341412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1342412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1343412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1344412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1345412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,  0,  0,
1346412e9a14SMatthew G. Knepley                                      1, -1,  1,  0,  0,  3,
1347412e9a14SMatthew G. Knepley                                      0, -4,  1, -1,  0,  3,
1348412e9a14SMatthew G. Knepley                                      1, -4,  3, -2, -4,  3};
1349412e9a14SMatthew G. Knepley   /* Add 3 quads inside every triangular prism, making 4 new prisms. */
1350412e9a14SMatthew G. Knepley   static DMPolytopeType tripT[]   = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON};
1351412e9a14SMatthew G. Knepley   static PetscInt       tripS[]   = {1, 5, 9, 6};
1352412e9a14SMatthew G. Knepley   static PetscInt       tripC[]   = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1353412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0,
1354412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0,
1355412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0,
1356412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0,
1357412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 1, 4, 1,
1358412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    2,
1359412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3,
1360412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 0,
1361412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 0,
1362412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 1, 4, 0,
1363412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 2,
1364412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 3, 2,
1365412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 4, 2,
1366412e9a14SMatthew 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,
1367412e9a14SMatthew 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,
1368412e9a14SMatthew 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,
1369412e9a14SMatthew 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,
1370412e9a14SMatthew 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,
1371412e9a14SMatthew 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};
1372412e9a14SMatthew G. Knepley   static PetscInt       tripO[]   = {0, 0,
1373412e9a14SMatthew G. Knepley                                      0, 0,
1374412e9a14SMatthew G. Knepley                                      0, 0,
1375412e9a14SMatthew G. Knepley                                      0, 0,
1376412e9a14SMatthew G. Knepley                                      0, 0,
1377412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1378412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1379412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1380412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1381412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1382412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1383412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1384412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1385412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1386412e9a14SMatthew G. Knepley                                      0,  0,  0, -1,  0,  1,
1387412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,  0, -4,
1388412e9a14SMatthew G. Knepley                                      0,  0,  0,  0, -1,  1,
1389412e9a14SMatthew G. Knepley                                     -4,  0,  0, -1,  0,  1,
1390412e9a14SMatthew G. Knepley                                     -4,  0,  0,  0,  0, -4,
1391412e9a14SMatthew G. Knepley                                     -4,  0,  0,  0, -1,  1};
1392412e9a14SMatthew G. Knepley   /* Add 3 tensor quads inside every tensor triangular prism, making 4 new tensor triangular prisms.
1393412e9a14SMatthew G. Knepley       2
1394412e9a14SMatthew G. Knepley       |\
1395412e9a14SMatthew G. Knepley       | \
1396412e9a14SMatthew G. Knepley       |  \
1397412e9a14SMatthew G. Knepley       0---1
139875d3a19aSMatthew G. Knepley 
1399412e9a14SMatthew G. Knepley       2
140075d3a19aSMatthew G. Knepley 
1401412e9a14SMatthew G. Knepley       0   1
140275d3a19aSMatthew G. Knepley 
1403412e9a14SMatthew G. Knepley       2
1404412e9a14SMatthew G. Knepley       |\
1405412e9a14SMatthew G. Knepley       | \
1406412e9a14SMatthew G. Knepley       |  \
1407412e9a14SMatthew G. Knepley       0---1
140875d3a19aSMatthew G. Knepley   */
1409412e9a14SMatthew G. Knepley   static DMPolytopeType ttripT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR};
1410412e9a14SMatthew G. Knepley   static PetscInt       ttripS[]  = {1, 3, 3};
1411412e9a14SMatthew G. Knepley   static PetscInt       ttripC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1412412e9a14SMatthew 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,
1413412e9a14SMatthew 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,
1414412e9a14SMatthew 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,
1415412e9a14SMatthew 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,
1416412e9a14SMatthew 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,
1417412e9a14SMatthew 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};
1418412e9a14SMatthew G. Knepley   static PetscInt       ttripO[]  = {0, 0,
1419412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1420412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1421412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1422412e9a14SMatthew G. Knepley                                      0, 0, 0,  0, -1, 0,
1423412e9a14SMatthew G. Knepley                                      0, 0, 0,  0,  0, -1,
1424412e9a14SMatthew G. Knepley                                      0, 0, 0, -1,  0, 0};
1425412e9a14SMatthew G. Knepley   /* TODO Add 3 quads inside every tensor triangular prism, making 4 new triangular prisms.
1426412e9a14SMatthew G. Knepley       2
1427412e9a14SMatthew G. Knepley       |\
1428412e9a14SMatthew G. Knepley       | \
1429412e9a14SMatthew G. Knepley       |  \
1430412e9a14SMatthew G. Knepley       0---1
143175d3a19aSMatthew G. Knepley 
1432412e9a14SMatthew G. Knepley       2
143375d3a19aSMatthew G. Knepley 
1434412e9a14SMatthew G. Knepley       0   1
143575d3a19aSMatthew G. Knepley 
1436412e9a14SMatthew G. Knepley       2
1437412e9a14SMatthew G. Knepley       |\
1438412e9a14SMatthew G. Knepley       | \
1439412e9a14SMatthew G. Knepley       |  \
1440412e9a14SMatthew G. Knepley       0---1
1441a97b51b8SMatthew G. Knepley   */
1442412e9a14SMatthew G. Knepley   static DMPolytopeType ctripT[]  = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON};
1443412e9a14SMatthew G. Knepley   static PetscInt       ctripS[]  = {1, 3, 3};
1444412e9a14SMatthew G. Knepley   static PetscInt       ctripC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1445412e9a14SMatthew 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,
1446412e9a14SMatthew 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,
1447412e9a14SMatthew 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,
1448412e9a14SMatthew 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,
1449412e9a14SMatthew 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,
1450412e9a14SMatthew 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};
1451412e9a14SMatthew G. Knepley   static PetscInt       ctripO[]  = {0, 0,
1452412e9a14SMatthew G. Knepley                                      0, 0, -2, -2,
1453412e9a14SMatthew G. Knepley                                      0, 0, -2, -2,
1454412e9a14SMatthew G. Knepley                                      0, 0, -2, -2,
1455412e9a14SMatthew G. Knepley                                     -4, 0, 0, -1,  0,  1,
1456412e9a14SMatthew G. Knepley                                     -4, 0, 0,  0,  0, -4,
1457412e9a14SMatthew G. Knepley                                     -4, 0, 0,  0, -1,  1};
1458412e9a14SMatthew G. Knepley   /* Add 1 edge and 4 quads inside every tensor quad prism, making 4 new hexahedra. */
1459412e9a14SMatthew G. Knepley   static DMPolytopeType tquadpT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR};
1460412e9a14SMatthew G. Knepley   static PetscInt       tquadpS[]  = {1, 4, 4};
1461412e9a14SMatthew G. Knepley   static PetscInt       tquadpC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1462412e9a14SMatthew 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,
1463412e9a14SMatthew 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,
1464412e9a14SMatthew 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,
1465412e9a14SMatthew 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,
1466412e9a14SMatthew 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,
1467412e9a14SMatthew 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,
1468412e9a14SMatthew 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,
1469412e9a14SMatthew 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};
1470412e9a14SMatthew G. Knepley   static PetscInt       tquadpO[]  = {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,
1475412e9a14SMatthew G. Knepley                                       0, 0,  0,  0, -1,  0,
1476412e9a14SMatthew G. Knepley                                       0, 0,  0,  0,  0, -1,
1477412e9a14SMatthew G. Knepley                                       0, 0, -1,  0,  0,  0,
1478412e9a14SMatthew G. Knepley                                       0, 0,  0, -1,  0,  0};
1479412e9a14SMatthew G. Knepley   PetscBool convertTensor = PETSC_TRUE;
1480a97b51b8SMatthew G. Knepley 
1481412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
1482412e9a14SMatthew G. Knepley   if (convertTensor) {
1483412e9a14SMatthew G. Knepley     switch (source) {
1484412e9a14SMatthew G. Knepley       case DM_POLYTOPE_POINT:
1485412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEGMENT:
1486412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUADRILATERAL:
1487412e9a14SMatthew G. Knepley       case DM_POLYTOPE_HEXAHEDRON:
1488412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1489a97b51b8SMatthew G. Knepley         break;
1490412e9a14SMatthew G. Knepley       case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT;  *size = tedgeS;  *cone = tedgeC;  *ornt = tedgeO;  break;
1491412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEG_PRISM_TENSOR:   *Nt = 2; *target = tquadT;  *size = tquadS;  *cone = tquadC;  *ornt = tquadO;  break;
1492412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRI_PRISM_TENSOR:   *Nt = 3; *target = ctripT;  *size = ctripS;  *cone = ctripC;  *ornt = ctripO;  break;
1493412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUAD_PRISM_TENSOR:  *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break;
1494412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRIANGLE:           *Nt = 3; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
1495412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TETRAHEDRON:        *Nt = 4; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
1496412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRI_PRISM:          *Nt = 4; *target = tripT;   *size = tripS;   *cone = tripC;   *ornt = tripO;   break;
1497*da9060c4SMatthew G. Knepley       /* TODO Fix pyramids: For now, we just ignore them */
1498*da9060c4SMatthew G. Knepley       case DM_POLYTOPE_PYRAMID:
1499*da9060c4SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1500*da9060c4SMatthew G. Knepley         break;
1501412e9a14SMatthew G. Knepley       default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1502b5da9499SMatthew G. Knepley     }
1503b5da9499SMatthew G. Knepley   } else {
1504412e9a14SMatthew G. Knepley     switch (source) {
1505412e9a14SMatthew G. Knepley       case DM_POLYTOPE_POINT:
1506412e9a14SMatthew G. Knepley       case DM_POLYTOPE_POINT_PRISM_TENSOR:
1507412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEGMENT:
1508412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUADRILATERAL:
1509412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEG_PRISM_TENSOR:
1510412e9a14SMatthew G. Knepley       case DM_POLYTOPE_HEXAHEDRON:
1511412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUAD_PRISM_TENSOR:
1512412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1513b5da9499SMatthew G. Knepley         break;
1514412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRIANGLE:           *Nt = 3; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
1515412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TETRAHEDRON:        *Nt = 4; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
1516412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRI_PRISM:          *Nt = 4; *target = tripT;   *size = tripS;   *cone = tripC;   *ornt = tripO;   break;
1517412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRI_PRISM_TENSOR:   *Nt = 3; *target = ttripT;  *size = ttripS;  *cone = ttripC;  *ornt = ttripO;  break;
1518*da9060c4SMatthew G. Knepley       /* TODO Fix pyramids: For now, we just ignore them */
1519*da9060c4SMatthew G. Knepley       case DM_POLYTOPE_PYRAMID:
1520*da9060c4SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1521*da9060c4SMatthew G. Knepley         break;
1522412e9a14SMatthew G. Knepley       default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
152327fcede3SMatthew G. Knepley     }
152475d3a19aSMatthew G. Knepley   }
152575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
152675d3a19aSMatthew G. Knepley }
152775d3a19aSMatthew G. Knepley 
1528412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
152975d3a19aSMatthew G. Knepley {
1530412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
1531412e9a14SMatthew G. Knepley 
1532412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
1533412e9a14SMatthew G. Knepley   switch (source) {
1534412e9a14SMatthew G. Knepley     case DM_POLYTOPE_POINT:
1535412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
1536412e9a14SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR:
1537412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:
1538412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:
1539412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:
1540412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:
1541412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
1542412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
1543412e9a14SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:
1544412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:
1545412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1546412e9a14SMatthew G. Knepley       break;
1547*da9060c4SMatthew G. Knepley     /* TODO Fix pyramids: For now, we just ignore them */
1548*da9060c4SMatthew G. Knepley     case DM_POLYTOPE_PYRAMID:
1549*da9060c4SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1550*da9060c4SMatthew G. Knepley       break;
1551412e9a14SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1552412e9a14SMatthew G. Knepley   }
1553412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1554412e9a14SMatthew G. Knepley }
1555412e9a14SMatthew G. Knepley 
1556cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld2D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
1557cf4091a3SMatthew G. Knepley {
1558cf4091a3SMatthew G. Knepley   PetscErrorCode ierr;
1559cf4091a3SMatthew G. Knepley   /* Add 1 vertex, 3 edges inside every triangle, making 3 new triangles.
1560cf4091a3SMatthew G. Knepley    2
1561cf4091a3SMatthew G. Knepley    |\
1562cf4091a3SMatthew G. Knepley    |\\
1563cf4091a3SMatthew G. Knepley    | |\
1564cf4091a3SMatthew G. Knepley    | \ \
1565cf4091a3SMatthew G. Knepley    | |  \
1566cf4091a3SMatthew G. Knepley    |  \  \
1567cf4091a3SMatthew G. Knepley    |   |  \
1568cf4091a3SMatthew G. Knepley    2   \   \
1569cf4091a3SMatthew G. Knepley    |   |    1
1570cf4091a3SMatthew G. Knepley    |   2    \
1571cf4091a3SMatthew G. Knepley    |   |    \
1572cf4091a3SMatthew G. Knepley    |   /\   \
1573cf4091a3SMatthew G. Knepley    |  0  1  |
1574cf4091a3SMatthew G. Knepley    | /    \ |
1575cf4091a3SMatthew G. Knepley    |/      \|
1576cf4091a3SMatthew G. Knepley    0---0----1
1577cf4091a3SMatthew G. Knepley   */
1578cf4091a3SMatthew G. Knepley   static DMPolytopeType triT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE};
1579cf4091a3SMatthew G. Knepley   static PetscInt       triS[]    = {1, 3, 3};
1580cf4091a3SMatthew G. Knepley   static PetscInt       triC[]    = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1581cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 2, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1582cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 2, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1583cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0,
1584cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1,
1585cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2};
1586cf4091a3SMatthew G. Knepley   static PetscInt       triO[]    = {0, 0,
1587cf4091a3SMatthew G. Knepley                                      0, 0,
1588cf4091a3SMatthew G. Knepley                                      0, 0,
1589cf4091a3SMatthew G. Knepley                                      0,  0, -2,
1590cf4091a3SMatthew G. Knepley                                      0,  0, -2,
1591cf4091a3SMatthew G. Knepley                                      0,  0, -2};
1592cf4091a3SMatthew G. Knepley 
1593cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
1594cf4091a3SMatthew G. Knepley   switch (source) {
1595cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT:
1596cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
1597cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR:
1598cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
1599cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
1600cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:
1601cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:
1602cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:
1603cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:
1604cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:
1605*da9060c4SMatthew G. Knepley     case DM_POLYTOPE_PYRAMID:
1606cf4091a3SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1607cf4091a3SMatthew G. Knepley       break;
1608cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:           *Nt = 3; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
1609cf4091a3SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1610cf4091a3SMatthew G. Knepley   }
1611cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
1612cf4091a3SMatthew G. Knepley }
1613cf4091a3SMatthew G. Knepley 
1614cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld3D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
1615cf4091a3SMatthew G. Knepley {
1616cf4091a3SMatthew G. Knepley   PetscErrorCode ierr;
1617cf4091a3SMatthew G. Knepley   /* Add 6 triangles inside every cell, making 4 new tets
1618cf4091a3SMatthew 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
1619cf4091a3SMatthew 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]
1620cf4091a3SMatthew G. Knepley      called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are
1621cf4091a3SMatthew G. Knepley        [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3]
1622cf4091a3SMatthew G. Knepley      We make a new tet on each face
1623cf4091a3SMatthew G. Knepley        [v0, v1, v2, (c0, 0)]
1624cf4091a3SMatthew G. Knepley        [v0, v3, v1, (c0, 0)]
1625cf4091a3SMatthew G. Knepley        [v0, v2, v3, (c0, 0)]
1626cf4091a3SMatthew G. Knepley        [v2, v1, v3, (c0, 0)]
1627cf4091a3SMatthew G. Knepley      We create a new face for each edge
1628cf4091a3SMatthew G. Knepley        [v0, (c0, 0), v1     ]
1629cf4091a3SMatthew G. Knepley        [v0, v2,      (c0, 0)]
1630cf4091a3SMatthew G. Knepley        [v2, v1,      (c0, 0)]
1631cf4091a3SMatthew G. Knepley        [v0, (c0, 0), v3     ]
1632cf4091a3SMatthew G. Knepley        [v1, v3,      (c0, 0)]
1633cf4091a3SMatthew G. Knepley        [v3, v2,      (c0, 0)]
1634cf4091a3SMatthew G. Knepley    */
1635cf4091a3SMatthew G. Knepley   static DMPolytopeType tetT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON};
1636cf4091a3SMatthew G. Knepley   static PetscInt       tetS[]    = {1, 4, 6, 4};
1637cf4091a3SMatthew G. Knepley   static PetscInt       tetC[]    = {DM_POLYTOPE_POINT, 3, 0, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1638cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 3, 0, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1639cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 3, 0, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1640cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 3, 1, 0, 1, 0, DM_POLYTOPE_POINT, 0, 0,
1641cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,       0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 2, 0, 0, 0,
1642cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 2, 0, 2, 0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,       0,
1643cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 2, 0, 1, 0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,       2,
1644cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,       0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 2, 1, 0, 0,
1645cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 2, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,       1,
1646cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 2, 2, 1, 0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,       3,
1647cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 2,
1648cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 4,
1649cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 5,
1650cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 3, 0, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 4};
1651cf4091a3SMatthew G. Knepley   static PetscInt       tetO[]    = {0, 0,
1652cf4091a3SMatthew G. Knepley                                      0, 0,
1653cf4091a3SMatthew G. Knepley                                      0, 0,
1654cf4091a3SMatthew G. Knepley                                      0, 0,
1655cf4091a3SMatthew G. Knepley                                      0, -2, -2,
1656cf4091a3SMatthew G. Knepley                                     -2,  0, -2,
1657cf4091a3SMatthew G. Knepley                                     -2,  0, -2,
1658cf4091a3SMatthew G. Knepley                                      0, -2, -2,
1659cf4091a3SMatthew G. Knepley                                     -2,  0, -2,
1660cf4091a3SMatthew G. Knepley                                     -2,  0, -2,
1661cf4091a3SMatthew G. Knepley                                      0,  0,  0,  0,
1662cf4091a3SMatthew G. Knepley                                      0,  0, -3,  0,
1663cf4091a3SMatthew G. Knepley                                      0, -3, -3,  0,
1664cf4091a3SMatthew G. Knepley                                      0, -3, -1, -1};
1665cf4091a3SMatthew G. Knepley 
1666cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
1667cf4091a3SMatthew G. Knepley   switch (source) {
1668cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT:
1669cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
1670cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR:
1671cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:
1672cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
1673cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
1674cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:
1675cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:
1676cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:
1677cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:
1678*da9060c4SMatthew G. Knepley     case DM_POLYTOPE_PYRAMID:
1679cf4091a3SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1680cf4091a3SMatthew G. Knepley       break;
1681cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:        *Nt = 4; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
1682cf4091a3SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1683cf4091a3SMatthew G. Knepley   }
1684cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
1685cf4091a3SMatthew G. Knepley }
1686cf4091a3SMatthew G. Knepley 
1687a5801f52SStefano Zampini typedef struct {
1688a5801f52SStefano Zampini   PetscInt       n;
1689a5801f52SStefano Zampini   PetscReal      r;
1690a5801f52SStefano Zampini   PetscScalar    *h;
1691a5801f52SStefano Zampini   PetscInt       *Nt;
1692a5801f52SStefano Zampini   DMPolytopeType **target;
1693a5801f52SStefano Zampini   PetscInt       **size;
1694a5801f52SStefano Zampini   PetscInt       **cone;
1695a5801f52SStefano Zampini   PetscInt       **ornt;
1696a5801f52SStefano Zampini } PlexRefiner_BL;
1697a5801f52SStefano Zampini 
1698a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerSetUp_BL(DMPlexCellRefiner cr)
1699a5801f52SStefano Zampini {
1700a5801f52SStefano Zampini   PlexRefiner_BL *crbl;
1701a5801f52SStefano Zampini   PetscErrorCode ierr;
1702a5801f52SStefano Zampini   PetscInt       i,n;
1703a5801f52SStefano Zampini   PetscReal      r;
1704a5801f52SStefano Zampini   PetscInt       c1,c2,o1,o2;
1705a5801f52SStefano Zampini 
1706a5801f52SStefano Zampini   PetscFunctionBegin;
1707a5801f52SStefano Zampini   ierr = PetscNew(&crbl);CHKERRQ(ierr);
1708a5801f52SStefano Zampini   cr->data = crbl;
1709a5801f52SStefano Zampini   crbl->n = 1; /* 1 split -> 2 new cells */
1710a5801f52SStefano Zampini   crbl->r = 1; /* linear progression */
1711a5801f52SStefano Zampini 
1712a5801f52SStefano Zampini   /* TODO: add setfromoptions to the refiners? */
1713a5801f52SStefano Zampini   ierr = PetscOptionsGetInt(((PetscObject) cr->dm)->options,((PetscObject) cr->dm)->prefix, "-dm_plex_refine_boundarylayer_splits", &crbl->n, NULL);CHKERRQ(ierr);
1714a5801f52SStefano Zampini   if (crbl->n < 1) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Number of splits %D must be positive",crbl->n);
1715a5801f52SStefano Zampini   ierr = PetscOptionsGetReal(((PetscObject) cr->dm)->options,((PetscObject) cr->dm)->prefix, "-dm_plex_refine_boundarylayer_progression", &crbl->r, NULL);CHKERRQ(ierr);
1716a5801f52SStefano Zampini   n = crbl->n;
1717a5801f52SStefano Zampini   r = crbl->r;
1718a5801f52SStefano Zampini 
1719a5801f52SStefano Zampini   /* we only split DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_TRI_PRISM_TENSOR and DM_POLYTOPE_QUAD_PRISM_TENSOR */
1720a5801f52SStefano Zampini   ierr = PetscMalloc5(4,&crbl->Nt,4,&crbl->target,4,&crbl->size,4,&crbl->cone,4,&crbl->ornt);CHKERRQ(ierr);
1721a5801f52SStefano Zampini 
1722a5801f52SStefano Zampini   /* progression */
1723a5801f52SStefano Zampini   ierr = PetscMalloc1(n,&crbl->h);CHKERRQ(ierr);
1724a5801f52SStefano Zampini   if (r > 1) {
1725a5801f52SStefano Zampini     PetscReal d = (r-1.)/(PetscPowRealInt(r,n+1)-1.);
1726a5801f52SStefano Zampini 
1727a5801f52SStefano Zampini     crbl->h[0] = d;
1728a5801f52SStefano Zampini     for (i = 1; i < n; i++) {
1729a5801f52SStefano Zampini       d *= r;
1730a5801f52SStefano Zampini       crbl->h[i] = crbl->h[i-1] + d;
1731a5801f52SStefano Zampini     }
1732a5801f52SStefano Zampini   } else { /* linear */
1733a5801f52SStefano Zampini     for (i = 0; i < n; i++) crbl->h[i] = (i + 1.)/(n+1); /* linear */
1734a5801f52SStefano Zampini   }
1735a5801f52SStefano Zampini 
1736a5801f52SStefano Zampini   /* DM_POLYTOPE_POINT_PRISM_TENSOR produces n points and n+1 tensor segments */
1737a5801f52SStefano Zampini   c1 = 14+6*(n-1);
1738a5801f52SStefano Zampini   o1 = 2*(n+1);
1739a5801f52SStefano Zampini   crbl->Nt[0] = 2;
1740a5801f52SStefano Zampini 
1741a5801f52SStefano Zampini   ierr = PetscMalloc4(crbl->Nt[0],&crbl->target[0],crbl->Nt[0],&crbl->size[0],c1,&crbl->cone[0],o1,&crbl->ornt[0]);CHKERRQ(ierr);
1742a5801f52SStefano Zampini 
1743a5801f52SStefano Zampini   crbl->target[0][0] = DM_POLYTOPE_POINT;
1744a5801f52SStefano Zampini   crbl->target[0][1] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1745a5801f52SStefano Zampini 
1746a5801f52SStefano Zampini   crbl->size[0][0] = n;
1747a5801f52SStefano Zampini   crbl->size[0][1] = n+1;
1748a5801f52SStefano Zampini 
1749a5801f52SStefano Zampini   /* the tensor segments */
1750a5801f52SStefano Zampini   crbl->cone[0][0] = DM_POLYTOPE_POINT;
1751a5801f52SStefano Zampini   crbl->cone[0][1] = 1;
1752a5801f52SStefano Zampini   crbl->cone[0][2] = 0;
1753a5801f52SStefano Zampini   crbl->cone[0][3] = 0;
1754a5801f52SStefano Zampini   crbl->cone[0][4] = DM_POLYTOPE_POINT;
1755a5801f52SStefano Zampini   crbl->cone[0][5] = 0;
1756a5801f52SStefano Zampini   crbl->cone[0][6] = 0;
1757a5801f52SStefano Zampini   for (i = 0; i < n-1; i++) {
1758a5801f52SStefano Zampini     crbl->cone[0][7+6*i+0] = DM_POLYTOPE_POINT;
1759a5801f52SStefano Zampini     crbl->cone[0][7+6*i+1] = 0;
1760a5801f52SStefano Zampini     crbl->cone[0][7+6*i+2] = i;
1761a5801f52SStefano Zampini     crbl->cone[0][7+6*i+3] = DM_POLYTOPE_POINT;
1762a5801f52SStefano Zampini     crbl->cone[0][7+6*i+4] = 0;
1763a5801f52SStefano Zampini     crbl->cone[0][7+6*i+5] = i+1;
1764a5801f52SStefano Zampini   }
1765a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+0] = DM_POLYTOPE_POINT;
1766a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+1] = 0;
1767a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+2] = n-1;
1768a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+3] = DM_POLYTOPE_POINT;
1769a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+4] = 1;
1770a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+5] = 1;
1771a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+6] = 0;
1772a5801f52SStefano Zampini   for (i = 0; i < o1; i++) crbl->ornt[0][i] = 0;
1773a5801f52SStefano Zampini 
1774a5801f52SStefano Zampini   /* DM_POLYTOPE_SEG_PRISM_TENSOR produces n segments and n+1 tensor quads */
1775a5801f52SStefano Zampini   c1 = 8*n;
1776a5801f52SStefano Zampini   c2 = 30+14*(n-1);
1777a5801f52SStefano Zampini   o1 = 2*n;
1778a5801f52SStefano Zampini   o2 = 4*(n+1);
1779a5801f52SStefano Zampini   crbl->Nt[1] = 2;
1780a5801f52SStefano Zampini 
1781a5801f52SStefano Zampini   ierr = PetscMalloc4(crbl->Nt[1],&crbl->target[1],crbl->Nt[1],&crbl->size[1],c1+c2,&crbl->cone[1],o1+o2,&crbl->ornt[1]);CHKERRQ(ierr);
1782a5801f52SStefano Zampini 
1783a5801f52SStefano Zampini   crbl->target[1][0] = DM_POLYTOPE_SEGMENT;
1784a5801f52SStefano Zampini   crbl->target[1][1] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1785a5801f52SStefano Zampini 
1786a5801f52SStefano Zampini   crbl->size[1][0] = n;
1787a5801f52SStefano Zampini   crbl->size[1][1] = n+1;
1788a5801f52SStefano Zampini 
1789a5801f52SStefano Zampini   /* the segments */
1790a5801f52SStefano Zampini   for (i = 0; i < n; i++) {
1791a5801f52SStefano Zampini     crbl->cone[1][8*i+0] = DM_POLYTOPE_POINT;
1792a5801f52SStefano Zampini     crbl->cone[1][8*i+1] = 1;
1793a5801f52SStefano Zampini     crbl->cone[1][8*i+2] = 2;
1794a5801f52SStefano Zampini     crbl->cone[1][8*i+3] = i;
1795a5801f52SStefano Zampini     crbl->cone[1][8*i+4] = DM_POLYTOPE_POINT;
1796a5801f52SStefano Zampini     crbl->cone[1][8*i+5] = 1;
1797a5801f52SStefano Zampini     crbl->cone[1][8*i+6] = 3;
1798a5801f52SStefano Zampini     crbl->cone[1][8*i+7] = i;
1799a5801f52SStefano Zampini   }
1800a5801f52SStefano Zampini 
1801a5801f52SStefano Zampini   /* the tensor quads */
1802a5801f52SStefano Zampini   crbl->cone[1][c1+ 0] = DM_POLYTOPE_SEGMENT;
1803a5801f52SStefano Zampini   crbl->cone[1][c1+ 1] = 1;
1804a5801f52SStefano Zampini   crbl->cone[1][c1+ 2] = 0;
1805a5801f52SStefano Zampini   crbl->cone[1][c1+ 3] = 0;
1806a5801f52SStefano Zampini   crbl->cone[1][c1+ 4] = DM_POLYTOPE_SEGMENT;
1807a5801f52SStefano Zampini   crbl->cone[1][c1+ 5] = 0;
1808a5801f52SStefano Zampini   crbl->cone[1][c1+ 6] = 0;
1809a5801f52SStefano Zampini   crbl->cone[1][c1+ 7] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1810a5801f52SStefano Zampini   crbl->cone[1][c1+ 8] = 1;
1811a5801f52SStefano Zampini   crbl->cone[1][c1+ 9] = 2;
1812a5801f52SStefano Zampini   crbl->cone[1][c1+10] = 0;
1813a5801f52SStefano Zampini   crbl->cone[1][c1+11] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1814a5801f52SStefano Zampini   crbl->cone[1][c1+12] = 1;
1815a5801f52SStefano Zampini   crbl->cone[1][c1+13] = 3;
1816a5801f52SStefano Zampini   crbl->cone[1][c1+14] = 0;
1817a5801f52SStefano Zampini   for (i = 0; i < n-1; i++) {
1818a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 0] = DM_POLYTOPE_SEGMENT;
1819a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 1] = 0;
1820a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 2] = i;
1821a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 3] = DM_POLYTOPE_SEGMENT;
1822a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 4] = 0;
1823a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 5] = i+1;
1824a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 6] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1825a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 7] = 1;
1826a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 8] = 2;
1827a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 9] = i+1;
1828a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+10] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1829a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+11] = 1;
1830a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+12] = 3;
1831a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+13] = i+1;
1832a5801f52SStefano Zampini   }
1833a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 0] = DM_POLYTOPE_SEGMENT;
1834a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 1] = 0;
1835a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 2] = n-1;
1836a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 3] = DM_POLYTOPE_SEGMENT;
1837a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 4] = 1;
1838a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 5] = 1;
1839a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 6] = 0;
1840a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 7] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1841a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 8] = 1;
1842a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 9] = 2;
1843a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+10] = n;
1844a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+11] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1845a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+12] = 1;
1846a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+13] = 3;
1847a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+14] = n;
1848a5801f52SStefano Zampini   for (i = 0; i < o1+o2; i++) crbl->ornt[1][i] = 0;
1849a5801f52SStefano Zampini 
1850a5801f52SStefano Zampini   /* DM_POLYTOPE_TRI_PRISM_TENSOR produces n triangles and n+1 tensor triangular prisms */
1851a5801f52SStefano Zampini   c1 = 12*n;
1852a5801f52SStefano Zampini   c2 = 38+18*(n-1);
1853a5801f52SStefano Zampini   o1 = 3*n;
1854a5801f52SStefano Zampini   o2 = 5*(n+1);
1855a5801f52SStefano Zampini   crbl->Nt[2] = 2;
1856a5801f52SStefano Zampini 
1857a5801f52SStefano Zampini   ierr = PetscMalloc4(crbl->Nt[2],&crbl->target[2],crbl->Nt[2],&crbl->size[2],c1+c2,&crbl->cone[2],o1+o2,&crbl->ornt[2]);CHKERRQ(ierr);
1858a5801f52SStefano Zampini 
1859a5801f52SStefano Zampini   crbl->target[2][0] = DM_POLYTOPE_TRIANGLE;
1860a5801f52SStefano Zampini   crbl->target[2][1] = DM_POLYTOPE_TRI_PRISM_TENSOR;
1861a5801f52SStefano Zampini 
1862a5801f52SStefano Zampini   crbl->size[2][0] = n;
1863a5801f52SStefano Zampini   crbl->size[2][1] = n+1;
1864a5801f52SStefano Zampini 
1865a5801f52SStefano Zampini   /* the triangles */
1866a5801f52SStefano Zampini   for (i = 0; i < n; i++) {
1867a5801f52SStefano Zampini     crbl->cone[2][12*i+ 0] = DM_POLYTOPE_SEGMENT;
1868a5801f52SStefano Zampini     crbl->cone[2][12*i+ 1] = 1;
1869a5801f52SStefano Zampini     crbl->cone[2][12*i+ 2] = 2;
1870a5801f52SStefano Zampini     crbl->cone[2][12*i+ 3] = i;
1871a5801f52SStefano Zampini     crbl->cone[2][12*i+ 4] = DM_POLYTOPE_SEGMENT;
1872a5801f52SStefano Zampini     crbl->cone[2][12*i+ 5] = 1;
1873a5801f52SStefano Zampini     crbl->cone[2][12*i+ 6] = 3;
1874a5801f52SStefano Zampini     crbl->cone[2][12*i+ 7] = i;
1875a5801f52SStefano Zampini     crbl->cone[2][12*i+ 8] = DM_POLYTOPE_SEGMENT;
1876a5801f52SStefano Zampini     crbl->cone[2][12*i+ 9] = 1;
1877a5801f52SStefano Zampini     crbl->cone[2][12*i+10] = 4;
1878a5801f52SStefano Zampini     crbl->cone[2][12*i+11] = i;
1879a5801f52SStefano Zampini   }
1880a5801f52SStefano Zampini 
1881a5801f52SStefano Zampini   /* the triangular prisms */
1882a5801f52SStefano Zampini   crbl->cone[2][c1+ 0] = DM_POLYTOPE_TRIANGLE;
1883a5801f52SStefano Zampini   crbl->cone[2][c1+ 1] = 1;
1884a5801f52SStefano Zampini   crbl->cone[2][c1+ 2] = 0;
1885a5801f52SStefano Zampini   crbl->cone[2][c1+ 3] = 0;
1886a5801f52SStefano Zampini   crbl->cone[2][c1+ 4] = DM_POLYTOPE_TRIANGLE;
1887a5801f52SStefano Zampini   crbl->cone[2][c1+ 5] = 0;
1888a5801f52SStefano Zampini   crbl->cone[2][c1+ 6] = 0;
1889a5801f52SStefano Zampini   crbl->cone[2][c1+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1890a5801f52SStefano Zampini   crbl->cone[2][c1+ 8] = 1;
1891a5801f52SStefano Zampini   crbl->cone[2][c1+ 9] = 2;
1892a5801f52SStefano Zampini   crbl->cone[2][c1+10] = 0;
1893a5801f52SStefano Zampini   crbl->cone[2][c1+11] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1894a5801f52SStefano Zampini   crbl->cone[2][c1+12] = 1;
1895a5801f52SStefano Zampini   crbl->cone[2][c1+13] = 3;
1896a5801f52SStefano Zampini   crbl->cone[2][c1+14] = 0;
1897a5801f52SStefano Zampini   crbl->cone[2][c1+15] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1898a5801f52SStefano Zampini   crbl->cone[2][c1+16] = 1;
1899a5801f52SStefano Zampini   crbl->cone[2][c1+17] = 4;
1900a5801f52SStefano Zampini   crbl->cone[2][c1+18] = 0;
1901a5801f52SStefano Zampini   for (i = 0; i < n-1; i++) {
1902a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 0] = DM_POLYTOPE_TRIANGLE;
1903a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 1] = 0;
1904a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 2] = i;
1905a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 3] = DM_POLYTOPE_TRIANGLE;
1906a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 4] = 0;
1907a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 5] = i+1;
1908a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 6] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1909a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 7] = 1;
1910a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 8] = 2;
1911a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 9] = i+1;
1912a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+10] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1913a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+11] = 1;
1914a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+12] = 3;
1915a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+13] = i+1;
1916a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+14] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1917a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+15] = 1;
1918a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+16] = 4;
1919a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+17] = i+1;
1920a5801f52SStefano Zampini   }
1921a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 0] = DM_POLYTOPE_TRIANGLE;
1922a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 1] = 0;
1923a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 2] = n-1;
1924a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 3] = DM_POLYTOPE_TRIANGLE;
1925a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 4] = 1;
1926a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 5] = 1;
1927a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 6] = 0;
1928a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1929a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 8] = 1;
1930a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 9] = 2;
1931a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+10] = n;
1932a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+11] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1933a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+12] = 1;
1934a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+13] = 3;
1935a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+14] = n;
1936a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+15] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1937a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+16] = 1;
1938a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+17] = 4;
1939a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+18] = n;
1940a5801f52SStefano Zampini   for (i = 0; i < o1+o2; i++) crbl->ornt[2][i] = 0;
1941a5801f52SStefano Zampini 
1942a5801f52SStefano Zampini   /* DM_POLYTOPE_QUAD_PRISM_TENSOR produces n quads and n+1 tensor quad prisms */
1943a5801f52SStefano Zampini   c1 = 16*n;
1944a5801f52SStefano Zampini   c2 = 46+22*(n-1);
1945a5801f52SStefano Zampini   o1 = 4*n;
1946a5801f52SStefano Zampini   o2 = 6*(n+1);
1947a5801f52SStefano Zampini   crbl->Nt[3] = 2;
1948a5801f52SStefano Zampini 
1949a5801f52SStefano Zampini   ierr = PetscMalloc4(crbl->Nt[3],&crbl->target[3],crbl->Nt[3],&crbl->size[3],c1+c2,&crbl->cone[3],o1+o2,&crbl->ornt[3]);CHKERRQ(ierr);
1950a5801f52SStefano Zampini 
1951a5801f52SStefano Zampini   crbl->target[3][0] = DM_POLYTOPE_QUADRILATERAL;
1952a5801f52SStefano Zampini   crbl->target[3][1] = DM_POLYTOPE_QUAD_PRISM_TENSOR;
1953a5801f52SStefano Zampini 
1954a5801f52SStefano Zampini   crbl->size[3][0] = n;
1955a5801f52SStefano Zampini   crbl->size[3][1] = n+1;
1956a5801f52SStefano Zampini 
1957a5801f52SStefano Zampini   /* the quads */
1958a5801f52SStefano Zampini   for (i = 0; i < n; i++) {
1959a5801f52SStefano Zampini     crbl->cone[3][16*i+ 0] = DM_POLYTOPE_SEGMENT;
1960a5801f52SStefano Zampini     crbl->cone[3][16*i+ 1] = 1;
1961a5801f52SStefano Zampini     crbl->cone[3][16*i+ 2] = 2;
1962a5801f52SStefano Zampini     crbl->cone[3][16*i+ 3] = i;
1963a5801f52SStefano Zampini     crbl->cone[3][16*i+ 4] = DM_POLYTOPE_SEGMENT;
1964a5801f52SStefano Zampini     crbl->cone[3][16*i+ 5] = 1;
1965a5801f52SStefano Zampini     crbl->cone[3][16*i+ 6] = 3;
1966a5801f52SStefano Zampini     crbl->cone[3][16*i+ 7] = i;
1967a5801f52SStefano Zampini     crbl->cone[3][16*i+ 8] = DM_POLYTOPE_SEGMENT;
1968a5801f52SStefano Zampini     crbl->cone[3][16*i+ 9] = 1;
1969a5801f52SStefano Zampini     crbl->cone[3][16*i+10] = 4;
1970a5801f52SStefano Zampini     crbl->cone[3][16*i+11] = i;
1971a5801f52SStefano Zampini     crbl->cone[3][16*i+12] = DM_POLYTOPE_SEGMENT;
1972a5801f52SStefano Zampini     crbl->cone[3][16*i+13] = 1;
1973a5801f52SStefano Zampini     crbl->cone[3][16*i+14] = 5;
1974a5801f52SStefano Zampini     crbl->cone[3][16*i+15] = i;
1975a5801f52SStefano Zampini   }
1976a5801f52SStefano Zampini 
1977a5801f52SStefano Zampini   /* the quad prisms */
1978a5801f52SStefano Zampini   crbl->cone[3][c1+ 0] = DM_POLYTOPE_QUADRILATERAL;
1979a5801f52SStefano Zampini   crbl->cone[3][c1+ 1] = 1;
1980a5801f52SStefano Zampini   crbl->cone[3][c1+ 2] = 0;
1981a5801f52SStefano Zampini   crbl->cone[3][c1+ 3] = 0;
1982a5801f52SStefano Zampini   crbl->cone[3][c1+ 4] = DM_POLYTOPE_QUADRILATERAL;
1983a5801f52SStefano Zampini   crbl->cone[3][c1+ 5] = 0;
1984a5801f52SStefano Zampini   crbl->cone[3][c1+ 6] = 0;
1985a5801f52SStefano Zampini   crbl->cone[3][c1+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1986a5801f52SStefano Zampini   crbl->cone[3][c1+ 8] = 1;
1987a5801f52SStefano Zampini   crbl->cone[3][c1+ 9] = 2;
1988a5801f52SStefano Zampini   crbl->cone[3][c1+10] = 0;
1989a5801f52SStefano Zampini   crbl->cone[3][c1+11] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1990a5801f52SStefano Zampini   crbl->cone[3][c1+12] = 1;
1991a5801f52SStefano Zampini   crbl->cone[3][c1+13] = 3;
1992a5801f52SStefano Zampini   crbl->cone[3][c1+14] = 0;
1993a5801f52SStefano Zampini   crbl->cone[3][c1+15] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1994a5801f52SStefano Zampini   crbl->cone[3][c1+16] = 1;
1995a5801f52SStefano Zampini   crbl->cone[3][c1+17] = 4;
1996a5801f52SStefano Zampini   crbl->cone[3][c1+18] = 0;
1997a5801f52SStefano Zampini   crbl->cone[3][c1+19] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1998a5801f52SStefano Zampini   crbl->cone[3][c1+20] = 1;
1999a5801f52SStefano Zampini   crbl->cone[3][c1+21] = 5;
2000a5801f52SStefano Zampini   crbl->cone[3][c1+22] = 0;
2001a5801f52SStefano Zampini   for (i = 0; i < n-1; i++) {
2002a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 0] = DM_POLYTOPE_QUADRILATERAL;
2003a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 1] = 0;
2004a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 2] = i;
2005a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 3] = DM_POLYTOPE_QUADRILATERAL;
2006a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 4] = 0;
2007a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 5] = i+1;
2008a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 6] = DM_POLYTOPE_SEG_PRISM_TENSOR;
2009a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 7] = 1;
2010a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 8] = 2;
2011a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 9] = i+1;
2012a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+10] = DM_POLYTOPE_SEG_PRISM_TENSOR;
2013a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+11] = 1;
2014a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+12] = 3;
2015a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+13] = i+1;
2016a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+14] = DM_POLYTOPE_SEG_PRISM_TENSOR;
2017a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+15] = 1;
2018a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+16] = 4;
2019a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+17] = i+1;
2020a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+18] = DM_POLYTOPE_SEG_PRISM_TENSOR;
2021a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+19] = 1;
2022a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+20] = 5;
2023a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+21] = i+1;
2024a5801f52SStefano Zampini   }
2025a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 0] = DM_POLYTOPE_QUADRILATERAL;
2026a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 1] = 0;
2027a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 2] = n-1;
2028a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 3] = DM_POLYTOPE_QUADRILATERAL;
2029a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 4] = 1;
2030a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 5] = 1;
2031a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 6] = 0;
2032a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR;
2033a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 8] = 1;
2034a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 9] = 2;
2035a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+10] = n;
2036a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+11] = DM_POLYTOPE_SEG_PRISM_TENSOR;
2037a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+12] = 1;
2038a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+13] = 3;
2039a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+14] = n;
2040a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+15] = DM_POLYTOPE_SEG_PRISM_TENSOR;
2041a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+16] = 1;
2042a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+17] = 4;
2043a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+18] = n;
2044a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+19] = DM_POLYTOPE_SEG_PRISM_TENSOR;
2045a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+20] = 1;
2046a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+21] = 5;
2047a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+22] = n;
2048a5801f52SStefano Zampini   for (i = 0; i < o1+o2; i++) crbl->ornt[3][i] = 0;
2049a5801f52SStefano Zampini   PetscFunctionReturn(0);
2050a5801f52SStefano Zampini }
2051a5801f52SStefano Zampini 
2052a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerDestroy_BL(DMPlexCellRefiner cr)
2053a5801f52SStefano Zampini {
2054a5801f52SStefano Zampini   PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data;
2055a5801f52SStefano Zampini   PetscErrorCode ierr;
2056a5801f52SStefano Zampini 
2057a5801f52SStefano Zampini   PetscFunctionBegin;
2058a5801f52SStefano Zampini   ierr = PetscFree4(crbl->target[0],crbl->size[0],crbl->cone[0],crbl->ornt[0]);CHKERRQ(ierr);
2059a5801f52SStefano Zampini   ierr = PetscFree4(crbl->target[1],crbl->size[1],crbl->cone[1],crbl->ornt[1]);CHKERRQ(ierr);
2060a5801f52SStefano Zampini   ierr = PetscFree4(crbl->target[2],crbl->size[2],crbl->cone[2],crbl->ornt[2]);CHKERRQ(ierr);
2061a5801f52SStefano Zampini   ierr = PetscFree4(crbl->target[3],crbl->size[3],crbl->cone[3],crbl->ornt[3]);CHKERRQ(ierr);
2062a5801f52SStefano Zampini   ierr = PetscFree5(crbl->Nt,crbl->target,crbl->size,crbl->cone,crbl->ornt);CHKERRQ(ierr);
2063a5801f52SStefano Zampini   ierr = PetscFree(crbl->h);CHKERRQ(ierr);
2064a5801f52SStefano Zampini   ierr = PetscFree(cr->data);CHKERRQ(ierr);
2065a5801f52SStefano Zampini   PetscFunctionReturn(0);
2066a5801f52SStefano Zampini }
2067a5801f52SStefano Zampini 
2068cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_BL(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
2069cf4091a3SMatthew G. Knepley {
2070a5801f52SStefano Zampini   PlexRefiner_BL  *crbl = (PlexRefiner_BL *)cr->data;
2071cf4091a3SMatthew G. Knepley   PetscErrorCode  ierr;
2072cf4091a3SMatthew G. Knepley 
2073cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
2074cf4091a3SMatthew G. Knepley   switch (source) {
2075a5801f52SStefano Zampini   case DM_POLYTOPE_POINT_PRISM_TENSOR:
2076a5801f52SStefano Zampini     *Nt     = crbl->Nt[0];
2077a5801f52SStefano Zampini     *target = crbl->target[0];
2078a5801f52SStefano Zampini     *size   = crbl->size[0];
2079a5801f52SStefano Zampini     *cone   = crbl->cone[0];
2080a5801f52SStefano Zampini     *ornt   = crbl->ornt[0];
2081cf4091a3SMatthew G. Knepley     break;
2082a5801f52SStefano Zampini   case DM_POLYTOPE_SEG_PRISM_TENSOR:
2083a5801f52SStefano Zampini     *Nt     = crbl->Nt[1];
2084a5801f52SStefano Zampini     *target = crbl->target[1];
2085a5801f52SStefano Zampini     *size   = crbl->size[1];
2086a5801f52SStefano Zampini     *cone   = crbl->cone[1];
2087a5801f52SStefano Zampini     *ornt   = crbl->ornt[1];
2088a5801f52SStefano Zampini     break;
2089a5801f52SStefano Zampini   case DM_POLYTOPE_TRI_PRISM_TENSOR:
2090a5801f52SStefano Zampini     *Nt     = crbl->Nt[2];
2091a5801f52SStefano Zampini     *target = crbl->target[2];
2092a5801f52SStefano Zampini     *size   = crbl->size[2];
2093a5801f52SStefano Zampini     *cone   = crbl->cone[2];
2094a5801f52SStefano Zampini     *ornt   = crbl->ornt[2];
2095a5801f52SStefano Zampini     break;
2096a5801f52SStefano Zampini   case DM_POLYTOPE_QUAD_PRISM_TENSOR:
2097a5801f52SStefano Zampini     *Nt     = crbl->Nt[3];
2098a5801f52SStefano Zampini     *target = crbl->target[3];
2099a5801f52SStefano Zampini     *size   = crbl->size[3];
2100a5801f52SStefano Zampini     *cone   = crbl->cone[3];
2101a5801f52SStefano Zampini     *ornt   = crbl->ornt[3];
2102a5801f52SStefano Zampini     break;
2103a5801f52SStefano Zampini   default:
2104a5801f52SStefano Zampini     ierr = DMPlexCellRefinerRefine_None(cr,source,Nt,target,size,cone,ornt);CHKERRQ(ierr);
2105a5801f52SStefano Zampini   }
2106a5801f52SStefano Zampini   PetscFunctionReturn(0);
2107a5801f52SStefano Zampini }
2108a5801f52SStefano Zampini 
2109a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapSubcells_BL(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
2110a5801f52SStefano Zampini {
2111a5801f52SStefano Zampini   /* We shift any input orientation in order to make it non-negative
2112a5801f52SStefano Zampini        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)
2113a5801f52SStefano Zampini        The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po
2114a5801f52SStefano Zampini        Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po
2115a5801f52SStefano Zampini   */
2116a5801f52SStefano Zampini   PetscInt       tquad_seg_o[]   = { 0,  1, -2, -1,
2117a5801f52SStefano Zampini                                      0,  1, -2, -1,
2118a5801f52SStefano Zampini                                     -2, -1,  0,  1,
2119a5801f52SStefano Zampini                                     -2, -1,  0,  1};
2120a5801f52SStefano Zampini   PetscInt       tquad_tquad_o[] = { 0,  1, -2, -1,
2121a5801f52SStefano Zampini                                      1,  0, -1, -2,
2122a5801f52SStefano Zampini                                     -2, -1,  0,  1,
2123a5801f52SStefano Zampini                                     -1, -2,  1,  0};
2124a5801f52SStefano Zampini   PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data;
2125a5801f52SStefano Zampini   const PetscInt n = crbl->n;
2126a5801f52SStefano Zampini   PetscErrorCode ierr;
2127a5801f52SStefano Zampini 
2128a5801f52SStefano Zampini   PetscFunctionBeginHot;
2129a5801f52SStefano Zampini   *rnew = r;
2130a5801f52SStefano Zampini   *onew = o;
2131a5801f52SStefano Zampini   switch (pct) {
2132a5801f52SStefano Zampini     case DM_POLYTOPE_POINT_PRISM_TENSOR:
2133a5801f52SStefano Zampini       if (ct == DM_POLYTOPE_POINT_PRISM_TENSOR) {
2134a5801f52SStefano Zampini         if      (po == 0 || po == -1) {*rnew = r;     *onew = o;}
2135a5801f52SStefano Zampini         else if (po == 1 || po == -2) {*rnew = n - r; *onew = (o == 0 || o == -1) ? -2 : 0;}
2136a5801f52SStefano Zampini         else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for tensor segment", po);
2137a5801f52SStefano Zampini       }
2138a5801f52SStefano Zampini       break;
2139a5801f52SStefano Zampini     case DM_POLYTOPE_SEG_PRISM_TENSOR:
2140a5801f52SStefano Zampini       switch (ct) {
2141a5801f52SStefano Zampini         case DM_POLYTOPE_SEGMENT:
2142a5801f52SStefano Zampini           *onew = tquad_seg_o[(po+2)*4+o+2];
2143a5801f52SStefano Zampini           *rnew = r;
2144a5801f52SStefano Zampini           break;
2145a5801f52SStefano Zampini         case DM_POLYTOPE_SEG_PRISM_TENSOR:
2146a5801f52SStefano Zampini           *onew = tquad_tquad_o[(po+2)*4+o+2];
2147a5801f52SStefano Zampini           *rnew = r;
2148a5801f52SStefano Zampini           break;
2149a5801f52SStefano Zampini         default: break;
2150a5801f52SStefano Zampini       }
2151a5801f52SStefano Zampini       break;
2152a5801f52SStefano Zampini     default:
2153a5801f52SStefano Zampini       ierr = DMPlexCellRefinerMapSubcells_None(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr);
2154a5801f52SStefano Zampini   }
2155a5801f52SStefano Zampini   PetscFunctionReturn(0);
2156a5801f52SStefano Zampini }
2157a5801f52SStefano Zampini 
2158a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapCoordinates_BL(DMPlexCellRefiner cr, DMPolytopeType pct, DMPolytopeType ct, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[])
2159a5801f52SStefano Zampini {
2160a5801f52SStefano Zampini   PlexRefiner_BL  *crbl = (PlexRefiner_BL *)cr->data;
2161a5801f52SStefano Zampini   PetscInt        d;
2162a5801f52SStefano Zampini   PetscErrorCode  ierr;
2163a5801f52SStefano Zampini 
2164a5801f52SStefano Zampini   PetscFunctionBeginHot;
2165a5801f52SStefano Zampini   switch (pct) {
2166a5801f52SStefano Zampini   case DM_POLYTOPE_POINT_PRISM_TENSOR:
2167a5801f52SStefano Zampini     if (ct != DM_POLYTOPE_POINT) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for refined point type %s",DMPolytopeTypes[ct]);
2168a5801f52SStefano Zampini     if (Nv != 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for parent vertices %D",Nv);
2169a5801f52SStefano Zampini     if (r >= crbl->n || r < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Invalid replica %D, must be in [0,%D)",r,crbl->n);
2170a5801f52SStefano Zampini     for (d = 0; d < dE; d++) out[d] = in[d] + crbl->h[r] * (in[d + dE] - in[d]);
2171a5801f52SStefano Zampini     break;
2172a5801f52SStefano Zampini   default:
2173a5801f52SStefano Zampini     ierr = DMPlexCellRefinerMapCoordinates_Barycenter(cr,pct,ct,r,Nv,dE,in,out);CHKERRQ(ierr);
2174cf4091a3SMatthew G. Knepley   }
2175cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
2176cf4091a3SMatthew G. Knepley }
2177cf4091a3SMatthew G. Knepley 
2178412e9a14SMatthew G. Knepley static PetscErrorCode CellRefinerCreateOffset_Internal(DMPlexCellRefiner cr, PetscInt ctOrder[], PetscInt ctStart[], PetscInt **offset)
2179412e9a14SMatthew G. Knepley {
2180412e9a14SMatthew G. Knepley   PetscInt       c, cN, *off;
218175d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
218275d3a19aSMatthew G. Knepley 
218375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
2184412e9a14SMatthew G. Knepley   ierr = PetscCalloc1(DM_NUM_POLYTOPES*DM_NUM_POLYTOPES, &off);CHKERRQ(ierr);
2185412e9a14SMatthew G. Knepley   for (c = DM_POLYTOPE_POINT; c < DM_NUM_POLYTOPES; ++c) {
2186412e9a14SMatthew G. Knepley     const DMPolytopeType ct = (DMPolytopeType) c;
2187412e9a14SMatthew G. Knepley     for (cN = DM_POLYTOPE_POINT; cN < DM_NUM_POLYTOPES; ++cN) {
2188412e9a14SMatthew G. Knepley       const DMPolytopeType ctNew = (DMPolytopeType) cN;
2189412e9a14SMatthew G. Knepley       DMPolytopeType      *rct;
2190412e9a14SMatthew G. Knepley       PetscInt            *rsize, *cone, *ornt;
2191412e9a14SMatthew G. Knepley       PetscInt             Nct, n, i;
2192412e9a14SMatthew G. Knepley 
2193412e9a14SMatthew G. Knepley       if (DMPolytopeTypeGetDim(ct) < 0 || DMPolytopeTypeGetDim(ctNew) < 0) {off[ct*DM_NUM_POLYTOPES+ctNew] = -1; break;}
2194412e9a14SMatthew G. Knepley       off[ct*DM_NUM_POLYTOPES+ctNew] = 0;
2195412e9a14SMatthew G. Knepley       for (i = DM_POLYTOPE_POINT; i < DM_NUM_POLYTOPES; ++i) {
2196412e9a14SMatthew G. Knepley         const DMPolytopeType ict  = (DMPolytopeType) ctOrder[i];
2197412e9a14SMatthew G. Knepley         const DMPolytopeType ictn = (DMPolytopeType) ctOrder[i+1];
2198412e9a14SMatthew G. Knepley 
2199412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine(cr, ict, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr);
2200412e9a14SMatthew G. Knepley         if (ict == ct) {
2201412e9a14SMatthew G. Knepley           for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) break;
2202412e9a14SMatthew G. Knepley           if (n == Nct) off[ct*DM_NUM_POLYTOPES+ctNew] = -1;
2203412e9a14SMatthew G. Knepley           break;
2204412e9a14SMatthew G. Knepley         }
2205412e9a14SMatthew G. Knepley         for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) off[ct*DM_NUM_POLYTOPES+ctNew] += (ctStart[ictn]-ctStart[ict]) * rsize[n];
2206412e9a14SMatthew G. Knepley       }
2207412e9a14SMatthew G. Knepley     }
2208412e9a14SMatthew G. Knepley   }
2209412e9a14SMatthew G. Knepley   *offset = off;
2210412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2211412e9a14SMatthew G. Knepley }
2212412e9a14SMatthew G. Knepley 
2213412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetStarts(DMPlexCellRefiner cr, const PetscInt ctStart[], const PetscInt ctStartNew[])
2214412e9a14SMatthew G. Knepley {
2215412e9a14SMatthew G. Knepley   const PetscInt ctSize = DM_NUM_POLYTOPES+1;
2216412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2217412e9a14SMatthew G. Knepley 
2218412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2219412e9a14SMatthew G. Knepley   if (cr->setupcalled) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_ARG_WRONGSTATE, "Must call this function before DMPlexCellRefinerSetUp()");
2220412e9a14SMatthew G. Knepley   ierr = PetscCalloc2(ctSize, &cr->ctStart, ctSize, &cr->ctStartNew);CHKERRQ(ierr);
2221412e9a14SMatthew G. Knepley   ierr = PetscArraycpy(cr->ctStart,    ctStart,    ctSize);CHKERRQ(ierr);
2222412e9a14SMatthew G. Knepley   ierr = PetscArraycpy(cr->ctStartNew, ctStartNew, ctSize);CHKERRQ(ierr);
2223412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2224412e9a14SMatthew G. Knepley }
2225412e9a14SMatthew G. Knepley 
2226412e9a14SMatthew G. Knepley /* Construct cell type order since we must loop over cell types in depth order */
2227412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCreateCellTypeOrder_Internal(DMPolytopeType ctCell, PetscInt *ctOrder[], PetscInt *ctOrderInv[])
2228412e9a14SMatthew G. Knepley {
2229412e9a14SMatthew G. Knepley   PetscInt      *ctO, *ctOInv;
2230412e9a14SMatthew G. Knepley   PetscInt       c, d, off = 0;
2231412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2232412e9a14SMatthew G. Knepley 
2233412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2234412e9a14SMatthew G. Knepley   ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctO, DM_NUM_POLYTOPES+1, &ctOInv);CHKERRQ(ierr);
2235412e9a14SMatthew G. Knepley   for (d = 3; d >= DMPolytopeTypeGetDim(ctCell); --d) {
2236412e9a14SMatthew G. Knepley     for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
2237412e9a14SMatthew G. Knepley       if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue;
2238412e9a14SMatthew G. Knepley       ctO[off++] = c;
2239412e9a14SMatthew G. Knepley     }
2240412e9a14SMatthew G. Knepley   }
2241412e9a14SMatthew G. Knepley   if (DMPolytopeTypeGetDim(ctCell) != 0) {
2242412e9a14SMatthew G. Knepley     for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
2243412e9a14SMatthew G. Knepley       if (DMPolytopeTypeGetDim((DMPolytopeType) c) != 0) continue;
2244412e9a14SMatthew G. Knepley       ctO[off++] = c;
2245412e9a14SMatthew G. Knepley     }
2246412e9a14SMatthew G. Knepley   }
2247412e9a14SMatthew G. Knepley   for (d = DMPolytopeTypeGetDim(ctCell)-1; d > 0; --d) {
2248412e9a14SMatthew G. Knepley     for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
2249412e9a14SMatthew G. Knepley       if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue;
2250412e9a14SMatthew G. Knepley       ctO[off++] = c;
2251412e9a14SMatthew G. Knepley     }
2252412e9a14SMatthew G. Knepley   }
2253412e9a14SMatthew G. Knepley   for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
2254412e9a14SMatthew G. Knepley     if (DMPolytopeTypeGetDim((DMPolytopeType) c) >= 0) continue;
2255412e9a14SMatthew G. Knepley     ctO[off++] = c;
2256412e9a14SMatthew G. Knepley   }
2257412e9a14SMatthew G. Knepley   if (off != DM_NUM_POLYTOPES+1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid offset %D for cell type order", off);
2258412e9a14SMatthew G. Knepley   for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
2259412e9a14SMatthew G. Knepley     ctOInv[ctO[c]] = c;
2260412e9a14SMatthew G. Knepley   }
2261412e9a14SMatthew G. Knepley   *ctOrder    = ctO;
2262412e9a14SMatthew G. Knepley   *ctOrderInv = ctOInv;
2263412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2264412e9a14SMatthew G. Knepley }
2265412e9a14SMatthew G. Knepley 
2266412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerSetUp(DMPlexCellRefiner cr)
2267412e9a14SMatthew G. Knepley {
2268412e9a14SMatthew G. Knepley   DM             dm = cr->dm;
2269412e9a14SMatthew G. Knepley   DMPolytopeType ctCell;
2270412e9a14SMatthew G. Knepley   PetscInt       pStart, pEnd, p, c;
2271412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2272412e9a14SMatthew G. Knepley 
2273412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2274412e9a14SMatthew G. Knepley   PetscValidHeader(cr, 1);
2275412e9a14SMatthew G. Knepley   if (cr->setupcalled) PetscFunctionReturn(0);
2276a5801f52SStefano Zampini   if (cr->ops->setup) {
2277a5801f52SStefano Zampini     ierr = (*cr->ops->setup)(cr);CHKERRQ(ierr);
2278a5801f52SStefano Zampini   }
2279412e9a14SMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
2280a5801f52SStefano Zampini   if (pEnd > pStart) {
2281a5801f52SStefano Zampini     ierr = DMPlexGetCellType(dm, 0, &ctCell);CHKERRQ(ierr);
2282a5801f52SStefano Zampini   } else {
2283412e9a14SMatthew G. Knepley     PetscInt dim;
2284a57030b0SMatthew G. Knepley     ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
2285412e9a14SMatthew G. Knepley     switch (dim) {
2286412e9a14SMatthew G. Knepley     case 0: ctCell = DM_POLYTOPE_POINT;break;
2287412e9a14SMatthew G. Knepley     case 1: ctCell = DM_POLYTOPE_SEGMENT;break;
2288412e9a14SMatthew G. Knepley     case 2: ctCell = DM_POLYTOPE_TRIANGLE;break;
2289412e9a14SMatthew G. Knepley     case 3: ctCell = DM_POLYTOPE_TETRAHEDRON;break;
2290a5801f52SStefano Zampini     default: ctCell = DM_POLYTOPE_UNKNOWN;
2291412e9a14SMatthew G. Knepley     }
2292412e9a14SMatthew G. Knepley   }
2293412e9a14SMatthew G. Knepley   ierr = DMPlexCreateCellTypeOrder_Internal(ctCell, &cr->ctOrder, &cr->ctOrderInv);CHKERRQ(ierr);
2294412e9a14SMatthew G. Knepley   /* Construct sizes and offsets for each cell type */
2295412e9a14SMatthew G. Knepley   if (!cr->ctStart) {
2296412e9a14SMatthew G. Knepley     PetscInt *ctS, *ctSN, *ctC, *ctCN;
2297412e9a14SMatthew G. Knepley 
2298412e9a14SMatthew G. Knepley     ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctS, DM_NUM_POLYTOPES+1, &ctSN);CHKERRQ(ierr);
2299412e9a14SMatthew G. Knepley     ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctC, DM_NUM_POLYTOPES+1, &ctCN);CHKERRQ(ierr);
2300412e9a14SMatthew G. Knepley     for (p = pStart; p < pEnd; ++p) {
2301412e9a14SMatthew G. Knepley       DMPolytopeType  ct;
2302412e9a14SMatthew G. Knepley       DMPolytopeType *rct;
2303412e9a14SMatthew G. Knepley       PetscInt       *rsize, *cone, *ornt;
2304412e9a14SMatthew G. Knepley       PetscInt        Nct, n;
2305412e9a14SMatthew G. Knepley 
2306412e9a14SMatthew G. Knepley       ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2307412e9a14SMatthew G. Knepley       if ((PetscInt) ct < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell type for point %D", p);
2308412e9a14SMatthew G. Knepley       ++ctC[ct];
2309412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr);
2310412e9a14SMatthew G. Knepley       for (n = 0; n < Nct; ++n) ctCN[rct[n]] += rsize[n];
2311412e9a14SMatthew G. Knepley     }
2312412e9a14SMatthew G. Knepley     for (c = 0; c < DM_NUM_POLYTOPES; ++c) {
2313412e9a14SMatthew G. Knepley       const PetscInt ct  = cr->ctOrder[c];
2314412e9a14SMatthew G. Knepley       const PetscInt ctn = cr->ctOrder[c+1];
2315412e9a14SMatthew G. Knepley 
2316412e9a14SMatthew G. Knepley       ctS[ctn]  = ctS[ct]  + ctC[ct];
2317412e9a14SMatthew G. Knepley       ctSN[ctn] = ctSN[ct] + ctCN[ct];
2318412e9a14SMatthew G. Knepley     }
2319412e9a14SMatthew G. Knepley     ierr = PetscFree2(ctC, ctCN);CHKERRQ(ierr);
2320412e9a14SMatthew G. Knepley     cr->ctStart    = ctS;
2321412e9a14SMatthew G. Knepley     cr->ctStartNew = ctSN;
2322412e9a14SMatthew G. Knepley   }
2323412e9a14SMatthew G. Knepley   ierr = CellRefinerCreateOffset_Internal(cr, cr->ctOrder, cr->ctStart, &cr->offset);CHKERRQ(ierr);
2324412e9a14SMatthew G. Knepley   cr->setupcalled = PETSC_TRUE;
2325412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2326412e9a14SMatthew G. Knepley }
2327412e9a14SMatthew G. Knepley 
2328412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView_Ascii(DMPlexCellRefiner cr, PetscViewer v)
2329412e9a14SMatthew G. Knepley {
2330412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2331412e9a14SMatthew G. Knepley 
2332412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2333412e9a14SMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(v, "Cell Refiner: %s\n", DMPlexCellRefinerTypes[cr->type]);CHKERRQ(ierr);
2334412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2335412e9a14SMatthew G. Knepley }
2336412e9a14SMatthew G. Knepley 
2337412e9a14SMatthew G. Knepley /*
2338412e9a14SMatthew G. Knepley   DMPlexCellRefinerView - Views a DMPlexCellRefiner object
2339412e9a14SMatthew G. Knepley 
2340412e9a14SMatthew G. Knepley   Collective on cr
2341412e9a14SMatthew G. Knepley 
2342412e9a14SMatthew G. Knepley   Input Parameters:
2343412e9a14SMatthew G. Knepley + cr     - The DMPlexCellRefiner object
2344412e9a14SMatthew G. Knepley - viewer - The PetscViewer object
2345412e9a14SMatthew G. Knepley 
2346412e9a14SMatthew G. Knepley   Level: beginner
2347412e9a14SMatthew G. Knepley 
2348412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerCreate()
2349412e9a14SMatthew G. Knepley */
2350412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView(DMPlexCellRefiner cr, PetscViewer viewer)
2351412e9a14SMatthew G. Knepley {
2352412e9a14SMatthew G. Knepley   PetscBool      iascii;
2353412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2354412e9a14SMatthew G. Knepley 
2355412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2356412e9a14SMatthew G. Knepley   PetscValidHeader(cr, 1);
2357412e9a14SMatthew G. Knepley   if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
2358412e9a14SMatthew G. Knepley   if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) cr), &viewer);CHKERRQ(ierr);}
2359412e9a14SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
2360412e9a14SMatthew G. Knepley   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2361412e9a14SMatthew G. Knepley   if (iascii) {ierr = DMPlexCellRefinerView_Ascii(cr, viewer);CHKERRQ(ierr);}
2362412e9a14SMatthew G. Knepley   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2363412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2364412e9a14SMatthew G. Knepley }
2365412e9a14SMatthew G. Knepley 
2366412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerDestroy(DMPlexCellRefiner *cr)
2367412e9a14SMatthew G. Knepley {
2368412e9a14SMatthew G. Knepley   PetscInt       c;
2369412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2370412e9a14SMatthew G. Knepley 
2371412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2372412e9a14SMatthew G. Knepley   if (!*cr) PetscFunctionReturn(0);
2373412e9a14SMatthew G. Knepley   PetscValidHeaderSpecific(*cr, DM_CLASSID, 1);
2374a5801f52SStefano Zampini   if ((*cr)->ops->destroy) {
2375a5801f52SStefano Zampini     ierr = ((*cr)->ops->destroy)(*cr);CHKERRQ(ierr);
2376a5801f52SStefano Zampini   }
2377412e9a14SMatthew G. Knepley   ierr = PetscObjectDereference((PetscObject) (*cr)->dm);CHKERRQ(ierr);
2378412e9a14SMatthew G. Knepley   ierr = PetscFree2((*cr)->ctOrder, (*cr)->ctOrderInv);CHKERRQ(ierr);
2379412e9a14SMatthew G. Knepley   ierr = PetscFree2((*cr)->ctStart, (*cr)->ctStartNew);CHKERRQ(ierr);
2380412e9a14SMatthew G. Knepley   ierr = PetscFree((*cr)->offset);CHKERRQ(ierr);
2381412e9a14SMatthew G. Knepley   for (c = 0; c < DM_NUM_POLYTOPES; ++c) {
2382412e9a14SMatthew G. Knepley     ierr = PetscFEDestroy(&(*cr)->coordFE[c]);CHKERRQ(ierr);
2383412e9a14SMatthew G. Knepley     ierr = PetscFEGeomDestroy(&(*cr)->refGeom[c]);CHKERRQ(ierr);
2384412e9a14SMatthew G. Knepley   }
2385412e9a14SMatthew G. Knepley   ierr = PetscFree2((*cr)->coordFE, (*cr)->refGeom);CHKERRQ(ierr);
2386412e9a14SMatthew G. Knepley   ierr = PetscHeaderDestroy(cr);CHKERRQ(ierr);
2387412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2388412e9a14SMatthew G. Knepley }
2389412e9a14SMatthew G. Knepley 
2390412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerCreate(DM dm, DMPlexCellRefiner *cr)
2391412e9a14SMatthew G. Knepley {
2392412e9a14SMatthew G. Knepley   DMPlexCellRefiner tmp;
2393412e9a14SMatthew G. Knepley   PetscErrorCode    ierr;
2394412e9a14SMatthew G. Knepley 
2395412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2396412e9a14SMatthew G. Knepley   PetscValidPointer(cr, 2);
2397412e9a14SMatthew G. Knepley   *cr  = NULL;
2398412e9a14SMatthew G. Knepley   ierr = PetscHeaderCreate(tmp, DM_CLASSID, "DMPlexCellRefiner", "Cell Refiner", "DMPlexCellRefiner", PETSC_COMM_SELF, DMPlexCellRefinerDestroy, DMPlexCellRefinerView);CHKERRQ(ierr);
2399412e9a14SMatthew G. Knepley   tmp->setupcalled = PETSC_FALSE;
2400412e9a14SMatthew G. Knepley 
2401412e9a14SMatthew G. Knepley   tmp->dm = dm;
2402412e9a14SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr);
2403412e9a14SMatthew G. Knepley   ierr = DMPlexGetCellRefinerType(dm, &tmp->type);CHKERRQ(ierr);
2404412e9a14SMatthew G. Knepley   switch (tmp->type) {
240596ca5757SLisandro Dalcin   case DM_REFINER_REGULAR:
2406412e9a14SMatthew G. Knepley     tmp->ops->refine                  = DMPlexCellRefinerRefine_Regular;
2407412e9a14SMatthew G. Knepley     tmp->ops->mapsubcells             = DMPlexCellRefinerMapSubcells_Regular;
2408412e9a14SMatthew G. Knepley     tmp->ops->getcellvertices         = DMPlexCellRefinerGetCellVertices_Regular;
2409412e9a14SMatthew G. Knepley     tmp->ops->getsubcellvertices      = DMPlexCellRefinerGetSubcellVertices_Regular;
2410a5801f52SStefano Zampini     tmp->ops->mapcoords               = DMPlexCellRefinerMapCoordinates_Barycenter;
2411412e9a14SMatthew G. Knepley     tmp->ops->getaffinetransforms     = DMPlexCellRefinerGetAffineTransforms_Regular;
2412412e9a14SMatthew G. Knepley     tmp->ops->getaffinefacetransforms = DMPlexCellRefinerGetAffineFaceTransforms_Regular;
2413412e9a14SMatthew G. Knepley     break;
241496ca5757SLisandro Dalcin   case DM_REFINER_TO_BOX:
241596ca5757SLisandro Dalcin     tmp->ops->refine             = DMPlexCellRefinerRefine_ToBox;
241696ca5757SLisandro Dalcin     tmp->ops->mapsubcells        = DMPlexCellRefinerMapSubcells_ToBox;
241796ca5757SLisandro Dalcin     tmp->ops->getcellvertices    = DMPlexCellRefinerGetCellVertices_ToBox;
241896ca5757SLisandro Dalcin     tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_ToBox;
2419a5801f52SStefano Zampini     tmp->ops->mapcoords          = DMPlexCellRefinerMapCoordinates_Barycenter;
2420412e9a14SMatthew G. Knepley     break;
242196ca5757SLisandro Dalcin   case DM_REFINER_TO_SIMPLEX:
2422412e9a14SMatthew G. Knepley     tmp->ops->refine      = DMPlexCellRefinerRefine_ToSimplex;
2423412e9a14SMatthew G. Knepley     tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToSimplex;
2424a5801f52SStefano Zampini     tmp->ops->mapcoords   = DMPlexCellRefinerMapCoordinates_Barycenter;
2425412e9a14SMatthew G. Knepley     break;
2426cf4091a3SMatthew G. Knepley   case DM_REFINER_ALFELD2D:
2427cf4091a3SMatthew G. Knepley     tmp->ops->refine      = DMPlexCellRefinerRefine_Alfeld2D;
2428cf4091a3SMatthew G. Knepley     tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None;
2429a5801f52SStefano Zampini     tmp->ops->mapcoords   = DMPlexCellRefinerMapCoordinates_Barycenter;
2430cf4091a3SMatthew G. Knepley     break;
2431cf4091a3SMatthew G. Knepley   case DM_REFINER_ALFELD3D:
2432cf4091a3SMatthew G. Knepley     tmp->ops->refine      = DMPlexCellRefinerRefine_Alfeld3D;
2433cf4091a3SMatthew G. Knepley     tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None;
2434a5801f52SStefano Zampini     tmp->ops->mapcoords   = DMPlexCellRefinerMapCoordinates_Barycenter;
2435cf4091a3SMatthew G. Knepley     break;
2436a5801f52SStefano Zampini   case DM_REFINER_BOUNDARYLAYER:
2437a5801f52SStefano Zampini     tmp->ops->setup       = DMPlexCellRefinerSetUp_BL;
2438a5801f52SStefano Zampini     tmp->ops->destroy     = DMPlexCellRefinerDestroy_BL;
2439cf4091a3SMatthew G. Knepley     tmp->ops->refine      = DMPlexCellRefinerRefine_BL;
2440cf4091a3SMatthew G. Knepley     tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_BL;
2441a5801f52SStefano Zampini     tmp->ops->mapcoords   = DMPlexCellRefinerMapCoordinates_BL;
2442cf4091a3SMatthew G. Knepley     break;
2443412e9a14SMatthew G. Knepley   default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Invalid cell refiner type %s", DMPlexCellRefinerTypes[tmp->type]);
2444412e9a14SMatthew G. Knepley   }
2445412e9a14SMatthew G. Knepley   ierr = PetscCalloc2(DM_NUM_POLYTOPES, &tmp->coordFE, DM_NUM_POLYTOPES, &tmp->refGeom);CHKERRQ(ierr);
2446412e9a14SMatthew G. Knepley   *cr = tmp;
2447412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2448412e9a14SMatthew G. Knepley }
2449412e9a14SMatthew G. Knepley 
2450412e9a14SMatthew G. Knepley /*@
2451412e9a14SMatthew G. Knepley   DMPlexCellRefinerGetAffineTransforms - Gets the affine map from the reference cell to each subcell
2452412e9a14SMatthew G. Knepley 
2453412e9a14SMatthew G. Knepley   Input Parameters:
2454412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object
2455412e9a14SMatthew G. Knepley - ct - The cell type
2456412e9a14SMatthew G. Knepley 
2457412e9a14SMatthew G. Knepley   Output Parameters:
2458412e9a14SMatthew G. Knepley + Nc   - The number of subcells produced from this cell type
2459412e9a14SMatthew G. Knepley . v0   - The translation of the first vertex for each subcell
2460412e9a14SMatthew G. Knepley . J    - The Jacobian for each subcell (map from reference cell to subcell)
2461412e9a14SMatthew G. Knepley - invJ - The inverse Jacobian for each subcell
2462412e9a14SMatthew G. Knepley 
2463412e9a14SMatthew G. Knepley   Level: developer
2464412e9a14SMatthew G. Knepley 
2465412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineFaceTransforms(), Create()
2466412e9a14SMatthew G. Knepley @*/
2467412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[])
2468412e9a14SMatthew G. Knepley {
2469412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2470412e9a14SMatthew G. Knepley 
2471412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2472412e9a14SMatthew G. Knepley   if (!cr->ops->getaffinetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine transforms from this refiner");
2473412e9a14SMatthew G. Knepley   ierr = (*cr->ops->getaffinetransforms)(cr, ct, Nc, v0, J, invJ);CHKERRQ(ierr);
2474412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2475412e9a14SMatthew G. Knepley }
2476412e9a14SMatthew G. Knepley 
2477412e9a14SMatthew G. Knepley /*@
2478412e9a14SMatthew G. Knepley   DMPlexCellRefinerGetAffineFaceTransforms - Gets the affine map from the reference face cell to each face in the given cell
2479412e9a14SMatthew G. Knepley 
2480412e9a14SMatthew G. Knepley   Input Parameters:
2481412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object
2482412e9a14SMatthew G. Knepley - ct - The cell type
2483412e9a14SMatthew G. Knepley 
2484412e9a14SMatthew G. Knepley   Output Parameters:
2485412e9a14SMatthew G. Knepley + Nf   - The number of faces for this cell type
2486412e9a14SMatthew G. Knepley . v0   - The translation of the first vertex for each face
2487412e9a14SMatthew G. Knepley . J    - The Jacobian for each face (map from original cell to subcell)
2488412e9a14SMatthew G. Knepley . invJ - The inverse Jacobian for each face
2489412e9a14SMatthew G. Knepley - detJ - The determinant of the Jacobian for each face
2490412e9a14SMatthew G. Knepley 
2491412e9a14SMatthew G. Knepley   Note: The Jacobian and inverse Jacboian will be rectangular, and the inverse is really a generalized inverse.
2492412e9a14SMatthew G. Knepley 
2493412e9a14SMatthew G. Knepley   Level: developer
2494412e9a14SMatthew G. Knepley 
2495412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineTransforms(), Create()
2496412e9a14SMatthew G. Knepley @*/
2497412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[])
2498412e9a14SMatthew G. Knepley {
2499412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2500412e9a14SMatthew G. Knepley 
2501412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2502412e9a14SMatthew G. Knepley   if (!cr->ops->getaffinefacetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine face transforms from this refiner");
2503412e9a14SMatthew G. Knepley   ierr = (*cr->ops->getaffinefacetransforms)(cr, ct, Nf, v0, J, invJ, detJ);CHKERRQ(ierr);
2504412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2505412e9a14SMatthew G. Knepley }
2506412e9a14SMatthew G. Knepley 
2507412e9a14SMatthew G. Knepley /* Numbering regularly refined meshes
2508412e9a14SMatthew G. Knepley 
2509412e9a14SMatthew G. Knepley    We want the numbering of the new mesh to respect the same depth stratification as the old mesh. We first compute
2510412e9a14SMatthew G. Knepley    the number of new points at each depth. This means that offsets for each depth can be computed, making no assumptions
2511412e9a14SMatthew G. Knepley    about the order of different cell types.
2512412e9a14SMatthew G. Knepley 
2513412e9a14SMatthew G. Knepley    However, when we want to order different depth strata, it will be very useful to make assumptions about contiguous
2514412e9a14SMatthew G. Knepley    numbering of different cell types, especially if we want to compute new numberings without communication. Therefore, we
2515412e9a14SMatthew G. Knepley    will require that cells are numbering contiguously for each cell type, and that those blocks come in the same order as
2516412e9a14SMatthew G. Knepley    the cell type enumeration within a given depth stratum.
2517412e9a14SMatthew G. Knepley 
2518412e9a14SMatthew 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
2519412e9a14SMatthew G. Knepley    start at the new depth offset, run through all prior cell types incrementing by the total addition from that type, then
2520412e9a14SMatthew G. Knepley    offset by the old cell type number and replica number for the insertion.
2521412e9a14SMatthew G. Knepley */
2522412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetNewPoint(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType ctNew, PetscInt p, PetscInt r, PetscInt *pNew)
2523412e9a14SMatthew G. Knepley {
2524412e9a14SMatthew G. Knepley   DMPolytopeType *rct;
2525412e9a14SMatthew G. Knepley   PetscInt       *rsize, *cone, *ornt;
2526412e9a14SMatthew G. Knepley   PetscInt       Nct, n;
2527412e9a14SMatthew G. Knepley   PetscInt       off  = cr->offset[ct*DM_NUM_POLYTOPES+ctNew];
2528412e9a14SMatthew G. Knepley   PetscInt       ctS  = cr->ctStart[ct],       ctE  = cr->ctStart[cr->ctOrder[cr->ctOrderInv[ct]+1]];
2529412e9a14SMatthew G. Knepley   PetscInt       ctSN = cr->ctStartNew[ctNew], ctEN = cr->ctStartNew[cr->ctOrder[cr->ctOrderInv[ctNew]+1]];
2530412e9a14SMatthew G. Knepley   PetscInt       newp = ctSN;
2531412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2532412e9a14SMatthew G. Knepley 
2533412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
2534412e9a14SMatthew 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);
2535412e9a14SMatthew 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]);
2536412e9a14SMatthew G. Knepley 
2537412e9a14SMatthew G. Knepley   newp += off;
2538412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr);
2539412e9a14SMatthew G. Knepley   for (n = 0; n < Nct; ++n) {
2540412e9a14SMatthew G. Knepley     if (rct[n] == ctNew) {
2541412e9a14SMatthew G. Knepley       if (rsize[n] && r >= rsize[n])
2542412e9a14SMatthew 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]);
2543412e9a14SMatthew G. Knepley       newp += (p - ctS) * rsize[n] + r;
2544412e9a14SMatthew G. Knepley       break;
2545412e9a14SMatthew G. Knepley     }
2546412e9a14SMatthew G. Knepley   }
2547412e9a14SMatthew G. Knepley 
2548412e9a14SMatthew 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);
2549412e9a14SMatthew G. Knepley   *pNew = newp;
2550412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2551412e9a14SMatthew G. Knepley }
2552412e9a14SMatthew G. Knepley 
2553412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetConeSizes(DMPlexCellRefiner cr, DM rdm)
2554412e9a14SMatthew G. Knepley {
2555412e9a14SMatthew G. Knepley   DM              dm = cr->dm;
2556412e9a14SMatthew G. Knepley   PetscInt        pStart, pEnd, p, pNew;
2557412e9a14SMatthew G. Knepley   PetscErrorCode  ierr;
2558412e9a14SMatthew G. Knepley 
2559412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2560412e9a14SMatthew G. Knepley   /* Must create the celltype label here so that we do not automatically try to compute the types */
2561412e9a14SMatthew G. Knepley   ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr);
2562412e9a14SMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
2563412e9a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2564412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
2565412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2566412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2567412e9a14SMatthew G. Knepley     PetscInt        Nct, n, r;
2568412e9a14SMatthew G. Knepley 
2569412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2570412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2571412e9a14SMatthew G. Knepley     for (n = 0; n < Nct; ++n) {
2572412e9a14SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r) {
2573412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr);
2574412e9a14SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, pNew, DMPolytopeTypeGetConeSize(rct[n]));CHKERRQ(ierr);
2575412e9a14SMatthew G. Knepley         ierr = DMPlexSetCellType(rdm, pNew, rct[n]);CHKERRQ(ierr);
2576412e9a14SMatthew G. Knepley       }
2577412e9a14SMatthew G. Knepley     }
2578412e9a14SMatthew G. Knepley   }
2579412e9a14SMatthew G. Knepley   {
2580412e9a14SMatthew G. Knepley     DMLabel  ctLabel;
2581412e9a14SMatthew G. Knepley     DM_Plex *plex = (DM_Plex *) rdm->data;
2582412e9a14SMatthew G. Knepley 
2583412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellTypeLabel(rdm, &ctLabel);CHKERRQ(ierr);
2584412e9a14SMatthew G. Knepley     ierr = PetscObjectStateGet((PetscObject) ctLabel, &plex->celltypeState);CHKERRQ(ierr);
2585412e9a14SMatthew G. Knepley   }
2586412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2587412e9a14SMatthew G. Knepley }
2588412e9a14SMatthew G. Knepley 
2589412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCones(DMPlexCellRefiner cr, DM rdm)
2590412e9a14SMatthew G. Knepley {
2591412e9a14SMatthew G. Knepley   DM             dm = cr->dm;
2592412e9a14SMatthew G. Knepley   DMPolytopeType ct;
2593412e9a14SMatthew G. Knepley   PetscInt      *coneNew, *orntNew;
2594412e9a14SMatthew G. Knepley   PetscInt       maxConeSize = 0, pStart, pEnd, p, pNew;
2595412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2596412e9a14SMatthew G. Knepley 
2597412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2598412e9a14SMatthew G. Knepley   for (p = 0; p < DM_NUM_POLYTOPES; ++p) maxConeSize = PetscMax(maxConeSize, DMPolytopeTypeGetConeSize((DMPolytopeType) p));
2599412e9a14SMatthew G. Knepley   ierr = PetscMalloc2(maxConeSize, &coneNew, maxConeSize, &orntNew);CHKERRQ(ierr);
2600412e9a14SMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
2601412e9a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2602412e9a14SMatthew G. Knepley     const PetscInt *cone, *ornt;
2603412e9a14SMatthew G. Knepley     PetscInt        coff, ooff, c;
2604412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2605412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2606412e9a14SMatthew G. Knepley     PetscInt        Nct, n, r;
2607412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2608412e9a14SMatthew G. Knepley     ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr);
2609412e9a14SMatthew G. Knepley     ierr = DMPlexGetConeOrientation(dm, p, &ornt);CHKERRQ(ierr);
2610412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2611412e9a14SMatthew G. Knepley     for (n = 0, coff = 0, ooff = 0; n < Nct; ++n) {
2612412e9a14SMatthew G. Knepley       const DMPolytopeType ctNew    = rct[n];
2613412e9a14SMatthew G. Knepley       const PetscInt       csizeNew = DMPolytopeTypeGetConeSize(ctNew);
2614412e9a14SMatthew G. Knepley 
2615412e9a14SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r) {
2616412e9a14SMatthew G. Knepley         /* pNew is a subcell produced by subdividing p */
2617412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr);
2618412e9a14SMatthew G. Knepley         for (c = 0; c < csizeNew; ++c) {
2619412e9a14SMatthew G. Knepley           PetscInt             ppp   = -1;                             /* Parent Parent point: Parent of point pp */
2620412e9a14SMatthew G. Knepley           PetscInt             pp    = p;                              /* Parent point: Point in the original mesh producing new cone point */
2621412e9a14SMatthew G. Knepley           PetscInt             po    = 0;                              /* Orientation of parent point pp in parent parent point ppp */
2622412e9a14SMatthew G. Knepley           DMPolytopeType       pct   = ct;                             /* Parent type: Cell type for parent of new cone point */
2623412e9a14SMatthew G. Knepley           const PetscInt      *pcone = cone;                           /* Parent cone: Cone of parent point pp */
2624412e9a14SMatthew G. Knepley           PetscInt             pr    = -1;                             /* Replica number of pp that produces new cone point  */
2625412e9a14SMatthew G. Knepley           const DMPolytopeType ft    = (DMPolytopeType) rcone[coff++]; /* Cell type for new cone point of pNew */
2626412e9a14SMatthew G. Knepley           const PetscInt       fn    = rcone[coff++];                  /* Number of cones of p that need to be taken when producing new cone point */
2627412e9a14SMatthew G. Knepley           PetscInt             fo    = rornt[ooff++];                  /* Orientation of new cone point in pNew */
2628412e9a14SMatthew G. Knepley           PetscInt             lc;
2629412e9a14SMatthew G. Knepley 
2630412e9a14SMatthew G. Knepley           /* Get the type (pct) and point number (pp) of the parent point in the original mesh which produces this cone point */
2631412e9a14SMatthew G. Knepley           for (lc = 0; lc < fn; ++lc) {
2632412e9a14SMatthew G. Knepley             const PetscInt *ppornt;
2633412e9a14SMatthew G. Knepley             PetscInt        pcp;
2634412e9a14SMatthew G. Knepley 
2635412e9a14SMatthew G. Knepley             ierr = DMPolytopeMapCell(pct, po, rcone[coff++], &pcp);CHKERRQ(ierr);
2636412e9a14SMatthew G. Knepley             ppp  = pp;
2637412e9a14SMatthew G. Knepley             pp   = pcone[pcp];
2638412e9a14SMatthew G. Knepley             ierr = DMPlexGetCellType(dm, pp, &pct);CHKERRQ(ierr);
2639412e9a14SMatthew G. Knepley             ierr = DMPlexGetCone(dm, pp, &pcone);CHKERRQ(ierr);
2640412e9a14SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, ppp, &ppornt);CHKERRQ(ierr);
2641cf4091a3SMatthew G. Knepley             if (po <  0 && pct != DM_POLYTOPE_POINT) {
2642cf4091a3SMatthew G. Knepley               const PetscInt pornt   = ppornt[pcp];
2643cf4091a3SMatthew G. Knepley               const PetscInt pcsize  = DMPolytopeTypeGetConeSize(pct);
2644cf4091a3SMatthew G. Knepley               const PetscInt pcstart = pornt < 0 ? -(pornt+1) : pornt;
2645cf4091a3SMatthew G. Knepley               const PetscInt rcstart = (pcstart+pcsize-1)%pcsize;
2646cf4091a3SMatthew G. Knepley               po = pornt < 0 ? -(rcstart+1) : rcstart;
2647cf4091a3SMatthew G. Knepley             } else {
2648412e9a14SMatthew G. Knepley               po = ppornt[pcp];
2649412e9a14SMatthew G. Knepley             }
2650cf4091a3SMatthew G. Knepley           }
2651412e9a14SMatthew G. Knepley           pr = rcone[coff++];
2652412e9a14SMatthew G. Knepley           /* Orientation po of pp maps (pr, fo) -> (pr', fo') */
2653412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerMapSubcells(cr, pct, po, ft, pr, fo, &pr, &fo);CHKERRQ(ierr);
2654412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerGetNewPoint(cr, pct, ft, pp, pr, &coneNew[c]);CHKERRQ(ierr);
2655412e9a14SMatthew G. Knepley           orntNew[c] = fo;
2656412e9a14SMatthew G. Knepley         }
2657412e9a14SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, pNew, coneNew);CHKERRQ(ierr);
2658412e9a14SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, pNew, orntNew);CHKERRQ(ierr);
2659412e9a14SMatthew G. Knepley       }
2660412e9a14SMatthew G. Knepley     }
2661412e9a14SMatthew G. Knepley   }
2662412e9a14SMatthew G. Knepley   ierr = PetscFree2(coneNew, orntNew);CHKERRQ(ierr);
2663412e9a14SMatthew G. Knepley   ierr = DMPlexSymmetrize(rdm);CHKERRQ(ierr);
2664412e9a14SMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
2665412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2666412e9a14SMatthew G. Knepley }
2667412e9a14SMatthew G. Knepley 
2668412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCoordinateFE(DMPlexCellRefiner cr, DMPolytopeType ct, PetscFE *fe)
2669412e9a14SMatthew G. Knepley {
2670412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2671412e9a14SMatthew G. Knepley 
2672412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2673412e9a14SMatthew G. Knepley   if (!cr->coordFE[ct]) {
2674412e9a14SMatthew G. Knepley     PetscInt  dim, cdim;
2675412e9a14SMatthew G. Knepley     PetscBool isSimplex;
2676412e9a14SMatthew G. Knepley 
2677412e9a14SMatthew G. Knepley     switch (ct) {
2678412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEGMENT:       dim = 1; isSimplex = PETSC_TRUE;  break;
2679412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRIANGLE:      dim = 2; isSimplex = PETSC_TRUE;  break;
2680412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUADRILATERAL: dim = 2; isSimplex = PETSC_FALSE; break;
2681412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TETRAHEDRON:   dim = 3; isSimplex = PETSC_TRUE;  break;
2682412e9a14SMatthew G. Knepley       case DM_POLYTOPE_HEXAHEDRON:    dim = 3; isSimplex = PETSC_FALSE; break;
2683412e9a14SMatthew G. Knepley       default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No coordinate FE for cell type %s", DMPolytopeTypes[ct]);
2684412e9a14SMatthew G. Knepley     }
2685412e9a14SMatthew G. Knepley     ierr = DMGetCoordinateDim(cr->dm, &cdim);CHKERRQ(ierr);
2686412e9a14SMatthew G. Knepley     ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, cdim, isSimplex, 1, PETSC_DETERMINE, &cr->coordFE[ct]);CHKERRQ(ierr);
2687412e9a14SMatthew G. Knepley     {
2688412e9a14SMatthew G. Knepley       PetscDualSpace  dsp;
2689412e9a14SMatthew G. Knepley       PetscQuadrature quad;
2690412e9a14SMatthew G. Knepley       DM              K;
2691412e9a14SMatthew G. Knepley       PetscFEGeom    *cg;
2692412e9a14SMatthew G. Knepley       PetscReal      *Xq, *xq, *wq;
2693412e9a14SMatthew G. Knepley       PetscInt        Nq, q;
2694412e9a14SMatthew G. Knepley 
2695412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerGetCellVertices(cr, ct, &Nq, &Xq);CHKERRQ(ierr);
2696412e9a14SMatthew G. Knepley       ierr = PetscMalloc1(Nq*cdim, &xq);CHKERRQ(ierr);
2697412e9a14SMatthew G. Knepley       for (q = 0; q < Nq*cdim; ++q) xq[q] = Xq[q];
2698412e9a14SMatthew G. Knepley       ierr = PetscMalloc1(Nq, &wq);CHKERRQ(ierr);
2699412e9a14SMatthew G. Knepley       for (q = 0; q < Nq; ++q) wq[q] = 1.0;
2700412e9a14SMatthew G. Knepley       ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &quad);CHKERRQ(ierr);
2701412e9a14SMatthew G. Knepley       ierr = PetscQuadratureSetData(quad, dim, 1, Nq, xq, wq);CHKERRQ(ierr);
2702412e9a14SMatthew G. Knepley       ierr = PetscFESetQuadrature(cr->coordFE[ct], quad);CHKERRQ(ierr);
2703412e9a14SMatthew G. Knepley 
2704412e9a14SMatthew G. Knepley       ierr = PetscFEGetDualSpace(cr->coordFE[ct], &dsp);CHKERRQ(ierr);
2705412e9a14SMatthew G. Knepley       ierr = PetscDualSpaceGetDM(dsp, &K);CHKERRQ(ierr);
2706412e9a14SMatthew G. Knepley       ierr = PetscFEGeomCreate(quad, 1, cdim, PETSC_FALSE, &cr->refGeom[ct]);CHKERRQ(ierr);
2707412e9a14SMatthew G. Knepley       cg   = cr->refGeom[ct];
2708412e9a14SMatthew G. Knepley       ierr = DMPlexComputeCellGeometryFEM(K, 0, NULL, cg->v, cg->J, cg->invJ, cg->detJ);CHKERRQ(ierr);
2709412e9a14SMatthew G. Knepley       ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr);
2710412e9a14SMatthew G. Knepley     }
2711412e9a14SMatthew G. Knepley   }
2712412e9a14SMatthew G. Knepley   *fe = cr->coordFE[ct];
2713412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2714412e9a14SMatthew G. Knepley }
2715412e9a14SMatthew G. Knepley 
2716412e9a14SMatthew G. Knepley /*
2717412e9a14SMatthew G. Knepley   DMPlexCellRefinerMapLocalizedCoordinates - Given a cell of type ct with localized coordinates x, we generate localized coordinates xr for subcell r of type rct.
2718412e9a14SMatthew G. Knepley 
2719412e9a14SMatthew G. Knepley   Not collective
2720412e9a14SMatthew G. Knepley 
2721412e9a14SMatthew G. Knepley   Input Parameters:
2722412e9a14SMatthew G. Knepley + cr  - The DMPlexCellRefiner
2723412e9a14SMatthew G. Knepley . ct  - The type of the parent cell
2724412e9a14SMatthew G. Knepley . rct - The type of the produced cell
2725412e9a14SMatthew G. Knepley . r   - The index of the produced cell
2726412e9a14SMatthew G. Knepley - x   - The localized coordinates for the parent cell
2727412e9a14SMatthew G. Knepley 
2728412e9a14SMatthew G. Knepley   Output Parameter:
2729412e9a14SMatthew G. Knepley . xr  - The localized coordinates for the produced cell
2730412e9a14SMatthew G. Knepley 
2731412e9a14SMatthew G. Knepley   Level: developer
2732412e9a14SMatthew G. Knepley 
2733412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerSetCoordinates()
2734412e9a14SMatthew G. Knepley */
2735412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapLocalizedCoordinates(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, const PetscScalar x[], PetscScalar xr[])
2736412e9a14SMatthew G. Knepley {
2737412e9a14SMatthew G. Knepley   PetscFE        fe = NULL;
2738412e9a14SMatthew G. Knepley   PetscInt       cdim, Nv, v, *subcellV;
2739412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2740412e9a14SMatthew G. Knepley 
2741412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2742412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerGetCoordinateFE(cr, ct, &fe);CHKERRQ(ierr);
2743412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerGetSubcellVertices(cr, ct, rct, r, &Nv, &subcellV);CHKERRQ(ierr);
2744412e9a14SMatthew G. Knepley   ierr = PetscFEGetNumComponents(fe, &cdim);CHKERRQ(ierr);
2745412e9a14SMatthew G. Knepley   for (v = 0; v < Nv; ++v) {
2746412e9a14SMatthew G. Knepley     ierr = PetscFEInterpolate_Static(fe, x, cr->refGeom[ct], subcellV[v], &xr[v*cdim]);CHKERRQ(ierr);
2747412e9a14SMatthew G. Knepley   }
2748412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2749412e9a14SMatthew G. Knepley }
2750412e9a14SMatthew G. Knepley 
2751412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCoordinates(DMPlexCellRefiner cr, DM rdm)
2752412e9a14SMatthew G. Knepley {
2753412e9a14SMatthew G. Knepley   DM                    dm = cr->dm, cdm;
2754412e9a14SMatthew G. Knepley   PetscSection          coordSection, coordSectionNew;
2755412e9a14SMatthew G. Knepley   Vec                   coordsLocal, coordsLocalNew;
2756412e9a14SMatthew G. Knepley   const PetscScalar    *coords;
2757412e9a14SMatthew G. Knepley   PetscScalar          *coordsNew;
2758412e9a14SMatthew G. Knepley   const DMBoundaryType *bd;
2759412e9a14SMatthew G. Knepley   const PetscReal      *maxCell, *L;
2760412e9a14SMatthew G. Knepley   PetscBool             isperiodic, localizeVertices = PETSC_FALSE, localizeCells = PETSC_FALSE;
2761412e9a14SMatthew G. Knepley   PetscInt              dE, d, cStart, cEnd, c, vStartNew, vEndNew, v, pStart, pEnd, p, ocStart, ocEnd;
2762412e9a14SMatthew G. Knepley   PetscErrorCode        ierr;
2763412e9a14SMatthew G. Knepley 
2764412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2765412e9a14SMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
276690b157c4SStefano Zampini   ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr);
276790b157c4SStefano Zampini   /* Determine if we need to localize coordinates when generating them */
2768b9ccc978SStefano Zampini   if (isperiodic) {
2769412e9a14SMatthew G. Knepley     localizeVertices = PETSC_TRUE;
2770412e9a14SMatthew G. Knepley     if (!maxCell) {
2771412e9a14SMatthew G. Knepley       PetscBool localized;
2772412e9a14SMatthew G. Knepley       ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
2773412e9a14SMatthew G. Knepley       if (!localized) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Cannot refine a periodic mesh if coordinates have not been localized");
2774412e9a14SMatthew G. Knepley       localizeCells = PETSC_TRUE;
2775b9ccc978SStefano Zampini     }
2776b9ccc978SStefano Zampini   }
2777b9ccc978SStefano Zampini 
2778b9ccc978SStefano Zampini   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
2779412e9a14SMatthew G. Knepley   ierr = PetscSectionGetFieldComponents(coordSection, 0, &dE);CHKERRQ(ierr);
2780412e9a14SMatthew G. Knepley   if (maxCell) {
2781412e9a14SMatthew G. Knepley     PetscReal maxCellNew[3];
2782412e9a14SMatthew G. Knepley 
2783412e9a14SMatthew G. Knepley     for (d = 0; d < dE; ++d) maxCellNew[d] = maxCell[d]/2.0;
2784412e9a14SMatthew G. Knepley     ierr = DMSetPeriodicity(rdm, isperiodic, maxCellNew, L, bd);CHKERRQ(ierr);
2785412e9a14SMatthew G. Knepley   } else {
2786412e9a14SMatthew G. Knepley     ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr);
2787412e9a14SMatthew G. Knepley   }
2788b9ccc978SStefano Zampini   ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &coordSectionNew);CHKERRQ(ierr);
2789b9ccc978SStefano Zampini   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
2790412e9a14SMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dE);CHKERRQ(ierr);
2791412e9a14SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(rdm, 0, &vStartNew, &vEndNew);CHKERRQ(ierr);
2792412e9a14SMatthew G. Knepley   if (localizeCells) {ierr = PetscSectionSetChart(coordSectionNew, 0,         vEndNew);CHKERRQ(ierr);}
2793412e9a14SMatthew G. Knepley   else               {ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vEndNew);CHKERRQ(ierr);}
2794b9ccc978SStefano Zampini 
2795412e9a14SMatthew G. Knepley   /* Localization should be inherited */
2796412e9a14SMatthew G. Knepley   /*   Stefano calculates parent cells for each new cell for localization */
2797412e9a14SMatthew G. Knepley   /*   Localized cells need coordinates of closure */
2798412e9a14SMatthew G. Knepley   for (v = vStartNew; v < vEndNew; ++v) {
2799412e9a14SMatthew G. Knepley     ierr = PetscSectionSetDof(coordSectionNew, v, dE);CHKERRQ(ierr);
2800412e9a14SMatthew G. Knepley     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dE);CHKERRQ(ierr);
2801412e9a14SMatthew G. Knepley   }
2802412e9a14SMatthew G. Knepley   if (localizeCells) {
2803412e9a14SMatthew G. Knepley     ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
2804412e9a14SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2805412e9a14SMatthew G. Knepley       PetscInt dof;
280690b157c4SStefano Zampini 
2807412e9a14SMatthew G. Knepley       ierr = PetscSectionGetDof(coordSection, c, &dof);CHKERRQ(ierr);
2808412e9a14SMatthew G. Knepley       if (dof) {
2809412e9a14SMatthew G. Knepley         DMPolytopeType  ct;
2810412e9a14SMatthew G. Knepley         DMPolytopeType *rct;
2811412e9a14SMatthew G. Knepley         PetscInt       *rsize, *rcone, *rornt;
2812412e9a14SMatthew G. Knepley         PetscInt        dim, cNew, Nct, n, r;
281390b157c4SStefano Zampini 
2814412e9a14SMatthew G. Knepley         ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr);
2815412e9a14SMatthew G. Knepley         dim  = DMPolytopeTypeGetDim(ct);
2816412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2817412e9a14SMatthew G. Knepley         /* This allows for different cell types */
2818412e9a14SMatthew G. Knepley         for (n = 0; n < Nct; ++n) {
2819412e9a14SMatthew G. Knepley           if (dim != DMPolytopeTypeGetDim(rct[n])) continue;
2820412e9a14SMatthew G. Knepley           for (r = 0; r < rsize[n]; ++r) {
2821412e9a14SMatthew G. Knepley             PetscInt *closure = NULL;
2822412e9a14SMatthew G. Knepley             PetscInt  clSize, cl, Nv = 0;
282390b157c4SStefano Zampini 
2824412e9a14SMatthew G. Knepley             ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], c, r, &cNew);CHKERRQ(ierr);
2825412e9a14SMatthew G. Knepley             ierr = DMPlexGetTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr);
2826412e9a14SMatthew G. Knepley             for (cl = 0; cl < clSize*2; cl += 2) {if ((closure[cl] >= vStartNew) && (closure[cl] < vEndNew)) ++Nv;}
2827412e9a14SMatthew G. Knepley             ierr = DMPlexRestoreTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr);
2828412e9a14SMatthew G. Knepley             ierr = PetscSectionSetDof(coordSectionNew, cNew, Nv * dE);CHKERRQ(ierr);
2829412e9a14SMatthew G. Knepley             ierr = PetscSectionSetFieldDof(coordSectionNew, cNew, 0, Nv * dE);CHKERRQ(ierr);
28309fc2a3f3SStefano Zampini           }
283190b157c4SStefano Zampini         }
283290b157c4SStefano Zampini       }
2833412e9a14SMatthew G. Knepley     }
283475d3a19aSMatthew G. Knepley   }
283575d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
2836412e9a14SMatthew G. Knepley   ierr = DMViewFromOptions(dm, NULL, "-coarse_dm_view");CHKERRQ(ierr);
283746e270d4SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr);
2838412e9a14SMatthew G. Knepley   {
2839412e9a14SMatthew G. Knepley     VecType     vtype;
2840412e9a14SMatthew G. Knepley     PetscInt    coordSizeNew, bs;
2841412e9a14SMatthew G. Knepley     const char *name;
2842412e9a14SMatthew G. Knepley 
2843412e9a14SMatthew G. Knepley     ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr);
2844412e9a14SMatthew G. Knepley     ierr = VecCreate(PETSC_COMM_SELF, &coordsLocalNew);CHKERRQ(ierr);
284575d3a19aSMatthew G. Knepley     ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
2846412e9a14SMatthew G. Knepley     ierr = VecSetSizes(coordsLocalNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
2847412e9a14SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) coordsLocal, &name);CHKERRQ(ierr);
2848412e9a14SMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) coordsLocalNew, name);CHKERRQ(ierr);
2849412e9a14SMatthew G. Knepley     ierr = VecGetBlockSize(coordsLocal, &bs);CHKERRQ(ierr);
2850412e9a14SMatthew G. Knepley     ierr = VecSetBlockSize(coordsLocalNew, bs);CHKERRQ(ierr);
2851412e9a14SMatthew G. Knepley     ierr = VecGetType(coordsLocal, &vtype);CHKERRQ(ierr);
2852412e9a14SMatthew G. Knepley     ierr = VecSetType(coordsLocalNew, vtype);CHKERRQ(ierr);
2853b5da9499SMatthew G. Knepley   }
2854412e9a14SMatthew G. Knepley   ierr = VecGetArrayRead(coordsLocal, &coords);CHKERRQ(ierr);
2855412e9a14SMatthew G. Knepley   ierr = VecGetArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr);
2856412e9a14SMatthew G. Knepley   ierr = PetscSectionGetChart(coordSection, &ocStart, &ocEnd);CHKERRQ(ierr);
2857412e9a14SMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
2858412e9a14SMatthew G. Knepley   /* First set coordinates for vertices*/
2859412e9a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2860412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
2861412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2862412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2863412e9a14SMatthew G. Knepley     PetscInt        Nct, n, r;
2864412e9a14SMatthew G. Knepley     PetscBool       hasVertex = PETSC_FALSE, isLocalized = PETSC_FALSE;
286590b157c4SStefano Zampini 
2866412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2867412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2868412e9a14SMatthew G. Knepley     for (n = 0; n < Nct; ++n) {
2869412e9a14SMatthew G. Knepley       if (rct[n] == DM_POLYTOPE_POINT) {hasVertex = PETSC_TRUE; break;}
2870412e9a14SMatthew G. Knepley     }
2871412e9a14SMatthew G. Knepley     if (localizeVertices && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) {
2872412e9a14SMatthew G. Knepley       PetscInt dof;
2873412e9a14SMatthew G. Knepley       ierr = PetscSectionGetDof(coordSection, p, &dof);CHKERRQ(ierr);
2874412e9a14SMatthew G. Knepley       if (dof) isLocalized = PETSC_TRUE;
2875412e9a14SMatthew G. Knepley     }
2876412e9a14SMatthew G. Knepley     if (hasVertex) {
2877a5801f52SStefano Zampini       const PetscScalar *icoords = NULL;
2878412e9a14SMatthew G. Knepley       PetscScalar       *pcoords = NULL;
2879412e9a14SMatthew G. Knepley       PetscInt          Nc, Nv, v, d;
288090b157c4SStefano Zampini 
2881412e9a14SMatthew G. Knepley       ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr);
2882a5801f52SStefano Zampini 
2883a5801f52SStefano Zampini       icoords = pcoords;
2884a5801f52SStefano Zampini       Nv      = Nc/dE;
2885a5801f52SStefano Zampini       if (ct != DM_POLYTOPE_POINT) {
2886412e9a14SMatthew G. Knepley         if (localizeVertices) {
2887412e9a14SMatthew G. Knepley           PetscScalar anchor[3];
288890b157c4SStefano Zampini 
2889412e9a14SMatthew G. Knepley           for (d = 0; d < dE; ++d) anchor[d] = pcoords[d];
2890412e9a14SMatthew G. Knepley           if (!isLocalized) {
2891a5801f52SStefano Zampini             for (v = 0; v < Nv; ++v) {ierr = DMLocalizeCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], &pcoords[v*dE]);CHKERRQ(ierr);}
2892412e9a14SMatthew G. Knepley           } else {
2893412e9a14SMatthew G. Knepley             Nv = Nc/(2*dE);
2894a5801f52SStefano Zampini             icoords = pcoords + Nv*dE;
2895a5801f52SStefano Zampini             for (v = Nv; v < Nv*2; ++v) {ierr = DMLocalizeCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], &pcoords[v*dE]);CHKERRQ(ierr);}
289690b157c4SStefano Zampini           }
2897b5da9499SMatthew G. Knepley         }
289890b157c4SStefano Zampini       }
2899412e9a14SMatthew G. Knepley       for (n = 0; n < Nct; ++n) {
2900412e9a14SMatthew G. Knepley         if (rct[n] != DM_POLYTOPE_POINT) continue;
2901412e9a14SMatthew G. Knepley         for (r = 0; r < rsize[n]; ++r) {
2902a5801f52SStefano Zampini           PetscScalar vcoords[3];
2903412e9a14SMatthew G. Knepley           PetscInt    vNew, off;
2904b5da9499SMatthew G. Knepley 
2905412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &vNew);CHKERRQ(ierr);
2906412e9a14SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSectionNew, vNew, &off);CHKERRQ(ierr);
2907a5801f52SStefano Zampini           ierr = DMPlexCellRefinerMapCoordinates(cr, ct, rct[n], r, Nv, dE, icoords, vcoords);CHKERRQ(ierr);
2908eac51794SMatthew G. Knepley           ierr = DMPlexSnapToGeomModel(dm, p, vcoords, &coordsNew[off]);CHKERRQ(ierr);
2909b5da9499SMatthew G. Knepley         }
29109fc2a3f3SStefano Zampini       }
2911a5801f52SStefano Zampini       ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr);
2912412e9a14SMatthew G. Knepley     }
2913412e9a14SMatthew G. Knepley   }
2914412e9a14SMatthew G. Knepley   /* Then set coordinates for cells by localizing */
2915412e9a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2916412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
2917412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2918412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2919412e9a14SMatthew G. Knepley     PetscInt        Nct, n, r;
2920412e9a14SMatthew G. Knepley     PetscBool       isLocalized = PETSC_FALSE;
292190b157c4SStefano Zampini 
2922412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2923412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2924412e9a14SMatthew G. Knepley     if (localizeCells && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) {
2925412e9a14SMatthew G. Knepley       PetscInt dof;
2926412e9a14SMatthew G. Knepley       ierr = PetscSectionGetDof(coordSection, p, &dof);CHKERRQ(ierr);
2927412e9a14SMatthew G. Knepley       if (dof) isLocalized = PETSC_TRUE;
2928b5da9499SMatthew G. Knepley     }
2929412e9a14SMatthew G. Knepley     if (isLocalized) {
2930412e9a14SMatthew G. Knepley       const PetscScalar *pcoords;
29319fc2a3f3SStefano Zampini 
2932412e9a14SMatthew G. Knepley       ierr = DMPlexPointLocalRead(cdm, p, coords, &pcoords);CHKERRQ(ierr);
2933412e9a14SMatthew G. Knepley       for (n = 0; n < Nct; ++n) {
2934412e9a14SMatthew G. Knepley         const PetscInt Nr = rsize[n];
293590b157c4SStefano Zampini 
2936412e9a14SMatthew G. Knepley         if (DMPolytopeTypeGetDim(ct) != DMPolytopeTypeGetDim(rct[n])) continue;
2937412e9a14SMatthew G. Knepley         for (r = 0; r < Nr; ++r) {
2938412e9a14SMatthew G. Knepley           PetscInt pNew, offNew;
293990b157c4SStefano Zampini 
2940412e9a14SMatthew G. Knepley           /* It looks like Stefano and Lisandro are allowing localized coordinates without defining the periodic boundary, which means that
2941412e9a14SMatthew G. Knepley              DMLocalizeCoordinate_Internal() will not work. Localized coordinates will have to have obtained by the affine map of the larger
2942412e9a14SMatthew G. Knepley              cell to the ones it produces. */
2943412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr);
2944412e9a14SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSectionNew, pNew, &offNew);CHKERRQ(ierr);
2945412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerMapLocalizedCoordinates(cr, ct, rct[n], r, pcoords, &coordsNew[offNew]);CHKERRQ(ierr);
294690b157c4SStefano Zampini         }
294790b157c4SStefano Zampini       }
294890b157c4SStefano Zampini     }
294990b157c4SStefano Zampini   }
2950412e9a14SMatthew G. Knepley   ierr = VecRestoreArrayRead(coordsLocal, &coords);CHKERRQ(ierr);
2951412e9a14SMatthew G. Knepley   ierr = VecRestoreArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr);
2952412e9a14SMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordsLocalNew);CHKERRQ(ierr);
2953412e9a14SMatthew G. Knepley   /* TODO Stefano has a final reduction if some hybrid coordinates cannot be found. (needcoords) Should not be needed. */
2954412e9a14SMatthew G. Knepley   ierr = VecDestroy(&coordsLocalNew);CHKERRQ(ierr);
295575d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
2956412e9a14SMatthew G. Knepley   if (!localizeCells) {ierr = DMLocalizeCoordinates(rdm);CHKERRQ(ierr);}
295775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
295875d3a19aSMatthew G. Knepley }
295975d3a19aSMatthew G. Knepley 
2960963fc26aSMatthew G. Knepley /*@
2961963fc26aSMatthew G. Knepley   DMPlexCreateProcessSF - Create an SF which just has process connectivity
2962963fc26aSMatthew G. Knepley 
2963d083f849SBarry Smith   Collective on dm
2964963fc26aSMatthew G. Knepley 
2965963fc26aSMatthew G. Knepley   Input Parameters:
2966963fc26aSMatthew G. Knepley + dm      - The DM
2967963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity
2968963fc26aSMatthew G. Knepley 
2969963fc26aSMatthew G. Knepley   Output Parameters:
2970963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL
2971963fc26aSMatthew G. Knepley - sfProcess    - An SF encoding the process connectivity, or NULL
2972963fc26aSMatthew G. Knepley 
2973963fc26aSMatthew G. Knepley   Level: developer
2974963fc26aSMatthew G. Knepley 
2975963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF()
2976963fc26aSMatthew G. Knepley @*/
2977963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
297875d3a19aSMatthew G. Knepley {
297975d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
298075d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
298175d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
298275d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
298375d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
298475d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
29859852e123SBarry Smith   PetscMPIInt        size;
298675d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
298775d3a19aSMatthew G. Knepley 
298875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
2989963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2990963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2);
2991963fc26aSMatthew G. Knepley   if (processRanks) {PetscValidPointer(processRanks, 3);}
2992963fc26aSMatthew G. Knepley   if (sfProcess)    {PetscValidPointer(sfProcess, 4);}
29939852e123SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr);
299475d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
2995785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
299675d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
299775d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
299875d3a19aSMatthew G. Knepley   }
299975d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
3000785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr);
3001785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr);
3002785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
300375d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
300475d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
300575d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
300675d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
300775d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
300875d3a19aSMatthew G. Knepley   }
300975d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
3010963fc26aSMatthew G. Knepley   if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);}
3011963fc26aSMatthew G. Knepley   else              {ierr = PetscFree(ranksNew);CHKERRQ(ierr);}
3012963fc26aSMatthew G. Knepley   if (sfProcess) {
301375d3a19aSMatthew G. Knepley     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
3014963fc26aSMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr);
301575d3a19aSMatthew G. Knepley     ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
30169852e123SBarry Smith     ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
3017963fc26aSMatthew G. Knepley   }
301875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
301975d3a19aSMatthew G. Knepley }
302075d3a19aSMatthew G. Knepley 
3021412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateSF(DMPlexCellRefiner cr, DM rdm)
302275d3a19aSMatthew G. Knepley {
3023412e9a14SMatthew G. Knepley   DM                 dm = cr->dm;
3024412e9a14SMatthew G. Knepley   DMPlexCellRefiner *crRem;
302575d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
302675d3a19aSMatthew G. Knepley   IS                 processRanks;
3027412e9a14SMatthew G. Knepley   MPI_Datatype       ctType;
302875d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
302975d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
303075d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
303175d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
303275d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
3033412e9a14SMatthew G. Knepley   PetscInt          *ctStartRem, *ctStartNewRem;
3034412e9a14SMatthew G. Knepley   PetscInt           ctSize = DM_NUM_POLYTOPES+1, numNeighbors, n, pStartNew, pEndNew, pNew, pNewRem;
303575d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
303675d3a19aSMatthew G. Knepley 
303775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
303875d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
303975d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
304075d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
3041add09238SMatthew G. Knepley   /* Calculate size of new SF */
304275d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
304375d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
304475d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
304575d3a19aSMatthew G. Knepley     const PetscInt  p = localPoints[l];
3046412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
3047412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
3048412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
3049412e9a14SMatthew G. Knepley     PetscInt        Nct, n;
305075d3a19aSMatthew G. Knepley 
3051412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
3052412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
3053412e9a14SMatthew G. Knepley     for (n = 0; n < Nct; ++n) numLeavesNew += rsize[n];
30540314a74cSLawrence Mitchell   }
3055412e9a14SMatthew G. Knepley   /* Communicate ctStart and cStartNew for each remote rank */
305675d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
305775d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
3058412e9a14SMatthew G. Knepley   ierr = PetscMalloc2(ctSize*numNeighbors, &ctStartRem, ctSize*numNeighbors, &ctStartNewRem);CHKERRQ(ierr);
3059412e9a14SMatthew G. Knepley   ierr = MPI_Type_contiguous(ctSize, MPIU_INT, &ctType);CHKERRQ(ierr);
3060412e9a14SMatthew G. Knepley   ierr = MPI_Type_commit(&ctType);CHKERRQ(ierr);
3061412e9a14SMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr);
3062412e9a14SMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr);
3063412e9a14SMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr);
3064412e9a14SMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr);
3065412e9a14SMatthew G. Knepley   ierr = MPI_Type_free(&ctType);CHKERRQ(ierr);
306675d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
3067412e9a14SMatthew G. Knepley   ierr = PetscMalloc1(numNeighbors, &crRem);CHKERRQ(ierr);
3068412e9a14SMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
3069412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerCreate(dm, &crRem[n]);CHKERRQ(ierr);
3070412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerSetStarts(crRem[n], &ctStartRem[n*ctSize], &ctStartNewRem[n*ctSize]);
3071412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerSetUp(crRem[n]);CHKERRQ(ierr);
3072412e9a14SMatthew G. Knepley   }
3073412e9a14SMatthew G. Knepley   ierr = PetscFree2(ctStartRem, ctStartNewRem);CHKERRQ(ierr);
307475d3a19aSMatthew G. Knepley   /* Calculate new point SF */
3075785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr);
3076785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
307775d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
307875d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
307975d3a19aSMatthew G. Knepley     PetscInt        p       = localPoints[l];
3080412e9a14SMatthew G. Knepley     PetscInt        pRem    = remotePoints[l].index;
3081412e9a14SMatthew G. Knepley     PetscMPIInt     rankRem = remotePoints[l].rank;
3082412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
3083412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
3084412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
3085412e9a14SMatthew G. Knepley     PetscInt        neighbor, Nct, n, r;
308675d3a19aSMatthew G. Knepley 
3087412e9a14SMatthew G. Knepley     ierr = PetscFindInt(rankRem, numNeighbors, neighbors, &neighbor);CHKERRQ(ierr);
3088412e9a14SMatthew G. Knepley     if (neighbor < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rankRem);
3089412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
3090412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
3091412e9a14SMatthew G. Knepley     for (n = 0; n < Nct; ++n) {
3092412e9a14SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r) {
3093412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr);
3094412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerGetNewPoint(crRem[neighbor], ct, rct[n], pRem, r, &pNewRem);CHKERRQ(ierr);
3095412e9a14SMatthew G. Knepley         localPointsNew[m]        = pNew;
3096412e9a14SMatthew G. Knepley         remotePointsNew[m].index = pNewRem;
3097412e9a14SMatthew G. Knepley         remotePointsNew[m].rank  = rankRem;
30980314a74cSLawrence Mitchell         ++m;
30990314a74cSLawrence Mitchell       }
31006ce3c06aSMatthew G. Knepley     }
31016ce3c06aSMatthew G. Knepley   }
3102412e9a14SMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {ierr = DMPlexCellRefinerDestroy(&crRem[n]);CHKERRQ(ierr);}
3103412e9a14SMatthew G. Knepley   ierr = PetscFree(crRem);CHKERRQ(ierr);
3104d7eabd03SStefano Zampini   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew);
310575d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
310675d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
3107ba3c3d50SMatthew G. Knepley   {
3108ba3c3d50SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
3109ba3c3d50SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
3110ba3c3d50SMatthew G. Knepley 
3111ba3c3d50SMatthew G. Knepley     /* SF needs sorted leaves to correct calculate Gather */
3112ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &idx);CHKERRQ(ierr);
3113ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr);
3114ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr);
3115c7c54c77SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
3116d7eabd03SStefano 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);
3117c7c54c77SMatthew G. Knepley       idx[i] = i;
3118c7c54c77SMatthew G. Knepley     }
3119ba3c3d50SMatthew G. Knepley     ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr);
3120ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
3121ba3c3d50SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
3122ba3c3d50SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
3123ba3c3d50SMatthew G. Knepley     }
3124ba3c3d50SMatthew G. Knepley     ltmp            = localPointsNew;
3125ba3c3d50SMatthew G. Knepley     localPointsNew  = lp;
3126ba3c3d50SMatthew G. Knepley     rtmp            = remotePointsNew;
3127ba3c3d50SMatthew G. Knepley     remotePointsNew = rp;
3128ba3c3d50SMatthew G. Knepley     ierr = PetscFree(idx);CHKERRQ(ierr);
3129ba3c3d50SMatthew G. Knepley     ierr = PetscFree(ltmp);CHKERRQ(ierr);
3130ba3c3d50SMatthew G. Knepley     ierr = PetscFree(rtmp);CHKERRQ(ierr);
3131ba3c3d50SMatthew G. Knepley   }
313275d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
313375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
313475d3a19aSMatthew G. Knepley }
313575d3a19aSMatthew G. Knepley 
3136e7887635SMatthew G. Knepley static PetscErrorCode RefineLabel_Internal(DMPlexCellRefiner cr, DMLabel label, DMLabel labelNew)
313775d3a19aSMatthew G. Knepley {
3138412e9a14SMatthew G. Knepley   DM              dm = cr->dm;
3139e7887635SMatthew G. Knepley   IS              valueIS;
3140e7887635SMatthew G. Knepley   const PetscInt *values;
3141e7887635SMatthew G. Knepley   PetscInt        defVal, Nv, val;
314275d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
314375d3a19aSMatthew G. Knepley 
314475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
31455aa44df4SToby Isaac   ierr = DMLabelGetDefaultValue(label, &defVal);CHKERRQ(ierr);
31465aa44df4SToby Isaac   ierr = DMLabelSetDefaultValue(labelNew, defVal);CHKERRQ(ierr);
314775d3a19aSMatthew G. Knepley   ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
3148e7887635SMatthew G. Knepley   ierr = ISGetLocalSize(valueIS, &Nv);CHKERRQ(ierr);
314975d3a19aSMatthew G. Knepley   ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
3150e7887635SMatthew G. Knepley   for (val = 0; val < Nv; ++val) {
315175d3a19aSMatthew G. Knepley     IS              pointIS;
315275d3a19aSMatthew G. Knepley     const PetscInt *points;
3153412e9a14SMatthew G. Knepley     PetscInt        numPoints, p;
315475d3a19aSMatthew G. Knepley 
31552bc5314cSMichael Lange     /* Ensure refined label is created with same number of strata as
31562bc5314cSMichael Lange      * original (even if no entries here). */
3157ad8374ffSToby Isaac     ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr);
3158412e9a14SMatthew G. Knepley     ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
3159412e9a14SMatthew G. Knepley     ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
3160412e9a14SMatthew G. Knepley     ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
3161412e9a14SMatthew G. Knepley     for (p = 0; p < numPoints; ++p) {
3162412e9a14SMatthew G. Knepley       const PetscInt  point = points[p];
3163412e9a14SMatthew G. Knepley       DMPolytopeType  ct;
3164412e9a14SMatthew G. Knepley       DMPolytopeType *rct;
3165412e9a14SMatthew G. Knepley       PetscInt       *rsize, *rcone, *rornt;
3166e7887635SMatthew G. Knepley       PetscInt        Nct, n, r, pNew;
3167412e9a14SMatthew G. Knepley 
3168412e9a14SMatthew G. Knepley       ierr = DMPlexGetCellType(dm, point, &ct);CHKERRQ(ierr);
3169412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
3170412e9a14SMatthew G. Knepley       for (n = 0; n < Nct; ++n) {
3171412e9a14SMatthew G. Knepley         for (r = 0; r < rsize[n]; ++r) {
3172412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], point, r, &pNew);CHKERRQ(ierr);
3173412e9a14SMatthew G. Knepley           ierr = DMLabelSetValue(labelNew, pNew, values[val]);CHKERRQ(ierr);
317427fcede3SMatthew G. Knepley         }
317575d3a19aSMatthew G. Knepley       }
317675d3a19aSMatthew G. Knepley     }
317775d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
317875d3a19aSMatthew G. Knepley     ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
317975d3a19aSMatthew G. Knepley   }
318075d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
318175d3a19aSMatthew G. Knepley   ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
3182e7887635SMatthew G. Knepley   PetscFunctionReturn(0);
3183e7887635SMatthew G. Knepley }
3184e7887635SMatthew G. Knepley 
3185e7887635SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateLabels(DMPlexCellRefiner cr, DM rdm)
3186e7887635SMatthew G. Knepley {
3187e7887635SMatthew G. Knepley   DM             dm = cr->dm;
3188e7887635SMatthew G. Knepley   PetscInt       numLabels, l;
3189e7887635SMatthew G. Knepley   PetscErrorCode ierr;
3190e7887635SMatthew G. Knepley 
3191e7887635SMatthew G. Knepley   PetscFunctionBegin;
3192e7887635SMatthew G. Knepley   ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
3193e7887635SMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
3194e7887635SMatthew G. Knepley     DMLabel         label, labelNew;
3195e7887635SMatthew G. Knepley     const char     *lname;
3196e7887635SMatthew G. Knepley     PetscBool       isDepth, isCellType;
3197e7887635SMatthew G. Knepley 
3198e7887635SMatthew G. Knepley     ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr);
3199e7887635SMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
3200e7887635SMatthew G. Knepley     if (isDepth) continue;
3201e7887635SMatthew G. Knepley     ierr = PetscStrcmp(lname, "celltype", &isCellType);CHKERRQ(ierr);
3202e7887635SMatthew G. Knepley     if (isCellType) continue;
3203e7887635SMatthew G. Knepley     ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr);
3204e7887635SMatthew G. Knepley     ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr);
3205e7887635SMatthew G. Knepley     ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
3206e7887635SMatthew G. Knepley     ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr);
320775d3a19aSMatthew G. Knepley   }
320875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
320975d3a19aSMatthew G. Knepley }
321075d3a19aSMatthew G. Knepley 
321175d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
3212412e9a14SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform(DM dm, DMPlexCellRefiner cr, DM *dmRefined)
321375d3a19aSMatthew G. Knepley {
321475d3a19aSMatthew G. Knepley   DM              rdm;
3215412e9a14SMatthew G. Knepley   PetscInt        dim, embedDim, depth;
321675d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
321775d3a19aSMatthew G. Knepley 
321875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
3219412e9a14SMatthew G. Knepley   PetscValidHeader(cr, 1);
322075d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
322175d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
3222c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
3223c73cfb54SMatthew G. Knepley   ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr);
32246dcbd917SStefano Zampini   ierr = DMGetCoordinateDim(dm, &embedDim);CHKERRQ(ierr);
32256dcbd917SStefano Zampini   ierr = DMSetCoordinateDim(rdm, embedDim);CHKERRQ(ierr);
322675d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
322775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
32281e573d11SMatthew G. Knepley   if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement");
322975d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
3230412e9a14SMatthew G. Knepley   ierr = DMPlexSetChart(rdm, 0, cr->ctStartNew[cr->ctOrder[DM_NUM_POLYTOPES]]);CHKERRQ(ierr);
32316d7373e8SToby Isaac   /* Step 2: Set cone/support sizes (automatically stratifies) */
3232412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerSetConeSizes(cr, rdm);CHKERRQ(ierr);
323375d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
323475d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
32356d7373e8SToby Isaac   /* Step 4: Set cones and supports (automatically symmetrizes) */
3236412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerSetCones(cr, rdm);CHKERRQ(ierr);
32376d7373e8SToby Isaac   /* Step 5: Create pointSF */
3238412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerCreateSF(cr, rdm);CHKERRQ(ierr);
32396d7373e8SToby Isaac   /* Step 6: Create labels */
3240412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerCreateLabels(cr, rdm);CHKERRQ(ierr);
32416d7373e8SToby Isaac   /* Step 7: Set coordinates */
3242412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerSetCoordinates(cr, rdm);CHKERRQ(ierr);
324375d3a19aSMatthew G. Knepley   *dmRefined = rdm;
324475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
324575d3a19aSMatthew G. Knepley }
324675d3a19aSMatthew G. Knepley 
32472389894bSMatthew G. Knepley /*@
32482389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
32492389894bSMatthew G. Knepley 
32502389894bSMatthew G. Knepley   Input Parameter:
32512389894bSMatthew G. Knepley . dm - The coarse DM
32522389894bSMatthew G. Knepley 
32532389894bSMatthew G. Knepley   Output Parameter:
32542389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
32552389894bSMatthew G. Knepley 
32562389894bSMatthew G. Knepley   Level: developer
32572389894bSMatthew G. Knepley 
325897d8846cSMatthew Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetSubpointIS()
32592389894bSMatthew G. Knepley @*/
32602389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
32612389894bSMatthew G. Knepley {
3262412e9a14SMatthew G. Knepley   DMPlexCellRefiner cr;
3263412e9a14SMatthew G. Knepley   PetscInt         *fpoints;
3264327c2912SStefano Zampini   PetscInt          pStart, pEnd, p, vStart, vEnd, v;
32652389894bSMatthew G. Knepley   PetscErrorCode    ierr;
32662389894bSMatthew G. Knepley 
32672389894bSMatthew G. Knepley   PetscFunctionBegin;
32682389894bSMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
32692389894bSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
3270412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr);
3271412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr);
32722389894bSMatthew G. Knepley   ierr = PetscMalloc1(pEnd-pStart, &fpoints);CHKERRQ(ierr);
32732389894bSMatthew G. Knepley   for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
3274412e9a14SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
3275327c2912SStefano Zampini     PetscInt vNew = -1; /* silent overzelous may be used uninitialized */
3276327c2912SStefano Zampini 
3277412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerGetNewPoint(cr, DM_POLYTOPE_POINT, DM_POLYTOPE_POINT, p, 0, &vNew);CHKERRQ(ierr);
3278412e9a14SMatthew G. Knepley     fpoints[v-pStart] = vNew;
32792389894bSMatthew G. Knepley   }
3280412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr);
32812389894bSMatthew G. Knepley   ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr);
32822389894bSMatthew G. Knepley   PetscFunctionReturn(0);
32832389894bSMatthew G. Knepley }
32842389894bSMatthew G. Knepley 
32850e2b6761SMatthew G. Knepley /*@
32860e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
32870e2b6761SMatthew G. Knepley 
32880e2b6761SMatthew G. Knepley   Input Parameters:
32890e2b6761SMatthew G. Knepley + dm - The DM
32900e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
32910e2b6761SMatthew G. Knepley 
32920e2b6761SMatthew G. Knepley   Level: developer
32930e2b6761SMatthew G. Knepley 
32940e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
32950e2b6761SMatthew G. Knepley @*/
329675d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
329775d3a19aSMatthew G. Knepley {
329875d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
329975d3a19aSMatthew G. Knepley 
330075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
330175d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
330275d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
330375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
330475d3a19aSMatthew G. Knepley }
330575d3a19aSMatthew G. Knepley 
33060e2b6761SMatthew G. Knepley /*@
33070e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
33080e2b6761SMatthew G. Knepley 
33090e2b6761SMatthew G. Knepley   Input Parameter:
33100e2b6761SMatthew G. Knepley . dm - The DM
33110e2b6761SMatthew G. Knepley 
33120e2b6761SMatthew G. Knepley   Output Parameter:
33130e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
33140e2b6761SMatthew G. Knepley 
33150e2b6761SMatthew G. Knepley   Level: developer
33160e2b6761SMatthew G. Knepley 
33170e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
33180e2b6761SMatthew G. Knepley @*/
331975d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
332075d3a19aSMatthew G. Knepley {
332175d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
332275d3a19aSMatthew G. Knepley 
332375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
332475d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
332575d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
332675d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
332775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
332875d3a19aSMatthew G. Knepley }
332975d3a19aSMatthew G. Knepley 
33300e2b6761SMatthew G. Knepley /*@
33310e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
33320e2b6761SMatthew G. Knepley 
33330e2b6761SMatthew G. Knepley   Input Parameters:
33340e2b6761SMatthew G. Knepley + dm - The DM
33350e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
33360e2b6761SMatthew G. Knepley 
33370e2b6761SMatthew G. Knepley   Level: developer
33380e2b6761SMatthew G. Knepley 
33390e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
33400e2b6761SMatthew G. Knepley @*/
334175d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
334275d3a19aSMatthew G. Knepley {
334375d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
334475d3a19aSMatthew G. Knepley 
334575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
334675d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
334775d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
334875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
334975d3a19aSMatthew G. Knepley }
335075d3a19aSMatthew G. Knepley 
33510e2b6761SMatthew G. Knepley /*@
33520e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
33530e2b6761SMatthew G. Knepley 
33540e2b6761SMatthew G. Knepley   Input Parameter:
33550e2b6761SMatthew G. Knepley . dm - The DM
33560e2b6761SMatthew G. Knepley 
33570e2b6761SMatthew G. Knepley   Output Parameter:
33580e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
33590e2b6761SMatthew G. Knepley 
33600e2b6761SMatthew G. Knepley   Level: developer
33610e2b6761SMatthew G. Knepley 
33620e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
33630e2b6761SMatthew G. Knepley @*/
336475d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
336575d3a19aSMatthew G. Knepley {
336675d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
336775d3a19aSMatthew G. Knepley 
336875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
336975d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
337075d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
337175d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
337275d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
337375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
337475d3a19aSMatthew G. Knepley }
337575d3a19aSMatthew G. Knepley 
3376b28003e6SMatthew G. Knepley /*@
3377b28003e6SMatthew G. Knepley   DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
3378b28003e6SMatthew G. Knepley 
3379b28003e6SMatthew G. Knepley   Input Parameters:
3380b28003e6SMatthew G. Knepley + dm - The DM
3381b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh
3382b28003e6SMatthew G. Knepley 
3383b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
3384b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
3385b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
3386b28003e6SMatthew G. Knepley 
3387b28003e6SMatthew G. Knepley   Level: developer
3388b28003e6SMatthew G. Knepley 
3389b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
3390b28003e6SMatthew G. Knepley @*/
3391b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *))
3392b28003e6SMatthew G. Knepley {
3393b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
3394b28003e6SMatthew G. Knepley 
3395b28003e6SMatthew G. Knepley   PetscFunctionBegin;
3396b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3397b28003e6SMatthew G. Knepley   mesh->refinementFunc = refinementFunc;
3398b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
3399b28003e6SMatthew G. Knepley }
3400b28003e6SMatthew G. Knepley 
3401b28003e6SMatthew G. Knepley /*@
3402b28003e6SMatthew G. Knepley   DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
3403b28003e6SMatthew G. Knepley 
3404b28003e6SMatthew G. Knepley   Input Parameter:
3405b28003e6SMatthew G. Knepley . dm - The DM
3406b28003e6SMatthew G. Knepley 
3407b28003e6SMatthew G. Knepley   Output Parameter:
3408b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh
3409b28003e6SMatthew G. Knepley 
3410b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
3411b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
3412b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
3413b28003e6SMatthew G. Knepley 
3414b28003e6SMatthew G. Knepley   Level: developer
3415b28003e6SMatthew G. Knepley 
3416b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
3417b28003e6SMatthew G. Knepley @*/
3418b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *))
3419b28003e6SMatthew G. Knepley {
3420b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
3421b28003e6SMatthew G. Knepley 
3422b28003e6SMatthew G. Knepley   PetscFunctionBegin;
3423b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3424b28003e6SMatthew G. Knepley   PetscValidPointer(refinementFunc,  2);
3425b28003e6SMatthew G. Knepley   *refinementFunc = mesh->refinementFunc;
3426b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
3427b28003e6SMatthew G. Knepley }
3428b28003e6SMatthew G. Knepley 
3429e7887635SMatthew G. Knepley static PetscErrorCode RefineDiscLabels_Internal(DMPlexCellRefiner cr, DM rdm)
3430e7887635SMatthew G. Knepley {
3431e7887635SMatthew G. Knepley   DM             dm = cr->dm;
3432e7887635SMatthew G. Knepley   PetscInt       Nf, f, Nds, s;
3433e7887635SMatthew G. Knepley   PetscErrorCode ierr;
3434e7887635SMatthew G. Knepley 
3435e7887635SMatthew G. Knepley   PetscFunctionBegin;
3436e7887635SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
3437e7887635SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
3438e7887635SMatthew G. Knepley     DMLabel     label, labelNew;
3439e7887635SMatthew G. Knepley     PetscObject obj;
3440e7887635SMatthew G. Knepley     const char *lname;
3441e7887635SMatthew G. Knepley 
3442e7887635SMatthew G. Knepley     ierr = DMGetField(rdm, f, &label, &obj);CHKERRQ(ierr);
3443e7887635SMatthew G. Knepley     if (!label) continue;
3444e7887635SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
3445e7887635SMatthew G. Knepley     ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr);
3446e7887635SMatthew G. Knepley     ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr);
3447e7887635SMatthew G. Knepley     ierr = DMSetField_Internal(rdm, f, labelNew, obj);CHKERRQ(ierr);
3448e7887635SMatthew G. Knepley     ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr);
3449e7887635SMatthew G. Knepley   }
3450e7887635SMatthew G. Knepley   ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
3451e7887635SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
3452e7887635SMatthew G. Knepley     DMLabel     label, labelNew;
3453e7887635SMatthew G. Knepley     const char *lname;
3454e7887635SMatthew G. Knepley 
3455e7887635SMatthew G. Knepley     ierr = DMGetRegionNumDS(rdm, s, &label, NULL, NULL);CHKERRQ(ierr);
3456e7887635SMatthew G. Knepley     if (!label) continue;
3457e7887635SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
3458e7887635SMatthew G. Knepley     ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr);
3459e7887635SMatthew G. Knepley     ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr);
3460e7887635SMatthew G. Knepley     ierr = DMSetRegionNumDS(rdm, s, labelNew, NULL, NULL);CHKERRQ(ierr);
3461e7887635SMatthew G. Knepley     ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr);
3462e7887635SMatthew G. Knepley   }
3463e7887635SMatthew G. Knepley   PetscFunctionReturn(0);
3464e7887635SMatthew G. Knepley }
3465e7887635SMatthew G. Knepley 
34660d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined)
34670d1cd5e0SMatthew G. Knepley {
3468492b8470SStefano Zampini   PetscBool         isUniform;
3469412e9a14SMatthew G. Knepley   DMPlexCellRefiner cr;
34700d1cd5e0SMatthew G. Knepley   PetscErrorCode    ierr;
34710d1cd5e0SMatthew G. Knepley 
34720d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
34730d1cd5e0SMatthew G. Knepley   ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr);
3474412e9a14SMatthew G. Knepley   ierr = DMViewFromOptions(dm, NULL, "-initref_dm_view");CHKERRQ(ierr);
34750d1cd5e0SMatthew G. Knepley   if (isUniform) {
347651a74b61SMatthew G. Knepley     DM        cdm, rcdm;
3477492b8470SStefano Zampini     PetscBool localized;
34780d1cd5e0SMatthew G. Knepley 
3479412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr);
3480412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr);
3481492b8470SStefano Zampini     ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
3482412e9a14SMatthew G. Knepley     ierr = DMPlexRefineUniform(dm, cr, dmRefined);CHKERRQ(ierr);
34839a7e3c0aSMatthew G. Knepley     ierr = DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);CHKERRQ(ierr);
3484e7887635SMatthew G. Knepley     ierr = DMCopyDisc(dm, *dmRefined);CHKERRQ(ierr);
348551a74b61SMatthew G. Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
348651a74b61SMatthew G. Knepley     ierr = DMGetCoordinateDM(*dmRefined, &rcdm);CHKERRQ(ierr);
348751a74b61SMatthew G. Knepley     ierr = DMCopyDisc(cdm, rcdm);CHKERRQ(ierr);
3488e7887635SMatthew G. Knepley     ierr = RefineDiscLabels_Internal(cr, *dmRefined);CHKERRQ(ierr);
34890d1cd5e0SMatthew G. Knepley     ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr);
3490412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr);
34910d1cd5e0SMatthew G. Knepley   } else {
34920d1cd5e0SMatthew G. Knepley     ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr);
34930d1cd5e0SMatthew G. Knepley   }
34940d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
34950d1cd5e0SMatthew G. Knepley }
34960d1cd5e0SMatthew G. Knepley 
34970d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[])
34980d1cd5e0SMatthew G. Knepley {
34990d1cd5e0SMatthew G. Knepley   DM             cdm = dm;
35000d1cd5e0SMatthew G. Knepley   PetscInt       r;
35010d1cd5e0SMatthew G. Knepley   PetscBool      isUniform, localized;
35020d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
35030d1cd5e0SMatthew G. Knepley 
35040d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
35050d1cd5e0SMatthew G. Knepley   ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr);
35060d1cd5e0SMatthew G. Knepley   ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
35070d1cd5e0SMatthew G. Knepley   if (isUniform) {
35080d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
3509412e9a14SMatthew G. Knepley       DMPlexCellRefiner cr;
351051a74b61SMatthew G. Knepley       DM                codm, rcodm;
35110d1cd5e0SMatthew G. Knepley 
3512412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerCreate(cdm, &cr);CHKERRQ(ierr);
3513412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr);
3514412e9a14SMatthew G. Knepley       ierr = DMPlexRefineUniform(cdm, cr, &dmRefined[r]);CHKERRQ(ierr);
35159a7e3c0aSMatthew G. Knepley       ierr = DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);CHKERRQ(ierr);
35169a7e3c0aSMatthew G. Knepley       ierr = DMSetRefineLevel(dmRefined[r], cdm->levelup+1);CHKERRQ(ierr);
3517e7887635SMatthew G. Knepley       ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr);
351851a74b61SMatthew G. Knepley       ierr = DMGetCoordinateDM(dm, &codm);CHKERRQ(ierr);
351951a74b61SMatthew G. Knepley       ierr = DMGetCoordinateDM(dmRefined[r], &rcodm);CHKERRQ(ierr);
352051a74b61SMatthew G. Knepley       ierr = DMCopyDisc(codm, rcodm);CHKERRQ(ierr);
3521e7887635SMatthew G. Knepley       ierr = RefineDiscLabels_Internal(cr, dmRefined[r]);CHKERRQ(ierr);
35220d1cd5e0SMatthew G. Knepley       ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr);
35230d1cd5e0SMatthew G. Knepley       ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr);
35240d1cd5e0SMatthew G. Knepley       ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr);
35250d1cd5e0SMatthew G. Knepley       cdm  = dmRefined[r];
3526412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr);
35270d1cd5e0SMatthew G. Knepley     }
35280d1cd5e0SMatthew G. Knepley   } else {
35290d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
35300d1cd5e0SMatthew G. Knepley       ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr);
3531e7887635SMatthew G. Knepley       ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr);
35320d1cd5e0SMatthew G. Knepley       ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr);
35330d1cd5e0SMatthew G. Knepley       if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);}
35340d1cd5e0SMatthew G. Knepley       ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr);
35350d1cd5e0SMatthew G. Knepley       cdm  = dmRefined[r];
35360d1cd5e0SMatthew G. Knepley     }
35370d1cd5e0SMatthew G. Knepley   }
35380d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
35390d1cd5e0SMatthew G. Knepley }
3540