xref: /petsc/src/dm/impls/plex/plexrefine.c (revision 51a74b61da039325a02b01be2105f3193d20ad5f)
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 
5cf4091a3SMatthew G. Knepley const char * const DMPlexCellRefinerTypes[] = {"Regular", "ToBox", "ToSimplex", "Alfeld2D", "Alfeld3D", "PowellSabin", "BoundaryLayer", "DMPlexCellRefinerTypes", "DM_REFINER_", 0};
675d3a19aSMatthew G. Knepley 
709789c4cSMatthew G. Knepley /*
809789c4cSMatthew G. Knepley   Note that j and invj are non-square:
909789c4cSMatthew G. Knepley          v0 + j x_face = x_cell
1009789c4cSMatthew G. Knepley     invj (x_cell - v0) = x_face
1109789c4cSMatthew G. Knepley */
12412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[])
1309789c4cSMatthew G. Knepley {
1409789c4cSMatthew G. Knepley   /*
1509789c4cSMatthew G. Knepley    2
1609789c4cSMatthew G. Knepley    |\
1709789c4cSMatthew G. Knepley    | \
1809789c4cSMatthew G. Knepley    |  \
1909789c4cSMatthew G. Knepley    |   \
2009789c4cSMatthew G. Knepley    |    \
2109789c4cSMatthew G. Knepley    |     \
2209789c4cSMatthew G. Knepley    |      \
2309789c4cSMatthew G. Knepley    2       1
2409789c4cSMatthew G. Knepley    |        \
2509789c4cSMatthew G. Knepley    |         \
2609789c4cSMatthew G. Knepley    |          \
2709789c4cSMatthew G. Knepley    0---0-------1
28412e9a14SMatthew G. Knepley    v0[Nf][dc]:       3 x 2
29412e9a14SMatthew G. Knepley    J[Nf][df][dc]:    3 x 1 x 2
30412e9a14SMatthew G. Knepley    invJ[Nf][dc][df]: 3 x 2 x 1
31412e9a14SMatthew G. Knepley    detJ[Nf]:         3
3209789c4cSMatthew G. Knepley    */
33412e9a14SMatthew G. Knepley   static PetscReal tri_v0[]   = {0.0, -1.0,  0.0, 0.0,  -1.0,  0.0};
34412e9a14SMatthew G. Knepley   static PetscReal tri_J[]    = {1.0, 0.0,  -1.0, 1.0,   0.0, -1.0};
35412e9a14SMatthew G. Knepley   static PetscReal tri_invJ[] = {1.0, 0.0,  -0.5, 0.5,   0.0, -1.0};
36412e9a14SMatthew G. Knepley   static PetscReal tri_detJ[] = {1.0,  1.414213562373095,  1.0};
3709789c4cSMatthew G. Knepley   /*
3809789c4cSMatthew G. Knepley    3---------2---------2
3909789c4cSMatthew G. Knepley    |                   |
4009789c4cSMatthew G. Knepley    |                   |
4109789c4cSMatthew G. Knepley    |                   |
4209789c4cSMatthew G. Knepley    3                   1
4309789c4cSMatthew G. Knepley    |                   |
4409789c4cSMatthew G. Knepley    |                   |
4509789c4cSMatthew G. Knepley    |                   |
4609789c4cSMatthew G. Knepley    0---------0---------1
47412e9a14SMatthew G. Knepley 
48412e9a14SMatthew G. Knepley    v0[Nf][dc]:       4 x 2
49412e9a14SMatthew G. Knepley    J[Nf][df][dc]:    4 x 1 x 2
50412e9a14SMatthew G. Knepley    invJ[Nf][dc][df]: 4 x 2 x 1
51412e9a14SMatthew G. Knepley    detJ[Nf]:         4
5209789c4cSMatthew G. Knepley    */
53412e9a14SMatthew G. Knepley   static PetscReal quad_v0[]   = {0.0, -1.0,  1.0, 0.0,   0.0, 1.0  -1.0,  0.0};
54412e9a14SMatthew G. Knepley   static PetscReal quad_J[]    = {1.0, 0.0,   0.0, 1.0,  -1.0, 0.0,  0.0, -1.0};
55412e9a14SMatthew G. Knepley   static PetscReal quad_invJ[] = {1.0, 0.0,   0.0, 1.0,  -1.0, 0.0,  0.0, -1.0};
56412e9a14SMatthew G. Knepley   static PetscReal quad_detJ[] = {1.0,  1.0,  1.0,  1.0};
57412e9a14SMatthew G. Knepley 
58412e9a14SMatthew G. Knepley   PetscFunctionBegin;
59412e9a14SMatthew G. Knepley   switch (ct) {
60412e9a14SMatthew G. Knepley   case DM_POLYTOPE_TRIANGLE:      if (Nf) *Nf = 3; if (v0) *v0 = tri_v0;  if (J) *J = tri_J;  if (invJ) *invJ = tri_invJ;  if (detJ) *detJ = tri_detJ;  break;
61412e9a14SMatthew G. Knepley   case DM_POLYTOPE_QUADRILATERAL: if (Nf) *Nf = 4; if (v0) *v0 = quad_v0; if (J) *J = quad_J; if (invJ) *invJ = quad_invJ; if (detJ) *detJ = quad_detJ; break;
6209789c4cSMatthew G. Knepley   default:
63412e9a14SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]);
6409789c4cSMatthew G. Knepley   }
6509789c4cSMatthew G. Knepley   PetscFunctionReturn(0);
6609789c4cSMatthew G. Knepley }
6709789c4cSMatthew G. Knepley 
68bed052eaSMatthew G. Knepley /* Gets the affine map from the original cell to each subcell */
69412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetAffineTransforms_Regular(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[])
70bed052eaSMatthew G. Knepley {
71260b6d3fSMatthew G. Knepley   /*
72260b6d3fSMatthew G. Knepley    2
73260b6d3fSMatthew G. Knepley    |\
74260b6d3fSMatthew G. Knepley    | \
75260b6d3fSMatthew G. Knepley    |  \
76260b6d3fSMatthew G. Knepley    |   \
77260b6d3fSMatthew G. Knepley    | C  \
78260b6d3fSMatthew G. Knepley    |     \
79260b6d3fSMatthew G. Knepley    |      \
80260b6d3fSMatthew G. Knepley    2---1---1
81260b6d3fSMatthew G. Knepley    |\  D  / \
82260b6d3fSMatthew G. Knepley    | 2   0   \
83260b6d3fSMatthew G. Knepley    |A \ /  B  \
84260b6d3fSMatthew G. Knepley    0---0-------1
85260b6d3fSMatthew G. Knepley    */
86412e9a14SMatthew G. Knepley   static PetscReal tri_v0[]   = {-1.0, -1.0,  0.0, -1.0,  -1.0, 0.0,  0.0, -1.0};
87412e9a14SMatthew G. Knepley   static PetscReal tri_J[]    = {0.5, 0.0,
88412e9a14SMatthew G. Knepley                                  0.0, 0.5,
89412e9a14SMatthew G. Knepley 
90412e9a14SMatthew G. Knepley                                  0.5, 0.0,
91412e9a14SMatthew G. Knepley                                  0.0, 0.5,
92412e9a14SMatthew G. Knepley 
93412e9a14SMatthew G. Knepley                                  0.5, 0.0,
94412e9a14SMatthew G. Knepley                                  0.0, 0.5,
95412e9a14SMatthew G. Knepley 
96412e9a14SMatthew G. Knepley                                  0.0, -0.5,
97412e9a14SMatthew G. Knepley                                  0.5,  0.5};
98412e9a14SMatthew G. Knepley   static PetscReal tri_invJ[] = {2.0, 0.0,
99412e9a14SMatthew G. Knepley                                  0.0, 2.0,
100412e9a14SMatthew G. Knepley 
101412e9a14SMatthew G. Knepley                                  2.0, 0.0,
102412e9a14SMatthew G. Knepley                                  0.0, 2.0,
103412e9a14SMatthew G. Knepley 
104412e9a14SMatthew G. Knepley                                  2.0, 0.0,
105412e9a14SMatthew G. Knepley                                  0.0, 2.0,
106412e9a14SMatthew G. Knepley 
107412e9a14SMatthew G. Knepley                                  2.0,  2.0,
108412e9a14SMatthew G. Knepley                                 -2.0,  0.0};
109260b6d3fSMatthew G. Knepley     /*
110260b6d3fSMatthew G. Knepley      3---------2---------2
111260b6d3fSMatthew G. Knepley      |         |         |
112260b6d3fSMatthew G. Knepley      |    D    2    C    |
113260b6d3fSMatthew G. Knepley      |         |         |
114260b6d3fSMatthew G. Knepley      3----3----0----1----1
115260b6d3fSMatthew G. Knepley      |         |         |
116260b6d3fSMatthew G. Knepley      |    A    0    B    |
117260b6d3fSMatthew G. Knepley      |         |         |
118260b6d3fSMatthew G. Knepley      0---------0---------1
119260b6d3fSMatthew G. Knepley      */
120412e9a14SMatthew G. Knepley   static PetscReal quad_v0[]   = {-1.0, -1.0,  0.0, -1.0,  0.0, 0.0,  -1.0, 0.0};
121412e9a14SMatthew G. Knepley   static PetscReal quad_J[]    = {0.5, 0.0,
122412e9a14SMatthew G. Knepley                                   0.0, 0.5,
123412e9a14SMatthew G. Knepley 
124412e9a14SMatthew G. Knepley                                   0.5, 0.0,
125412e9a14SMatthew G. Knepley                                   0.0, 0.5,
126412e9a14SMatthew G. Knepley 
127412e9a14SMatthew G. Knepley                                   0.5, 0.0,
128412e9a14SMatthew G. Knepley                                   0.0, 0.5,
129412e9a14SMatthew G. Knepley 
130412e9a14SMatthew G. Knepley                                   0.5, 0.0,
131412e9a14SMatthew G. Knepley                                   0.0, 0.5};
132412e9a14SMatthew G. Knepley   static PetscReal quad_invJ[] = {2.0, 0.0,
133412e9a14SMatthew G. Knepley                                   0.0, 2.0,
134412e9a14SMatthew G. Knepley 
135412e9a14SMatthew G. Knepley                                   2.0, 0.0,
136412e9a14SMatthew G. Knepley                                   0.0, 2.0,
137412e9a14SMatthew G. Knepley 
138412e9a14SMatthew G. Knepley                                   2.0, 0.0,
139412e9a14SMatthew G. Knepley                                   0.0, 2.0,
140412e9a14SMatthew G. Knepley 
141412e9a14SMatthew G. Knepley                                   2.0, 0.0,
142412e9a14SMatthew G. Knepley                                   0.0, 2.0};
143c1879b55SMatthew G. Knepley     /*
144c1879b55SMatthew G. Knepley      Bottom (viewed from top)    Top
145c1879b55SMatthew G. Knepley      1---------2---------2       7---------2---------6
146c1879b55SMatthew G. Knepley      |         |         |       |         |         |
147c1879b55SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
148c1879b55SMatthew G. Knepley      |         |         |       |         |         |
149c1879b55SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
150c1879b55SMatthew G. Knepley      |         |         |       |         |         |
151c1879b55SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
152c1879b55SMatthew G. Knepley      |         |         |       |         |         |
153c1879b55SMatthew G. Knepley      0---------0---------3       4---------0---------5
154c1879b55SMatthew G. Knepley      */
155412e9a14SMatthew G. Knepley   static PetscReal hex_v0[]   = {-1.0, -1.0, -1.0,  -1.0,  0.0, -1.0,  0.0, 0.0, -1.0,   0.0, -1.0, -1.0,
156412e9a14SMatthew G. Knepley                                  -1.0, -1.0,  0.0,   0.0, -1.0,  0.0,  0.0, 0.0,  0.0,  -1.0,  0.0,  0.0};
157412e9a14SMatthew G. Knepley   static PetscReal hex_J[]    = {0.5, 0.0, 0.0,
158412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
159412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
160bed052eaSMatthew G. Knepley 
161412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
162412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
163412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
164412e9a14SMatthew G. Knepley 
165412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
166412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
167412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
168412e9a14SMatthew G. Knepley 
169412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
170412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
171412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
172412e9a14SMatthew G. Knepley 
173412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
174412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
175412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
176412e9a14SMatthew G. Knepley 
177412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
178412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
179412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
180412e9a14SMatthew G. Knepley 
181412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
182412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
183412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5,
184412e9a14SMatthew G. Knepley 
185412e9a14SMatthew G. Knepley                                  0.5, 0.0, 0.0,
186412e9a14SMatthew G. Knepley                                  0.0, 0.5, 0.0,
187412e9a14SMatthew G. Knepley                                  0.0, 0.0, 0.5};
188412e9a14SMatthew G. Knepley   static PetscReal hex_invJ[] = {2.0, 0.0, 0.0,
189412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
190412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
191412e9a14SMatthew G. Knepley 
192412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
193412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
194412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
195412e9a14SMatthew G. Knepley 
196412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
197412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
198412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
199412e9a14SMatthew G. Knepley 
200412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
201412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
202412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
203412e9a14SMatthew G. Knepley 
204412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
205412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
206412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
207412e9a14SMatthew G. Knepley 
208412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
209412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
210412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
211412e9a14SMatthew G. Knepley 
212412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
213412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
214412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0,
215412e9a14SMatthew G. Knepley 
216412e9a14SMatthew G. Knepley                                  2.0, 0.0, 0.0,
217412e9a14SMatthew G. Knepley                                  0.0, 2.0, 0.0,
218412e9a14SMatthew G. Knepley                                  0.0, 0.0, 2.0};
219bed052eaSMatthew G. Knepley 
220bed052eaSMatthew G. Knepley   PetscFunctionBegin;
221412e9a14SMatthew G. Knepley   switch (ct) {
222412e9a14SMatthew G. Knepley   case DM_POLYTOPE_TRIANGLE:      if (Nc) *Nc = 4; if (v0) *v0 = tri_v0;  if (J) *J = tri_J;  if (invJ) *invJ = tri_invJ;  break;
223412e9a14SMatthew G. Knepley   case DM_POLYTOPE_QUADRILATERAL: if (Nc) *Nc = 4; if (v0) *v0 = quad_v0; if (J) *J = quad_J; if (invJ) *invJ = quad_invJ; break;
224412e9a14SMatthew G. Knepley   case DM_POLYTOPE_HEXAHEDRON:    if (Nc) *Nc = 8; if (v0) *v0 = hex_v0;  if (J) *J = hex_J;  if (invJ) *invJ = hex_invJ;  break;
225412e9a14SMatthew G. Knepley   default:
226412e9a14SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]);
227412e9a14SMatthew G. Knepley   }
228bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
229bed052eaSMatthew G. Knepley }
230bed052eaSMatthew G. Knepley 
23180389061SMatthew G. Knepley /* Should this be here or in the DualSpace somehow? */
232412e9a14SMatthew G. Knepley PetscErrorCode CellRefinerInCellTest_Internal(DMPolytopeType ct, const PetscReal point[], PetscBool *inside)
23380389061SMatthew G. Knepley {
23480389061SMatthew G. Knepley   PetscReal sum = 0.0;
23580389061SMatthew G. Knepley   PetscInt  d;
23680389061SMatthew G. Knepley 
23780389061SMatthew G. Knepley   PetscFunctionBegin;
23880389061SMatthew G. Knepley   *inside = PETSC_TRUE;
239412e9a14SMatthew G. Knepley   switch (ct) {
240412e9a14SMatthew G. Knepley   case DM_POLYTOPE_TRIANGLE:
241412e9a14SMatthew G. Knepley   case DM_POLYTOPE_TETRAHEDRON:
242412e9a14SMatthew G. Knepley     for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d) {
24380389061SMatthew G. Knepley       if (point[d] < -1.0) {*inside = PETSC_FALSE; break;}
24480389061SMatthew G. Knepley       sum += point[d];
24580389061SMatthew G. Knepley     }
246412e9a14SMatthew G. Knepley     if (sum > PETSC_SMALL) {*inside = PETSC_FALSE; break;}
24780389061SMatthew G. Knepley     break;
248412e9a14SMatthew G. Knepley   case DM_POLYTOPE_QUADRILATERAL:
249412e9a14SMatthew G. Knepley   case DM_POLYTOPE_HEXAHEDRON:
250412e9a14SMatthew G. Knepley     for (d = 0; d < DMPolytopeTypeGetDim(ct); ++d)
251412e9a14SMatthew G. Knepley       if (PetscAbsReal(point[d]) > 1.+PETSC_SMALL) {*inside = PETSC_FALSE; break;}
25294339e62SJed Brown     break;
25380389061SMatthew G. Knepley   default:
254412e9a14SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unsupported polytope type %s", DMPolytopeTypes[ct]);
25580389061SMatthew G. Knepley   }
25680389061SMatthew G. Knepley   PetscFunctionReturn(0);
25780389061SMatthew G. Knepley }
25880389061SMatthew G. Knepley 
259412e9a14SMatthew G. Knepley /* Regular Refinment of Hybrid Meshes
26075d3a19aSMatthew G. Knepley 
261412e9a14SMatthew G. Knepley    We would like to express regular refinement as a small set of rules that can be applied on every point of the Plex
262412e9a14SMatthew G. Knepley    to automatically generate a refined Plex. In fact, we would like these rules to be general enough to encompass other
263412e9a14SMatthew G. Knepley    transformations, such as changing from one type of cell to another, as simplex to hex.
26475d3a19aSMatthew G. Knepley 
265412e9a14SMatthew G. Knepley    To start, we can create a function that takes an original cell type and returns the number of new cells replacing it
266412e9a14SMatthew G. Knepley    and the types of the new cells.
267518a8359SMatthew G. Knepley 
268412e9a14SMatthew G. Knepley    We need the group multiplication table for group actions from the dihedral group for each cell type.
26942525629SMatthew G. Knepley 
270412e9a14SMatthew G. Knepley    We need an operator which takes in a cell, and produces a new set of cells with new faces and correct orientations. I think
271412e9a14SMatthew G. Knepley    we can just write this operator for faces with identity, and then compose the face orientation actions to get the actual
272412e9a14SMatthew G. Knepley    (face, orient) pairs for each subcell.
273412e9a14SMatthew G. Knepley */
2740314a74cSLawrence Mitchell 
27575d3a19aSMatthew G. Knepley /*
276412e9a14SMatthew G. Knepley   Input Parameters:
277412e9a14SMatthew G. Knepley + ct - The type of the input cell
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};
842cf4091a3SMatthew G. Knepley 
843cf4091a3SMatthew G. Knepley   PetscFunctionBegin;
844cf4091a3SMatthew G. Knepley   switch (source) {
845cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT:              *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break;
846cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:            *Nt = 1; *target = edgeT;   *size = edgeS;   *cone = edgeC;   *ornt = edgeO;   break;
847cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT;  *size = tedgeS;  *cone = tedgeC;  *ornt = tedgeO;  break;
848cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:           *Nt = 1; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
849cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:      *Nt = 1; *target = quadT;   *size = quadS;   *cone = quadC;   *ornt = quadO;   break;
850cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:   *Nt = 1; *target = tquadT;  *size = tquadS;  *cone = tquadC;  *ornt = tquadO;  break;
851cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:        *Nt = 1; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
852cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:         *Nt = 1; *target = hexT;    *size = hexS;    *cone = hexC;    *ornt = hexO;    break;
853cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:          *Nt = 1; *target = tripT;   *size = tripS;   *cone = tripC;   *ornt = tripO;   break;
854cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:   *Nt = 1; *target = ttripT;  *size = ttripS;  *cone = ttripC;  *ornt = ttripO;  break;
855cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  *Nt = 1; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break;
856cf4091a3SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
857cf4091a3SMatthew G. Knepley   }
858cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
859cf4091a3SMatthew G. Knepley }
860cf4091a3SMatthew G. Knepley 
861412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Regular(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
862412e9a14SMatthew G. Knepley {
863412e9a14SMatthew G. Knepley   /* All vertices remain in the refined mesh */
864412e9a14SMatthew G. Knepley   static DMPolytopeType vertexT[] = {DM_POLYTOPE_POINT};
865412e9a14SMatthew G. Knepley   static PetscInt       vertexS[] = {1};
866412e9a14SMatthew G. Knepley   static PetscInt       vertexC[] = {0};
867412e9a14SMatthew G. Knepley   static PetscInt       vertexO[] = {0};
868412e9a14SMatthew G. Knepley   /* Split all edges with a new vertex, making two new 2 edges
869412e9a14SMatthew G. Knepley      0--0--0--1--1
870412e9a14SMatthew G. Knepley   */
871412e9a14SMatthew G. Knepley   static DMPolytopeType edgeT[]   = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT};
872412e9a14SMatthew G. Knepley   static PetscInt       edgeS[]   = {1, 2};
873412e9a14SMatthew 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};
874412e9a14SMatthew G. Knepley   static PetscInt       edgeO[]   = {                         0,                       0,                        0,                          0};
875412e9a14SMatthew G. Knepley   /* Do not split tensor edges */
876412e9a14SMatthew G. Knepley   static DMPolytopeType tedgeT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR};
877412e9a14SMatthew G. Knepley   static PetscInt       tedgeS[]  = {1};
878412e9a14SMatthew G. Knepley   static PetscInt       tedgeC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
879412e9a14SMatthew G. Knepley   static PetscInt       tedgeO[]  = {                         0,                          0};
880412e9a14SMatthew G. Knepley   /* Add 3 edges inside every triangle, making 4 new triangles.
88175d3a19aSMatthew G. Knepley    2
88275d3a19aSMatthew G. Knepley    |\
88375d3a19aSMatthew G. Knepley    | \
88475d3a19aSMatthew G. Knepley    |  \
885412e9a14SMatthew G. Knepley    0   1
88675d3a19aSMatthew G. Knepley    | C  \
88775d3a19aSMatthew G. Knepley    |     \
88875d3a19aSMatthew G. Knepley    |      \
88975d3a19aSMatthew G. Knepley    2---1---1
89075d3a19aSMatthew G. Knepley    |\  D  / \
891412e9a14SMatthew G. Knepley    1 2   0   0
89275d3a19aSMatthew G. Knepley    |A \ /  B  \
893412e9a14SMatthew G. Knepley    0-0-0---1---1
89475d3a19aSMatthew G. Knepley   */
895412e9a14SMatthew G. Knepley   static DMPolytopeType triT[]    = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE};
896412e9a14SMatthew G. Knepley   static PetscInt       triS[]    = {3, 4};
897412e9a14SMatthew G. Knepley   static PetscInt       triC[]    = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
898412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 1, 2, 0,
899412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 0, 0,
900412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 1,
901412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    0,
902412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0,
903412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    2};
904412e9a14SMatthew G. Knepley   static PetscInt       triO[]    = {0, 0,
905412e9a14SMatthew G. Knepley                                      0, 0,
906412e9a14SMatthew G. Knepley                                      0, 0,
907412e9a14SMatthew G. Knepley                                      0, -2,  0,
908412e9a14SMatthew G. Knepley                                      0,  0, -2,
909412e9a14SMatthew G. Knepley                                     -2,  0,  0,
910412e9a14SMatthew G. Knepley                                      0,  0,  0};
911412e9a14SMatthew G. Knepley   /* Add a vertex in the center of each quadrilateral, and 4 edges inside, making 4 new quads.
912412e9a14SMatthew G. Knepley      3----1----2----0----2
913412e9a14SMatthew G. Knepley      |         |         |
914412e9a14SMatthew G. Knepley      0    D    2    C    1
915412e9a14SMatthew G. Knepley      |         |         |
916412e9a14SMatthew G. Knepley      3----3----0----1----1
917412e9a14SMatthew G. Knepley      |         |         |
918412e9a14SMatthew G. Knepley      1    A    0    B    0
919412e9a14SMatthew G. Knepley      |         |         |
920412e9a14SMatthew G. Knepley      0----0----0----1----1
921412e9a14SMatthew G. Knepley   */
922412e9a14SMatthew G. Knepley   static DMPolytopeType quadT[]   = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL};
923412e9a14SMatthew G. Knepley   static PetscInt       quadS[]   = {1, 4, 4};
924412e9a14SMatthew G. Knepley   static PetscInt       quadC[]   = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
925412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0,
926412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0,
927412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0,
928412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 1,
929412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    0,
930412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0,    2,
931412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 0};
932412e9a14SMatthew G. Knepley   static PetscInt       quadO[]   = {0, 0,
933412e9a14SMatthew G. Knepley                                      0, 0,
934412e9a14SMatthew G. Knepley                                      0, 0,
935412e9a14SMatthew G. Knepley                                      0, 0,
936412e9a14SMatthew G. Knepley                                      0,  0, -2,  0,
937412e9a14SMatthew G. Knepley                                      0,  0,  0, -2,
938412e9a14SMatthew G. Knepley                                     -2,  0,  0,  0,
939412e9a14SMatthew G. Knepley                                      0, -2,  0,  0};
940412e9a14SMatthew G. Knepley   /* Add 1 edge inside every tensor quad, making 2 new tensor quads
941412e9a14SMatthew G. Knepley      2----2----1----3----3
942412e9a14SMatthew G. Knepley      |         |         |
943412e9a14SMatthew G. Knepley      |         |         |
944412e9a14SMatthew G. Knepley      |         |         |
945412e9a14SMatthew G. Knepley      4    A    6    B    5
946412e9a14SMatthew G. Knepley      |         |         |
947412e9a14SMatthew G. Knepley      |         |         |
948412e9a14SMatthew G. Knepley      |         |         |
949412e9a14SMatthew G. Knepley      0----0----0----1----1
950412e9a14SMatthew G. Knepley   */
951412e9a14SMatthew G. Knepley   static DMPolytopeType tquadT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR};
952412e9a14SMatthew G. Knepley   static PetscInt       tquadS[]  = {1, 2};
953412e9a14SMatthew G. Knepley   static PetscInt       tquadC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
954412e9a14SMatthew 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,
955412e9a14SMatthew 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};
956412e9a14SMatthew G. Knepley   static PetscInt       tquadO[]  = {0, 0,
957412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
958412e9a14SMatthew G. Knepley                                      0, 0, 0, 0};
959412e9a14SMatthew G. Knepley   /* Add 1 edge and 8 triangles inside every cell, making 8 new tets
960412e9a14SMatthew 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
961412e9a14SMatthew 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]
962412e9a14SMatthew G. Knepley      called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are
963412e9a14SMatthew G. Knepley        [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3]
964412e9a14SMatthew G. Knepley      The first four tets just cut off the corners, using the replica notation for new vertices,
965412e9a14SMatthew G. Knepley        [v0,      (e0, 0), (e2, 0), (e3, 0)]
966412e9a14SMatthew G. Knepley        [(e0, 0), v1,      (e1, 0), (e4, 0)]
967412e9a14SMatthew G. Knepley        [(e2, 0), (e1, 0), v2,      (e5, 0)]
968412e9a14SMatthew G. Knepley        [(e3, 0), (e4, 0), (e5, 0), v3     ]
969412e9a14SMatthew G. Knepley      The next four tets match a vertex to the newly created faces from cutting off those first tets.
970412e9a14SMatthew G. Knepley        [(e2, 0), (e3, 0), (e0, 0), (e5, 0)]
971412e9a14SMatthew G. Knepley        [(e4, 0), (e1, 0), (e0, 0), (e5, 0)]
972412e9a14SMatthew G. Knepley        [(e5, 0), (e0, 0), (e2, 0), (e1, 0)]
973412e9a14SMatthew G. Knepley        [(e5, 0), (e0, 0), (e4, 0), (e3, 0)]
974412e9a14SMatthew 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
975412e9a14SMatthew G. Knepley        [(e2, 0), (e0, 0), (e3, 0)]
976412e9a14SMatthew G. Knepley        [(e0, 0), (e1, 0), (e4, 0)]
977412e9a14SMatthew G. Knepley        [(e2, 0), (e5, 0), (e1, 0)]
978412e9a14SMatthew G. Knepley        [(e3, 0), (e4, 0), (e5, 0)]
979412e9a14SMatthew G. Knepley      The next four, from the second group of tets, are
980412e9a14SMatthew G. Knepley        [(e2, 0), (e0, 0), (e5, 0)]
981412e9a14SMatthew G. Knepley        [(e4, 0), (e0, 0), (e5, 0)]
982412e9a14SMatthew G. Knepley        [(e0, 0), (e1, 0), (e5, 0)]
983412e9a14SMatthew G. Knepley        [(e5, 0), (e3, 0), (e0, 0)]
984412e9a14SMatthew G. Knepley      I could write a program to generate these orientations by comparing the faces from GetRawFaces() with my existing table.
985412e9a14SMatthew G. Knepley    */
986412e9a14SMatthew G. Knepley   static DMPolytopeType tetT[]    = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON};
987412e9a14SMatthew G. Knepley   static PetscInt       tetS[]    = {1, 8, 8};
988412e9a14SMatthew G. Knepley   static PetscInt       tetC[]    = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 2, 2, 1, 0,
989412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 2, 2,
990412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 1, 1,
991412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 1, 0, 1,
992412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 2, 1,
993412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 2, 0,
994412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 3, 1,
995412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0,    0,
996412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0,    0,
997412e9a14SMatthew 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,
998412e9a14SMatthew 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,
999412e9a14SMatthew 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,
1000412e9a14SMatthew 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,
1001412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    0, DM_POLYTOPE_TRIANGLE, 1, 2, 3, DM_POLYTOPE_TRIANGLE, 0,    4, DM_POLYTOPE_TRIANGLE, 0,    7,
1002412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    1, DM_POLYTOPE_TRIANGLE, 1, 3, 3, DM_POLYTOPE_TRIANGLE, 0,    5, DM_POLYTOPE_TRIANGLE, 0,    6,
1003412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    4, DM_POLYTOPE_TRIANGLE, 0,    6, DM_POLYTOPE_TRIANGLE, 0,    2, DM_POLYTOPE_TRIANGLE, 1, 0, 3,
1004412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 0,    5, DM_POLYTOPE_TRIANGLE, 0,    7, DM_POLYTOPE_TRIANGLE, 0,    3, DM_POLYTOPE_TRIANGLE, 1, 1, 3};
1005412e9a14SMatthew G. Knepley   static PetscInt       tetO[]    = {0, 0,
1006412e9a14SMatthew G. Knepley                                      0,  0,  0,
1007412e9a14SMatthew G. Knepley                                      0,  0,  0,
1008412e9a14SMatthew G. Knepley                                      0,  0,  0,
1009412e9a14SMatthew G. Knepley                                      0,  0,  0,
1010412e9a14SMatthew G. Knepley                                      0,  0, -2,
1011412e9a14SMatthew G. Knepley                                      0,  0, -2,
1012412e9a14SMatthew G. Knepley                                      0, -2, -2,
1013412e9a14SMatthew G. Knepley                                      0, -2,  0,
1014412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,
1015412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,
1016412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,
1017412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,
1018412e9a14SMatthew G. Knepley                                     -3,  0,  0, -2,
1019412e9a14SMatthew G. Knepley                                     -2,  1,  0,  0,
1020412e9a14SMatthew G. Knepley                                     -2, -2, -1,  2,
1021412e9a14SMatthew G. Knepley                                     -2,  0, -2,  1};
1022412e9a14SMatthew G. Knepley   /* Add a vertex in the center of each cell, add 6 edges and 12 quads inside every cell, making 8 new hexes
1023412e9a14SMatthew 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
1024412e9a14SMatthew G. Knepley        [v0, v1, v2, v3] f0 bottom
1025412e9a14SMatthew G. Knepley        [v4, v5, v6, v7] f1 top
1026412e9a14SMatthew G. Knepley        [v0, v3, v5, v4] f2 front
1027412e9a14SMatthew G. Knepley        [v2, v1, v7, v6] f3 back
1028412e9a14SMatthew G. Knepley        [v3, v2, v6, v5] f4 right
1029412e9a14SMatthew G. Knepley        [v0, v4, v7, v1] f5 left
1030412e9a14SMatthew G. Knepley      The eight hexes are divided into four on the bottom, and four on the top,
1031412e9a14SMatthew G. Knepley        [v0,      (e0, 0),  (f0, 0),  (e3, 0),  (e9, 0), (f2, 0),  (c0, 0),  (f5, 0)]
1032412e9a14SMatthew G. Knepley        [(e0, 0), v1,       (e1, 0),  (f0, 0),  (f5, 0), (c0, 0),  (f3, 0),  (e10, 0)]
1033412e9a14SMatthew G. Knepley        [(f0, 0), (e1, 0),  v2,       (e2, 0),  (c0, 0), (f4, 0),  (e11, 0), (f3, 0)]
1034412e9a14SMatthew G. Knepley        [(e3, 0), (f0, 0),  (e2, 0),  v3,       (f2, 0), (e8, 0),  (f4, 0),  (c0, 0)]
1035412e9a14SMatthew G. Knepley        [(e9, 0), (f5, 0),  (c0, 0),  (f2, 0),  v4,      (e4, 0),  (f1, 0),  (e7, 0)]
1036412e9a14SMatthew G. Knepley        [(f2, 0), (c0, 0),  (f4, 0),  (e8, 0),  (e4, 0), v5,       (e5, 0),  (f1, 0)]
1037412e9a14SMatthew G. Knepley        [(c0, 0), (f3, 0),  (e11, 0), (f4, 0),  (f1, 0), (e5, 0),  v6,       (e6, 0)]
1038412e9a14SMatthew G. Knepley        [(f5, 0), (e10, 0), (f3, 0),  (c0, 0),  (e7, 0), (f1, 0),  (e6, 0),  v7]
1039412e9a14SMatthew 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,
1040412e9a14SMatthew G. Knepley        [(e9, 0), (f2, 0),  (c0, 0),  (f5, 0)]
1041412e9a14SMatthew G. Knepley        [(f5, 0), (c0, 0),  (f3, 0),  (e10, 0)]
1042412e9a14SMatthew G. Knepley        [(c0, 0), (f4, 0),  (e11, 0), (f3, 0)]
1043412e9a14SMatthew G. Knepley        [(f2, 0), (e8, 0),  (f4, 0),  (c0, 0)]
1044412e9a14SMatthew G. Knepley      and on the x-z plane,
1045412e9a14SMatthew G. Knepley        [(f0, 0), (e0, 0), (f5, 0), (c0, 0)]
1046412e9a14SMatthew G. Knepley        [(c0, 0), (f5, 0), (e7, 0), (f1, 0)]
1047412e9a14SMatthew G. Knepley        [(f4, 0), (c0, 0), (f1, 0), (e5, 0)]
1048412e9a14SMatthew G. Knepley        [(e2, 0), (f0, 0), (c0, 0), (f4, 0)]
1049412e9a14SMatthew G. Knepley      and on the y-z plane,
1050412e9a14SMatthew G. Knepley        [(e3, 0), (f2, 0), (c0, 0), (f0, 0)]
1051412e9a14SMatthew G. Knepley        [(f2, 0), (e4, 0), (f1, 0), (c0, 0)]
1052412e9a14SMatthew G. Knepley        [(c0, 0), (f1, 0), (e6, 0), (f3, 0)]
1053412e9a14SMatthew G. Knepley        [(f0, 0), (c0, 0), (f3, 0), (e1, 0)]
1054412e9a14SMatthew G. Knepley   */
1055412e9a14SMatthew G. Knepley   static DMPolytopeType hexT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON};
1056412e9a14SMatthew G. Knepley   static PetscInt       hexS[]    = {1, 6, 12, 8};
1057412e9a14SMatthew G. Knepley   static PetscInt       hexC[]    = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1058412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0,
1059412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0,
1060412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0,
1061412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0,
1062412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 5, 0, DM_POLYTOPE_POINT, 0, 0,
1063412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    5, DM_POLYTOPE_SEGMENT, 1, 5, 0,
1064412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    5, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 5, 2,
1065412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 1, 4, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0,    3,
1066412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3, DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 0,    2,
1067412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 5, 3, DM_POLYTOPE_SEGMENT, 0,    5, DM_POLYTOPE_SEGMENT, 0,    0,
1068412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    5, DM_POLYTOPE_SEGMENT, 1, 5, 1, DM_POLYTOPE_SEGMENT, 1, 1, 3, DM_POLYTOPE_SEGMENT, 0,    1,
1069412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 4, 2,
1070412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 1, 4, 0,
1071412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 0, 3,
1072412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    2,
1073412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0,    3,
1074412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 1, 0, 1,
1075412e9a14SMatthew 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,
1076412e9a14SMatthew 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,
1077412e9a14SMatthew 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,
1078412e9a14SMatthew 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,
1079412e9a14SMatthew 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,
1080412e9a14SMatthew 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,
1081412e9a14SMatthew 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,
1082412e9a14SMatthew 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};
1083412e9a14SMatthew G. Knepley   static PetscInt       hexO[]    = {0, 0,
1084412e9a14SMatthew G. Knepley                                      0, 0,
1085412e9a14SMatthew G. Knepley                                      0, 0,
1086412e9a14SMatthew G. Knepley                                      0, 0,
1087412e9a14SMatthew G. Knepley                                      0, 0,
1088412e9a14SMatthew G. Knepley                                      0, 0,
1089412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1090412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1091412e9a14SMatthew G. Knepley                                     -2, -2,  0,  0,
1092412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1093412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1094412e9a14SMatthew G. Knepley                                     -2, -2,  0,  0,
1095412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1096412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1097412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1098412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1099412e9a14SMatthew G. Knepley                                     -2, -2,  0,  0,
1100412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1101412e9a14SMatthew G. Knepley                                      0, 0,  0, 0, -4, 0,
1102412e9a14SMatthew G. Knepley                                      0, 0, -1, 0, -4, 0,
1103412e9a14SMatthew G. Knepley                                      0, 0, -1, 0,  0, 0,
1104412e9a14SMatthew G. Knepley                                      0, 0,  0, 0,  0, 0,
1105412e9a14SMatthew G. Knepley                                     -4, 0,  0, 0, -4, 0,
1106412e9a14SMatthew G. Knepley                                     -4, 0,  0, 0,  0, 0,
1107412e9a14SMatthew G. Knepley                                     -4, 0, -1, 0,  0, 0,
1108412e9a14SMatthew G. Knepley                                     -4, 0, -1, 0, -4, 0};
1109412e9a14SMatthew G. Knepley   /* Add 3 quads inside every triangular prism, making 4 new prisms. */
1110412e9a14SMatthew G. Knepley   static DMPolytopeType tripT[]   = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_TRI_PRISM};
1111412e9a14SMatthew G. Knepley   static PetscInt       tripS[]   = {3, 4, 6, 8};
1112412e9a14SMatthew G. Knepley   static PetscInt       tripC[]   = {DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 1, 3, 0,
1113412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 1, 4, 0,
1114412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 1, 2, 0,
1115412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 4, 1,
1116412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0,    0,
1117412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3,
1118412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    2,
1119412e9a14SMatthew 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,
1120412e9a14SMatthew 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,
1121412e9a14SMatthew 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,
1122412e9a14SMatthew 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,
1123412e9a14SMatthew 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,
1124412e9a14SMatthew 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,
1125412e9a14SMatthew 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,
1126412e9a14SMatthew 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,
1127412e9a14SMatthew 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,
1128412e9a14SMatthew 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,
1129412e9a14SMatthew 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,
1130412e9a14SMatthew 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,
1131412e9a14SMatthew 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,
1132412e9a14SMatthew 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};
1133412e9a14SMatthew G. Knepley   static PetscInt       tripO[]   = {0, 0,
1134412e9a14SMatthew G. Knepley                                      0, 0,
1135412e9a14SMatthew G. Knepley                                      0, 0,
1136412e9a14SMatthew G. Knepley                                      0, -2, -2,
1137412e9a14SMatthew G. Knepley                                     -2,  0, -2,
1138412e9a14SMatthew G. Knepley                                     -2, -2,  0,
1139412e9a14SMatthew G. Knepley                                      0,  0,  0,
1140412e9a14SMatthew G. Knepley                                     -2,  0, -2, -2,
1141412e9a14SMatthew G. Knepley                                     -2,  0, -2, -2,
1142412e9a14SMatthew G. Knepley                                     -2,  0, -2, -2,
1143412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1144412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1145412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1146412e9a14SMatthew G. Knepley                                      0,  0,  0, -1,  0,
1147412e9a14SMatthew G. Knepley                                      0,  0,  0,  0, -1,
1148412e9a14SMatthew G. Knepley                                      0,  0, -1,  0,  0,
1149412e9a14SMatthew G. Knepley                                      2,  0,  0,  0,  0,
1150412e9a14SMatthew G. Knepley                                     -3,  0,  0, -1,  0,
1151412e9a14SMatthew G. Knepley                                     -3,  0,  0,  0, -1,
1152412e9a14SMatthew G. Knepley                                     -3,  0, -1,  0,  0,
1153412e9a14SMatthew G. Knepley                                     -3,  0,  0,  0,  0};
1154412e9a14SMatthew G. Knepley   /* Add 3 tensor quads inside every tensor triangular prism, making 4 new prisms.
1155412e9a14SMatthew G. Knepley       2
1156412e9a14SMatthew G. Knepley       |\
1157412e9a14SMatthew G. Knepley       | \
1158412e9a14SMatthew G. Knepley       |  \
1159412e9a14SMatthew G. Knepley       0---1
116075d3a19aSMatthew G. Knepley 
1161412e9a14SMatthew G. Knepley       2
116275d3a19aSMatthew G. Knepley 
1163412e9a14SMatthew G. Knepley       0   1
116475d3a19aSMatthew G. Knepley 
1165412e9a14SMatthew G. Knepley       2
1166412e9a14SMatthew G. Knepley       |\
1167412e9a14SMatthew G. Knepley       | \
1168412e9a14SMatthew G. Knepley       |  \
1169412e9a14SMatthew G. Knepley       0---1
1170412e9a14SMatthew G. Knepley   */
1171412e9a14SMatthew G. Knepley   static DMPolytopeType ttripT[]  = {DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_TRI_PRISM_TENSOR};
1172412e9a14SMatthew G. Knepley   static PetscInt       ttripS[]  = {3, 4};
1173412e9a14SMatthew 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,
1174412e9a14SMatthew 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,
1175412e9a14SMatthew 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,
1176412e9a14SMatthew 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,
1177412e9a14SMatthew 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,
1178412e9a14SMatthew 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,
1179412e9a14SMatthew 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};
1180412e9a14SMatthew G. Knepley   static PetscInt       ttripO[]  = {0, 0, 0, 0,
1181412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1182412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1183412e9a14SMatthew G. Knepley                                      0, 0,  0, -1,  0,
1184412e9a14SMatthew G. Knepley                                      0, 0,  0,  0, -1,
1185412e9a14SMatthew G. Knepley                                      0, 0, -1,  0,  0,
1186412e9a14SMatthew G. Knepley                                      0, 0,  0,  0,  0};
1187412e9a14SMatthew G. Knepley   /* Add 1 edge and 4 tensor quads inside every tensor quad prism, making 4 new prisms. */
1188412e9a14SMatthew G. Knepley   static DMPolytopeType tquadpT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR};
1189412e9a14SMatthew G. Knepley   static PetscInt       tquadpS[]  = {1, 4, 4};
1190412e9a14SMatthew G. Knepley   static PetscInt       tquadpC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1191412e9a14SMatthew 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,
1192412e9a14SMatthew 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,
1193412e9a14SMatthew 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,
1194412e9a14SMatthew 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,
1195412e9a14SMatthew 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,
1196412e9a14SMatthew 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,
1197412e9a14SMatthew 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,
1198412e9a14SMatthew 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};
1199412e9a14SMatthew G. Knepley   static PetscInt       tquadpO[]  = {0, 0,
1200412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1201412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1202412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1203412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1204412e9a14SMatthew G. Knepley                                       0, 0,  0,  0, -1,  0,
1205412e9a14SMatthew G. Knepley                                       0, 0,  0,  0,  0, -1,
1206412e9a14SMatthew G. Knepley                                       0, 0, -1,  0,  0,  0,
1207412e9a14SMatthew G. Knepley                                       0, 0,  0, -1,  0,  0};
120875d3a19aSMatthew G. Knepley 
1209412e9a14SMatthew G. Knepley   PetscFunctionBegin;
1210412e9a14SMatthew G. Knepley   switch (source) {
1211412e9a14SMatthew G. Knepley     case DM_POLYTOPE_POINT:              *Nt = 1; *target = vertexT; *size = vertexS; *cone = vertexC; *ornt = vertexO; break;
1212412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:            *Nt = 2; *target = edgeT;   *size = edgeS;   *cone = edgeC;   *ornt = edgeO;   break;
1213412e9a14SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT;  *size = tedgeS;  *cone = tedgeC;  *ornt = tedgeO;  break;
1214412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:           *Nt = 2; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
1215412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:      *Nt = 3; *target = quadT;   *size = quadS;   *cone = quadC;   *ornt = quadO;   break;
1216412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:   *Nt = 2; *target = tquadT;  *size = tquadS;  *cone = tquadC;  *ornt = tquadO;  break;
1217412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:        *Nt = 3; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
1218412e9a14SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:         *Nt = 4; *target = hexT;    *size = hexS;    *cone = hexC;    *ornt = hexO;    break;
1219412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:          *Nt = 4; *target = tripT;   *size = tripS;   *cone = tripC;   *ornt = tripO;   break;
1220412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:   *Nt = 2; *target = ttripT;  *size = ttripS;  *cone = ttripC;  *ornt = ttripO;  break;
1221412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:  *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break;
1222412e9a14SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1223412e9a14SMatthew G. Knepley   }
1224412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1225412e9a14SMatthew G. Knepley }
122675d3a19aSMatthew G. Knepley 
122796ca5757SLisandro Dalcin static PetscErrorCode DMPlexCellRefinerRefine_ToBox(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
1228412e9a14SMatthew G. Knepley {
1229412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
1230412e9a14SMatthew G. Knepley   /* Change tensor edges to segments */
1231412e9a14SMatthew G. Knepley   static DMPolytopeType tedgeT[]  = {DM_POLYTOPE_SEGMENT};
1232412e9a14SMatthew G. Knepley   static PetscInt       tedgeS[]  = {1};
1233412e9a14SMatthew G. Knepley   static PetscInt       tedgeC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0};
1234412e9a14SMatthew G. Knepley   static PetscInt       tedgeO[]  = {                         0,                          0};
1235412e9a14SMatthew G. Knepley   /* Add 1 vertex, 3 edges inside every triangle, making 3 new quadrilaterals.
1236e5337592SStefano Zampini    2
1237e5337592SStefano Zampini    |\
1238e5337592SStefano Zampini    | \
1239e5337592SStefano Zampini    |  \
1240e5337592SStefano Zampini    |   \
1241412e9a14SMatthew G. Knepley    0    1
1242412e9a14SMatthew G. Knepley    |     \
1243e5337592SStefano Zampini    |      \
1244e5337592SStefano Zampini    2       1
1245e5337592SStefano Zampini    |\     / \
1246e5337592SStefano Zampini    | 2   1   \
1247e5337592SStefano Zampini    |  \ /     \
1248412e9a14SMatthew G. Knepley    1   |       0
1249e5337592SStefano Zampini    |   0        \
1250e5337592SStefano Zampini    |   |         \
1251412e9a14SMatthew G. Knepley    |   |          \
1252412e9a14SMatthew G. Knepley    0-0-0-----1-----1
1253e5337592SStefano Zampini   */
1254412e9a14SMatthew G. Knepley   static DMPolytopeType triT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL};
1255412e9a14SMatthew G. Knepley   static PetscInt       triS[]    = {1, 3, 3};
1256412e9a14SMatthew G. Knepley   static PetscInt       triC[]    = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0,    0,
1257412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0,    0,
1258412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0,    0,
1259412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 1,
1260412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    0,
1261412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 2, 0};
1262412e9a14SMatthew G. Knepley   static PetscInt       triO[]    = {0, 0,
1263412e9a14SMatthew G. Knepley                                      0, 0,
1264412e9a14SMatthew G. Knepley                                      0, 0,
1265412e9a14SMatthew G. Knepley                                      0,  0, -2,  0,
1266412e9a14SMatthew G. Knepley                                      0,  0,  0, -2,
1267412e9a14SMatthew G. Knepley                                      0, -2,  0,  0};
1268412e9a14SMatthew G. Knepley   /* Add 1 edge inside every tensor quad, making 2 new quadrilaterals
1269412e9a14SMatthew G. Knepley      2----2----1----3----3
12704330a3fcSStefano Zampini      |         |         |
12714330a3fcSStefano Zampini      |         |         |
12724330a3fcSStefano Zampini      |         |         |
1273412e9a14SMatthew G. Knepley      4    A    6    B    5
12744330a3fcSStefano Zampini      |         |         |
1275412e9a14SMatthew G. Knepley      |         |         |
1276412e9a14SMatthew G. Knepley      |         |         |
1277412e9a14SMatthew G. Knepley      0----0----0----1----1
12784330a3fcSStefano Zampini   */
1279412e9a14SMatthew G. Knepley   static DMPolytopeType tquadT[]  = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL};
1280412e9a14SMatthew G. Knepley   static PetscInt       tquadS[]  = {1, 2};
1281412e9a14SMatthew G. Knepley   static PetscInt       tquadC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1282412e9a14SMatthew G. Knepley                                      /* TODO  Fix these */
1283412e9a14SMatthew 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,
1284412e9a14SMatthew 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};
1285412e9a14SMatthew G. Knepley   static PetscInt       tquadO[]  = {0, 0,
1286412e9a14SMatthew G. Knepley                                      0, 0, -2, -2,
1287412e9a14SMatthew G. Knepley                                      0, 0, -2, -2};
1288412e9a14SMatthew G. Knepley   /* Add 6 triangles inside every cell, making 4 new hexs
1289412e9a14SMatthew G. Knepley      TODO: Need different SubcellMap(). Need to make a struct with the function pointers in it
1290412e9a14SMatthew 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
1291412e9a14SMatthew 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]
1292412e9a14SMatthew G. Knepley      called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are
1293412e9a14SMatthew G. Knepley        [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3]
1294412e9a14SMatthew G. Knepley      We make a new hex in each corner
1295412e9a14SMatthew G. Knepley        [v0, (e0, 0), (f0, 0), (e2, 0), (e3, 0), (f2, 0), (c0, 0), (f1, 0)]
1296412e9a14SMatthew G. Knepley        [v1, (e4, 0), (f3, 0), (e1, 0), (e0, 0), (f0, 0), (c0, 0), (f1, 0)]
1297412e9a14SMatthew G. Knepley        [v2, (e1, 0), (f3, 0), (e5, 0), (e2, 0), (f2, 0), (c0, 0), (f0, 0)]
1298412e9a14SMatthew G. Knepley        [v3, (e4, 0), (f1, 0), (e3, 0), (e5, 0), (f2, 0), (c0, 0), (f3, 0)]
1299412e9a14SMatthew G. Knepley      We create a new face for each edge
1300412e9a14SMatthew G. Knepley        [(e3, 0), (f2, 0), (c0, 0), (f1, 0)]
1301412e9a14SMatthew G. Knepley        [(f0, 0), (e0, 0), (f1, 0), (c0, 0)]
1302412e9a14SMatthew G. Knepley        [(e2, 0), (f0, 0), (c0, 0), (f2, 0)]
1303412e9a14SMatthew G. Knepley        [(f3, 0), (e4, 0), (f1, 0), (c0, 0)]
1304412e9a14SMatthew G. Knepley        [(e1, 0), (f3, 0), (c0, 0), (f0, 0)]
1305412e9a14SMatthew G. Knepley        [(e5, 0), (f3, 0), (c0, 0), (f2, 0)]
1306412e9a14SMatthew 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.
130775d3a19aSMatthew G. Knepley    */
1308412e9a14SMatthew G. Knepley   static DMPolytopeType tetT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON};
1309412e9a14SMatthew G. Knepley   static PetscInt       tetS[]    = {1, 4, 6, 4};
1310412e9a14SMatthew G. Knepley   static PetscInt       tetC[]    = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1311412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0,
1312412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0,
1313412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0,
1314412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 2, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 0,
1315412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    0,
1316412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 0,
1317412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,    3,
1318412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 3, 0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 1, 0, 1,
1319412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 3, 2, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 1,
1320412e9a14SMatthew 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,
1321412e9a14SMatthew 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,
1322412e9a14SMatthew 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,
1323412e9a14SMatthew 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};
1324412e9a14SMatthew G. Knepley   static PetscInt       tetO[]    = {0, 0,
1325412e9a14SMatthew G. Knepley                                      0, 0,
1326412e9a14SMatthew G. Knepley                                      0, 0,
1327412e9a14SMatthew G. Knepley                                      0, 0,
1328412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1329412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1330412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1331412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1332412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1333412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1334412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,  0,  0,
1335412e9a14SMatthew G. Knepley                                      1, -1,  1,  0,  0,  3,
1336412e9a14SMatthew G. Knepley                                      0, -4,  1, -1,  0,  3,
1337412e9a14SMatthew G. Knepley                                      1, -4,  3, -2, -4,  3};
1338412e9a14SMatthew G. Knepley   /* Add 3 quads inside every triangular prism, making 4 new prisms. */
1339412e9a14SMatthew G. Knepley   static DMPolytopeType tripT[]   = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON};
1340412e9a14SMatthew G. Knepley   static PetscInt       tripS[]   = {1, 5, 9, 6};
1341412e9a14SMatthew G. Knepley   static PetscInt       tripC[]   = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1342412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 1, 0, DM_POLYTOPE_POINT, 0, 0,
1343412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 2, 0, DM_POLYTOPE_POINT, 0, 0,
1344412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 3, 0, DM_POLYTOPE_POINT, 0, 0,
1345412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 1, 4, 0, DM_POLYTOPE_POINT, 0, 0,
1346412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 3, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 1, 4, 1,
1347412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 1, DM_POLYTOPE_SEGMENT, 1, 3, 3, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    2,
1348412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 1, DM_POLYTOPE_SEGMENT, 1, 4, 3,
1349412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 2, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 1, 2, 0,
1350412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 1, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 1, 3, 0,
1351412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0,    0, DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 1, 4, 0,
1352412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 1, 2, 2,
1353412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 1, DM_POLYTOPE_SEGMENT, 1, 3, 2,
1354412e9a14SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,    4, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 1, 1, 2, DM_POLYTOPE_SEGMENT, 1, 4, 2,
1355412e9a14SMatthew 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,
1356412e9a14SMatthew 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,
1357412e9a14SMatthew 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,
1358412e9a14SMatthew 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,
1359412e9a14SMatthew 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,
1360412e9a14SMatthew 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};
1361412e9a14SMatthew G. Knepley   static PetscInt       tripO[]   = {0, 0,
1362412e9a14SMatthew G. Knepley                                      0, 0,
1363412e9a14SMatthew G. Knepley                                      0, 0,
1364412e9a14SMatthew G. Knepley                                      0, 0,
1365412e9a14SMatthew G. Knepley                                      0, 0,
1366412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1367412e9a14SMatthew G. Knepley                                     -2,  0,  0, -2,
1368412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1369412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1370412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1371412e9a14SMatthew G. Knepley                                      0,  0, -2, -2,
1372412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1373412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1374412e9a14SMatthew G. Knepley                                      0, -2, -2,  0,
1375412e9a14SMatthew G. Knepley                                      0,  0,  0, -1,  0,  1,
1376412e9a14SMatthew G. Knepley                                      0,  0,  0,  0,  0, -4,
1377412e9a14SMatthew G. Knepley                                      0,  0,  0,  0, -1,  1,
1378412e9a14SMatthew G. Knepley                                     -4,  0,  0, -1,  0,  1,
1379412e9a14SMatthew G. Knepley                                     -4,  0,  0,  0,  0, -4,
1380412e9a14SMatthew G. Knepley                                     -4,  0,  0,  0, -1,  1};
1381412e9a14SMatthew G. Knepley   /* Add 3 tensor quads inside every tensor triangular prism, making 4 new tensor triangular prisms.
1382412e9a14SMatthew G. Knepley       2
1383412e9a14SMatthew G. Knepley       |\
1384412e9a14SMatthew G. Knepley       | \
1385412e9a14SMatthew G. Knepley       |  \
1386412e9a14SMatthew G. Knepley       0---1
138775d3a19aSMatthew G. Knepley 
1388412e9a14SMatthew G. Knepley       2
138975d3a19aSMatthew G. Knepley 
1390412e9a14SMatthew G. Knepley       0   1
139175d3a19aSMatthew G. Knepley 
1392412e9a14SMatthew G. Knepley       2
1393412e9a14SMatthew G. Knepley       |\
1394412e9a14SMatthew G. Knepley       | \
1395412e9a14SMatthew G. Knepley       |  \
1396412e9a14SMatthew G. Knepley       0---1
139775d3a19aSMatthew G. Knepley   */
1398412e9a14SMatthew G. Knepley   static DMPolytopeType ttripT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR};
1399412e9a14SMatthew G. Knepley   static PetscInt       ttripS[]  = {1, 3, 3};
1400412e9a14SMatthew G. Knepley   static PetscInt       ttripC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1401412e9a14SMatthew 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,
1402412e9a14SMatthew 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,
1403412e9a14SMatthew 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,
1404412e9a14SMatthew 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,
1405412e9a14SMatthew 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,
1406412e9a14SMatthew 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};
1407412e9a14SMatthew G. Knepley   static PetscInt       ttripO[]  = {0, 0,
1408412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1409412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1410412e9a14SMatthew G. Knepley                                      0, 0, 0, 0,
1411412e9a14SMatthew G. Knepley                                      0, 0, 0,  0, -1, 0,
1412412e9a14SMatthew G. Knepley                                      0, 0, 0,  0,  0, -1,
1413412e9a14SMatthew G. Knepley                                      0, 0, 0, -1,  0, 0};
1414412e9a14SMatthew G. Knepley   /* TODO Add 3 quads inside every tensor triangular prism, making 4 new triangular prisms.
1415412e9a14SMatthew G. Knepley       2
1416412e9a14SMatthew G. Knepley       |\
1417412e9a14SMatthew G. Knepley       | \
1418412e9a14SMatthew G. Knepley       |  \
1419412e9a14SMatthew G. Knepley       0---1
142075d3a19aSMatthew G. Knepley 
1421412e9a14SMatthew G. Knepley       2
142275d3a19aSMatthew G. Knepley 
1423412e9a14SMatthew G. Knepley       0   1
142475d3a19aSMatthew G. Knepley 
1425412e9a14SMatthew G. Knepley       2
1426412e9a14SMatthew G. Knepley       |\
1427412e9a14SMatthew G. Knepley       | \
1428412e9a14SMatthew G. Knepley       |  \
1429412e9a14SMatthew G. Knepley       0---1
1430a97b51b8SMatthew G. Knepley   */
1431412e9a14SMatthew G. Knepley   static DMPolytopeType ctripT[]  = {DM_POLYTOPE_SEGMENT, DM_POLYTOPE_QUADRILATERAL, DM_POLYTOPE_HEXAHEDRON};
1432412e9a14SMatthew G. Knepley   static PetscInt       ctripS[]  = {1, 3, 3};
1433412e9a14SMatthew G. Knepley   static PetscInt       ctripC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1434412e9a14SMatthew 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,
1435412e9a14SMatthew 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,
1436412e9a14SMatthew 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,
1437412e9a14SMatthew 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,
1438412e9a14SMatthew 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,
1439412e9a14SMatthew 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};
1440412e9a14SMatthew G. Knepley   static PetscInt       ctripO[]  = {0, 0,
1441412e9a14SMatthew G. Knepley                                      0, 0, -2, -2,
1442412e9a14SMatthew G. Knepley                                      0, 0, -2, -2,
1443412e9a14SMatthew G. Knepley                                      0, 0, -2, -2,
1444412e9a14SMatthew G. Knepley                                     -4, 0, 0, -1,  0,  1,
1445412e9a14SMatthew G. Knepley                                     -4, 0, 0,  0,  0, -4,
1446412e9a14SMatthew G. Knepley                                     -4, 0, 0,  0, -1,  1};
1447412e9a14SMatthew G. Knepley   /* Add 1 edge and 4 quads inside every tensor quad prism, making 4 new hexahedra. */
1448412e9a14SMatthew G. Knepley   static DMPolytopeType tquadpT[]  = {DM_POLYTOPE_POINT_PRISM_TENSOR, DM_POLYTOPE_SEG_PRISM_TENSOR, DM_POLYTOPE_QUAD_PRISM_TENSOR};
1449412e9a14SMatthew G. Knepley   static PetscInt       tquadpS[]  = {1, 4, 4};
1450412e9a14SMatthew G. Knepley   static PetscInt       tquadpC[]  = {DM_POLYTOPE_POINT, 1, 0, 0, DM_POLYTOPE_POINT, 1, 1, 0,
1451412e9a14SMatthew 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,
1452412e9a14SMatthew 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,
1453412e9a14SMatthew 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,
1454412e9a14SMatthew 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,
1455412e9a14SMatthew 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,
1456412e9a14SMatthew 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,
1457412e9a14SMatthew 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,
1458412e9a14SMatthew 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};
1459412e9a14SMatthew G. Knepley   static PetscInt       tquadpO[]  = {0, 0,
1460412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1461412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1462412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1463412e9a14SMatthew G. Knepley                                       0, 0, 0, 0,
1464412e9a14SMatthew G. Knepley                                       0, 0,  0,  0, -1,  0,
1465412e9a14SMatthew G. Knepley                                       0, 0,  0,  0,  0, -1,
1466412e9a14SMatthew G. Knepley                                       0, 0, -1,  0,  0,  0,
1467412e9a14SMatthew G. Knepley                                       0, 0,  0, -1,  0,  0};
1468412e9a14SMatthew G. Knepley   PetscBool convertTensor = PETSC_TRUE;
1469a97b51b8SMatthew G. Knepley 
1470412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
1471412e9a14SMatthew G. Knepley   if (convertTensor) {
1472412e9a14SMatthew G. Knepley     switch (source) {
1473412e9a14SMatthew G. Knepley       case DM_POLYTOPE_POINT:
1474412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEGMENT:
1475412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUADRILATERAL:
1476412e9a14SMatthew G. Knepley       case DM_POLYTOPE_HEXAHEDRON:
1477412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1478a97b51b8SMatthew G. Knepley         break;
1479412e9a14SMatthew G. Knepley       case DM_POLYTOPE_POINT_PRISM_TENSOR: *Nt = 1; *target = tedgeT;  *size = tedgeS;  *cone = tedgeC;  *ornt = tedgeO;  break;
1480412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEG_PRISM_TENSOR:   *Nt = 2; *target = tquadT;  *size = tquadS;  *cone = tquadC;  *ornt = tquadO;  break;
1481412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRI_PRISM_TENSOR:   *Nt = 3; *target = ctripT;  *size = ctripS;  *cone = ctripC;  *ornt = ctripO;  break;
1482412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUAD_PRISM_TENSOR:  *Nt = 3; *target = tquadpT; *size = tquadpS; *cone = tquadpC; *ornt = tquadpO; break;
1483412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRIANGLE:           *Nt = 3; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
1484412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TETRAHEDRON:        *Nt = 4; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
1485412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRI_PRISM:          *Nt = 4; *target = tripT;   *size = tripS;   *cone = tripC;   *ornt = tripO;   break;
1486412e9a14SMatthew G. Knepley       default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1487b5da9499SMatthew G. Knepley     }
1488b5da9499SMatthew G. Knepley   } else {
1489412e9a14SMatthew G. Knepley     switch (source) {
1490412e9a14SMatthew G. Knepley       case DM_POLYTOPE_POINT:
1491412e9a14SMatthew G. Knepley       case DM_POLYTOPE_POINT_PRISM_TENSOR:
1492412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEGMENT:
1493412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUADRILATERAL:
1494412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEG_PRISM_TENSOR:
1495412e9a14SMatthew G. Knepley       case DM_POLYTOPE_HEXAHEDRON:
1496412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUAD_PRISM_TENSOR:
1497412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1498b5da9499SMatthew G. Knepley         break;
1499412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRIANGLE:           *Nt = 3; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
1500412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TETRAHEDRON:        *Nt = 4; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
1501412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRI_PRISM:          *Nt = 4; *target = tripT;   *size = tripS;   *cone = tripC;   *ornt = tripO;   break;
1502412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRI_PRISM_TENSOR:   *Nt = 3; *target = ttripT;  *size = ttripS;  *cone = ttripC;  *ornt = ttripO;  break;
1503412e9a14SMatthew G. Knepley       default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
150427fcede3SMatthew G. Knepley     }
150575d3a19aSMatthew G. Knepley   }
150675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
150775d3a19aSMatthew G. Knepley }
150875d3a19aSMatthew G. Knepley 
1509412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_ToSimplex(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
151075d3a19aSMatthew G. Knepley {
1511412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
1512412e9a14SMatthew G. Knepley 
1513412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
1514412e9a14SMatthew G. Knepley   switch (source) {
1515412e9a14SMatthew G. Knepley     case DM_POLYTOPE_POINT:
1516412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
1517412e9a14SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR:
1518412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:
1519412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:
1520412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:
1521412e9a14SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:
1522412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
1523412e9a14SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
1524412e9a14SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:
1525412e9a14SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:
1526412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine_Regular(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1527412e9a14SMatthew G. Knepley       break;
1528412e9a14SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1529412e9a14SMatthew G. Knepley   }
1530412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
1531412e9a14SMatthew G. Knepley }
1532412e9a14SMatthew G. Knepley 
1533cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld2D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
1534cf4091a3SMatthew G. Knepley {
1535cf4091a3SMatthew G. Knepley   PetscErrorCode ierr;
1536cf4091a3SMatthew G. Knepley   /* Add 1 vertex, 3 edges inside every triangle, making 3 new triangles.
1537cf4091a3SMatthew G. Knepley    2
1538cf4091a3SMatthew G. Knepley    |\
1539cf4091a3SMatthew G. Knepley    |\\
1540cf4091a3SMatthew G. Knepley    | |\
1541cf4091a3SMatthew G. Knepley    | \ \
1542cf4091a3SMatthew G. Knepley    | |  \
1543cf4091a3SMatthew G. Knepley    |  \  \
1544cf4091a3SMatthew G. Knepley    |   |  \
1545cf4091a3SMatthew G. Knepley    2   \   \
1546cf4091a3SMatthew G. Knepley    |   |    1
1547cf4091a3SMatthew G. Knepley    |   2    \
1548cf4091a3SMatthew G. Knepley    |   |    \
1549cf4091a3SMatthew G. Knepley    |   /\   \
1550cf4091a3SMatthew G. Knepley    |  0  1  |
1551cf4091a3SMatthew G. Knepley    | /    \ |
1552cf4091a3SMatthew G. Knepley    |/      \|
1553cf4091a3SMatthew G. Knepley    0---0----1
1554cf4091a3SMatthew G. Knepley   */
1555cf4091a3SMatthew G. Knepley   static DMPolytopeType triT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE};
1556cf4091a3SMatthew G. Knepley   static PetscInt       triS[]    = {1, 3, 3};
1557cf4091a3SMatthew G. Knepley   static PetscInt       triC[]    = {DM_POLYTOPE_POINT, 2, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1558cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 2, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1559cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 2, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1560cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 0, 0, DM_POLYTOPE_SEGMENT, 0, 1, DM_POLYTOPE_SEGMENT, 0, 0,
1561cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0, 2, DM_POLYTOPE_SEGMENT, 0, 1,
1562cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 1, 2, 0, DM_POLYTOPE_SEGMENT, 0, 0, DM_POLYTOPE_SEGMENT, 0, 2};
1563cf4091a3SMatthew G. Knepley   static PetscInt       triO[]    = {0, 0,
1564cf4091a3SMatthew G. Knepley                                      0, 0,
1565cf4091a3SMatthew G. Knepley                                      0, 0,
1566cf4091a3SMatthew G. Knepley                                      0,  0, -2,
1567cf4091a3SMatthew G. Knepley                                      0,  0, -2,
1568cf4091a3SMatthew G. Knepley                                      0,  0, -2};
1569cf4091a3SMatthew G. Knepley 
1570cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
1571cf4091a3SMatthew G. Knepley   switch (source) {
1572cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT:
1573cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
1574cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR:
1575cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
1576cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
1577cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:
1578cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:
1579cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:
1580cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:
1581cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:
1582cf4091a3SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1583cf4091a3SMatthew G. Knepley       break;
1584cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:           *Nt = 3; *target = triT;    *size = triS;    *cone = triC;    *ornt = triO;    break;
1585cf4091a3SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1586cf4091a3SMatthew G. Knepley   }
1587cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
1588cf4091a3SMatthew G. Knepley }
1589cf4091a3SMatthew G. Knepley 
1590cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_Alfeld3D(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
1591cf4091a3SMatthew G. Knepley {
1592cf4091a3SMatthew G. Knepley   PetscErrorCode ierr;
1593cf4091a3SMatthew G. Knepley   /* Add 6 triangles inside every cell, making 4 new tets
1594cf4091a3SMatthew 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
1595cf4091a3SMatthew 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]
1596cf4091a3SMatthew G. Knepley      called e3, e4, and e5. The faces of a tet, given in DMPlexGetRawFaces_Internal() are
1597cf4091a3SMatthew G. Knepley        [v0, v1, v2], [v0, v3, v1], [v0, v2, v3], [v2, v1, v3]
1598cf4091a3SMatthew G. Knepley      We make a new tet on each face
1599cf4091a3SMatthew G. Knepley        [v0, v1, v2, (c0, 0)]
1600cf4091a3SMatthew G. Knepley        [v0, v3, v1, (c0, 0)]
1601cf4091a3SMatthew G. Knepley        [v0, v2, v3, (c0, 0)]
1602cf4091a3SMatthew G. Knepley        [v2, v1, v3, (c0, 0)]
1603cf4091a3SMatthew G. Knepley      We create a new face for each edge
1604cf4091a3SMatthew G. Knepley        [v0, (c0, 0), v1     ]
1605cf4091a3SMatthew G. Knepley        [v0, v2,      (c0, 0)]
1606cf4091a3SMatthew G. Knepley        [v2, v1,      (c0, 0)]
1607cf4091a3SMatthew G. Knepley        [v0, (c0, 0), v3     ]
1608cf4091a3SMatthew G. Knepley        [v1, v3,      (c0, 0)]
1609cf4091a3SMatthew G. Knepley        [v3, v2,      (c0, 0)]
1610cf4091a3SMatthew G. Knepley    */
1611cf4091a3SMatthew G. Knepley   static DMPolytopeType tetT[]    = {DM_POLYTOPE_POINT, DM_POLYTOPE_SEGMENT, DM_POLYTOPE_TRIANGLE, DM_POLYTOPE_TETRAHEDRON};
1612cf4091a3SMatthew G. Knepley   static PetscInt       tetS[]    = {1, 4, 6, 4};
1613cf4091a3SMatthew G. Knepley   static PetscInt       tetC[]    = {DM_POLYTOPE_POINT, 3, 0, 0, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1614cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 3, 0, 1, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1615cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 3, 0, 2, 0, 0, DM_POLYTOPE_POINT, 0, 0,
1616cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_POINT, 3, 1, 0, 1, 0, DM_POLYTOPE_POINT, 0, 0,
1617cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,       0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 2, 0, 0, 0,
1618cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 2, 0, 2, 0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,       0,
1619cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 2, 0, 1, 0, DM_POLYTOPE_SEGMENT, 0,    1, DM_POLYTOPE_SEGMENT, 0,       2,
1620cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 0,       0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 2, 1, 0, 0,
1621cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 2, 1, 1, 0, DM_POLYTOPE_SEGMENT, 0,    3, DM_POLYTOPE_SEGMENT, 0,       1,
1622cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_SEGMENT, 2, 2, 1, 0, DM_POLYTOPE_SEGMENT, 0,    2, DM_POLYTOPE_SEGMENT, 0,       3,
1623cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 2,
1624cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 1, 0, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 0, DM_POLYTOPE_TRIANGLE, 0, 4,
1625cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 2, 0, DM_POLYTOPE_TRIANGLE, 0, 1, DM_POLYTOPE_TRIANGLE, 0, 3, DM_POLYTOPE_TRIANGLE, 0, 5,
1626cf4091a3SMatthew G. Knepley                                      DM_POLYTOPE_TRIANGLE, 1, 3, 0, DM_POLYTOPE_TRIANGLE, 0, 2, DM_POLYTOPE_TRIANGLE, 0, 5, DM_POLYTOPE_TRIANGLE, 0, 4};
1627cf4091a3SMatthew G. Knepley   static PetscInt       tetO[]    = {0, 0,
1628cf4091a3SMatthew G. Knepley                                      0, 0,
1629cf4091a3SMatthew G. Knepley                                      0, 0,
1630cf4091a3SMatthew G. Knepley                                      0, 0,
1631cf4091a3SMatthew G. Knepley                                      0, -2, -2,
1632cf4091a3SMatthew G. Knepley                                     -2,  0, -2,
1633cf4091a3SMatthew G. Knepley                                     -2,  0, -2,
1634cf4091a3SMatthew G. Knepley                                      0, -2, -2,
1635cf4091a3SMatthew G. Knepley                                     -2,  0, -2,
1636cf4091a3SMatthew G. Knepley                                     -2,  0, -2,
1637cf4091a3SMatthew G. Knepley                                      0,  0,  0,  0,
1638cf4091a3SMatthew G. Knepley                                      0,  0, -3,  0,
1639cf4091a3SMatthew G. Knepley                                      0, -3, -3,  0,
1640cf4091a3SMatthew G. Knepley                                      0, -3, -1, -1};
1641cf4091a3SMatthew G. Knepley 
1642cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
1643cf4091a3SMatthew G. Knepley   switch (source) {
1644cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT:
1645cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEGMENT:
1646cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_POINT_PRISM_TENSOR:
1647cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRIANGLE:
1648cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUADRILATERAL:
1649cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_SEG_PRISM_TENSOR:
1650cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_HEXAHEDRON:
1651cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM:
1652cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TRI_PRISM_TENSOR:
1653cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_QUAD_PRISM_TENSOR:
1654cf4091a3SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine_None(cr, source, Nt, target, size, cone, ornt);CHKERRQ(ierr);
1655cf4091a3SMatthew G. Knepley       break;
1656cf4091a3SMatthew G. Knepley     case DM_POLYTOPE_TETRAHEDRON:        *Nt = 4; *target = tetT;    *size = tetS;    *cone = tetC;    *ornt = tetO;    break;
1657cf4091a3SMatthew G. Knepley     default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No refinement strategy for %s", DMPolytopeTypes[source]);
1658cf4091a3SMatthew G. Knepley   }
1659cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
1660cf4091a3SMatthew G. Knepley }
1661cf4091a3SMatthew G. Knepley 
1662a5801f52SStefano Zampini typedef struct {
1663a5801f52SStefano Zampini   PetscInt       n;
1664a5801f52SStefano Zampini   PetscReal      r;
1665a5801f52SStefano Zampini   PetscScalar    *h;
1666a5801f52SStefano Zampini   PetscInt       *Nt;
1667a5801f52SStefano Zampini   DMPolytopeType **target;
1668a5801f52SStefano Zampini   PetscInt       **size;
1669a5801f52SStefano Zampini   PetscInt       **cone;
1670a5801f52SStefano Zampini   PetscInt       **ornt;
1671a5801f52SStefano Zampini } PlexRefiner_BL;
1672a5801f52SStefano Zampini 
1673a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerSetUp_BL(DMPlexCellRefiner cr)
1674a5801f52SStefano Zampini {
1675a5801f52SStefano Zampini   PlexRefiner_BL *crbl;
1676a5801f52SStefano Zampini   PetscErrorCode ierr;
1677a5801f52SStefano Zampini   PetscInt       i,n;
1678a5801f52SStefano Zampini   PetscReal      r;
1679a5801f52SStefano Zampini   PetscInt       c1,c2,o1,o2;
1680a5801f52SStefano Zampini 
1681a5801f52SStefano Zampini   PetscFunctionBegin;
1682a5801f52SStefano Zampini   ierr = PetscNew(&crbl);CHKERRQ(ierr);
1683a5801f52SStefano Zampini   cr->data = crbl;
1684a5801f52SStefano Zampini   crbl->n = 1; /* 1 split -> 2 new cells */
1685a5801f52SStefano Zampini   crbl->r = 1; /* linear progression */
1686a5801f52SStefano Zampini 
1687a5801f52SStefano Zampini   /* TODO: add setfromoptions to the refiners? */
1688a5801f52SStefano Zampini   ierr = PetscOptionsGetInt(((PetscObject) cr->dm)->options,((PetscObject) cr->dm)->prefix, "-dm_plex_refine_boundarylayer_splits", &crbl->n, NULL);CHKERRQ(ierr);
1689a5801f52SStefano Zampini   if (crbl->n < 1) SETERRQ1(PetscObjectComm((PetscObject)cr),PETSC_ERR_SUP,"Number of splits %D must be positive",crbl->n);
1690a5801f52SStefano Zampini   ierr = PetscOptionsGetReal(((PetscObject) cr->dm)->options,((PetscObject) cr->dm)->prefix, "-dm_plex_refine_boundarylayer_progression", &crbl->r, NULL);CHKERRQ(ierr);
1691a5801f52SStefano Zampini   n = crbl->n;
1692a5801f52SStefano Zampini   r = crbl->r;
1693a5801f52SStefano Zampini 
1694a5801f52SStefano 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 */
1695a5801f52SStefano Zampini   ierr = PetscMalloc5(4,&crbl->Nt,4,&crbl->target,4,&crbl->size,4,&crbl->cone,4,&crbl->ornt);CHKERRQ(ierr);
1696a5801f52SStefano Zampini 
1697a5801f52SStefano Zampini   /* progression */
1698a5801f52SStefano Zampini   ierr = PetscMalloc1(n,&crbl->h);CHKERRQ(ierr);
1699a5801f52SStefano Zampini   if (r > 1) {
1700a5801f52SStefano Zampini     PetscReal d = (r-1.)/(PetscPowRealInt(r,n+1)-1.);
1701a5801f52SStefano Zampini 
1702a5801f52SStefano Zampini     crbl->h[0] = d;
1703a5801f52SStefano Zampini     for (i = 1; i < n; i++) {
1704a5801f52SStefano Zampini       d *= r;
1705a5801f52SStefano Zampini       crbl->h[i] = crbl->h[i-1] + d;
1706a5801f52SStefano Zampini     }
1707a5801f52SStefano Zampini   } else { /* linear */
1708a5801f52SStefano Zampini     for (i = 0; i < n; i++) crbl->h[i] = (i + 1.)/(n+1); /* linear */
1709a5801f52SStefano Zampini   }
1710a5801f52SStefano Zampini 
1711a5801f52SStefano Zampini   /* DM_POLYTOPE_POINT_PRISM_TENSOR produces n points and n+1 tensor segments */
1712a5801f52SStefano Zampini   c1 = 14+6*(n-1);
1713a5801f52SStefano Zampini   o1 = 2*(n+1);
1714a5801f52SStefano Zampini   crbl->Nt[0] = 2;
1715a5801f52SStefano Zampini 
1716a5801f52SStefano 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);
1717a5801f52SStefano Zampini 
1718a5801f52SStefano Zampini   crbl->target[0][0] = DM_POLYTOPE_POINT;
1719a5801f52SStefano Zampini   crbl->target[0][1] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1720a5801f52SStefano Zampini 
1721a5801f52SStefano Zampini   crbl->size[0][0] = n;
1722a5801f52SStefano Zampini   crbl->size[0][1] = n+1;
1723a5801f52SStefano Zampini 
1724a5801f52SStefano Zampini   /* the tensor segments */
1725a5801f52SStefano Zampini   crbl->cone[0][0] = DM_POLYTOPE_POINT;
1726a5801f52SStefano Zampini   crbl->cone[0][1] = 1;
1727a5801f52SStefano Zampini   crbl->cone[0][2] = 0;
1728a5801f52SStefano Zampini   crbl->cone[0][3] = 0;
1729a5801f52SStefano Zampini   crbl->cone[0][4] = DM_POLYTOPE_POINT;
1730a5801f52SStefano Zampini   crbl->cone[0][5] = 0;
1731a5801f52SStefano Zampini   crbl->cone[0][6] = 0;
1732a5801f52SStefano Zampini   for (i = 0; i < n-1; i++) {
1733a5801f52SStefano Zampini     crbl->cone[0][7+6*i+0] = DM_POLYTOPE_POINT;
1734a5801f52SStefano Zampini     crbl->cone[0][7+6*i+1] = 0;
1735a5801f52SStefano Zampini     crbl->cone[0][7+6*i+2] = i;
1736a5801f52SStefano Zampini     crbl->cone[0][7+6*i+3] = DM_POLYTOPE_POINT;
1737a5801f52SStefano Zampini     crbl->cone[0][7+6*i+4] = 0;
1738a5801f52SStefano Zampini     crbl->cone[0][7+6*i+5] = i+1;
1739a5801f52SStefano Zampini   }
1740a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+0] = DM_POLYTOPE_POINT;
1741a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+1] = 0;
1742a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+2] = n-1;
1743a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+3] = DM_POLYTOPE_POINT;
1744a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+4] = 1;
1745a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+5] = 1;
1746a5801f52SStefano Zampini   crbl->cone[0][7+6*(n-1)+6] = 0;
1747a5801f52SStefano Zampini   for (i = 0; i < o1; i++) crbl->ornt[0][i] = 0;
1748a5801f52SStefano Zampini 
1749a5801f52SStefano Zampini   /* DM_POLYTOPE_SEG_PRISM_TENSOR produces n segments and n+1 tensor quads */
1750a5801f52SStefano Zampini   c1 = 8*n;
1751a5801f52SStefano Zampini   c2 = 30+14*(n-1);
1752a5801f52SStefano Zampini   o1 = 2*n;
1753a5801f52SStefano Zampini   o2 = 4*(n+1);
1754a5801f52SStefano Zampini   crbl->Nt[1] = 2;
1755a5801f52SStefano Zampini 
1756a5801f52SStefano 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);
1757a5801f52SStefano Zampini 
1758a5801f52SStefano Zampini   crbl->target[1][0] = DM_POLYTOPE_SEGMENT;
1759a5801f52SStefano Zampini   crbl->target[1][1] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1760a5801f52SStefano Zampini 
1761a5801f52SStefano Zampini   crbl->size[1][0] = n;
1762a5801f52SStefano Zampini   crbl->size[1][1] = n+1;
1763a5801f52SStefano Zampini 
1764a5801f52SStefano Zampini   /* the segments */
1765a5801f52SStefano Zampini   for (i = 0; i < n; i++) {
1766a5801f52SStefano Zampini     crbl->cone[1][8*i+0] = DM_POLYTOPE_POINT;
1767a5801f52SStefano Zampini     crbl->cone[1][8*i+1] = 1;
1768a5801f52SStefano Zampini     crbl->cone[1][8*i+2] = 2;
1769a5801f52SStefano Zampini     crbl->cone[1][8*i+3] = i;
1770a5801f52SStefano Zampini     crbl->cone[1][8*i+4] = DM_POLYTOPE_POINT;
1771a5801f52SStefano Zampini     crbl->cone[1][8*i+5] = 1;
1772a5801f52SStefano Zampini     crbl->cone[1][8*i+6] = 3;
1773a5801f52SStefano Zampini     crbl->cone[1][8*i+7] = i;
1774a5801f52SStefano Zampini   }
1775a5801f52SStefano Zampini 
1776a5801f52SStefano Zampini   /* the tensor quads */
1777a5801f52SStefano Zampini   crbl->cone[1][c1+ 0] = DM_POLYTOPE_SEGMENT;
1778a5801f52SStefano Zampini   crbl->cone[1][c1+ 1] = 1;
1779a5801f52SStefano Zampini   crbl->cone[1][c1+ 2] = 0;
1780a5801f52SStefano Zampini   crbl->cone[1][c1+ 3] = 0;
1781a5801f52SStefano Zampini   crbl->cone[1][c1+ 4] = DM_POLYTOPE_SEGMENT;
1782a5801f52SStefano Zampini   crbl->cone[1][c1+ 5] = 0;
1783a5801f52SStefano Zampini   crbl->cone[1][c1+ 6] = 0;
1784a5801f52SStefano Zampini   crbl->cone[1][c1+ 7] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1785a5801f52SStefano Zampini   crbl->cone[1][c1+ 8] = 1;
1786a5801f52SStefano Zampini   crbl->cone[1][c1+ 9] = 2;
1787a5801f52SStefano Zampini   crbl->cone[1][c1+10] = 0;
1788a5801f52SStefano Zampini   crbl->cone[1][c1+11] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1789a5801f52SStefano Zampini   crbl->cone[1][c1+12] = 1;
1790a5801f52SStefano Zampini   crbl->cone[1][c1+13] = 3;
1791a5801f52SStefano Zampini   crbl->cone[1][c1+14] = 0;
1792a5801f52SStefano Zampini   for (i = 0; i < n-1; i++) {
1793a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 0] = DM_POLYTOPE_SEGMENT;
1794a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 1] = 0;
1795a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 2] = i;
1796a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 3] = DM_POLYTOPE_SEGMENT;
1797a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 4] = 0;
1798a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 5] = i+1;
1799a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 6] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1800a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 7] = 1;
1801a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 8] = 2;
1802a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+ 9] = i+1;
1803a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+10] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1804a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+11] = 1;
1805a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+12] = 3;
1806a5801f52SStefano Zampini     crbl->cone[1][c1+15+14*i+13] = i+1;
1807a5801f52SStefano Zampini   }
1808a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 0] = DM_POLYTOPE_SEGMENT;
1809a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 1] = 0;
1810a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 2] = n-1;
1811a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 3] = DM_POLYTOPE_SEGMENT;
1812a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 4] = 1;
1813a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 5] = 1;
1814a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 6] = 0;
1815a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 7] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1816a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 8] = 1;
1817a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+ 9] = 2;
1818a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+10] = n;
1819a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+11] = DM_POLYTOPE_POINT_PRISM_TENSOR;
1820a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+12] = 1;
1821a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+13] = 3;
1822a5801f52SStefano Zampini   crbl->cone[1][c1+15+14*(n-1)+14] = n;
1823a5801f52SStefano Zampini   for (i = 0; i < o1+o2; i++) crbl->ornt[1][i] = 0;
1824a5801f52SStefano Zampini 
1825a5801f52SStefano Zampini   /* DM_POLYTOPE_TRI_PRISM_TENSOR produces n triangles and n+1 tensor triangular prisms */
1826a5801f52SStefano Zampini   c1 = 12*n;
1827a5801f52SStefano Zampini   c2 = 38+18*(n-1);
1828a5801f52SStefano Zampini   o1 = 3*n;
1829a5801f52SStefano Zampini   o2 = 5*(n+1);
1830a5801f52SStefano Zampini   crbl->Nt[2] = 2;
1831a5801f52SStefano Zampini 
1832a5801f52SStefano 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);
1833a5801f52SStefano Zampini 
1834a5801f52SStefano Zampini   crbl->target[2][0] = DM_POLYTOPE_TRIANGLE;
1835a5801f52SStefano Zampini   crbl->target[2][1] = DM_POLYTOPE_TRI_PRISM_TENSOR;
1836a5801f52SStefano Zampini 
1837a5801f52SStefano Zampini   crbl->size[2][0] = n;
1838a5801f52SStefano Zampini   crbl->size[2][1] = n+1;
1839a5801f52SStefano Zampini 
1840a5801f52SStefano Zampini   /* the triangles */
1841a5801f52SStefano Zampini   for (i = 0; i < n; i++) {
1842a5801f52SStefano Zampini     crbl->cone[2][12*i+ 0] = DM_POLYTOPE_SEGMENT;
1843a5801f52SStefano Zampini     crbl->cone[2][12*i+ 1] = 1;
1844a5801f52SStefano Zampini     crbl->cone[2][12*i+ 2] = 2;
1845a5801f52SStefano Zampini     crbl->cone[2][12*i+ 3] = i;
1846a5801f52SStefano Zampini     crbl->cone[2][12*i+ 4] = DM_POLYTOPE_SEGMENT;
1847a5801f52SStefano Zampini     crbl->cone[2][12*i+ 5] = 1;
1848a5801f52SStefano Zampini     crbl->cone[2][12*i+ 6] = 3;
1849a5801f52SStefano Zampini     crbl->cone[2][12*i+ 7] = i;
1850a5801f52SStefano Zampini     crbl->cone[2][12*i+ 8] = DM_POLYTOPE_SEGMENT;
1851a5801f52SStefano Zampini     crbl->cone[2][12*i+ 9] = 1;
1852a5801f52SStefano Zampini     crbl->cone[2][12*i+10] = 4;
1853a5801f52SStefano Zampini     crbl->cone[2][12*i+11] = i;
1854a5801f52SStefano Zampini   }
1855a5801f52SStefano Zampini 
1856a5801f52SStefano Zampini   /* the triangular prisms */
1857a5801f52SStefano Zampini   crbl->cone[2][c1+ 0] = DM_POLYTOPE_TRIANGLE;
1858a5801f52SStefano Zampini   crbl->cone[2][c1+ 1] = 1;
1859a5801f52SStefano Zampini   crbl->cone[2][c1+ 2] = 0;
1860a5801f52SStefano Zampini   crbl->cone[2][c1+ 3] = 0;
1861a5801f52SStefano Zampini   crbl->cone[2][c1+ 4] = DM_POLYTOPE_TRIANGLE;
1862a5801f52SStefano Zampini   crbl->cone[2][c1+ 5] = 0;
1863a5801f52SStefano Zampini   crbl->cone[2][c1+ 6] = 0;
1864a5801f52SStefano Zampini   crbl->cone[2][c1+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1865a5801f52SStefano Zampini   crbl->cone[2][c1+ 8] = 1;
1866a5801f52SStefano Zampini   crbl->cone[2][c1+ 9] = 2;
1867a5801f52SStefano Zampini   crbl->cone[2][c1+10] = 0;
1868a5801f52SStefano Zampini   crbl->cone[2][c1+11] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1869a5801f52SStefano Zampini   crbl->cone[2][c1+12] = 1;
1870a5801f52SStefano Zampini   crbl->cone[2][c1+13] = 3;
1871a5801f52SStefano Zampini   crbl->cone[2][c1+14] = 0;
1872a5801f52SStefano Zampini   crbl->cone[2][c1+15] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1873a5801f52SStefano Zampini   crbl->cone[2][c1+16] = 1;
1874a5801f52SStefano Zampini   crbl->cone[2][c1+17] = 4;
1875a5801f52SStefano Zampini   crbl->cone[2][c1+18] = 0;
1876a5801f52SStefano Zampini   for (i = 0; i < n-1; i++) {
1877a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 0] = DM_POLYTOPE_TRIANGLE;
1878a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 1] = 0;
1879a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 2] = i;
1880a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 3] = DM_POLYTOPE_TRIANGLE;
1881a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 4] = 0;
1882a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 5] = i+1;
1883a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 6] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1884a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 7] = 1;
1885a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 8] = 2;
1886a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+ 9] = i+1;
1887a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+10] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1888a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+11] = 1;
1889a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+12] = 3;
1890a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+13] = i+1;
1891a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+14] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1892a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+15] = 1;
1893a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+16] = 4;
1894a5801f52SStefano Zampini     crbl->cone[2][c1+19+18*i+17] = i+1;
1895a5801f52SStefano Zampini   }
1896a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 0] = DM_POLYTOPE_TRIANGLE;
1897a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 1] = 0;
1898a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 2] = n-1;
1899a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 3] = DM_POLYTOPE_TRIANGLE;
1900a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 4] = 1;
1901a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 5] = 1;
1902a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 6] = 0;
1903a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1904a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 8] = 1;
1905a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+ 9] = 2;
1906a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+10] = n;
1907a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+11] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1908a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+12] = 1;
1909a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+13] = 3;
1910a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+14] = n;
1911a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+15] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1912a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+16] = 1;
1913a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+17] = 4;
1914a5801f52SStefano Zampini   crbl->cone[2][c1+19+18*(n-1)+18] = n;
1915a5801f52SStefano Zampini   for (i = 0; i < o1+o2; i++) crbl->ornt[2][i] = 0;
1916a5801f52SStefano Zampini 
1917a5801f52SStefano Zampini   /* DM_POLYTOPE_QUAD_PRISM_TENSOR produces n quads and n+1 tensor quad prisms */
1918a5801f52SStefano Zampini   c1 = 16*n;
1919a5801f52SStefano Zampini   c2 = 46+22*(n-1);
1920a5801f52SStefano Zampini   o1 = 4*n;
1921a5801f52SStefano Zampini   o2 = 6*(n+1);
1922a5801f52SStefano Zampini   crbl->Nt[3] = 2;
1923a5801f52SStefano Zampini 
1924a5801f52SStefano 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);
1925a5801f52SStefano Zampini 
1926a5801f52SStefano Zampini   crbl->target[3][0] = DM_POLYTOPE_QUADRILATERAL;
1927a5801f52SStefano Zampini   crbl->target[3][1] = DM_POLYTOPE_QUAD_PRISM_TENSOR;
1928a5801f52SStefano Zampini 
1929a5801f52SStefano Zampini   crbl->size[3][0] = n;
1930a5801f52SStefano Zampini   crbl->size[3][1] = n+1;
1931a5801f52SStefano Zampini 
1932a5801f52SStefano Zampini   /* the quads */
1933a5801f52SStefano Zampini   for (i = 0; i < n; i++) {
1934a5801f52SStefano Zampini     crbl->cone[3][16*i+ 0] = DM_POLYTOPE_SEGMENT;
1935a5801f52SStefano Zampini     crbl->cone[3][16*i+ 1] = 1;
1936a5801f52SStefano Zampini     crbl->cone[3][16*i+ 2] = 2;
1937a5801f52SStefano Zampini     crbl->cone[3][16*i+ 3] = i;
1938a5801f52SStefano Zampini     crbl->cone[3][16*i+ 4] = DM_POLYTOPE_SEGMENT;
1939a5801f52SStefano Zampini     crbl->cone[3][16*i+ 5] = 1;
1940a5801f52SStefano Zampini     crbl->cone[3][16*i+ 6] = 3;
1941a5801f52SStefano Zampini     crbl->cone[3][16*i+ 7] = i;
1942a5801f52SStefano Zampini     crbl->cone[3][16*i+ 8] = DM_POLYTOPE_SEGMENT;
1943a5801f52SStefano Zampini     crbl->cone[3][16*i+ 9] = 1;
1944a5801f52SStefano Zampini     crbl->cone[3][16*i+10] = 4;
1945a5801f52SStefano Zampini     crbl->cone[3][16*i+11] = i;
1946a5801f52SStefano Zampini     crbl->cone[3][16*i+12] = DM_POLYTOPE_SEGMENT;
1947a5801f52SStefano Zampini     crbl->cone[3][16*i+13] = 1;
1948a5801f52SStefano Zampini     crbl->cone[3][16*i+14] = 5;
1949a5801f52SStefano Zampini     crbl->cone[3][16*i+15] = i;
1950a5801f52SStefano Zampini   }
1951a5801f52SStefano Zampini 
1952a5801f52SStefano Zampini   /* the quad prisms */
1953a5801f52SStefano Zampini   crbl->cone[3][c1+ 0] = DM_POLYTOPE_QUADRILATERAL;
1954a5801f52SStefano Zampini   crbl->cone[3][c1+ 1] = 1;
1955a5801f52SStefano Zampini   crbl->cone[3][c1+ 2] = 0;
1956a5801f52SStefano Zampini   crbl->cone[3][c1+ 3] = 0;
1957a5801f52SStefano Zampini   crbl->cone[3][c1+ 4] = DM_POLYTOPE_QUADRILATERAL;
1958a5801f52SStefano Zampini   crbl->cone[3][c1+ 5] = 0;
1959a5801f52SStefano Zampini   crbl->cone[3][c1+ 6] = 0;
1960a5801f52SStefano Zampini   crbl->cone[3][c1+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1961a5801f52SStefano Zampini   crbl->cone[3][c1+ 8] = 1;
1962a5801f52SStefano Zampini   crbl->cone[3][c1+ 9] = 2;
1963a5801f52SStefano Zampini   crbl->cone[3][c1+10] = 0;
1964a5801f52SStefano Zampini   crbl->cone[3][c1+11] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1965a5801f52SStefano Zampini   crbl->cone[3][c1+12] = 1;
1966a5801f52SStefano Zampini   crbl->cone[3][c1+13] = 3;
1967a5801f52SStefano Zampini   crbl->cone[3][c1+14] = 0;
1968a5801f52SStefano Zampini   crbl->cone[3][c1+15] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1969a5801f52SStefano Zampini   crbl->cone[3][c1+16] = 1;
1970a5801f52SStefano Zampini   crbl->cone[3][c1+17] = 4;
1971a5801f52SStefano Zampini   crbl->cone[3][c1+18] = 0;
1972a5801f52SStefano Zampini   crbl->cone[3][c1+19] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1973a5801f52SStefano Zampini   crbl->cone[3][c1+20] = 1;
1974a5801f52SStefano Zampini   crbl->cone[3][c1+21] = 5;
1975a5801f52SStefano Zampini   crbl->cone[3][c1+22] = 0;
1976a5801f52SStefano Zampini   for (i = 0; i < n-1; i++) {
1977a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 0] = DM_POLYTOPE_QUADRILATERAL;
1978a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 1] = 0;
1979a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 2] = i;
1980a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 3] = DM_POLYTOPE_QUADRILATERAL;
1981a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 4] = 0;
1982a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 5] = i+1;
1983a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 6] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1984a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 7] = 1;
1985a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 8] = 2;
1986a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+ 9] = i+1;
1987a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+10] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1988a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+11] = 1;
1989a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+12] = 3;
1990a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+13] = i+1;
1991a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+14] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1992a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+15] = 1;
1993a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+16] = 4;
1994a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+17] = i+1;
1995a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+18] = DM_POLYTOPE_SEG_PRISM_TENSOR;
1996a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+19] = 1;
1997a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+20] = 5;
1998a5801f52SStefano Zampini     crbl->cone[3][c1+23+22*i+21] = i+1;
1999a5801f52SStefano Zampini   }
2000a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 0] = DM_POLYTOPE_QUADRILATERAL;
2001a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 1] = 0;
2002a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 2] = n-1;
2003a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 3] = DM_POLYTOPE_QUADRILATERAL;
2004a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 4] = 1;
2005a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 5] = 1;
2006a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 6] = 0;
2007a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 7] = DM_POLYTOPE_SEG_PRISM_TENSOR;
2008a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 8] = 1;
2009a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+ 9] = 2;
2010a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+10] = n;
2011a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+11] = DM_POLYTOPE_SEG_PRISM_TENSOR;
2012a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+12] = 1;
2013a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+13] = 3;
2014a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+14] = n;
2015a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+15] = DM_POLYTOPE_SEG_PRISM_TENSOR;
2016a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+16] = 1;
2017a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+17] = 4;
2018a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+18] = n;
2019a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+19] = DM_POLYTOPE_SEG_PRISM_TENSOR;
2020a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+20] = 1;
2021a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+21] = 5;
2022a5801f52SStefano Zampini   crbl->cone[3][c1+23+22*(n-1)+22] = n;
2023a5801f52SStefano Zampini   for (i = 0; i < o1+o2; i++) crbl->ornt[3][i] = 0;
2024a5801f52SStefano Zampini   PetscFunctionReturn(0);
2025a5801f52SStefano Zampini }
2026a5801f52SStefano Zampini 
2027a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerDestroy_BL(DMPlexCellRefiner cr)
2028a5801f52SStefano Zampini {
2029a5801f52SStefano Zampini   PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data;
2030a5801f52SStefano Zampini   PetscErrorCode ierr;
2031a5801f52SStefano Zampini 
2032a5801f52SStefano Zampini   PetscFunctionBegin;
2033a5801f52SStefano Zampini   ierr = PetscFree4(crbl->target[0],crbl->size[0],crbl->cone[0],crbl->ornt[0]);CHKERRQ(ierr);
2034a5801f52SStefano Zampini   ierr = PetscFree4(crbl->target[1],crbl->size[1],crbl->cone[1],crbl->ornt[1]);CHKERRQ(ierr);
2035a5801f52SStefano Zampini   ierr = PetscFree4(crbl->target[2],crbl->size[2],crbl->cone[2],crbl->ornt[2]);CHKERRQ(ierr);
2036a5801f52SStefano Zampini   ierr = PetscFree4(crbl->target[3],crbl->size[3],crbl->cone[3],crbl->ornt[3]);CHKERRQ(ierr);
2037a5801f52SStefano Zampini   ierr = PetscFree5(crbl->Nt,crbl->target,crbl->size,crbl->cone,crbl->ornt);CHKERRQ(ierr);
2038a5801f52SStefano Zampini   ierr = PetscFree(crbl->h);CHKERRQ(ierr);
2039a5801f52SStefano Zampini   ierr = PetscFree(cr->data);CHKERRQ(ierr);
2040a5801f52SStefano Zampini   PetscFunctionReturn(0);
2041a5801f52SStefano Zampini }
2042a5801f52SStefano Zampini 
2043cf4091a3SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerRefine_BL(DMPlexCellRefiner cr, DMPolytopeType source, PetscInt *Nt, DMPolytopeType *target[], PetscInt *size[], PetscInt *cone[], PetscInt *ornt[])
2044cf4091a3SMatthew G. Knepley {
2045a5801f52SStefano Zampini   PlexRefiner_BL  *crbl = (PlexRefiner_BL *)cr->data;
2046cf4091a3SMatthew G. Knepley   PetscErrorCode  ierr;
2047cf4091a3SMatthew G. Knepley 
2048cf4091a3SMatthew G. Knepley   PetscFunctionBeginHot;
2049cf4091a3SMatthew G. Knepley   switch (source) {
2050a5801f52SStefano Zampini   case DM_POLYTOPE_POINT_PRISM_TENSOR:
2051a5801f52SStefano Zampini     *Nt     = crbl->Nt[0];
2052a5801f52SStefano Zampini     *target = crbl->target[0];
2053a5801f52SStefano Zampini     *size   = crbl->size[0];
2054a5801f52SStefano Zampini     *cone   = crbl->cone[0];
2055a5801f52SStefano Zampini     *ornt   = crbl->ornt[0];
2056cf4091a3SMatthew G. Knepley     break;
2057a5801f52SStefano Zampini   case DM_POLYTOPE_SEG_PRISM_TENSOR:
2058a5801f52SStefano Zampini     *Nt     = crbl->Nt[1];
2059a5801f52SStefano Zampini     *target = crbl->target[1];
2060a5801f52SStefano Zampini     *size   = crbl->size[1];
2061a5801f52SStefano Zampini     *cone   = crbl->cone[1];
2062a5801f52SStefano Zampini     *ornt   = crbl->ornt[1];
2063a5801f52SStefano Zampini     break;
2064a5801f52SStefano Zampini   case DM_POLYTOPE_TRI_PRISM_TENSOR:
2065a5801f52SStefano Zampini     *Nt     = crbl->Nt[2];
2066a5801f52SStefano Zampini     *target = crbl->target[2];
2067a5801f52SStefano Zampini     *size   = crbl->size[2];
2068a5801f52SStefano Zampini     *cone   = crbl->cone[2];
2069a5801f52SStefano Zampini     *ornt   = crbl->ornt[2];
2070a5801f52SStefano Zampini     break;
2071a5801f52SStefano Zampini   case DM_POLYTOPE_QUAD_PRISM_TENSOR:
2072a5801f52SStefano Zampini     *Nt     = crbl->Nt[3];
2073a5801f52SStefano Zampini     *target = crbl->target[3];
2074a5801f52SStefano Zampini     *size   = crbl->size[3];
2075a5801f52SStefano Zampini     *cone   = crbl->cone[3];
2076a5801f52SStefano Zampini     *ornt   = crbl->ornt[3];
2077a5801f52SStefano Zampini     break;
2078a5801f52SStefano Zampini   default:
2079a5801f52SStefano Zampini     ierr = DMPlexCellRefinerRefine_None(cr,source,Nt,target,size,cone,ornt);CHKERRQ(ierr);
2080a5801f52SStefano Zampini   }
2081a5801f52SStefano Zampini   PetscFunctionReturn(0);
2082a5801f52SStefano Zampini }
2083a5801f52SStefano Zampini 
2084a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapSubcells_BL(DMPlexCellRefiner cr, DMPolytopeType pct, PetscInt po, DMPolytopeType ct, PetscInt r, PetscInt o, PetscInt *rnew, PetscInt *onew)
2085a5801f52SStefano Zampini {
2086a5801f52SStefano Zampini   /* We shift any input orientation in order to make it non-negative
2087a5801f52SStefano 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)
2088a5801f52SStefano Zampini        The replica array r[po][r] gives the new replica number rnew given that the parent point has orientation po
2089a5801f52SStefano Zampini        Overall, replica (r, o) in a parent with orientation 0 matches replica (rnew, onew) in a parent with orientation po
2090a5801f52SStefano Zampini   */
2091a5801f52SStefano Zampini   PetscInt       tquad_seg_o[]   = { 0,  1, -2, -1,
2092a5801f52SStefano Zampini                                      0,  1, -2, -1,
2093a5801f52SStefano Zampini                                     -2, -1,  0,  1,
2094a5801f52SStefano Zampini                                     -2, -1,  0,  1};
2095a5801f52SStefano Zampini   PetscInt       tquad_tquad_o[] = { 0,  1, -2, -1,
2096a5801f52SStefano Zampini                                      1,  0, -1, -2,
2097a5801f52SStefano Zampini                                     -2, -1,  0,  1,
2098a5801f52SStefano Zampini                                     -1, -2,  1,  0};
2099a5801f52SStefano Zampini   PlexRefiner_BL *crbl = (PlexRefiner_BL *)cr->data;
2100a5801f52SStefano Zampini   const PetscInt n = crbl->n;
2101a5801f52SStefano Zampini   PetscErrorCode ierr;
2102a5801f52SStefano Zampini 
2103a5801f52SStefano Zampini   PetscFunctionBeginHot;
2104a5801f52SStefano Zampini   *rnew = r;
2105a5801f52SStefano Zampini   *onew = o;
2106a5801f52SStefano Zampini   switch (pct) {
2107a5801f52SStefano Zampini     case DM_POLYTOPE_POINT_PRISM_TENSOR:
2108a5801f52SStefano Zampini       if (ct == DM_POLYTOPE_POINT_PRISM_TENSOR) {
2109a5801f52SStefano Zampini         if      (po == 0 || po == -1) {*rnew = r;     *onew = o;}
2110a5801f52SStefano Zampini         else if (po == 1 || po == -2) {*rnew = n - r; *onew = (o == 0 || o == -1) ? -2 : 0;}
2111a5801f52SStefano Zampini         else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Invalid orientation %D for tensor segment", po);
2112a5801f52SStefano Zampini       }
2113a5801f52SStefano Zampini       break;
2114a5801f52SStefano Zampini     case DM_POLYTOPE_SEG_PRISM_TENSOR:
2115a5801f52SStefano Zampini       switch (ct) {
2116a5801f52SStefano Zampini         case DM_POLYTOPE_SEGMENT:
2117a5801f52SStefano Zampini           *onew = tquad_seg_o[(po+2)*4+o+2];
2118a5801f52SStefano Zampini           *rnew = r;
2119a5801f52SStefano Zampini           break;
2120a5801f52SStefano Zampini         case DM_POLYTOPE_SEG_PRISM_TENSOR:
2121a5801f52SStefano Zampini           *onew = tquad_tquad_o[(po+2)*4+o+2];
2122a5801f52SStefano Zampini           *rnew = r;
2123a5801f52SStefano Zampini           break;
2124a5801f52SStefano Zampini         default: break;
2125a5801f52SStefano Zampini       }
2126a5801f52SStefano Zampini       break;
2127a5801f52SStefano Zampini     default:
2128a5801f52SStefano Zampini       ierr = DMPlexCellRefinerMapSubcells_None(cr, pct, po, ct, r, o, rnew, onew);CHKERRQ(ierr);
2129a5801f52SStefano Zampini   }
2130a5801f52SStefano Zampini   PetscFunctionReturn(0);
2131a5801f52SStefano Zampini }
2132a5801f52SStefano Zampini 
2133a5801f52SStefano Zampini static PetscErrorCode DMPlexCellRefinerMapCoordinates_BL(DMPlexCellRefiner cr, DMPolytopeType pct, DMPolytopeType ct, PetscInt r, PetscInt Nv, PetscInt dE, const PetscScalar in[], PetscScalar out[])
2134a5801f52SStefano Zampini {
2135a5801f52SStefano Zampini   PlexRefiner_BL  *crbl = (PlexRefiner_BL *)cr->data;
2136a5801f52SStefano Zampini   PetscInt        d;
2137a5801f52SStefano Zampini   PetscErrorCode  ierr;
2138a5801f52SStefano Zampini 
2139a5801f52SStefano Zampini   PetscFunctionBeginHot;
2140a5801f52SStefano Zampini   switch (pct) {
2141a5801f52SStefano Zampini   case DM_POLYTOPE_POINT_PRISM_TENSOR:
2142a5801f52SStefano Zampini     if (ct != DM_POLYTOPE_POINT) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for refined point type %s",DMPolytopeTypes[ct]);
2143a5801f52SStefano Zampini     if (Nv != 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for parent vertices %D",Nv);
2144a5801f52SStefano 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);
2145a5801f52SStefano Zampini     for (d = 0; d < dE; d++) out[d] = in[d] + crbl->h[r] * (in[d + dE] - in[d]);
2146a5801f52SStefano Zampini     break;
2147a5801f52SStefano Zampini   default:
2148a5801f52SStefano Zampini     ierr = DMPlexCellRefinerMapCoordinates_Barycenter(cr,pct,ct,r,Nv,dE,in,out);CHKERRQ(ierr);
2149cf4091a3SMatthew G. Knepley   }
2150cf4091a3SMatthew G. Knepley   PetscFunctionReturn(0);
2151cf4091a3SMatthew G. Knepley }
2152cf4091a3SMatthew G. Knepley 
2153412e9a14SMatthew G. Knepley static PetscErrorCode CellRefinerCreateOffset_Internal(DMPlexCellRefiner cr, PetscInt ctOrder[], PetscInt ctStart[], PetscInt **offset)
2154412e9a14SMatthew G. Knepley {
2155412e9a14SMatthew G. Knepley   PetscInt       c, cN, *off;
215675d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
215775d3a19aSMatthew G. Knepley 
215875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
2159412e9a14SMatthew G. Knepley   ierr = PetscCalloc1(DM_NUM_POLYTOPES*DM_NUM_POLYTOPES, &off);CHKERRQ(ierr);
2160412e9a14SMatthew G. Knepley   for (c = DM_POLYTOPE_POINT; c < DM_NUM_POLYTOPES; ++c) {
2161412e9a14SMatthew G. Knepley     const DMPolytopeType ct = (DMPolytopeType) c;
2162412e9a14SMatthew G. Knepley     for (cN = DM_POLYTOPE_POINT; cN < DM_NUM_POLYTOPES; ++cN) {
2163412e9a14SMatthew G. Knepley       const DMPolytopeType ctNew = (DMPolytopeType) cN;
2164412e9a14SMatthew G. Knepley       DMPolytopeType      *rct;
2165412e9a14SMatthew G. Knepley       PetscInt            *rsize, *cone, *ornt;
2166412e9a14SMatthew G. Knepley       PetscInt             Nct, n, i;
2167412e9a14SMatthew G. Knepley 
2168412e9a14SMatthew G. Knepley       if (DMPolytopeTypeGetDim(ct) < 0 || DMPolytopeTypeGetDim(ctNew) < 0) {off[ct*DM_NUM_POLYTOPES+ctNew] = -1; break;}
2169412e9a14SMatthew G. Knepley       off[ct*DM_NUM_POLYTOPES+ctNew] = 0;
2170412e9a14SMatthew G. Knepley       for (i = DM_POLYTOPE_POINT; i < DM_NUM_POLYTOPES; ++i) {
2171412e9a14SMatthew G. Knepley         const DMPolytopeType ict  = (DMPolytopeType) ctOrder[i];
2172412e9a14SMatthew G. Knepley         const DMPolytopeType ictn = (DMPolytopeType) ctOrder[i+1];
2173412e9a14SMatthew G. Knepley 
2174412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine(cr, ict, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr);
2175412e9a14SMatthew G. Knepley         if (ict == ct) {
2176412e9a14SMatthew G. Knepley           for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) break;
2177412e9a14SMatthew G. Knepley           if (n == Nct) off[ct*DM_NUM_POLYTOPES+ctNew] = -1;
2178412e9a14SMatthew G. Knepley           break;
2179412e9a14SMatthew G. Knepley         }
2180412e9a14SMatthew G. Knepley         for (n = 0; n < Nct; ++n) if (rct[n] == ctNew) off[ct*DM_NUM_POLYTOPES+ctNew] += (ctStart[ictn]-ctStart[ict]) * rsize[n];
2181412e9a14SMatthew G. Knepley       }
2182412e9a14SMatthew G. Knepley     }
2183412e9a14SMatthew G. Knepley   }
2184412e9a14SMatthew G. Knepley   *offset = off;
2185412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2186412e9a14SMatthew G. Knepley }
2187412e9a14SMatthew G. Knepley 
2188412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetStarts(DMPlexCellRefiner cr, const PetscInt ctStart[], const PetscInt ctStartNew[])
2189412e9a14SMatthew G. Knepley {
2190412e9a14SMatthew G. Knepley   const PetscInt ctSize = DM_NUM_POLYTOPES+1;
2191412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2192412e9a14SMatthew G. Knepley 
2193412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2194412e9a14SMatthew G. Knepley   if (cr->setupcalled) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_ARG_WRONGSTATE, "Must call this function before DMPlexCellRefinerSetUp()");
2195412e9a14SMatthew G. Knepley   ierr = PetscCalloc2(ctSize, &cr->ctStart, ctSize, &cr->ctStartNew);CHKERRQ(ierr);
2196412e9a14SMatthew G. Knepley   ierr = PetscArraycpy(cr->ctStart,    ctStart,    ctSize);CHKERRQ(ierr);
2197412e9a14SMatthew G. Knepley   ierr = PetscArraycpy(cr->ctStartNew, ctStartNew, ctSize);CHKERRQ(ierr);
2198412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2199412e9a14SMatthew G. Knepley }
2200412e9a14SMatthew G. Knepley 
2201412e9a14SMatthew G. Knepley /* Construct cell type order since we must loop over cell types in depth order */
2202412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCreateCellTypeOrder_Internal(DMPolytopeType ctCell, PetscInt *ctOrder[], PetscInt *ctOrderInv[])
2203412e9a14SMatthew G. Knepley {
2204412e9a14SMatthew G. Knepley   PetscInt      *ctO, *ctOInv;
2205412e9a14SMatthew G. Knepley   PetscInt       c, d, off = 0;
2206412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2207412e9a14SMatthew G. Knepley 
2208412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2209412e9a14SMatthew G. Knepley   ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctO, DM_NUM_POLYTOPES+1, &ctOInv);CHKERRQ(ierr);
2210412e9a14SMatthew G. Knepley   for (d = 3; d >= DMPolytopeTypeGetDim(ctCell); --d) {
2211412e9a14SMatthew G. Knepley     for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
2212412e9a14SMatthew G. Knepley       if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue;
2213412e9a14SMatthew G. Knepley       ctO[off++] = c;
2214412e9a14SMatthew G. Knepley     }
2215412e9a14SMatthew G. Knepley   }
2216412e9a14SMatthew G. Knepley   if (DMPolytopeTypeGetDim(ctCell) != 0) {
2217412e9a14SMatthew G. Knepley     for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
2218412e9a14SMatthew G. Knepley       if (DMPolytopeTypeGetDim((DMPolytopeType) c) != 0) continue;
2219412e9a14SMatthew G. Knepley       ctO[off++] = c;
2220412e9a14SMatthew G. Knepley     }
2221412e9a14SMatthew G. Knepley   }
2222412e9a14SMatthew G. Knepley   for (d = DMPolytopeTypeGetDim(ctCell)-1; d > 0; --d) {
2223412e9a14SMatthew G. Knepley     for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
2224412e9a14SMatthew G. Knepley       if (DMPolytopeTypeGetDim((DMPolytopeType) c) != d) continue;
2225412e9a14SMatthew G. Knepley       ctO[off++] = c;
2226412e9a14SMatthew G. Knepley     }
2227412e9a14SMatthew G. Knepley   }
2228412e9a14SMatthew G. Knepley   for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
2229412e9a14SMatthew G. Knepley     if (DMPolytopeTypeGetDim((DMPolytopeType) c) >= 0) continue;
2230412e9a14SMatthew G. Knepley     ctO[off++] = c;
2231412e9a14SMatthew G. Knepley   }
2232412e9a14SMatthew G. Knepley   if (off != DM_NUM_POLYTOPES+1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid offset %D for cell type order", off);
2233412e9a14SMatthew G. Knepley   for (c = 0; c <= DM_NUM_POLYTOPES; ++c) {
2234412e9a14SMatthew G. Knepley     ctOInv[ctO[c]] = c;
2235412e9a14SMatthew G. Knepley   }
2236412e9a14SMatthew G. Knepley   *ctOrder    = ctO;
2237412e9a14SMatthew G. Knepley   *ctOrderInv = ctOInv;
2238412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2239412e9a14SMatthew G. Knepley }
2240412e9a14SMatthew G. Knepley 
2241412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerSetUp(DMPlexCellRefiner cr)
2242412e9a14SMatthew G. Knepley {
2243412e9a14SMatthew G. Knepley   DM             dm = cr->dm;
2244412e9a14SMatthew G. Knepley   DMPolytopeType ctCell;
2245412e9a14SMatthew G. Knepley   PetscInt       pStart, pEnd, p, c;
2246412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2247412e9a14SMatthew G. Knepley 
2248412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2249412e9a14SMatthew G. Knepley   PetscValidHeader(cr, 1);
2250412e9a14SMatthew G. Knepley   if (cr->setupcalled) PetscFunctionReturn(0);
2251a5801f52SStefano Zampini   if (cr->ops->setup) {
2252a5801f52SStefano Zampini     ierr = (*cr->ops->setup)(cr);CHKERRQ(ierr);
2253a5801f52SStefano Zampini   }
2254412e9a14SMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
2255a5801f52SStefano Zampini   if (pEnd > pStart) {
2256a5801f52SStefano Zampini     ierr = DMPlexGetCellType(dm, 0, &ctCell);CHKERRQ(ierr);
2257a5801f52SStefano Zampini   } else {
2258412e9a14SMatthew G. Knepley     PetscInt dim;
2259a57030b0SMatthew G. Knepley     ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
2260412e9a14SMatthew G. Knepley     switch (dim) {
2261412e9a14SMatthew G. Knepley     case 0: ctCell = DM_POLYTOPE_POINT;break;
2262412e9a14SMatthew G. Knepley     case 1: ctCell = DM_POLYTOPE_SEGMENT;break;
2263412e9a14SMatthew G. Knepley     case 2: ctCell = DM_POLYTOPE_TRIANGLE;break;
2264412e9a14SMatthew G. Knepley     case 3: ctCell = DM_POLYTOPE_TETRAHEDRON;break;
2265a5801f52SStefano Zampini     default: ctCell = DM_POLYTOPE_UNKNOWN;
2266412e9a14SMatthew G. Knepley     }
2267412e9a14SMatthew G. Knepley   }
2268412e9a14SMatthew G. Knepley   ierr = DMPlexCreateCellTypeOrder_Internal(ctCell, &cr->ctOrder, &cr->ctOrderInv);CHKERRQ(ierr);
2269412e9a14SMatthew G. Knepley   /* Construct sizes and offsets for each cell type */
2270412e9a14SMatthew G. Knepley   if (!cr->ctStart) {
2271412e9a14SMatthew G. Knepley     PetscInt *ctS, *ctSN, *ctC, *ctCN;
2272412e9a14SMatthew G. Knepley 
2273412e9a14SMatthew G. Knepley     ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctS, DM_NUM_POLYTOPES+1, &ctSN);CHKERRQ(ierr);
2274412e9a14SMatthew G. Knepley     ierr = PetscCalloc2(DM_NUM_POLYTOPES+1, &ctC, DM_NUM_POLYTOPES+1, &ctCN);CHKERRQ(ierr);
2275412e9a14SMatthew G. Knepley     for (p = pStart; p < pEnd; ++p) {
2276412e9a14SMatthew G. Knepley       DMPolytopeType  ct;
2277412e9a14SMatthew G. Knepley       DMPolytopeType *rct;
2278412e9a14SMatthew G. Knepley       PetscInt       *rsize, *cone, *ornt;
2279412e9a14SMatthew G. Knepley       PetscInt        Nct, n;
2280412e9a14SMatthew G. Knepley 
2281412e9a14SMatthew G. Knepley       ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2282412e9a14SMatthew G. Knepley       if ((PetscInt) ct < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No cell type for point %D", p);
2283412e9a14SMatthew G. Knepley       ++ctC[ct];
2284412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr);
2285412e9a14SMatthew G. Knepley       for (n = 0; n < Nct; ++n) ctCN[rct[n]] += rsize[n];
2286412e9a14SMatthew G. Knepley     }
2287412e9a14SMatthew G. Knepley     for (c = 0; c < DM_NUM_POLYTOPES; ++c) {
2288412e9a14SMatthew G. Knepley       const PetscInt ct  = cr->ctOrder[c];
2289412e9a14SMatthew G. Knepley       const PetscInt ctn = cr->ctOrder[c+1];
2290412e9a14SMatthew G. Knepley 
2291412e9a14SMatthew G. Knepley       ctS[ctn]  = ctS[ct]  + ctC[ct];
2292412e9a14SMatthew G. Knepley       ctSN[ctn] = ctSN[ct] + ctCN[ct];
2293412e9a14SMatthew G. Knepley     }
2294412e9a14SMatthew G. Knepley     ierr = PetscFree2(ctC, ctCN);CHKERRQ(ierr);
2295412e9a14SMatthew G. Knepley     cr->ctStart    = ctS;
2296412e9a14SMatthew G. Knepley     cr->ctStartNew = ctSN;
2297412e9a14SMatthew G. Knepley   }
2298412e9a14SMatthew G. Knepley   ierr = CellRefinerCreateOffset_Internal(cr, cr->ctOrder, cr->ctStart, &cr->offset);CHKERRQ(ierr);
2299412e9a14SMatthew G. Knepley   cr->setupcalled = PETSC_TRUE;
2300412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2301412e9a14SMatthew G. Knepley }
2302412e9a14SMatthew G. Knepley 
2303412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView_Ascii(DMPlexCellRefiner cr, PetscViewer v)
2304412e9a14SMatthew G. Knepley {
2305412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2306412e9a14SMatthew G. Knepley 
2307412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2308412e9a14SMatthew G. Knepley   ierr = PetscViewerASCIIPrintf(v, "Cell Refiner: %s\n", DMPlexCellRefinerTypes[cr->type]);CHKERRQ(ierr);
2309412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2310412e9a14SMatthew G. Knepley }
2311412e9a14SMatthew G. Knepley 
2312412e9a14SMatthew G. Knepley /*
2313412e9a14SMatthew G. Knepley   DMPlexCellRefinerView - Views a DMPlexCellRefiner object
2314412e9a14SMatthew G. Knepley 
2315412e9a14SMatthew G. Knepley   Collective on cr
2316412e9a14SMatthew G. Knepley 
2317412e9a14SMatthew G. Knepley   Input Parameters:
2318412e9a14SMatthew G. Knepley + cr     - The DMPlexCellRefiner object
2319412e9a14SMatthew G. Knepley - viewer - The PetscViewer object
2320412e9a14SMatthew G. Knepley 
2321412e9a14SMatthew G. Knepley   Level: beginner
2322412e9a14SMatthew G. Knepley 
2323412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerCreate()
2324412e9a14SMatthew G. Knepley */
2325412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerView(DMPlexCellRefiner cr, PetscViewer viewer)
2326412e9a14SMatthew G. Knepley {
2327412e9a14SMatthew G. Knepley   PetscBool      iascii;
2328412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2329412e9a14SMatthew G. Knepley 
2330412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2331412e9a14SMatthew G. Knepley   PetscValidHeader(cr, 1);
2332412e9a14SMatthew G. Knepley   if (viewer) PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
2333412e9a14SMatthew G. Knepley   if (!viewer) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) cr), &viewer);CHKERRQ(ierr);}
2334412e9a14SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
2335412e9a14SMatthew G. Knepley   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2336412e9a14SMatthew G. Knepley   if (iascii) {ierr = DMPlexCellRefinerView_Ascii(cr, viewer);CHKERRQ(ierr);}
2337412e9a14SMatthew G. Knepley   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2338412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2339412e9a14SMatthew G. Knepley }
2340412e9a14SMatthew G. Knepley 
2341412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerDestroy(DMPlexCellRefiner *cr)
2342412e9a14SMatthew G. Knepley {
2343412e9a14SMatthew G. Knepley   PetscInt       c;
2344412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2345412e9a14SMatthew G. Knepley 
2346412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2347412e9a14SMatthew G. Knepley   if (!*cr) PetscFunctionReturn(0);
2348412e9a14SMatthew G. Knepley   PetscValidHeaderSpecific(*cr, DM_CLASSID, 1);
2349a5801f52SStefano Zampini   if ((*cr)->ops->destroy) {
2350a5801f52SStefano Zampini     ierr = ((*cr)->ops->destroy)(*cr);CHKERRQ(ierr);
2351a5801f52SStefano Zampini   }
2352412e9a14SMatthew G. Knepley   ierr = PetscObjectDereference((PetscObject) (*cr)->dm);CHKERRQ(ierr);
2353412e9a14SMatthew G. Knepley   ierr = PetscFree2((*cr)->ctOrder, (*cr)->ctOrderInv);CHKERRQ(ierr);
2354412e9a14SMatthew G. Knepley   ierr = PetscFree2((*cr)->ctStart, (*cr)->ctStartNew);CHKERRQ(ierr);
2355412e9a14SMatthew G. Knepley   ierr = PetscFree((*cr)->offset);CHKERRQ(ierr);
2356412e9a14SMatthew G. Knepley   for (c = 0; c < DM_NUM_POLYTOPES; ++c) {
2357412e9a14SMatthew G. Knepley     ierr = PetscFEDestroy(&(*cr)->coordFE[c]);CHKERRQ(ierr);
2358412e9a14SMatthew G. Knepley     ierr = PetscFEGeomDestroy(&(*cr)->refGeom[c]);CHKERRQ(ierr);
2359412e9a14SMatthew G. Knepley   }
2360412e9a14SMatthew G. Knepley   ierr = PetscFree2((*cr)->coordFE, (*cr)->refGeom);CHKERRQ(ierr);
2361412e9a14SMatthew G. Knepley   ierr = PetscHeaderDestroy(cr);CHKERRQ(ierr);
2362412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2363412e9a14SMatthew G. Knepley }
2364412e9a14SMatthew G. Knepley 
2365412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerCreate(DM dm, DMPlexCellRefiner *cr)
2366412e9a14SMatthew G. Knepley {
2367412e9a14SMatthew G. Knepley   DMPlexCellRefiner tmp;
2368412e9a14SMatthew G. Knepley   PetscErrorCode    ierr;
2369412e9a14SMatthew G. Knepley 
2370412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2371412e9a14SMatthew G. Knepley   PetscValidPointer(cr, 2);
2372412e9a14SMatthew G. Knepley   *cr  = NULL;
2373412e9a14SMatthew G. Knepley   ierr = PetscHeaderCreate(tmp, DM_CLASSID, "DMPlexCellRefiner", "Cell Refiner", "DMPlexCellRefiner", PETSC_COMM_SELF, DMPlexCellRefinerDestroy, DMPlexCellRefinerView);CHKERRQ(ierr);
2374412e9a14SMatthew G. Knepley   tmp->setupcalled = PETSC_FALSE;
2375412e9a14SMatthew G. Knepley 
2376412e9a14SMatthew G. Knepley   tmp->dm = dm;
2377412e9a14SMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr);
2378412e9a14SMatthew G. Knepley   ierr = DMPlexGetCellRefinerType(dm, &tmp->type);CHKERRQ(ierr);
2379412e9a14SMatthew G. Knepley   switch (tmp->type) {
238096ca5757SLisandro Dalcin   case DM_REFINER_REGULAR:
2381412e9a14SMatthew G. Knepley     tmp->ops->refine                  = DMPlexCellRefinerRefine_Regular;
2382412e9a14SMatthew G. Knepley     tmp->ops->mapsubcells             = DMPlexCellRefinerMapSubcells_Regular;
2383412e9a14SMatthew G. Knepley     tmp->ops->getcellvertices         = DMPlexCellRefinerGetCellVertices_Regular;
2384412e9a14SMatthew G. Knepley     tmp->ops->getsubcellvertices      = DMPlexCellRefinerGetSubcellVertices_Regular;
2385a5801f52SStefano Zampini     tmp->ops->mapcoords               = DMPlexCellRefinerMapCoordinates_Barycenter;
2386412e9a14SMatthew G. Knepley     tmp->ops->getaffinetransforms     = DMPlexCellRefinerGetAffineTransforms_Regular;
2387412e9a14SMatthew G. Knepley     tmp->ops->getaffinefacetransforms = DMPlexCellRefinerGetAffineFaceTransforms_Regular;
2388412e9a14SMatthew G. Knepley     break;
238996ca5757SLisandro Dalcin   case DM_REFINER_TO_BOX:
239096ca5757SLisandro Dalcin     tmp->ops->refine             = DMPlexCellRefinerRefine_ToBox;
239196ca5757SLisandro Dalcin     tmp->ops->mapsubcells        = DMPlexCellRefinerMapSubcells_ToBox;
239296ca5757SLisandro Dalcin     tmp->ops->getcellvertices    = DMPlexCellRefinerGetCellVertices_ToBox;
239396ca5757SLisandro Dalcin     tmp->ops->getsubcellvertices = DMPlexCellRefinerGetSubcellVertices_ToBox;
2394a5801f52SStefano Zampini     tmp->ops->mapcoords          = DMPlexCellRefinerMapCoordinates_Barycenter;
2395412e9a14SMatthew G. Knepley     break;
239696ca5757SLisandro Dalcin   case DM_REFINER_TO_SIMPLEX:
2397412e9a14SMatthew G. Knepley     tmp->ops->refine      = DMPlexCellRefinerRefine_ToSimplex;
2398412e9a14SMatthew G. Knepley     tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_ToSimplex;
2399a5801f52SStefano Zampini     tmp->ops->mapcoords   = DMPlexCellRefinerMapCoordinates_Barycenter;
2400412e9a14SMatthew G. Knepley     break;
2401cf4091a3SMatthew G. Knepley   case DM_REFINER_ALFELD2D:
2402cf4091a3SMatthew G. Knepley     tmp->ops->refine      = DMPlexCellRefinerRefine_Alfeld2D;
2403cf4091a3SMatthew G. Knepley     tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None;
2404a5801f52SStefano Zampini     tmp->ops->mapcoords   = DMPlexCellRefinerMapCoordinates_Barycenter;
2405cf4091a3SMatthew G. Knepley     break;
2406cf4091a3SMatthew G. Knepley   case DM_REFINER_ALFELD3D:
2407cf4091a3SMatthew G. Knepley     tmp->ops->refine      = DMPlexCellRefinerRefine_Alfeld3D;
2408cf4091a3SMatthew G. Knepley     tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_None;
2409a5801f52SStefano Zampini     tmp->ops->mapcoords   = DMPlexCellRefinerMapCoordinates_Barycenter;
2410cf4091a3SMatthew G. Knepley     break;
2411a5801f52SStefano Zampini   case DM_REFINER_BOUNDARYLAYER:
2412a5801f52SStefano Zampini     tmp->ops->setup       = DMPlexCellRefinerSetUp_BL;
2413a5801f52SStefano Zampini     tmp->ops->destroy     = DMPlexCellRefinerDestroy_BL;
2414cf4091a3SMatthew G. Knepley     tmp->ops->refine      = DMPlexCellRefinerRefine_BL;
2415cf4091a3SMatthew G. Knepley     tmp->ops->mapsubcells = DMPlexCellRefinerMapSubcells_BL;
2416a5801f52SStefano Zampini     tmp->ops->mapcoords   = DMPlexCellRefinerMapCoordinates_BL;
2417cf4091a3SMatthew G. Knepley     break;
2418412e9a14SMatthew G. Knepley   default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Invalid cell refiner type %s", DMPlexCellRefinerTypes[tmp->type]);
2419412e9a14SMatthew G. Knepley   }
2420412e9a14SMatthew G. Knepley   ierr = PetscCalloc2(DM_NUM_POLYTOPES, &tmp->coordFE, DM_NUM_POLYTOPES, &tmp->refGeom);CHKERRQ(ierr);
2421412e9a14SMatthew G. Knepley   *cr = tmp;
2422412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2423412e9a14SMatthew G. Knepley }
2424412e9a14SMatthew G. Knepley 
2425412e9a14SMatthew G. Knepley /*@
2426412e9a14SMatthew G. Knepley   DMPlexCellRefinerGetAffineTransforms - Gets the affine map from the reference cell to each subcell
2427412e9a14SMatthew G. Knepley 
2428412e9a14SMatthew G. Knepley   Input Parameters:
2429412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object
2430412e9a14SMatthew G. Knepley - ct - The cell type
2431412e9a14SMatthew G. Knepley 
2432412e9a14SMatthew G. Knepley   Output Parameters:
2433412e9a14SMatthew G. Knepley + Nc   - The number of subcells produced from this cell type
2434412e9a14SMatthew G. Knepley . v0   - The translation of the first vertex for each subcell
2435412e9a14SMatthew G. Knepley . J    - The Jacobian for each subcell (map from reference cell to subcell)
2436412e9a14SMatthew G. Knepley - invJ - The inverse Jacobian for each subcell
2437412e9a14SMatthew G. Knepley 
2438412e9a14SMatthew G. Knepley   Level: developer
2439412e9a14SMatthew G. Knepley 
2440412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineFaceTransforms(), Create()
2441412e9a14SMatthew G. Knepley @*/
2442412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nc, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[])
2443412e9a14SMatthew G. Knepley {
2444412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2445412e9a14SMatthew G. Knepley 
2446412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2447412e9a14SMatthew G. Knepley   if (!cr->ops->getaffinetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine transforms from this refiner");
2448412e9a14SMatthew G. Knepley   ierr = (*cr->ops->getaffinetransforms)(cr, ct, Nc, v0, J, invJ);CHKERRQ(ierr);
2449412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2450412e9a14SMatthew G. Knepley }
2451412e9a14SMatthew G. Knepley 
2452412e9a14SMatthew G. Knepley /*@
2453412e9a14SMatthew G. Knepley   DMPlexCellRefinerGetAffineFaceTransforms - Gets the affine map from the reference face cell to each face in the given cell
2454412e9a14SMatthew G. Knepley 
2455412e9a14SMatthew G. Knepley   Input Parameters:
2456412e9a14SMatthew G. Knepley + cr - The DMPlexCellRefiner object
2457412e9a14SMatthew G. Knepley - ct - The cell type
2458412e9a14SMatthew G. Knepley 
2459412e9a14SMatthew G. Knepley   Output Parameters:
2460412e9a14SMatthew G. Knepley + Nf   - The number of faces for this cell type
2461412e9a14SMatthew G. Knepley . v0   - The translation of the first vertex for each face
2462412e9a14SMatthew G. Knepley . J    - The Jacobian for each face (map from original cell to subcell)
2463412e9a14SMatthew G. Knepley . invJ - The inverse Jacobian for each face
2464412e9a14SMatthew G. Knepley - detJ - The determinant of the Jacobian for each face
2465412e9a14SMatthew G. Knepley 
2466412e9a14SMatthew G. Knepley   Note: The Jacobian and inverse Jacboian will be rectangular, and the inverse is really a generalized inverse.
2467412e9a14SMatthew G. Knepley 
2468412e9a14SMatthew G. Knepley   Level: developer
2469412e9a14SMatthew G. Knepley 
2470412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerGetAffineTransforms(), Create()
2471412e9a14SMatthew G. Knepley @*/
2472412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetAffineFaceTransforms(DMPlexCellRefiner cr, DMPolytopeType ct, PetscInt *Nf, PetscReal *v0[], PetscReal *J[], PetscReal *invJ[], PetscReal *detJ[])
2473412e9a14SMatthew G. Knepley {
2474412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2475412e9a14SMatthew G. Knepley 
2476412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2477412e9a14SMatthew G. Knepley   if (!cr->ops->getaffinefacetransforms) SETERRQ(PetscObjectComm((PetscObject) cr), PETSC_ERR_SUP, "No support for affine face transforms from this refiner");
2478412e9a14SMatthew G. Knepley   ierr = (*cr->ops->getaffinefacetransforms)(cr, ct, Nf, v0, J, invJ, detJ);CHKERRQ(ierr);
2479412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2480412e9a14SMatthew G. Knepley }
2481412e9a14SMatthew G. Knepley 
2482412e9a14SMatthew G. Knepley /* Numbering regularly refined meshes
2483412e9a14SMatthew G. Knepley 
2484412e9a14SMatthew G. Knepley    We want the numbering of the new mesh to respect the same depth stratification as the old mesh. We first compute
2485412e9a14SMatthew G. Knepley    the number of new points at each depth. This means that offsets for each depth can be computed, making no assumptions
2486412e9a14SMatthew G. Knepley    about the order of different cell types.
2487412e9a14SMatthew G. Knepley 
2488412e9a14SMatthew G. Knepley    However, when we want to order different depth strata, it will be very useful to make assumptions about contiguous
2489412e9a14SMatthew G. Knepley    numbering of different cell types, especially if we want to compute new numberings without communication. Therefore, we
2490412e9a14SMatthew G. Knepley    will require that cells are numbering contiguously for each cell type, and that those blocks come in the same order as
2491412e9a14SMatthew G. Knepley    the cell type enumeration within a given depth stratum.
2492412e9a14SMatthew G. Knepley 
2493412e9a14SMatthew 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
2494412e9a14SMatthew G. Knepley    start at the new depth offset, run through all prior cell types incrementing by the total addition from that type, then
2495412e9a14SMatthew G. Knepley    offset by the old cell type number and replica number for the insertion.
2496412e9a14SMatthew G. Knepley */
2497412e9a14SMatthew G. Knepley PetscErrorCode DMPlexCellRefinerGetNewPoint(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType ctNew, PetscInt p, PetscInt r, PetscInt *pNew)
2498412e9a14SMatthew G. Knepley {
2499412e9a14SMatthew G. Knepley   DMPolytopeType *rct;
2500412e9a14SMatthew G. Knepley   PetscInt       *rsize, *cone, *ornt;
2501412e9a14SMatthew G. Knepley   PetscInt       Nct, n;
2502412e9a14SMatthew G. Knepley   PetscInt       off  = cr->offset[ct*DM_NUM_POLYTOPES+ctNew];
2503412e9a14SMatthew G. Knepley   PetscInt       ctS  = cr->ctStart[ct],       ctE  = cr->ctStart[cr->ctOrder[cr->ctOrderInv[ct]+1]];
2504412e9a14SMatthew G. Knepley   PetscInt       ctSN = cr->ctStartNew[ctNew], ctEN = cr->ctStartNew[cr->ctOrder[cr->ctOrderInv[ctNew]+1]];
2505412e9a14SMatthew G. Knepley   PetscInt       newp = ctSN;
2506412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2507412e9a14SMatthew G. Knepley 
2508412e9a14SMatthew G. Knepley   PetscFunctionBeginHot;
2509412e9a14SMatthew 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);
2510412e9a14SMatthew 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]);
2511412e9a14SMatthew G. Knepley 
2512412e9a14SMatthew G. Knepley   newp += off;
2513412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &cone, &ornt);CHKERRQ(ierr);
2514412e9a14SMatthew G. Knepley   for (n = 0; n < Nct; ++n) {
2515412e9a14SMatthew G. Knepley     if (rct[n] == ctNew) {
2516412e9a14SMatthew G. Knepley       if (rsize[n] && r >= rsize[n])
2517412e9a14SMatthew 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]);
2518412e9a14SMatthew G. Knepley       newp += (p - ctS) * rsize[n] + r;
2519412e9a14SMatthew G. Knepley       break;
2520412e9a14SMatthew G. Knepley     }
2521412e9a14SMatthew G. Knepley   }
2522412e9a14SMatthew G. Knepley 
2523412e9a14SMatthew 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);
2524412e9a14SMatthew G. Knepley   *pNew = newp;
2525412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2526412e9a14SMatthew G. Knepley }
2527412e9a14SMatthew G. Knepley 
2528412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetConeSizes(DMPlexCellRefiner cr, DM rdm)
2529412e9a14SMatthew G. Knepley {
2530412e9a14SMatthew G. Knepley   DM              dm = cr->dm;
2531412e9a14SMatthew G. Knepley   PetscInt        pStart, pEnd, p, pNew;
2532412e9a14SMatthew G. Knepley   PetscErrorCode  ierr;
2533412e9a14SMatthew G. Knepley 
2534412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2535412e9a14SMatthew G. Knepley   /* Must create the celltype label here so that we do not automatically try to compute the types */
2536412e9a14SMatthew G. Knepley   ierr = DMCreateLabel(rdm, "celltype");CHKERRQ(ierr);
2537412e9a14SMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
2538412e9a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2539412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
2540412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2541412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2542412e9a14SMatthew G. Knepley     PetscInt        Nct, n, r;
2543412e9a14SMatthew G. Knepley 
2544412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2545412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2546412e9a14SMatthew G. Knepley     for (n = 0; n < Nct; ++n) {
2547412e9a14SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r) {
2548412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr);
2549412e9a14SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, pNew, DMPolytopeTypeGetConeSize(rct[n]));CHKERRQ(ierr);
2550412e9a14SMatthew G. Knepley         ierr = DMPlexSetCellType(rdm, pNew, rct[n]);CHKERRQ(ierr);
2551412e9a14SMatthew G. Knepley       }
2552412e9a14SMatthew G. Knepley     }
2553412e9a14SMatthew G. Knepley   }
2554412e9a14SMatthew G. Knepley   {
2555412e9a14SMatthew G. Knepley     DMLabel  ctLabel;
2556412e9a14SMatthew G. Knepley     DM_Plex *plex = (DM_Plex *) rdm->data;
2557412e9a14SMatthew G. Knepley 
2558412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellTypeLabel(rdm, &ctLabel);CHKERRQ(ierr);
2559412e9a14SMatthew G. Knepley     ierr = PetscObjectStateGet((PetscObject) ctLabel, &plex->celltypeState);CHKERRQ(ierr);
2560412e9a14SMatthew G. Knepley   }
2561412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2562412e9a14SMatthew G. Knepley }
2563412e9a14SMatthew G. Knepley 
2564412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCones(DMPlexCellRefiner cr, DM rdm)
2565412e9a14SMatthew G. Knepley {
2566412e9a14SMatthew G. Knepley   DM             dm = cr->dm;
2567412e9a14SMatthew G. Knepley   DMPolytopeType ct;
2568412e9a14SMatthew G. Knepley   PetscInt      *coneNew, *orntNew;
2569412e9a14SMatthew G. Knepley   PetscInt       maxConeSize = 0, pStart, pEnd, p, pNew;
2570412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2571412e9a14SMatthew G. Knepley 
2572412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2573412e9a14SMatthew G. Knepley   for (p = 0; p < DM_NUM_POLYTOPES; ++p) maxConeSize = PetscMax(maxConeSize, DMPolytopeTypeGetConeSize((DMPolytopeType) p));
2574412e9a14SMatthew G. Knepley   ierr = PetscMalloc2(maxConeSize, &coneNew, maxConeSize, &orntNew);CHKERRQ(ierr);
2575412e9a14SMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
2576412e9a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2577412e9a14SMatthew G. Knepley     const PetscInt *cone, *ornt;
2578412e9a14SMatthew G. Knepley     PetscInt        coff, ooff, c;
2579412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2580412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2581412e9a14SMatthew G. Knepley     PetscInt        Nct, n, r;
2582412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2583412e9a14SMatthew G. Knepley     ierr = DMPlexGetCone(dm, p, &cone);CHKERRQ(ierr);
2584412e9a14SMatthew G. Knepley     ierr = DMPlexGetConeOrientation(dm, p, &ornt);CHKERRQ(ierr);
2585412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2586412e9a14SMatthew G. Knepley     for (n = 0, coff = 0, ooff = 0; n < Nct; ++n) {
2587412e9a14SMatthew G. Knepley       const DMPolytopeType ctNew    = rct[n];
2588412e9a14SMatthew G. Knepley       const PetscInt       csizeNew = DMPolytopeTypeGetConeSize(ctNew);
2589412e9a14SMatthew G. Knepley 
2590412e9a14SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r) {
2591412e9a14SMatthew G. Knepley         /* pNew is a subcell produced by subdividing p */
2592412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr);
2593412e9a14SMatthew G. Knepley         for (c = 0; c < csizeNew; ++c) {
2594412e9a14SMatthew G. Knepley           PetscInt             ppp   = -1;                             /* Parent Parent point: Parent of point pp */
2595412e9a14SMatthew G. Knepley           PetscInt             pp    = p;                              /* Parent point: Point in the original mesh producing new cone point */
2596412e9a14SMatthew G. Knepley           PetscInt             po    = 0;                              /* Orientation of parent point pp in parent parent point ppp */
2597412e9a14SMatthew G. Knepley           DMPolytopeType       pct   = ct;                             /* Parent type: Cell type for parent of new cone point */
2598412e9a14SMatthew G. Knepley           const PetscInt      *pcone = cone;                           /* Parent cone: Cone of parent point pp */
2599412e9a14SMatthew G. Knepley           PetscInt             pr    = -1;                             /* Replica number of pp that produces new cone point  */
2600412e9a14SMatthew G. Knepley           const DMPolytopeType ft    = (DMPolytopeType) rcone[coff++]; /* Cell type for new cone point of pNew */
2601412e9a14SMatthew G. Knepley           const PetscInt       fn    = rcone[coff++];                  /* Number of cones of p that need to be taken when producing new cone point */
2602412e9a14SMatthew G. Knepley           PetscInt             fo    = rornt[ooff++];                  /* Orientation of new cone point in pNew */
2603412e9a14SMatthew G. Knepley           PetscInt             lc;
2604412e9a14SMatthew G. Knepley 
2605412e9a14SMatthew G. Knepley           /* Get the type (pct) and point number (pp) of the parent point in the original mesh which produces this cone point */
2606412e9a14SMatthew G. Knepley           for (lc = 0; lc < fn; ++lc) {
2607412e9a14SMatthew G. Knepley             const PetscInt *ppornt;
2608412e9a14SMatthew G. Knepley             PetscInt        pcp;
2609412e9a14SMatthew G. Knepley 
2610412e9a14SMatthew G. Knepley             ierr = DMPolytopeMapCell(pct, po, rcone[coff++], &pcp);CHKERRQ(ierr);
2611412e9a14SMatthew G. Knepley             ppp  = pp;
2612412e9a14SMatthew G. Knepley             pp   = pcone[pcp];
2613412e9a14SMatthew G. Knepley             ierr = DMPlexGetCellType(dm, pp, &pct);CHKERRQ(ierr);
2614412e9a14SMatthew G. Knepley             ierr = DMPlexGetCone(dm, pp, &pcone);CHKERRQ(ierr);
2615412e9a14SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, ppp, &ppornt);CHKERRQ(ierr);
2616cf4091a3SMatthew G. Knepley             if (po <  0 && pct != DM_POLYTOPE_POINT) {
2617cf4091a3SMatthew G. Knepley               const PetscInt pornt   = ppornt[pcp];
2618cf4091a3SMatthew G. Knepley               const PetscInt pcsize  = DMPolytopeTypeGetConeSize(pct);
2619cf4091a3SMatthew G. Knepley               const PetscInt pcstart = pornt < 0 ? -(pornt+1) : pornt;
2620cf4091a3SMatthew G. Knepley               const PetscInt rcstart = (pcstart+pcsize-1)%pcsize;
2621cf4091a3SMatthew G. Knepley               po = pornt < 0 ? -(rcstart+1) : rcstart;
2622cf4091a3SMatthew G. Knepley             } else {
2623412e9a14SMatthew G. Knepley               po = ppornt[pcp];
2624412e9a14SMatthew G. Knepley             }
2625cf4091a3SMatthew G. Knepley           }
2626412e9a14SMatthew G. Knepley           pr = rcone[coff++];
2627412e9a14SMatthew G. Knepley           /* Orientation po of pp maps (pr, fo) -> (pr', fo') */
2628412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerMapSubcells(cr, pct, po, ft, pr, fo, &pr, &fo);CHKERRQ(ierr);
2629412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerGetNewPoint(cr, pct, ft, pp, pr, &coneNew[c]);CHKERRQ(ierr);
2630412e9a14SMatthew G. Knepley           orntNew[c] = fo;
2631412e9a14SMatthew G. Knepley         }
2632412e9a14SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, pNew, coneNew);CHKERRQ(ierr);
2633412e9a14SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, pNew, orntNew);CHKERRQ(ierr);
2634412e9a14SMatthew G. Knepley       }
2635412e9a14SMatthew G. Knepley     }
2636412e9a14SMatthew G. Knepley   }
2637412e9a14SMatthew G. Knepley   ierr = PetscFree2(coneNew, orntNew);CHKERRQ(ierr);
2638412e9a14SMatthew G. Knepley   ierr = DMPlexSymmetrize(rdm);CHKERRQ(ierr);
2639412e9a14SMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
2640412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2641412e9a14SMatthew G. Knepley }
2642412e9a14SMatthew G. Knepley 
2643412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerGetCoordinateFE(DMPlexCellRefiner cr, DMPolytopeType ct, PetscFE *fe)
2644412e9a14SMatthew G. Knepley {
2645412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2646412e9a14SMatthew G. Knepley 
2647412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2648412e9a14SMatthew G. Knepley   if (!cr->coordFE[ct]) {
2649412e9a14SMatthew G. Knepley     PetscInt  dim, cdim;
2650412e9a14SMatthew G. Knepley     PetscBool isSimplex;
2651412e9a14SMatthew G. Knepley 
2652412e9a14SMatthew G. Knepley     switch (ct) {
2653412e9a14SMatthew G. Knepley       case DM_POLYTOPE_SEGMENT:       dim = 1; isSimplex = PETSC_TRUE;  break;
2654412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TRIANGLE:      dim = 2; isSimplex = PETSC_TRUE;  break;
2655412e9a14SMatthew G. Knepley       case DM_POLYTOPE_QUADRILATERAL: dim = 2; isSimplex = PETSC_FALSE; break;
2656412e9a14SMatthew G. Knepley       case DM_POLYTOPE_TETRAHEDRON:   dim = 3; isSimplex = PETSC_TRUE;  break;
2657412e9a14SMatthew G. Knepley       case DM_POLYTOPE_HEXAHEDRON:    dim = 3; isSimplex = PETSC_FALSE; break;
2658412e9a14SMatthew G. Knepley       default: SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "No coordinate FE for cell type %s", DMPolytopeTypes[ct]);
2659412e9a14SMatthew G. Knepley     }
2660412e9a14SMatthew G. Knepley     ierr = DMGetCoordinateDim(cr->dm, &cdim);CHKERRQ(ierr);
2661412e9a14SMatthew G. Knepley     ierr = PetscFECreateLagrange(PETSC_COMM_SELF, dim, cdim, isSimplex, 1, PETSC_DETERMINE, &cr->coordFE[ct]);CHKERRQ(ierr);
2662412e9a14SMatthew G. Knepley     {
2663412e9a14SMatthew G. Knepley       PetscDualSpace  dsp;
2664412e9a14SMatthew G. Knepley       PetscQuadrature quad;
2665412e9a14SMatthew G. Knepley       DM              K;
2666412e9a14SMatthew G. Knepley       PetscFEGeom    *cg;
2667412e9a14SMatthew G. Knepley       PetscReal      *Xq, *xq, *wq;
2668412e9a14SMatthew G. Knepley       PetscInt        Nq, q;
2669412e9a14SMatthew G. Knepley 
2670412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerGetCellVertices(cr, ct, &Nq, &Xq);CHKERRQ(ierr);
2671412e9a14SMatthew G. Knepley       ierr = PetscMalloc1(Nq*cdim, &xq);CHKERRQ(ierr);
2672412e9a14SMatthew G. Knepley       for (q = 0; q < Nq*cdim; ++q) xq[q] = Xq[q];
2673412e9a14SMatthew G. Knepley       ierr = PetscMalloc1(Nq, &wq);CHKERRQ(ierr);
2674412e9a14SMatthew G. Knepley       for (q = 0; q < Nq; ++q) wq[q] = 1.0;
2675412e9a14SMatthew G. Knepley       ierr = PetscQuadratureCreate(PETSC_COMM_SELF, &quad);CHKERRQ(ierr);
2676412e9a14SMatthew G. Knepley       ierr = PetscQuadratureSetData(quad, dim, 1, Nq, xq, wq);CHKERRQ(ierr);
2677412e9a14SMatthew G. Knepley       ierr = PetscFESetQuadrature(cr->coordFE[ct], quad);CHKERRQ(ierr);
2678412e9a14SMatthew G. Knepley 
2679412e9a14SMatthew G. Knepley       ierr = PetscFEGetDualSpace(cr->coordFE[ct], &dsp);CHKERRQ(ierr);
2680412e9a14SMatthew G. Knepley       ierr = PetscDualSpaceGetDM(dsp, &K);CHKERRQ(ierr);
2681412e9a14SMatthew G. Knepley       ierr = PetscFEGeomCreate(quad, 1, cdim, PETSC_FALSE, &cr->refGeom[ct]);CHKERRQ(ierr);
2682412e9a14SMatthew G. Knepley       cg   = cr->refGeom[ct];
2683412e9a14SMatthew G. Knepley       ierr = DMPlexComputeCellGeometryFEM(K, 0, NULL, cg->v, cg->J, cg->invJ, cg->detJ);CHKERRQ(ierr);
2684412e9a14SMatthew G. Knepley       ierr = PetscQuadratureDestroy(&quad);CHKERRQ(ierr);
2685412e9a14SMatthew G. Knepley     }
2686412e9a14SMatthew G. Knepley   }
2687412e9a14SMatthew G. Knepley   *fe = cr->coordFE[ct];
2688412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2689412e9a14SMatthew G. Knepley }
2690412e9a14SMatthew G. Knepley 
2691412e9a14SMatthew G. Knepley /*
2692412e9a14SMatthew G. Knepley   DMPlexCellRefinerMapLocalizedCoordinates - Given a cell of type ct with localized coordinates x, we generate localized coordinates xr for subcell r of type rct.
2693412e9a14SMatthew G. Knepley 
2694412e9a14SMatthew G. Knepley   Not collective
2695412e9a14SMatthew G. Knepley 
2696412e9a14SMatthew G. Knepley   Input Parameters:
2697412e9a14SMatthew G. Knepley + cr  - The DMPlexCellRefiner
2698412e9a14SMatthew G. Knepley . ct  - The type of the parent cell
2699412e9a14SMatthew G. Knepley . rct - The type of the produced cell
2700412e9a14SMatthew G. Knepley . r   - The index of the produced cell
2701412e9a14SMatthew G. Knepley - x   - The localized coordinates for the parent cell
2702412e9a14SMatthew G. Knepley 
2703412e9a14SMatthew G. Knepley   Output Parameter:
2704412e9a14SMatthew G. Knepley . xr  - The localized coordinates for the produced cell
2705412e9a14SMatthew G. Knepley 
2706412e9a14SMatthew G. Knepley   Level: developer
2707412e9a14SMatthew G. Knepley 
2708412e9a14SMatthew G. Knepley .seealso: DMPlexCellRefinerSetCoordinates()
2709412e9a14SMatthew G. Knepley */
2710412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerMapLocalizedCoordinates(DMPlexCellRefiner cr, DMPolytopeType ct, DMPolytopeType rct, PetscInt r, const PetscScalar x[], PetscScalar xr[])
2711412e9a14SMatthew G. Knepley {
2712412e9a14SMatthew G. Knepley   PetscFE        fe = NULL;
2713412e9a14SMatthew G. Knepley   PetscInt       cdim, Nv, v, *subcellV;
2714412e9a14SMatthew G. Knepley   PetscErrorCode ierr;
2715412e9a14SMatthew G. Knepley 
2716412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2717412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerGetCoordinateFE(cr, ct, &fe);CHKERRQ(ierr);
2718412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerGetSubcellVertices(cr, ct, rct, r, &Nv, &subcellV);CHKERRQ(ierr);
2719412e9a14SMatthew G. Knepley   ierr = PetscFEGetNumComponents(fe, &cdim);CHKERRQ(ierr);
2720412e9a14SMatthew G. Knepley   for (v = 0; v < Nv; ++v) {
2721412e9a14SMatthew G. Knepley     ierr = PetscFEInterpolate_Static(fe, x, cr->refGeom[ct], subcellV[v], &xr[v*cdim]);CHKERRQ(ierr);
2722412e9a14SMatthew G. Knepley   }
2723412e9a14SMatthew G. Knepley   PetscFunctionReturn(0);
2724412e9a14SMatthew G. Knepley }
2725412e9a14SMatthew G. Knepley 
2726412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerSetCoordinates(DMPlexCellRefiner cr, DM rdm)
2727412e9a14SMatthew G. Knepley {
2728412e9a14SMatthew G. Knepley   DM                    dm = cr->dm, cdm;
2729412e9a14SMatthew G. Knepley   PetscSection          coordSection, coordSectionNew;
2730412e9a14SMatthew G. Knepley   Vec                   coordsLocal, coordsLocalNew;
2731412e9a14SMatthew G. Knepley   const PetscScalar    *coords;
2732412e9a14SMatthew G. Knepley   PetscScalar          *coordsNew;
2733412e9a14SMatthew G. Knepley   const DMBoundaryType *bd;
2734412e9a14SMatthew G. Knepley   const PetscReal      *maxCell, *L;
2735412e9a14SMatthew G. Knepley   PetscBool             isperiodic, localizeVertices = PETSC_FALSE, localizeCells = PETSC_FALSE;
2736412e9a14SMatthew G. Knepley   PetscInt              dE, d, cStart, cEnd, c, vStartNew, vEndNew, v, pStart, pEnd, p, ocStart, ocEnd;
2737412e9a14SMatthew G. Knepley   PetscErrorCode        ierr;
2738412e9a14SMatthew G. Knepley 
2739412e9a14SMatthew G. Knepley   PetscFunctionBegin;
2740412e9a14SMatthew G. Knepley   ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
274190b157c4SStefano Zampini   ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr);
274290b157c4SStefano Zampini   /* Determine if we need to localize coordinates when generating them */
2743b9ccc978SStefano Zampini   if (isperiodic) {
2744412e9a14SMatthew G. Knepley     localizeVertices = PETSC_TRUE;
2745412e9a14SMatthew G. Knepley     if (!maxCell) {
2746412e9a14SMatthew G. Knepley       PetscBool localized;
2747412e9a14SMatthew G. Knepley       ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
2748412e9a14SMatthew G. Knepley       if (!localized) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Cannot refine a periodic mesh if coordinates have not been localized");
2749412e9a14SMatthew G. Knepley       localizeCells = PETSC_TRUE;
2750b9ccc978SStefano Zampini     }
2751b9ccc978SStefano Zampini   }
2752b9ccc978SStefano Zampini 
2753b9ccc978SStefano Zampini   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
2754412e9a14SMatthew G. Knepley   ierr = PetscSectionGetFieldComponents(coordSection, 0, &dE);CHKERRQ(ierr);
2755412e9a14SMatthew G. Knepley   if (maxCell) {
2756412e9a14SMatthew G. Knepley     PetscReal maxCellNew[3];
2757412e9a14SMatthew G. Knepley 
2758412e9a14SMatthew G. Knepley     for (d = 0; d < dE; ++d) maxCellNew[d] = maxCell[d]/2.0;
2759412e9a14SMatthew G. Knepley     ierr = DMSetPeriodicity(rdm, isperiodic, maxCellNew, L, bd);CHKERRQ(ierr);
2760412e9a14SMatthew G. Knepley   } else {
2761412e9a14SMatthew G. Knepley     ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr);
2762412e9a14SMatthew G. Knepley   }
2763b9ccc978SStefano Zampini   ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), &coordSectionNew);CHKERRQ(ierr);
2764b9ccc978SStefano Zampini   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
2765412e9a14SMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dE);CHKERRQ(ierr);
2766412e9a14SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(rdm, 0, &vStartNew, &vEndNew);CHKERRQ(ierr);
2767412e9a14SMatthew G. Knepley   if (localizeCells) {ierr = PetscSectionSetChart(coordSectionNew, 0,         vEndNew);CHKERRQ(ierr);}
2768412e9a14SMatthew G. Knepley   else               {ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vEndNew);CHKERRQ(ierr);}
2769b9ccc978SStefano Zampini 
2770412e9a14SMatthew G. Knepley   /* Localization should be inherited */
2771412e9a14SMatthew G. Knepley   /*   Stefano calculates parent cells for each new cell for localization */
2772412e9a14SMatthew G. Knepley   /*   Localized cells need coordinates of closure */
2773412e9a14SMatthew G. Knepley   for (v = vStartNew; v < vEndNew; ++v) {
2774412e9a14SMatthew G. Knepley     ierr = PetscSectionSetDof(coordSectionNew, v, dE);CHKERRQ(ierr);
2775412e9a14SMatthew G. Knepley     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dE);CHKERRQ(ierr);
2776412e9a14SMatthew G. Knepley   }
2777412e9a14SMatthew G. Knepley   if (localizeCells) {
2778412e9a14SMatthew G. Knepley     ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
2779412e9a14SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2780412e9a14SMatthew G. Knepley       PetscInt dof;
278190b157c4SStefano Zampini 
2782412e9a14SMatthew G. Knepley       ierr = PetscSectionGetDof(coordSection, c, &dof); CHKERRQ(ierr);
2783412e9a14SMatthew G. Knepley       if (dof) {
2784412e9a14SMatthew G. Knepley         DMPolytopeType  ct;
2785412e9a14SMatthew G. Knepley         DMPolytopeType *rct;
2786412e9a14SMatthew G. Knepley         PetscInt       *rsize, *rcone, *rornt;
2787412e9a14SMatthew G. Knepley         PetscInt        dim, cNew, Nct, n, r;
278890b157c4SStefano Zampini 
2789412e9a14SMatthew G. Knepley         ierr = DMPlexGetCellType(dm, c, &ct);CHKERRQ(ierr);
2790412e9a14SMatthew G. Knepley         dim  = DMPolytopeTypeGetDim(ct);
2791412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2792412e9a14SMatthew G. Knepley         /* This allows for different cell types */
2793412e9a14SMatthew G. Knepley         for (n = 0; n < Nct; ++n) {
2794412e9a14SMatthew G. Knepley           if (dim != DMPolytopeTypeGetDim(rct[n])) continue;
2795412e9a14SMatthew G. Knepley           for (r = 0; r < rsize[n]; ++r) {
2796412e9a14SMatthew G. Knepley             PetscInt *closure = NULL;
2797412e9a14SMatthew G. Knepley             PetscInt  clSize, cl, Nv = 0;
279890b157c4SStefano Zampini 
2799412e9a14SMatthew G. Knepley             ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], c, r, &cNew);CHKERRQ(ierr);
2800412e9a14SMatthew G. Knepley             ierr = DMPlexGetTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr);
2801412e9a14SMatthew G. Knepley             for (cl = 0; cl < clSize*2; cl += 2) {if ((closure[cl] >= vStartNew) && (closure[cl] < vEndNew)) ++Nv;}
2802412e9a14SMatthew G. Knepley             ierr = DMPlexRestoreTransitiveClosure(rdm, cNew, PETSC_TRUE, &clSize, &closure);CHKERRQ(ierr);
2803412e9a14SMatthew G. Knepley             ierr = PetscSectionSetDof(coordSectionNew, cNew, Nv * dE);CHKERRQ(ierr);
2804412e9a14SMatthew G. Knepley             ierr = PetscSectionSetFieldDof(coordSectionNew, cNew, 0, Nv * dE);CHKERRQ(ierr);
28059fc2a3f3SStefano Zampini           }
280690b157c4SStefano Zampini         }
280790b157c4SStefano Zampini       }
2808412e9a14SMatthew G. Knepley     }
280975d3a19aSMatthew G. Knepley   }
281075d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
2811412e9a14SMatthew G. Knepley   ierr = DMViewFromOptions(dm, NULL, "-coarse_dm_view");CHKERRQ(ierr);
281246e270d4SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr);
2813412e9a14SMatthew G. Knepley   {
2814412e9a14SMatthew G. Knepley     VecType     vtype;
2815412e9a14SMatthew G. Knepley     PetscInt    coordSizeNew, bs;
2816412e9a14SMatthew G. Knepley     const char *name;
2817412e9a14SMatthew G. Knepley 
2818412e9a14SMatthew G. Knepley     ierr = DMGetCoordinatesLocal(dm, &coordsLocal);CHKERRQ(ierr);
2819412e9a14SMatthew G. Knepley     ierr = VecCreate(PETSC_COMM_SELF, &coordsLocalNew);CHKERRQ(ierr);
282075d3a19aSMatthew G. Knepley     ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
2821412e9a14SMatthew G. Knepley     ierr = VecSetSizes(coordsLocalNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
2822412e9a14SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) coordsLocal, &name);CHKERRQ(ierr);
2823412e9a14SMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) coordsLocalNew, name);CHKERRQ(ierr);
2824412e9a14SMatthew G. Knepley     ierr = VecGetBlockSize(coordsLocal, &bs);CHKERRQ(ierr);
2825412e9a14SMatthew G. Knepley     ierr = VecSetBlockSize(coordsLocalNew, bs);CHKERRQ(ierr);
2826412e9a14SMatthew G. Knepley     ierr = VecGetType(coordsLocal, &vtype);CHKERRQ(ierr);
2827412e9a14SMatthew G. Knepley     ierr = VecSetType(coordsLocalNew, vtype);CHKERRQ(ierr);
2828b5da9499SMatthew G. Knepley   }
2829412e9a14SMatthew G. Knepley   ierr = VecGetArrayRead(coordsLocal, &coords);CHKERRQ(ierr);
2830412e9a14SMatthew G. Knepley   ierr = VecGetArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr);
2831412e9a14SMatthew G. Knepley   ierr = PetscSectionGetChart(coordSection, &ocStart, &ocEnd);CHKERRQ(ierr);
2832412e9a14SMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
2833412e9a14SMatthew G. Knepley   /* First set coordinates for vertices*/
2834412e9a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2835412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
2836412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2837412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2838412e9a14SMatthew G. Knepley     PetscInt        Nct, n, r;
2839412e9a14SMatthew G. Knepley     PetscBool       hasVertex = PETSC_FALSE, isLocalized = PETSC_FALSE;
284090b157c4SStefano Zampini 
2841412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2842412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2843412e9a14SMatthew G. Knepley     for (n = 0; n < Nct; ++n) {
2844412e9a14SMatthew G. Knepley       if (rct[n] == DM_POLYTOPE_POINT) {hasVertex = PETSC_TRUE; break;}
2845412e9a14SMatthew G. Knepley     }
2846412e9a14SMatthew G. Knepley     if (localizeVertices && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) {
2847412e9a14SMatthew G. Knepley       PetscInt dof;
2848412e9a14SMatthew G. Knepley       ierr = PetscSectionGetDof(coordSection, p, &dof); CHKERRQ(ierr);
2849412e9a14SMatthew G. Knepley       if (dof) isLocalized = PETSC_TRUE;
2850412e9a14SMatthew G. Knepley     }
2851412e9a14SMatthew G. Knepley     if (hasVertex) {
2852a5801f52SStefano Zampini       const PetscScalar *icoords = NULL;
2853412e9a14SMatthew G. Knepley       PetscScalar       *pcoords = NULL;
2854412e9a14SMatthew G. Knepley       PetscInt          Nc, Nv, v, d;
285590b157c4SStefano Zampini 
2856412e9a14SMatthew G. Knepley       ierr = DMPlexVecGetClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr);
2857a5801f52SStefano Zampini 
2858a5801f52SStefano Zampini       icoords = pcoords;
2859a5801f52SStefano Zampini       Nv      = Nc/dE;
2860a5801f52SStefano Zampini       if (ct != DM_POLYTOPE_POINT) {
2861412e9a14SMatthew G. Knepley         if (localizeVertices) {
2862412e9a14SMatthew G. Knepley           PetscScalar anchor[3];
286390b157c4SStefano Zampini 
2864412e9a14SMatthew G. Knepley           for (d = 0; d < dE; ++d) anchor[d] = pcoords[d];
2865412e9a14SMatthew G. Knepley           if (!isLocalized) {
2866a5801f52SStefano Zampini             for (v = 0; v < Nv; ++v) {ierr = DMLocalizeCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], &pcoords[v*dE]);CHKERRQ(ierr);}
2867412e9a14SMatthew G. Knepley           } else {
2868412e9a14SMatthew G. Knepley             Nv = Nc/(2*dE);
2869a5801f52SStefano Zampini             icoords = pcoords + Nv*dE;
2870a5801f52SStefano Zampini             for (v = Nv; v < Nv*2; ++v) {ierr = DMLocalizeCoordinate_Internal(dm, dE, anchor, &pcoords[v*dE], &pcoords[v*dE]);CHKERRQ(ierr);}
287190b157c4SStefano Zampini           }
2872b5da9499SMatthew G. Knepley         }
287390b157c4SStefano Zampini       }
2874412e9a14SMatthew G. Knepley       for (n = 0; n < Nct; ++n) {
2875412e9a14SMatthew G. Knepley         if (rct[n] != DM_POLYTOPE_POINT) continue;
2876412e9a14SMatthew G. Knepley         for (r = 0; r < rsize[n]; ++r) {
2877a5801f52SStefano Zampini           PetscScalar vcoords[3];
2878412e9a14SMatthew G. Knepley           PetscInt    vNew, off;
2879b5da9499SMatthew G. Knepley 
2880412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &vNew);CHKERRQ(ierr);
2881412e9a14SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSectionNew, vNew, &off);CHKERRQ(ierr);
2882a5801f52SStefano Zampini           ierr = DMPlexCellRefinerMapCoordinates(cr, ct, rct[n], r, Nv, dE, icoords, vcoords);CHKERRQ(ierr);
2883eac51794SMatthew G. Knepley           ierr = DMPlexSnapToGeomModel(dm, p, vcoords, &coordsNew[off]);CHKERRQ(ierr);
2884b5da9499SMatthew G. Knepley         }
28859fc2a3f3SStefano Zampini       }
2886a5801f52SStefano Zampini       ierr = DMPlexVecRestoreClosure(dm, coordSection, coordsLocal, p, &Nc, &pcoords);CHKERRQ(ierr);
2887412e9a14SMatthew G. Knepley     }
2888412e9a14SMatthew G. Knepley   }
2889412e9a14SMatthew G. Knepley   /* Then set coordinates for cells by localizing */
2890412e9a14SMatthew G. Knepley   for (p = pStart; p < pEnd; ++p) {
2891412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
2892412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
2893412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
2894412e9a14SMatthew G. Knepley     PetscInt        Nct, n, r;
2895412e9a14SMatthew G. Knepley     PetscBool       isLocalized = PETSC_FALSE;
289690b157c4SStefano Zampini 
2897412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
2898412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
2899412e9a14SMatthew G. Knepley     if (localizeCells && ct != DM_POLYTOPE_POINT && (p >= ocStart) && (p < ocEnd)) {
2900412e9a14SMatthew G. Knepley       PetscInt dof;
2901412e9a14SMatthew G. Knepley       ierr = PetscSectionGetDof(coordSection, p, &dof); CHKERRQ(ierr);
2902412e9a14SMatthew G. Knepley       if (dof) isLocalized = PETSC_TRUE;
2903b5da9499SMatthew G. Knepley     }
2904412e9a14SMatthew G. Knepley     if (isLocalized) {
2905412e9a14SMatthew G. Knepley       const PetscScalar *pcoords;
29069fc2a3f3SStefano Zampini 
2907412e9a14SMatthew G. Knepley       ierr = DMPlexPointLocalRead(cdm, p, coords, &pcoords);CHKERRQ(ierr);
2908412e9a14SMatthew G. Knepley       for (n = 0; n < Nct; ++n) {
2909412e9a14SMatthew G. Knepley         const PetscInt Nr = rsize[n];
291090b157c4SStefano Zampini 
2911412e9a14SMatthew G. Knepley         if (DMPolytopeTypeGetDim(ct) != DMPolytopeTypeGetDim(rct[n])) continue;
2912412e9a14SMatthew G. Knepley         for (r = 0; r < Nr; ++r) {
2913412e9a14SMatthew G. Knepley           PetscInt pNew, offNew;
291490b157c4SStefano Zampini 
2915412e9a14SMatthew G. Knepley           /* It looks like Stefano and Lisandro are allowing localized coordinates without defining the periodic boundary, which means that
2916412e9a14SMatthew G. Knepley              DMLocalizeCoordinate_Internal() will not work. Localized coordinates will have to have obtained by the affine map of the larger
2917412e9a14SMatthew G. Knepley              cell to the ones it produces. */
2918412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr);
2919412e9a14SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSectionNew, pNew, &offNew);CHKERRQ(ierr);
2920412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerMapLocalizedCoordinates(cr, ct, rct[n], r, pcoords, &coordsNew[offNew]);CHKERRQ(ierr);
292190b157c4SStefano Zampini         }
292290b157c4SStefano Zampini       }
292390b157c4SStefano Zampini     }
292490b157c4SStefano Zampini   }
2925412e9a14SMatthew G. Knepley   ierr = VecRestoreArrayRead(coordsLocal, &coords);CHKERRQ(ierr);
2926412e9a14SMatthew G. Knepley   ierr = VecRestoreArray(coordsLocalNew, &coordsNew);CHKERRQ(ierr);
2927412e9a14SMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordsLocalNew);CHKERRQ(ierr);
2928412e9a14SMatthew G. Knepley   /* TODO Stefano has a final reduction if some hybrid coordinates cannot be found. (needcoords) Should not be needed. */
2929412e9a14SMatthew G. Knepley   ierr = VecDestroy(&coordsLocalNew);CHKERRQ(ierr);
293075d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
2931412e9a14SMatthew G. Knepley   if (!localizeCells) {ierr = DMLocalizeCoordinates(rdm);CHKERRQ(ierr);}
293275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
293375d3a19aSMatthew G. Knepley }
293475d3a19aSMatthew G. Knepley 
2935963fc26aSMatthew G. Knepley /*@
2936963fc26aSMatthew G. Knepley   DMPlexCreateProcessSF - Create an SF which just has process connectivity
2937963fc26aSMatthew G. Knepley 
2938d083f849SBarry Smith   Collective on dm
2939963fc26aSMatthew G. Knepley 
2940963fc26aSMatthew G. Knepley   Input Parameters:
2941963fc26aSMatthew G. Knepley + dm      - The DM
2942963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity
2943963fc26aSMatthew G. Knepley 
2944963fc26aSMatthew G. Knepley   Output Parameters:
2945963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL
2946963fc26aSMatthew G. Knepley - sfProcess    - An SF encoding the process connectivity, or NULL
2947963fc26aSMatthew G. Knepley 
2948963fc26aSMatthew G. Knepley   Level: developer
2949963fc26aSMatthew G. Knepley 
2950963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF()
2951963fc26aSMatthew G. Knepley @*/
2952963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
295375d3a19aSMatthew G. Knepley {
295475d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
295575d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
295675d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
295775d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
295875d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
295975d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
29609852e123SBarry Smith   PetscMPIInt        size;
296175d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
296275d3a19aSMatthew G. Knepley 
296375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
2964963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
2965963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2);
2966963fc26aSMatthew G. Knepley   if (processRanks) {PetscValidPointer(processRanks, 3);}
2967963fc26aSMatthew G. Knepley   if (sfProcess)    {PetscValidPointer(sfProcess, 4);}
29689852e123SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr);
296975d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
2970785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
297175d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
297275d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
297375d3a19aSMatthew G. Knepley   }
297475d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
2975785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr);
2976785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr);
2977785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
297875d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
297975d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
298075d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
298175d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
298275d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
298375d3a19aSMatthew G. Knepley   }
298475d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
2985963fc26aSMatthew G. Knepley   if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);}
2986963fc26aSMatthew G. Knepley   else              {ierr = PetscFree(ranksNew);CHKERRQ(ierr);}
2987963fc26aSMatthew G. Knepley   if (sfProcess) {
298875d3a19aSMatthew G. Knepley     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
2989963fc26aSMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr);
299075d3a19aSMatthew G. Knepley     ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
29919852e123SBarry Smith     ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
2992963fc26aSMatthew G. Knepley   }
299375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
299475d3a19aSMatthew G. Knepley }
299575d3a19aSMatthew G. Knepley 
2996412e9a14SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateSF(DMPlexCellRefiner cr, DM rdm)
299775d3a19aSMatthew G. Knepley {
2998412e9a14SMatthew G. Knepley   DM                 dm = cr->dm;
2999412e9a14SMatthew G. Knepley   DMPlexCellRefiner *crRem;
300075d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
300175d3a19aSMatthew G. Knepley   IS                 processRanks;
3002412e9a14SMatthew G. Knepley   MPI_Datatype       ctType;
300375d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
300475d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
300575d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
300675d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
300775d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
3008412e9a14SMatthew G. Knepley   PetscInt          *ctStartRem, *ctStartNewRem;
3009412e9a14SMatthew G. Knepley   PetscInt           ctSize = DM_NUM_POLYTOPES+1, numNeighbors, n, pStartNew, pEndNew, pNew, pNewRem;
301075d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
301175d3a19aSMatthew G. Knepley 
301275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
301375d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
301475d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
301575d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
3016add09238SMatthew G. Knepley   /* Calculate size of new SF */
301775d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
301875d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
301975d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
302075d3a19aSMatthew G. Knepley     const PetscInt  p = localPoints[l];
3021412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
3022412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
3023412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
3024412e9a14SMatthew G. Knepley     PetscInt        Nct, n;
302575d3a19aSMatthew G. Knepley 
3026412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
3027412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
3028412e9a14SMatthew G. Knepley     for (n = 0; n < Nct; ++n) numLeavesNew += rsize[n];
30290314a74cSLawrence Mitchell   }
3030412e9a14SMatthew G. Knepley   /* Communicate ctStart and cStartNew for each remote rank */
303175d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
303275d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
3033412e9a14SMatthew G. Knepley   ierr = PetscMalloc2(ctSize*numNeighbors, &ctStartRem, ctSize*numNeighbors, &ctStartNewRem);CHKERRQ(ierr);
3034412e9a14SMatthew G. Knepley   ierr = MPI_Type_contiguous(ctSize, MPIU_INT, &ctType);CHKERRQ(ierr);
3035412e9a14SMatthew G. Knepley   ierr = MPI_Type_commit(&ctType);CHKERRQ(ierr);
3036412e9a14SMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr);
3037412e9a14SMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStart, ctStartRem);CHKERRQ(ierr);
3038412e9a14SMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr);
3039412e9a14SMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, ctType, cr->ctStartNew, ctStartNewRem);CHKERRQ(ierr);
3040412e9a14SMatthew G. Knepley   ierr = MPI_Type_free(&ctType);CHKERRQ(ierr);
304175d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
3042412e9a14SMatthew G. Knepley   ierr = PetscMalloc1(numNeighbors, &crRem);CHKERRQ(ierr);
3043412e9a14SMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
3044412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerCreate(dm, &crRem[n]);CHKERRQ(ierr);
3045412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerSetStarts(crRem[n], &ctStartRem[n*ctSize], &ctStartNewRem[n*ctSize]);
3046412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerSetUp(crRem[n]);CHKERRQ(ierr);
3047412e9a14SMatthew G. Knepley   }
3048412e9a14SMatthew G. Knepley   ierr = PetscFree2(ctStartRem, ctStartNewRem);CHKERRQ(ierr);
304975d3a19aSMatthew G. Knepley   /* Calculate new point SF */
3050785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr);
3051785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
305275d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
305375d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
305475d3a19aSMatthew G. Knepley     PetscInt        p       = localPoints[l];
3055412e9a14SMatthew G. Knepley     PetscInt        pRem    = remotePoints[l].index;
3056412e9a14SMatthew G. Knepley     PetscMPIInt     rankRem = remotePoints[l].rank;
3057412e9a14SMatthew G. Knepley     DMPolytopeType  ct;
3058412e9a14SMatthew G. Knepley     DMPolytopeType *rct;
3059412e9a14SMatthew G. Knepley     PetscInt       *rsize, *rcone, *rornt;
3060412e9a14SMatthew G. Knepley     PetscInt        neighbor, Nct, n, r;
306175d3a19aSMatthew G. Knepley 
3062412e9a14SMatthew G. Knepley     ierr = PetscFindInt(rankRem, numNeighbors, neighbors, &neighbor);CHKERRQ(ierr);
3063412e9a14SMatthew G. Knepley     if (neighbor < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rankRem);
3064412e9a14SMatthew G. Knepley     ierr = DMPlexGetCellType(dm, p, &ct);CHKERRQ(ierr);
3065412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
3066412e9a14SMatthew G. Knepley     for (n = 0; n < Nct; ++n) {
3067412e9a14SMatthew G. Knepley       for (r = 0; r < rsize[n]; ++r) {
3068412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], p, r, &pNew);CHKERRQ(ierr);
3069412e9a14SMatthew G. Knepley         ierr = DMPlexCellRefinerGetNewPoint(crRem[neighbor], ct, rct[n], pRem, r, &pNewRem);CHKERRQ(ierr);
3070412e9a14SMatthew G. Knepley         localPointsNew[m]        = pNew;
3071412e9a14SMatthew G. Knepley         remotePointsNew[m].index = pNewRem;
3072412e9a14SMatthew G. Knepley         remotePointsNew[m].rank  = rankRem;
30730314a74cSLawrence Mitchell         ++m;
30740314a74cSLawrence Mitchell       }
30756ce3c06aSMatthew G. Knepley     }
30766ce3c06aSMatthew G. Knepley   }
3077412e9a14SMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {ierr = DMPlexCellRefinerDestroy(&crRem[n]);CHKERRQ(ierr);}
3078412e9a14SMatthew G. Knepley   ierr = PetscFree(crRem);CHKERRQ(ierr);
3079d7eabd03SStefano Zampini   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew);
308075d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
308175d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
3082ba3c3d50SMatthew G. Knepley   {
3083ba3c3d50SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
3084ba3c3d50SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
3085ba3c3d50SMatthew G. Knepley 
3086ba3c3d50SMatthew G. Knepley     /* SF needs sorted leaves to correct calculate Gather */
3087ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &idx);CHKERRQ(ierr);
3088ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr);
3089ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr);
3090c7c54c77SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
3091d7eabd03SStefano 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);
3092c7c54c77SMatthew G. Knepley       idx[i] = i;
3093c7c54c77SMatthew G. Knepley     }
3094ba3c3d50SMatthew G. Knepley     ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr);
3095ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
3096ba3c3d50SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
3097ba3c3d50SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
3098ba3c3d50SMatthew G. Knepley     }
3099ba3c3d50SMatthew G. Knepley     ltmp            = localPointsNew;
3100ba3c3d50SMatthew G. Knepley     localPointsNew  = lp;
3101ba3c3d50SMatthew G. Knepley     rtmp            = remotePointsNew;
3102ba3c3d50SMatthew G. Knepley     remotePointsNew = rp;
3103ba3c3d50SMatthew G. Knepley     ierr = PetscFree(idx);CHKERRQ(ierr);
3104ba3c3d50SMatthew G. Knepley     ierr = PetscFree(ltmp);CHKERRQ(ierr);
3105ba3c3d50SMatthew G. Knepley     ierr = PetscFree(rtmp);CHKERRQ(ierr);
3106ba3c3d50SMatthew G. Knepley   }
310775d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
310875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
310975d3a19aSMatthew G. Knepley }
311075d3a19aSMatthew G. Knepley 
3111e7887635SMatthew G. Knepley static PetscErrorCode RefineLabel_Internal(DMPlexCellRefiner cr, DMLabel label, DMLabel labelNew)
311275d3a19aSMatthew G. Knepley {
3113412e9a14SMatthew G. Knepley   DM              dm = cr->dm;
3114e7887635SMatthew G. Knepley   IS              valueIS;
3115e7887635SMatthew G. Knepley   const PetscInt *values;
3116e7887635SMatthew G. Knepley   PetscInt        defVal, Nv, val;
311775d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
311875d3a19aSMatthew G. Knepley 
311975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
31205aa44df4SToby Isaac   ierr = DMLabelGetDefaultValue(label, &defVal);CHKERRQ(ierr);
31215aa44df4SToby Isaac   ierr = DMLabelSetDefaultValue(labelNew, defVal);CHKERRQ(ierr);
312275d3a19aSMatthew G. Knepley   ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
3123e7887635SMatthew G. Knepley   ierr = ISGetLocalSize(valueIS, &Nv);CHKERRQ(ierr);
312475d3a19aSMatthew G. Knepley   ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
3125e7887635SMatthew G. Knepley   for (val = 0; val < Nv; ++val) {
312675d3a19aSMatthew G. Knepley     IS              pointIS;
312775d3a19aSMatthew G. Knepley     const PetscInt *points;
3128412e9a14SMatthew G. Knepley     PetscInt        numPoints, p;
312975d3a19aSMatthew G. Knepley 
31302bc5314cSMichael Lange     /* Ensure refined label is created with same number of strata as
31312bc5314cSMichael Lange      * original (even if no entries here). */
3132ad8374ffSToby Isaac     ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr);
3133412e9a14SMatthew G. Knepley     ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
3134412e9a14SMatthew G. Knepley     ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
3135412e9a14SMatthew G. Knepley     ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
3136412e9a14SMatthew G. Knepley     for (p = 0; p < numPoints; ++p) {
3137412e9a14SMatthew G. Knepley       const PetscInt  point = points[p];
3138412e9a14SMatthew G. Knepley       DMPolytopeType  ct;
3139412e9a14SMatthew G. Knepley       DMPolytopeType *rct;
3140412e9a14SMatthew G. Knepley       PetscInt       *rsize, *rcone, *rornt;
3141e7887635SMatthew G. Knepley       PetscInt        Nct, n, r, pNew;
3142412e9a14SMatthew G. Knepley 
3143412e9a14SMatthew G. Knepley       ierr = DMPlexGetCellType(dm, point, &ct);CHKERRQ(ierr);
3144412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerRefine(cr, ct, &Nct, &rct, &rsize, &rcone, &rornt);CHKERRQ(ierr);
3145412e9a14SMatthew G. Knepley       for (n = 0; n < Nct; ++n) {
3146412e9a14SMatthew G. Knepley         for (r = 0; r < rsize[n]; ++r) {
3147412e9a14SMatthew G. Knepley           ierr = DMPlexCellRefinerGetNewPoint(cr, ct, rct[n], point, r, &pNew);CHKERRQ(ierr);
3148412e9a14SMatthew G. Knepley           ierr = DMLabelSetValue(labelNew, pNew, values[val]);CHKERRQ(ierr);
314927fcede3SMatthew G. Knepley         }
315075d3a19aSMatthew G. Knepley       }
315175d3a19aSMatthew G. Knepley     }
315275d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
315375d3a19aSMatthew G. Knepley     ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
315475d3a19aSMatthew G. Knepley   }
315575d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
315675d3a19aSMatthew G. Knepley   ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
3157e7887635SMatthew G. Knepley   PetscFunctionReturn(0);
3158e7887635SMatthew G. Knepley }
3159e7887635SMatthew G. Knepley 
3160e7887635SMatthew G. Knepley static PetscErrorCode DMPlexCellRefinerCreateLabels(DMPlexCellRefiner cr, DM rdm)
3161e7887635SMatthew G. Knepley {
3162e7887635SMatthew G. Knepley   DM             dm = cr->dm;
3163e7887635SMatthew G. Knepley   PetscInt       numLabels, l;
3164e7887635SMatthew G. Knepley   PetscErrorCode ierr;
3165e7887635SMatthew G. Knepley 
3166e7887635SMatthew G. Knepley   PetscFunctionBegin;
3167e7887635SMatthew G. Knepley   ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
3168e7887635SMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
3169e7887635SMatthew G. Knepley     DMLabel         label, labelNew;
3170e7887635SMatthew G. Knepley     const char     *lname;
3171e7887635SMatthew G. Knepley     PetscBool       isDepth, isCellType;
3172e7887635SMatthew G. Knepley 
3173e7887635SMatthew G. Knepley     ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr);
3174e7887635SMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
3175e7887635SMatthew G. Knepley     if (isDepth) continue;
3176e7887635SMatthew G. Knepley     ierr = PetscStrcmp(lname, "celltype", &isCellType);CHKERRQ(ierr);
3177e7887635SMatthew G. Knepley     if (isCellType) continue;
3178e7887635SMatthew G. Knepley     ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr);
3179e7887635SMatthew G. Knepley     ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr);
3180e7887635SMatthew G. Knepley     ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
3181e7887635SMatthew G. Knepley     ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr);
318275d3a19aSMatthew G. Knepley   }
318375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
318475d3a19aSMatthew G. Knepley }
318575d3a19aSMatthew G. Knepley 
318675d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
3187412e9a14SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform(DM dm, DMPlexCellRefiner cr, DM *dmRefined)
318875d3a19aSMatthew G. Knepley {
318975d3a19aSMatthew G. Knepley   DM              rdm;
3190412e9a14SMatthew G. Knepley   PetscInt        dim, embedDim, depth;
319175d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
319275d3a19aSMatthew G. Knepley 
319375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
3194412e9a14SMatthew G. Knepley   PetscValidHeader(cr, 1);
319575d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
319675d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
3197c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
3198c73cfb54SMatthew G. Knepley   ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr);
31996dcbd917SStefano Zampini   ierr = DMGetCoordinateDim(dm, &embedDim);CHKERRQ(ierr);
32006dcbd917SStefano Zampini   ierr = DMSetCoordinateDim(rdm, embedDim);CHKERRQ(ierr);
320175d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
320275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
32031e573d11SMatthew G. Knepley   if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement");
320475d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
3205412e9a14SMatthew G. Knepley   ierr = DMPlexSetChart(rdm, 0, cr->ctStartNew[cr->ctOrder[DM_NUM_POLYTOPES]]);CHKERRQ(ierr);
32066d7373e8SToby Isaac   /* Step 2: Set cone/support sizes (automatically stratifies) */
3207412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerSetConeSizes(cr, rdm);CHKERRQ(ierr);
320875d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
320975d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
32106d7373e8SToby Isaac   /* Step 4: Set cones and supports (automatically symmetrizes) */
3211412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerSetCones(cr, rdm);CHKERRQ(ierr);
32126d7373e8SToby Isaac   /* Step 5: Create pointSF */
3213412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerCreateSF(cr, rdm);CHKERRQ(ierr);
32146d7373e8SToby Isaac   /* Step 6: Create labels */
3215412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerCreateLabels(cr, rdm);CHKERRQ(ierr);
32166d7373e8SToby Isaac   /* Step 7: Set coordinates */
3217412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerSetCoordinates(cr, rdm);CHKERRQ(ierr);
321875d3a19aSMatthew G. Knepley   *dmRefined = rdm;
321975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
322075d3a19aSMatthew G. Knepley }
322175d3a19aSMatthew G. Knepley 
32222389894bSMatthew G. Knepley /*@
32232389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
32242389894bSMatthew G. Knepley 
32252389894bSMatthew G. Knepley   Input Parameter:
32262389894bSMatthew G. Knepley . dm - The coarse DM
32272389894bSMatthew G. Knepley 
32282389894bSMatthew G. Knepley   Output Parameter:
32292389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
32302389894bSMatthew G. Knepley 
32312389894bSMatthew G. Knepley   Level: developer
32322389894bSMatthew G. Knepley 
323397d8846cSMatthew Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetSubpointIS()
32342389894bSMatthew G. Knepley @*/
32352389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
32362389894bSMatthew G. Knepley {
3237412e9a14SMatthew G. Knepley   DMPlexCellRefiner cr;
3238412e9a14SMatthew G. Knepley   PetscInt         *fpoints;
3239327c2912SStefano Zampini   PetscInt          pStart, pEnd, p, vStart, vEnd, v;
32402389894bSMatthew G. Knepley   PetscErrorCode    ierr;
32412389894bSMatthew G. Knepley 
32422389894bSMatthew G. Knepley   PetscFunctionBegin;
32432389894bSMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
32442389894bSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
3245412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr);
3246412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr);
32472389894bSMatthew G. Knepley   ierr = PetscMalloc1(pEnd-pStart, &fpoints);CHKERRQ(ierr);
32482389894bSMatthew G. Knepley   for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
3249412e9a14SMatthew G. Knepley   for (v = vStart; v < vEnd; ++v) {
3250327c2912SStefano Zampini     PetscInt vNew = -1; /* silent overzelous may be used uninitialized */
3251327c2912SStefano Zampini 
3252412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerGetNewPoint(cr, DM_POLYTOPE_POINT, DM_POLYTOPE_POINT, p, 0, &vNew);CHKERRQ(ierr);
3253412e9a14SMatthew G. Knepley     fpoints[v-pStart] = vNew;
32542389894bSMatthew G. Knepley   }
3255412e9a14SMatthew G. Knepley   ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr);
32562389894bSMatthew G. Knepley   ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr);
32572389894bSMatthew G. Knepley   PetscFunctionReturn(0);
32582389894bSMatthew G. Knepley }
32592389894bSMatthew G. Knepley 
32600e2b6761SMatthew G. Knepley /*@
32610e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
32620e2b6761SMatthew G. Knepley 
32630e2b6761SMatthew G. Knepley   Input Parameters:
32640e2b6761SMatthew G. Knepley + dm - The DM
32650e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
32660e2b6761SMatthew G. Knepley 
32670e2b6761SMatthew G. Knepley   Level: developer
32680e2b6761SMatthew G. Knepley 
32690e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
32700e2b6761SMatthew G. Knepley @*/
327175d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
327275d3a19aSMatthew G. Knepley {
327375d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
327475d3a19aSMatthew G. Knepley 
327575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
327675d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
327775d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
327875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
327975d3a19aSMatthew G. Knepley }
328075d3a19aSMatthew G. Knepley 
32810e2b6761SMatthew G. Knepley /*@
32820e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
32830e2b6761SMatthew G. Knepley 
32840e2b6761SMatthew G. Knepley   Input Parameter:
32850e2b6761SMatthew G. Knepley . dm - The DM
32860e2b6761SMatthew G. Knepley 
32870e2b6761SMatthew G. Knepley   Output Parameter:
32880e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
32890e2b6761SMatthew G. Knepley 
32900e2b6761SMatthew G. Knepley   Level: developer
32910e2b6761SMatthew G. Knepley 
32920e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
32930e2b6761SMatthew G. Knepley @*/
329475d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
329575d3a19aSMatthew G. Knepley {
329675d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
329775d3a19aSMatthew G. Knepley 
329875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
329975d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
330075d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
330175d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
330275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
330375d3a19aSMatthew G. Knepley }
330475d3a19aSMatthew G. Knepley 
33050e2b6761SMatthew G. Knepley /*@
33060e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
33070e2b6761SMatthew G. Knepley 
33080e2b6761SMatthew G. Knepley   Input Parameters:
33090e2b6761SMatthew G. Knepley + dm - The DM
33100e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
33110e2b6761SMatthew G. Knepley 
33120e2b6761SMatthew G. Knepley   Level: developer
33130e2b6761SMatthew G. Knepley 
33140e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
33150e2b6761SMatthew G. Knepley @*/
331675d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
331775d3a19aSMatthew G. Knepley {
331875d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
331975d3a19aSMatthew G. Knepley 
332075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
332175d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
332275d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
332375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
332475d3a19aSMatthew G. Knepley }
332575d3a19aSMatthew G. Knepley 
33260e2b6761SMatthew G. Knepley /*@
33270e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
33280e2b6761SMatthew G. Knepley 
33290e2b6761SMatthew G. Knepley   Input Parameter:
33300e2b6761SMatthew G. Knepley . dm - The DM
33310e2b6761SMatthew G. Knepley 
33320e2b6761SMatthew G. Knepley   Output Parameter:
33330e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
33340e2b6761SMatthew G. Knepley 
33350e2b6761SMatthew G. Knepley   Level: developer
33360e2b6761SMatthew G. Knepley 
33370e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
33380e2b6761SMatthew G. Knepley @*/
333975d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
334075d3a19aSMatthew G. Knepley {
334175d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
334275d3a19aSMatthew G. Knepley 
334375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
334475d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
334575d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
334675d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
334775d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
334875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
334975d3a19aSMatthew G. Knepley }
335075d3a19aSMatthew G. Knepley 
3351b28003e6SMatthew G. Knepley /*@
3352b28003e6SMatthew G. Knepley   DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
3353b28003e6SMatthew G. Knepley 
3354b28003e6SMatthew G. Knepley   Input Parameters:
3355b28003e6SMatthew G. Knepley + dm - The DM
3356b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh
3357b28003e6SMatthew G. Knepley 
3358b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
3359b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
3360b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
3361b28003e6SMatthew G. Knepley 
3362b28003e6SMatthew G. Knepley   Level: developer
3363b28003e6SMatthew G. Knepley 
3364b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
3365b28003e6SMatthew G. Knepley @*/
3366b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *))
3367b28003e6SMatthew G. Knepley {
3368b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
3369b28003e6SMatthew G. Knepley 
3370b28003e6SMatthew G. Knepley   PetscFunctionBegin;
3371b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3372b28003e6SMatthew G. Knepley   mesh->refinementFunc = refinementFunc;
3373b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
3374b28003e6SMatthew G. Knepley }
3375b28003e6SMatthew G. Knepley 
3376b28003e6SMatthew G. Knepley /*@
3377b28003e6SMatthew G. Knepley   DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
3378b28003e6SMatthew G. Knepley 
3379b28003e6SMatthew G. Knepley   Input Parameter:
3380b28003e6SMatthew G. Knepley . dm - The DM
3381b28003e6SMatthew G. Knepley 
3382b28003e6SMatthew G. Knepley   Output Parameter:
3383b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh
3384b28003e6SMatthew G. Knepley 
3385b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
3386b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
3387b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
3388b28003e6SMatthew G. Knepley 
3389b28003e6SMatthew G. Knepley   Level: developer
3390b28003e6SMatthew G. Knepley 
3391b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
3392b28003e6SMatthew G. Knepley @*/
3393b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *))
3394b28003e6SMatthew G. Knepley {
3395b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
3396b28003e6SMatthew G. Knepley 
3397b28003e6SMatthew G. Knepley   PetscFunctionBegin;
3398b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
3399b28003e6SMatthew G. Knepley   PetscValidPointer(refinementFunc,  2);
3400b28003e6SMatthew G. Knepley   *refinementFunc = mesh->refinementFunc;
3401b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
3402b28003e6SMatthew G. Knepley }
3403b28003e6SMatthew G. Knepley 
3404e7887635SMatthew G. Knepley static PetscErrorCode RefineDiscLabels_Internal(DMPlexCellRefiner cr, DM rdm)
3405e7887635SMatthew G. Knepley {
3406e7887635SMatthew G. Knepley   DM             dm = cr->dm;
3407e7887635SMatthew G. Knepley   PetscInt       Nf, f, Nds, s;
3408e7887635SMatthew G. Knepley   PetscErrorCode ierr;
3409e7887635SMatthew G. Knepley 
3410e7887635SMatthew G. Knepley   PetscFunctionBegin;
3411e7887635SMatthew G. Knepley   ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
3412e7887635SMatthew G. Knepley   for (f = 0; f < Nf; ++f) {
3413e7887635SMatthew G. Knepley     DMLabel     label, labelNew;
3414e7887635SMatthew G. Knepley     PetscObject obj;
3415e7887635SMatthew G. Knepley     const char *lname;
3416e7887635SMatthew G. Knepley 
3417e7887635SMatthew G. Knepley     ierr = DMGetField(rdm, f, &label, &obj);CHKERRQ(ierr);
3418e7887635SMatthew G. Knepley     if (!label) continue;
3419e7887635SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
3420e7887635SMatthew G. Knepley     ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr);
3421e7887635SMatthew G. Knepley     ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr);
3422e7887635SMatthew G. Knepley     ierr = DMSetField_Internal(rdm, f, labelNew, obj);CHKERRQ(ierr);
3423e7887635SMatthew G. Knepley     ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr);
3424e7887635SMatthew G. Knepley   }
3425e7887635SMatthew G. Knepley   ierr = DMGetNumDS(dm, &Nds);CHKERRQ(ierr);
3426e7887635SMatthew G. Knepley   for (s = 0; s < Nds; ++s) {
3427e7887635SMatthew G. Knepley     DMLabel     label, labelNew;
3428e7887635SMatthew G. Knepley     const char *lname;
3429e7887635SMatthew G. Knepley 
3430e7887635SMatthew G. Knepley     ierr = DMGetRegionNumDS(rdm, s, &label, NULL, NULL);CHKERRQ(ierr);
3431e7887635SMatthew G. Knepley     if (!label) continue;
3432e7887635SMatthew G. Knepley     ierr = PetscObjectGetName((PetscObject) label, &lname);CHKERRQ(ierr);
3433e7887635SMatthew G. Knepley     ierr = DMLabelCreate(PETSC_COMM_SELF, lname, &labelNew);CHKERRQ(ierr);
3434e7887635SMatthew G. Knepley     ierr = RefineLabel_Internal(cr, label, labelNew);CHKERRQ(ierr);
3435e7887635SMatthew G. Knepley     ierr = DMSetRegionNumDS(rdm, s, labelNew, NULL, NULL);CHKERRQ(ierr);
3436e7887635SMatthew G. Knepley     ierr = DMLabelDestroy(&labelNew);CHKERRQ(ierr);
3437e7887635SMatthew G. Knepley   }
3438e7887635SMatthew G. Knepley   PetscFunctionReturn(0);
3439e7887635SMatthew G. Knepley }
3440e7887635SMatthew G. Knepley 
34410d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined)
34420d1cd5e0SMatthew G. Knepley {
3443492b8470SStefano Zampini   PetscBool         isUniform;
3444412e9a14SMatthew G. Knepley   DMPlexCellRefiner cr;
34450d1cd5e0SMatthew G. Knepley   PetscErrorCode    ierr;
34460d1cd5e0SMatthew G. Knepley 
34470d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
34480d1cd5e0SMatthew G. Knepley   ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr);
3449412e9a14SMatthew G. Knepley   ierr = DMViewFromOptions(dm, NULL, "-initref_dm_view");CHKERRQ(ierr);
34500d1cd5e0SMatthew G. Knepley   if (isUniform) {
3451*51a74b61SMatthew G. Knepley     DM        cdm, rcdm;
3452492b8470SStefano Zampini     PetscBool localized;
34530d1cd5e0SMatthew G. Knepley 
3454412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerCreate(dm, &cr);CHKERRQ(ierr);
3455412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr);
3456492b8470SStefano Zampini     ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
3457412e9a14SMatthew G. Knepley     ierr = DMPlexRefineUniform(dm, cr, dmRefined);CHKERRQ(ierr);
34589a7e3c0aSMatthew G. Knepley     ierr = DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);CHKERRQ(ierr);
3459e7887635SMatthew G. Knepley     ierr = DMCopyDisc(dm, *dmRefined);CHKERRQ(ierr);
3460*51a74b61SMatthew G. Knepley     ierr = DMGetCoordinateDM(dm, &cdm);CHKERRQ(ierr);
3461*51a74b61SMatthew G. Knepley     ierr = DMGetCoordinateDM(*dmRefined, &rcdm);CHKERRQ(ierr);
3462*51a74b61SMatthew G. Knepley     ierr = DMCopyDisc(cdm, rcdm);CHKERRQ(ierr);
3463e7887635SMatthew G. Knepley     ierr = RefineDiscLabels_Internal(cr, *dmRefined);CHKERRQ(ierr);
34640d1cd5e0SMatthew G. Knepley     ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr);
3465412e9a14SMatthew G. Knepley     ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr);
34660d1cd5e0SMatthew G. Knepley   } else {
34670d1cd5e0SMatthew G. Knepley     ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr);
34680d1cd5e0SMatthew G. Knepley   }
34690d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
34700d1cd5e0SMatthew G. Knepley }
34710d1cd5e0SMatthew G. Knepley 
34720d1cd5e0SMatthew G. Knepley PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[])
34730d1cd5e0SMatthew G. Knepley {
34740d1cd5e0SMatthew G. Knepley   DM             cdm = dm;
34750d1cd5e0SMatthew G. Knepley   PetscInt       r;
34760d1cd5e0SMatthew G. Knepley   PetscBool      isUniform, localized;
34770d1cd5e0SMatthew G. Knepley   PetscErrorCode ierr;
34780d1cd5e0SMatthew G. Knepley 
34790d1cd5e0SMatthew G. Knepley   PetscFunctionBegin;
34800d1cd5e0SMatthew G. Knepley   ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr);
34810d1cd5e0SMatthew G. Knepley   ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr);
34820d1cd5e0SMatthew G. Knepley   if (isUniform) {
34830d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
3484412e9a14SMatthew G. Knepley       DMPlexCellRefiner cr;
3485*51a74b61SMatthew G. Knepley       DM                codm, rcodm;
34860d1cd5e0SMatthew G. Knepley 
3487412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerCreate(cdm, &cr);CHKERRQ(ierr);
3488412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerSetUp(cr);CHKERRQ(ierr);
3489412e9a14SMatthew G. Knepley       ierr = DMPlexRefineUniform(cdm, cr, &dmRefined[r]);CHKERRQ(ierr);
34909a7e3c0aSMatthew G. Knepley       ierr = DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);CHKERRQ(ierr);
34919a7e3c0aSMatthew G. Knepley       ierr = DMSetRefineLevel(dmRefined[r], cdm->levelup+1);CHKERRQ(ierr);
3492e7887635SMatthew G. Knepley       ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr);
3493*51a74b61SMatthew G. Knepley       ierr = DMGetCoordinateDM(dm, &codm);CHKERRQ(ierr);
3494*51a74b61SMatthew G. Knepley       ierr = DMGetCoordinateDM(dmRefined[r], &rcodm);CHKERRQ(ierr);
3495*51a74b61SMatthew G. Knepley       ierr = DMCopyDisc(codm, rcodm);CHKERRQ(ierr);
3496e7887635SMatthew G. Knepley       ierr = RefineDiscLabels_Internal(cr, dmRefined[r]);CHKERRQ(ierr);
34970d1cd5e0SMatthew G. Knepley       ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr);
34980d1cd5e0SMatthew G. Knepley       ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr);
34990d1cd5e0SMatthew G. Knepley       ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr);
35000d1cd5e0SMatthew G. Knepley       cdm  = dmRefined[r];
3501412e9a14SMatthew G. Knepley       ierr = DMPlexCellRefinerDestroy(&cr);CHKERRQ(ierr);
35020d1cd5e0SMatthew G. Knepley     }
35030d1cd5e0SMatthew G. Knepley   } else {
35040d1cd5e0SMatthew G. Knepley     for (r = 0; r < nlevels; ++r) {
35050d1cd5e0SMatthew G. Knepley       ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr);
3506e7887635SMatthew G. Knepley       ierr = DMCopyDisc(cdm, dmRefined[r]);CHKERRQ(ierr);
35070d1cd5e0SMatthew G. Knepley       ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr);
35080d1cd5e0SMatthew G. Knepley       if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);}
35090d1cd5e0SMatthew G. Knepley       ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr);
35100d1cd5e0SMatthew G. Knepley       cdm  = dmRefined[r];
35110d1cd5e0SMatthew G. Knepley     }
35120d1cd5e0SMatthew G. Knepley   }
35130d1cd5e0SMatthew G. Knepley   PetscFunctionReturn(0);
35140d1cd5e0SMatthew G. Knepley }
3515