xref: /petsc/src/dm/impls/plex/plexrefine.c (revision add0923806ceb8cd559cd2112efc108b7cfb2180)
175d3a19aSMatthew G. Knepley #include <petsc-private/dmpleximpl.h>   /*I      "petscdmplex.h"   I*/
275d3a19aSMatthew G. Knepley #include <petscsf.h>
375d3a19aSMatthew G. Knepley 
475d3a19aSMatthew G. Knepley #undef __FUNCT__
575d3a19aSMatthew G. Knepley #define __FUNCT__ "GetDepthStart_Private"
675d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart)
775d3a19aSMatthew G. Knepley {
875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
975d3a19aSMatthew G. Knepley   if (cStart) *cStart = 0;
1075d3a19aSMatthew G. Knepley   if (vStart) *vStart = depthSize[depth];
1175d3a19aSMatthew G. Knepley   if (fStart) *fStart = depthSize[depth] + depthSize[0];
1275d3a19aSMatthew G. Knepley   if (eStart) *eStart = depthSize[depth] + depthSize[0] + depthSize[depth-1];
1375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
1475d3a19aSMatthew G. Knepley }
1575d3a19aSMatthew G. Knepley 
1675d3a19aSMatthew G. Knepley #undef __FUNCT__
1775d3a19aSMatthew G. Knepley #define __FUNCT__ "GetDepthEnd_Private"
1875d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd)
1975d3a19aSMatthew G. Knepley {
2075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
2175d3a19aSMatthew G. Knepley   if (cEnd) *cEnd = depthSize[depth];
2275d3a19aSMatthew G. Knepley   if (vEnd) *vEnd = depthSize[depth] + depthSize[0];
2375d3a19aSMatthew G. Knepley   if (fEnd) *fEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1];
2475d3a19aSMatthew G. Knepley   if (eEnd) *eEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1];
2575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
2675d3a19aSMatthew G. Knepley }
2775d3a19aSMatthew G. Knepley 
2875d3a19aSMatthew G. Knepley #undef __FUNCT__
29bed052eaSMatthew G. Knepley #define __FUNCT__ "CellRefinerGetAffineTransforms_Internal"
30bed052eaSMatthew G. Knepley /* Gets the affine map from the original cell to each subcell */
31bed052eaSMatthew G. Knepley PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
32bed052eaSMatthew G. Knepley {
33bed052eaSMatthew G. Knepley   PetscReal     *v = NULL, *j = NULL, *invj = NULL, detJ;
34bed052eaSMatthew G. Knepley   PetscInt       dim, s;
35bed052eaSMatthew G. Knepley   PetscErrorCode ierr;
36bed052eaSMatthew G. Knepley 
37bed052eaSMatthew G. Knepley   PetscFunctionBegin;
38bed052eaSMatthew G. Knepley   switch (refiner) {
39bed052eaSMatthew G. Knepley   case 0: break;
40bed052eaSMatthew G. Knepley   case 1:
41bed052eaSMatthew G. Knepley     dim  = 2;
42bed052eaSMatthew G. Knepley     if (numSubcells) *numSubcells = 4;
43bed052eaSMatthew G. Knepley     if (v0) {
44bed052eaSMatthew G. Knepley       ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr);
45bed052eaSMatthew G. Knepley       /* A */
46bed052eaSMatthew G. Knepley       v[0+0] = -1.0; v[0+1] = -1.0;
47bed052eaSMatthew G. Knepley       j[0+0] =  0.5; j[0+1] =  0.0;
48bed052eaSMatthew G. Knepley       j[0+2] =  0.0; j[0+3] =  0.5;
49bed052eaSMatthew G. Knepley       /* B */
50bed052eaSMatthew G. Knepley       v[2+0] =  0.0; v[2+1] = -1.0;
51bed052eaSMatthew G. Knepley       j[4+0] =  0.5; j[4+1] =  0.0;
52bed052eaSMatthew G. Knepley       j[4+2] =  0.0; j[4+3] =  0.5;
53bed052eaSMatthew G. Knepley       /* C */
54bed052eaSMatthew G. Knepley       v[4+0] = -1.0; v[4+1] =  0.0;
55bed052eaSMatthew G. Knepley       j[8+0] =  0.5; j[8+1] =  0.0;
56bed052eaSMatthew G. Knepley       j[8+2] =  0.0; j[8+3] =  0.5;
57bed052eaSMatthew G. Knepley       /* D */
58bed052eaSMatthew G. Knepley       v[6+0]  =  0.0; v[6+1]  = -1.0;
59bed052eaSMatthew G. Knepley       j[12+0] =  0.0; j[12+1] = -0.5;
60bed052eaSMatthew G. Knepley       j[12+2] =  0.5; j[12+3] =  0.5;
61bed052eaSMatthew G. Knepley       for (s = 0; s < 4; ++s) {
62bed052eaSMatthew G. Knepley         DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
63bed052eaSMatthew G. Knepley         DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
64bed052eaSMatthew G. Knepley       }
65bed052eaSMatthew G. Knepley     }
66bed052eaSMatthew G. Knepley     break;
67bed052eaSMatthew G. Knepley   default:
68bed052eaSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
69bed052eaSMatthew G. Knepley   }
70bed052eaSMatthew G. Knepley   if (v0) {*v0 = v; *jac = j; *invjac = invj;}
71bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
72bed052eaSMatthew G. Knepley }
73bed052eaSMatthew G. Knepley 
74bed052eaSMatthew G. Knepley #undef __FUNCT__
75bed052eaSMatthew G. Knepley #define __FUNCT__ "CellRefinerRestoreAffineTransforms_Internal"
76bed052eaSMatthew G. Knepley PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
77bed052eaSMatthew G. Knepley {
78bed052eaSMatthew G. Knepley   PetscErrorCode ierr;
79bed052eaSMatthew G. Knepley 
80bed052eaSMatthew G. Knepley   PetscFunctionBegin;
81bed052eaSMatthew G. Knepley   ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr);
82bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
83bed052eaSMatthew G. Knepley }
84bed052eaSMatthew G. Knepley 
85bed052eaSMatthew G. Knepley #undef __FUNCT__
8675d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerGetSizes"
8786150812SJed Brown static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[])
8875d3a19aSMatthew G. Knepley {
896ce3c06aSMatthew G. Knepley   PetscInt       cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
9075d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
9175d3a19aSMatthew G. Knepley 
9275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
9375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
9475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
9575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
9675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
9775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
9875d3a19aSMatthew G. Knepley   switch (refiner) {
993478d7aaSMatthew G. Knepley   case 0:
1003478d7aaSMatthew G. Knepley     break;
10175d3a19aSMatthew G. Knepley   case 1:
10275d3a19aSMatthew G. Knepley     /* Simplicial 2D */
10375d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart;         /* Add a vertex on every face */
10475d3a19aSMatthew G. Knepley     depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */
10575d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                     /* Every cell split into 4 cells */
10675d3a19aSMatthew G. Knepley     break;
10775d3a19aSMatthew G. Knepley   case 3:
108d963de37SMatthew G. Knepley     /* Hybrid Simplicial 2D */
10975d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
11075d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
11175d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart;                                         /* Add a vertex on every face, but not hybrid faces */
11275d3a19aSMatthew G. Knepley     depthSize[1] = 2*(fMax - fStart) + 3*(cMax - cStart) + (fEnd - fMax) + (cEnd - cMax); /* Every interior face is split into 2 faces, 3 faces are added for each interior cell, and one in each hybrid cell */
11375d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax);                                   /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */
11475d3a19aSMatthew G. Knepley     break;
11575d3a19aSMatthew G. Knepley   case 2:
11675d3a19aSMatthew G. Knepley     /* Hex 2D */
117149f48fdSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
11875d3a19aSMatthew G. Knepley     depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart);         /* Every face is split into 2 faces and 4 faces are added for each cell */
11975d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                             /* Every cell split into 4 cells */
12075d3a19aSMatthew G. Knepley     break;
121a97b51b8SMatthew G. Knepley   case 4:
122a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
123a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
124a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
125a97b51b8SMatthew G. Knepley     /* Quadrilateral */
126a97b51b8SMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart;                 /* Add a vertex on every face and cell */
127a97b51b8SMatthew G. Knepley     depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart);                         /* Every face is split into 2 faces, and 4 faces are added for each cell */
128a97b51b8SMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart);                                             /* Every cell split into 4 cells */
129a97b51b8SMatthew G. Knepley     /* Segment Prisms */
130a97b51b8SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
131a97b51b8SMatthew G. Knepley     depthSize[1] +=   (fEnd - fMax)  +   (cEnd - cMax);                           /* Every hybrid face remains and 1 faces is added for each hybrid cell */
132a97b51b8SMatthew G. Knepley     depthSize[2] += 2*(cEnd - cMax);                                              /* Every hybrid cell split into 2 cells */
133a97b51b8SMatthew G. Knepley     break;
134b5da9499SMatthew G. Knepley   case 5:
135b5da9499SMatthew G. Knepley     /* Simplicial 3D */
136b5da9499SMatthew G. Knepley     depthSize[0] =    vEnd - vStart  +    eEnd - eStart;                    /* Add a vertex on every edge */
137b5da9499SMatthew G. Knepley     depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + (cEnd - cStart); /* Every edge is split into 2 edges, 3 edges are added for each face, and 1 edge for each cell */
138b5da9499SMatthew G. Knepley     depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart);                   /* Every face split into 4 faces and 8 faces are added for each cell */
139b5da9499SMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                       /* Every cell split into 8 cells */
140b5da9499SMatthew G. Knepley     break;
141b5da9499SMatthew G. Knepley   case 7:
142b5da9499SMatthew G. Knepley     /* Hybrid Simplicial 3D */
143b5da9499SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
1446ce3c06aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
145b5da9499SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
146dae4404aSMatthew G. Knepley     /* Tetrahedra */
147dae4404aSMatthew G. Knepley     depthSize[0]  =    vEnd - vStart  +    eMax - eStart;                    /* Add a vertex on every interior edge */
148dae4404aSMatthew G. Knepley     depthSize[1]  = 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart); /* Every interior edge split into 2 edges, 3 edges added for each interior face, 1 edge for each interior cell */
149dae4404aSMatthew G. Knepley     depthSize[2]  = 4*(fMax - fStart) + 8*(cMax - cStart);                   /* Every interior face split into 4 faces, 8 faces added for each interior cell */
150dae4404aSMatthew G. Knepley     depthSize[3]  = 8*(cMax - cStart);                                       /* Every interior cell split into 8 cells */
151dae4404aSMatthew G. Knepley     /* Triangular Prisms */
152dae4404aSMatthew G. Knepley     depthSize[0] += 0;                                                       /* No hybrid vertices */
153dae4404aSMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax);                     /* Every hybrid edge remains, 1 edge for every hybrid face */
1546ce3c06aSMatthew G. Knepley     depthSize[2] += 2*(fEnd - fMax)   + 3*(cEnd - cMax);                     /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */
155dae4404aSMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                         /* Every hybrid cell split into 4 cells */
156b5da9499SMatthew G. Knepley     break;
1576ce3c06aSMatthew G. Knepley   case 6:
1586ce3c06aSMatthew G. Knepley     /* Hex 3D */
1596ce3c06aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
1606ce3c06aSMatthew G. Knepley     depthSize[1] = 2*(eEnd - eStart) +  4*(fEnd - fStart) + 6*(cEnd - cStart);    /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */
1616ce3c06aSMatthew G. Knepley     depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart);                        /* Every face is split into 4 faces, and 12 faces are added for each cell */
1626ce3c06aSMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                             /* Every cell split into 8 cells */
1636ce3c06aSMatthew G. Knepley     break;
16427fcede3SMatthew G. Knepley   case 8:
16527fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
16627fcede3SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
16727fcede3SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
16827fcede3SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
16927fcede3SMatthew G. Knepley     /* Hexahedra */
17027fcede3SMatthew G. Knepley     depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
17127fcede3SMatthew G. Knepley     depthSize[1] = 2*(eMax - eStart) +  4*(fMax - fStart) + 6*(cMax - cStart);    /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */
17227fcede3SMatthew G. Knepley     depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart);                        /* Every face is split into 4 faces, and 12 faces are added for each cell */
17327fcede3SMatthew G. Knepley     depthSize[3] = 8*(cMax - cStart);                                             /* Every cell split into 8 cells */
17427fcede3SMatthew G. Knepley     /* Quadrilateral Prisms */
17527fcede3SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
17627fcede3SMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax)   +   (cEnd - cMax);      /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
17727fcede3SMatthew G. Knepley     depthSize[2] += 2*(fEnd - fMax)   + 4*(cEnd - cMax);                          /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */
17827fcede3SMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                              /* Every hybrid cell split into 4 cells */
17927fcede3SMatthew G. Knepley     break;
18075d3a19aSMatthew G. Knepley   default:
18175d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
18275d3a19aSMatthew G. Knepley   }
18375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
18475d3a19aSMatthew G. Knepley }
18575d3a19aSMatthew G. Knepley 
18642525629SMatthew G. Knepley /* Return triangle edge for orientation o, if it is r for o == 0 */
18742525629SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
188518a8359SMatthew G. Knepley   return (o < 0 ? 2-(o+r) : o+r)%3;
189518a8359SMatthew G. Knepley }
190de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
191de65f515SMatthew G. Knepley   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
192de65f515SMatthew G. Knepley }
193518a8359SMatthew G. Knepley 
194518a8359SMatthew G. Knepley /* Return triangle subface for orientation o, if it is r for o == 0 */
195518a8359SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
1964bae88c7SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%3;
19742525629SMatthew G. Knepley }
198de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
199de65f515SMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 3+s-o)%3;
200de65f515SMatthew G. Knepley }
20142525629SMatthew G. Knepley 
202431647a4SMatthew G. Knepley /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */
203431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) {
204431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+r) : o+r)%3;
205431647a4SMatthew G. Knepley }
206431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) {
207431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+s) : 3+s-o)%3;
208431647a4SMatthew G. Knepley }
209431647a4SMatthew G. Knepley 
21042525629SMatthew G. Knepley 
211e3f8b1d6SMatthew G. Knepley /* Return quad edge for orientation o, if it is r for o == 0 */
212e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
213e3f8b1d6SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%4;
214e3f8b1d6SMatthew G. Knepley }
215d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
216d6d937efSMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 4+s-o)%4;
217d6d937efSMatthew G. Knepley }
218e3f8b1d6SMatthew G. Knepley 
219e3f8b1d6SMatthew G. Knepley /* Return quad subface for orientation o, if it is r for o == 0 */
220e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
2214bae88c7SMatthew G. Knepley   return (o < 0 ? 4-(o+r) : o+r)%4;
22242525629SMatthew G. Knepley }
223d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
224d6d937efSMatthew G. Knepley   return (o < 0 ? 4-(o+s) : 4+s-o)%4;
225d6d937efSMatthew G. Knepley }
22642525629SMatthew G. Knepley 
22775d3a19aSMatthew G. Knepley #undef __FUNCT__
22875d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetConeSizes"
22986150812SJed Brown static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
23075d3a19aSMatthew G. Knepley {
231b5da9499SMatthew G. Knepley   PetscInt       depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r;
23275d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
23375d3a19aSMatthew G. Knepley 
23475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
2352a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
23675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
23775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
23875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
23975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
24075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
24175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
2422a5d0125SJed Brown   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
24375d3a19aSMatthew G. Knepley   switch (refiner) {
24475d3a19aSMatthew G. Knepley   case 1:
24575d3a19aSMatthew G. Knepley     /* Simplicial 2D */
24675d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
24775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
24875d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
24975d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
25075d3a19aSMatthew G. Knepley 
25175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
25275d3a19aSMatthew G. Knepley       }
25375d3a19aSMatthew G. Knepley     }
25475d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
25575d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
25675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
25775d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
25875d3a19aSMatthew G. Knepley         PetscInt       size;
25975d3a19aSMatthew G. Knepley 
26075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
26175d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
26275d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
26375d3a19aSMatthew G. Knepley       }
26475d3a19aSMatthew G. Knepley     }
26575d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
26675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
26775d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
26875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
26975d3a19aSMatthew G. Knepley 
27075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
27175d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
27275d3a19aSMatthew G. Knepley       }
27375d3a19aSMatthew G. Knepley     }
27475d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
27575d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
27675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
27775d3a19aSMatthew G. Knepley       PetscInt       size;
27875d3a19aSMatthew G. Knepley 
27975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
28075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
28175d3a19aSMatthew G. Knepley     }
28275d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
28375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
28475d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
28575d3a19aSMatthew G. Knepley       PetscInt       size;
28675d3a19aSMatthew G. Knepley 
28775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
28875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
28975d3a19aSMatthew G. Knepley     }
29075d3a19aSMatthew G. Knepley     break;
29175d3a19aSMatthew G. Knepley   case 2:
29275d3a19aSMatthew G. Knepley     /* Hex 2D */
29375d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
29475d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
29575d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
296149f48fdSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
29775d3a19aSMatthew G. Knepley 
29875d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
29975d3a19aSMatthew G. Knepley       }
30075d3a19aSMatthew G. Knepley     }
30175d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
30275d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
30375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
30475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
30575d3a19aSMatthew G. Knepley         PetscInt       size;
30675d3a19aSMatthew G. Knepley 
30775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
30875d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
30975d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
31075d3a19aSMatthew G. Knepley       }
31175d3a19aSMatthew G. Knepley     }
31275d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
31375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
31475d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
31575d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
31675d3a19aSMatthew G. Knepley 
31775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
31875d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
31975d3a19aSMatthew G. Knepley       }
32075d3a19aSMatthew G. Knepley     }
32175d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
32275d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
32375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
32475d3a19aSMatthew G. Knepley       PetscInt       size;
32575d3a19aSMatthew G. Knepley 
32675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
32775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
32875d3a19aSMatthew G. Knepley     }
32975d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
33075d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
33175d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
33275d3a19aSMatthew G. Knepley       PetscInt       size;
33375d3a19aSMatthew G. Knepley 
33475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
33575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
33675d3a19aSMatthew G. Knepley     }
33775d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
33875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
33975d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
34075d3a19aSMatthew G. Knepley 
34175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
34275d3a19aSMatthew G. Knepley     }
34375d3a19aSMatthew G. Knepley     break;
34475d3a19aSMatthew G. Knepley   case 3:
345d963de37SMatthew G. Knepley     /* Hybrid Simplicial 2D */
34675d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
34775d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
34875d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
34975d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
35075d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
35175d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
35275d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
35375d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
35475d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
35575d3a19aSMatthew G. Knepley 
35675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
35775d3a19aSMatthew G. Knepley       }
35875d3a19aSMatthew G. Knepley     }
35975d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
36075d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
36175d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
36275d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
36375d3a19aSMatthew G. Knepley 
36475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
36575d3a19aSMatthew G. Knepley       }
36675d3a19aSMatthew G. Knepley     }
36775d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
36875d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
36975d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
37075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
37175d3a19aSMatthew G. Knepley         PetscInt       size;
37275d3a19aSMatthew G. Knepley 
37375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
37475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
37575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
37675d3a19aSMatthew G. Knepley       }
37775d3a19aSMatthew G. Knepley     }
37875d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
37975d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
38075d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
38175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
38275d3a19aSMatthew G. Knepley 
38375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
38475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
38575d3a19aSMatthew G. Knepley       }
38675d3a19aSMatthew G. Knepley     }
38775d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
38875d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
38975d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
39075d3a19aSMatthew G. Knepley       PetscInt       size;
39175d3a19aSMatthew G. Knepley 
39275d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
39375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
39475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
39575d3a19aSMatthew G. Knepley     }
39675d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
39775d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
39875d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
39975d3a19aSMatthew G. Knepley 
40075d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
40175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
40275d3a19aSMatthew G. Knepley     }
40375d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
40475d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
40575d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
40675d3a19aSMatthew G. Knepley       PetscInt       size;
40775d3a19aSMatthew G. Knepley 
40875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
40975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
41075d3a19aSMatthew G. Knepley     }
41175d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
41275d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
41375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
41475d3a19aSMatthew G. Knepley       const PetscInt *support;
41575d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
41675d3a19aSMatthew G. Knepley 
41775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
41875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
41975d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
42075d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
42175d3a19aSMatthew G. Knepley         else newSize += 2;
42275d3a19aSMatthew G. Knepley       }
42375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
42475d3a19aSMatthew G. Knepley     }
42575d3a19aSMatthew G. Knepley     break;
426a97b51b8SMatthew G. Knepley   case 4:
427a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
428a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
429a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
430a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
431a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
432a97b51b8SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
433a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
434a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
435a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
436a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
437a97b51b8SMatthew G. Knepley 
438a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
439a97b51b8SMatthew G. Knepley       }
440a97b51b8SMatthew G. Knepley     }
441a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
442a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
443a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
444a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
445a97b51b8SMatthew G. Knepley 
446a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
447a97b51b8SMatthew G. Knepley       }
448a97b51b8SMatthew G. Knepley     }
449a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
450a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
451a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
452a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
453a97b51b8SMatthew G. Knepley         PetscInt       size;
454a97b51b8SMatthew G. Knepley 
455a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
456a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
457a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
458a97b51b8SMatthew G. Knepley       }
459a97b51b8SMatthew G. Knepley     }
460a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
461a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
462a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
463a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
464a97b51b8SMatthew G. Knepley 
465a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
466a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
467a97b51b8SMatthew G. Knepley       }
468a97b51b8SMatthew G. Knepley     }
469a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
470a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
471a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
472a97b51b8SMatthew G. Knepley       PetscInt       size;
473a97b51b8SMatthew G. Knepley 
474a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
475a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
476a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
477a97b51b8SMatthew G. Knepley     }
478a97b51b8SMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
479a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
480a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
481a97b51b8SMatthew G. Knepley 
482a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
483a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
484a97b51b8SMatthew G. Knepley     }
485a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
486a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
487a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
488a97b51b8SMatthew G. Knepley       PetscInt       size;
489a97b51b8SMatthew G. Knepley 
490a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
491a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
492a97b51b8SMatthew G. Knepley     }
493a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
494a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
495a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
496a97b51b8SMatthew G. Knepley       PetscInt       size;
497a97b51b8SMatthew G. Knepley 
498a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
499a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
500a97b51b8SMatthew G. Knepley     }
501a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
502a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
503a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
504a97b51b8SMatthew G. Knepley 
505a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
506a97b51b8SMatthew G. Knepley     }
507a97b51b8SMatthew G. Knepley     break;
508b5da9499SMatthew G. Knepley   case 5:
509b5da9499SMatthew G. Knepley     /* Simplicial 3D */
510b5da9499SMatthew G. Knepley     /* All cells have 4 faces */
511b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
512b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
513dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
514b5da9499SMatthew G. Knepley 
515b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
516b5da9499SMatthew G. Knepley       }
517b5da9499SMatthew G. Knepley     }
518b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
519b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
520b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
521b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
522b5da9499SMatthew G. Knepley         PetscInt       size;
523b5da9499SMatthew G. Knepley 
524b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
525b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
526b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
527b5da9499SMatthew G. Knepley       }
528b5da9499SMatthew G. Knepley     }
5299ddff745SMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
530b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
531b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
532b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
533b5da9499SMatthew G. Knepley 
534b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
535b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
536b5da9499SMatthew G. Knepley       }
537b5da9499SMatthew G. Knepley     }
538b5da9499SMatthew G. Knepley     /* Split edges have 2 vertices and the same faces */
539b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
540b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
541b5da9499SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
542b5da9499SMatthew G. Knepley         PetscInt       size;
543b5da9499SMatthew G. Knepley 
544b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
545b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
546b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
547b5da9499SMatthew G. Knepley       }
548b5da9499SMatthew G. Knepley     }
549b5da9499SMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
550b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
551b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
552b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
553b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
554b5da9499SMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
555b5da9499SMatthew G. Knepley 
556b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
557b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
558b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
559b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
560b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
561b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
562b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
563b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
56486f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
5659ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
566b5da9499SMatthew G. Knepley           if (er == eint[c]) {
567b5da9499SMatthew G. Knepley             intFaces += 1;
568b5da9499SMatthew G. Knepley           } else {
569b5da9499SMatthew G. Knepley             intFaces += 2;
570b5da9499SMatthew G. Knepley           }
571b5da9499SMatthew G. Knepley         }
572b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
573b5da9499SMatthew G. Knepley       }
574b5da9499SMatthew G. Knepley     }
5759ddff745SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
576b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
577b5da9499SMatthew G. Knepley       const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
578b5da9499SMatthew G. Knepley 
579b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
580b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
581b5da9499SMatthew G. Knepley     }
582b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
583b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
584b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
585b5da9499SMatthew G. Knepley       PetscInt       size;
586b5da9499SMatthew G. Knepley 
587b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
588b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
589b5da9499SMatthew G. Knepley     }
590b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
591b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
592b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
593b5da9499SMatthew G. Knepley       PetscInt       size, *star = NULL, starSize, s, cellSize = 0;
594b5da9499SMatthew G. Knepley 
595b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
596b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
597b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
598b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
599b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
600b5da9499SMatthew G. Knepley 
601b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
602b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
603b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
604b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
605b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
60642525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
607b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
608b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
609b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
61042525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
61142525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
612b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
613b5da9499SMatthew G. Knepley         }
614b5da9499SMatthew G. Knepley       }
615b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
616b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr);
617b5da9499SMatthew G. Knepley     }
618b5da9499SMatthew G. Knepley     break;
619dae4404aSMatthew G. Knepley   case 7:
6206ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
6216ce3c06aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
6226ce3c06aSMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
623dae4404aSMatthew G. Knepley     /* Interior cells have 4 faces */
624dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
625dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
626dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
627dae4404aSMatthew G. Knepley 
628dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
629dae4404aSMatthew G. Knepley       }
630dae4404aSMatthew G. Knepley     }
631dae4404aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
632dae4404aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
633dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
634dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
635dae4404aSMatthew G. Knepley 
636dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr);
637dae4404aSMatthew G. Knepley       }
638dae4404aSMatthew G. Knepley     }
6396ce3c06aSMatthew G. Knepley     /* Interior split faces have 3 edges and the same cells as the parent */
640dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
641dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
642dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
643dae4404aSMatthew G. Knepley         PetscInt       size;
644dae4404aSMatthew G. Knepley 
645dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
646dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
647dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
648dae4404aSMatthew G. Knepley       }
649dae4404aSMatthew G. Knepley     }
650dae4404aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
651dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
652dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
653dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
654dae4404aSMatthew G. Knepley 
655dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
656dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
657dae4404aSMatthew G. Knepley       }
658dae4404aSMatthew G. Knepley     }
6596ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
6606ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
6616ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
6626ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
6636ce3c06aSMatthew G. Knepley         PetscInt       size;
6646ce3c06aSMatthew G. Knepley 
6656ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
6666ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
6676ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6686ce3c06aSMatthew G. Knepley       }
6696ce3c06aSMatthew G. Knepley     }
6706ce3c06aSMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
6716ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
6726ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
6736ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
6746ce3c06aSMatthew G. Knepley 
6756ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
6766ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
6776ce3c06aSMatthew G. Knepley       }
6786ce3c06aSMatthew G. Knepley     }
6796ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces */
680dae4404aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
681dae4404aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
682dae4404aSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
683dae4404aSMatthew G. Knepley         PetscInt       size;
684dae4404aSMatthew G. Knepley 
685dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
686dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
687dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
688dae4404aSMatthew G. Knepley       }
689dae4404aSMatthew G. Knepley     }
6906ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
691dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
692dae4404aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
693dae4404aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
694dae4404aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
695dae4404aSMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
696dae4404aSMatthew G. Knepley 
697dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
698dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
699dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
700dae4404aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
701dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
702dae4404aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
703dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
704dae4404aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
7056ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
706dae4404aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
7079ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
708dae4404aSMatthew G. Knepley             if (er == eint[c]) {
709dae4404aSMatthew G. Knepley               intFaces += 1;
710dae4404aSMatthew G. Knepley             } else {
711dae4404aSMatthew G. Knepley               intFaces += 2;
712dae4404aSMatthew G. Knepley             }
7136ce3c06aSMatthew G. Knepley           } else {
7146ce3c06aSMatthew G. Knepley             intFaces += 1;
7156ce3c06aSMatthew G. Knepley           }
716dae4404aSMatthew G. Knepley         }
717dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
718dae4404aSMatthew G. Knepley       }
719dae4404aSMatthew G. Knepley     }
7206ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
721dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
722dae4404aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
723dae4404aSMatthew G. Knepley 
724dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
725dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
726dae4404aSMatthew G. Knepley     }
7276ce3c06aSMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
728dae4404aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
7296ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
7306ce3c06aSMatthew G. Knepley       PetscInt       size;
7316ce3c06aSMatthew G. Knepley 
7326ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
7336ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
7346ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
7356ce3c06aSMatthew G. Knepley     }
7366ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
7376ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
7386ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
739dae4404aSMatthew G. Knepley       PetscInt       size;
740dae4404aSMatthew G. Knepley 
741dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
742dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
7436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr);
744dae4404aSMatthew G. Knepley     }
7456ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
746dae4404aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
747dae4404aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
748dae4404aSMatthew G. Knepley       PetscInt       size;
749dae4404aSMatthew G. Knepley 
750dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
751dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
752dae4404aSMatthew G. Knepley     }
7536ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
7546ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
7556ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
756dae4404aSMatthew G. Knepley       const PetscInt *support;
7576ce3c06aSMatthew G. Knepley       PetscInt        size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
758dae4404aSMatthew G. Knepley 
7596ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
7606ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
761dae4404aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
7626ce3c06aSMatthew G. Knepley         if (support[s] < fMax) faceSize += 2;
7636ce3c06aSMatthew G. Knepley         else                   faceSize += 1;
764dae4404aSMatthew G. Knepley       }
7656ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
7666ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
7676ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
7686ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
7696ce3c06aSMatthew G. Knepley 
7706ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
7716ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
7726ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
7736ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
7746ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
7756ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
7766ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
7776ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
7786ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
7796ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
7806ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
7816ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
7826ce3c06aSMatthew G. Knepley         }
7836ce3c06aSMatthew G. Knepley       }
7846ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
7856ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr);
786dae4404aSMatthew G. Knepley     }
787dae4404aSMatthew G. Knepley     break;
7882eabf88fSMatthew G. Knepley   case 6:
7892eabf88fSMatthew G. Knepley     /* Hex 3D */
7902eabf88fSMatthew G. Knepley     /* All cells have 6 faces */
7912eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
7922eabf88fSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
7932eabf88fSMatthew G. Knepley         const PetscInt newp = (c - cStart)*8 + r;
7942eabf88fSMatthew G. Knepley 
7952eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
7962eabf88fSMatthew G. Knepley       }
7972eabf88fSMatthew G. Knepley     }
7982eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
7992eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
8002eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
8012eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
8022eabf88fSMatthew G. Knepley         PetscInt       size;
8032eabf88fSMatthew G. Knepley 
8042eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
8052eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
8062eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
8072eabf88fSMatthew G. Knepley       }
8082eabf88fSMatthew G. Knepley     }
8092eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
8102eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
8112eabf88fSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
8122eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
8132eabf88fSMatthew G. Knepley 
8142eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
8152eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
8162eabf88fSMatthew G. Knepley       }
8172eabf88fSMatthew G. Knepley     }
8182eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
8192eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
8202eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
8212eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
8222eabf88fSMatthew G. Knepley         PetscInt       size;
8232eabf88fSMatthew G. Knepley 
8242eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
8252eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
8262eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
8272eabf88fSMatthew G. Knepley       }
8282eabf88fSMatthew G. Knepley     }
8292eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
8302eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
8312eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
8322eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
8332eabf88fSMatthew G. Knepley         PetscInt       size;
8342eabf88fSMatthew G. Knepley 
8352eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
8362eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
8372eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
8382eabf88fSMatthew G. Knepley       }
8392eabf88fSMatthew G. Knepley     }
8402eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
8412eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
8422eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
8432eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
8442eabf88fSMatthew G. Knepley 
8452eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
8462eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
8472eabf88fSMatthew G. Knepley       }
8482eabf88fSMatthew G. Knepley     }
8492eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
8502eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
8512eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
8522eabf88fSMatthew G. Knepley       PetscInt       size;
8532eabf88fSMatthew G. Knepley 
8542eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
8552eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
8562eabf88fSMatthew G. Knepley     }
8572eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
8582eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
8592eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
8602eabf88fSMatthew G. Knepley       PetscInt       size;
8612eabf88fSMatthew G. Knepley 
8622eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
8632eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
8642eabf88fSMatthew G. Knepley     }
8652eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
8662eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
8672eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
8682eabf88fSMatthew G. Knepley       PetscInt       size;
8692eabf88fSMatthew G. Knepley 
8702eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
8712eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
8722eabf88fSMatthew G. Knepley     }
8732eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
8742eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
8752eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
8762eabf88fSMatthew G. Knepley 
8772eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
8782eabf88fSMatthew G. Knepley     }
8792eabf88fSMatthew G. Knepley     break;
88027fcede3SMatthew G. Knepley   case 8:
88127fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
88227fcede3SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
88327fcede3SMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
88427fcede3SMatthew G. Knepley     /* Interior cells have 6 faces */
88527fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
88627fcede3SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
88727fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
88827fcede3SMatthew G. Knepley 
88927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
89027fcede3SMatthew G. Knepley       }
89127fcede3SMatthew G. Knepley     }
89227fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces */
89327fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
89427fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
89527fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
89627fcede3SMatthew G. Knepley 
89727fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
89827fcede3SMatthew G. Knepley       }
89927fcede3SMatthew G. Knepley     }
90027fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
90127fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
90227fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
90327fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
90427fcede3SMatthew G. Knepley         PetscInt       size;
90527fcede3SMatthew G. Knepley 
90627fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
90727fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
90827fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
90927fcede3SMatthew G. Knepley       }
91027fcede3SMatthew G. Knepley     }
91127fcede3SMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
91227fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
91327fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
91427fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
91527fcede3SMatthew G. Knepley 
91627fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
91727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
91827fcede3SMatthew G. Knepley       }
91927fcede3SMatthew G. Knepley     }
92027fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
92127fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
92227fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
92327fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
92427fcede3SMatthew G. Knepley         PetscInt       size;
92527fcede3SMatthew G. Knepley 
92627fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
92727fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
92827fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
92927fcede3SMatthew G. Knepley       }
93027fcede3SMatthew G. Knepley     }
93127fcede3SMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
93227fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
93327fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
93427fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
93527fcede3SMatthew G. Knepley 
93627fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
93727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
93827fcede3SMatthew G. Knepley       }
93927fcede3SMatthew G. Knepley     }
94027fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
94127fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
94227fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
94327fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
94427fcede3SMatthew G. Knepley         PetscInt       size;
94527fcede3SMatthew G. Knepley 
94627fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
94727fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
94827fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
94927fcede3SMatthew G. Knepley       }
95027fcede3SMatthew G. Knepley     }
95127fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
95227fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
95327fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
95427fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
95527fcede3SMatthew G. Knepley         PetscInt       size;
95627fcede3SMatthew G. Knepley 
95727fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
95827fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
95927fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
96027fcede3SMatthew G. Knepley       }
96127fcede3SMatthew G. Knepley     }
96227fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
96327fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
96427fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
96527fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
96627fcede3SMatthew G. Knepley 
96727fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
96827fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
96927fcede3SMatthew G. Knepley       }
97027fcede3SMatthew G. Knepley     }
97127fcede3SMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
97227fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
97327fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
97427fcede3SMatthew G. Knepley       PetscInt       size;
97527fcede3SMatthew G. Knepley 
97627fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
97727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
97827fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
97927fcede3SMatthew G. Knepley     }
98027fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
98127fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
98227fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
98327fcede3SMatthew G. Knepley       PetscInt       size;
98427fcede3SMatthew G. Knepley 
98527fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
98627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
98727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
98827fcede3SMatthew G. Knepley     }
98927fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
99027fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
99127fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
99227fcede3SMatthew G. Knepley 
99327fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
99427fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
99527fcede3SMatthew G. Knepley     }
99627fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
99727fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
99827fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
99927fcede3SMatthew G. Knepley       PetscInt       size;
100027fcede3SMatthew G. Knepley 
100127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
100227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
100327fcede3SMatthew G. Knepley     }
100427fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
100527fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
100627fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
100727fcede3SMatthew G. Knepley       PetscInt       size;
100827fcede3SMatthew G. Knepley 
100927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
101027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
101127fcede3SMatthew G. Knepley     }
101227fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
101327fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
101427fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
101527fcede3SMatthew G. Knepley       PetscInt       size;
101627fcede3SMatthew G. Knepley 
101727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
101827fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
101927fcede3SMatthew G. Knepley     }
102027fcede3SMatthew G. Knepley     /* Interior cell vertices have 6 supports */
102127fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
102227fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
102327fcede3SMatthew G. Knepley 
102427fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
102527fcede3SMatthew G. Knepley     }
102627fcede3SMatthew G. Knepley     break;
102775d3a19aSMatthew G. Knepley   default:
102875d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
102975d3a19aSMatthew G. Knepley   }
103075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
103175d3a19aSMatthew G. Knepley }
103275d3a19aSMatthew G. Knepley 
103375d3a19aSMatthew G. Knepley #undef __FUNCT__
103475d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCones"
103586150812SJed Brown static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
103675d3a19aSMatthew G. Knepley {
1037b5da9499SMatthew G. Knepley   const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
10386ce3c06aSMatthew G. Knepley   PetscInt        cStart,    cEnd,    cMax,    vStart,    vEnd, vMax, fStart,    fEnd,    fMax,    eStart,    eEnd,    eMax;
10396ce3c06aSMatthew G. Knepley   PetscInt        cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew,    fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
10406ce3c06aSMatthew G. Knepley   PetscInt        depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
104175d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
104275d3a19aSMatthew G. Knepley 
104375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
10442a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
104575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
104675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
104775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
104875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
104975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
105075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
105175d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
105275d3a19aSMatthew G. Knepley   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
105375d3a19aSMatthew G. Knepley   switch (refiner) {
105475d3a19aSMatthew G. Knepley   case 1:
105575d3a19aSMatthew G. Knepley     /* Simplicial 2D */
105675d3a19aSMatthew G. Knepley     /*
105775d3a19aSMatthew G. Knepley      2
105875d3a19aSMatthew G. Knepley      |\
105975d3a19aSMatthew G. Knepley      | \
106075d3a19aSMatthew G. Knepley      |  \
106175d3a19aSMatthew G. Knepley      |   \
106275d3a19aSMatthew G. Knepley      | C  \
106375d3a19aSMatthew G. Knepley      |     \
106475d3a19aSMatthew G. Knepley      |      \
106575d3a19aSMatthew G. Knepley      2---1---1
106675d3a19aSMatthew G. Knepley      |\  D  / \
106775d3a19aSMatthew G. Knepley      | 2   0   \
106875d3a19aSMatthew G. Knepley      |A \ /  B  \
106975d3a19aSMatthew G. Knepley      0---0-------1
107075d3a19aSMatthew G. Knepley      */
107175d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
107275d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
107375d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
107475d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
107575d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
107675d3a19aSMatthew G. Knepley 
107775d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
107875d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
107975d3a19aSMatthew G. Knepley       /* A triangle */
108075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
108175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
108275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
108375d3a19aSMatthew G. Knepley       orntNew[1] = -2;
108475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
108575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
108675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
108775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
108875d3a19aSMatthew G. Knepley #if 1
108975d3a19aSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
109075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
109175d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
109275d3a19aSMatthew G. Knepley       }
109375d3a19aSMatthew G. Knepley #endif
109475d3a19aSMatthew G. Knepley       /* B triangle */
109575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
109675d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
109775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
109875d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
109975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
110075d3a19aSMatthew G. Knepley       orntNew[2] = -2;
110175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
110275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
110375d3a19aSMatthew G. Knepley #if 1
110475d3a19aSMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
110575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
110675d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
110775d3a19aSMatthew G. Knepley       }
110875d3a19aSMatthew G. Knepley #endif
110975d3a19aSMatthew G. Knepley       /* C triangle */
111075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
111175d3a19aSMatthew G. Knepley       orntNew[0] = -2;
111275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
111375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
111475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
111575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
111675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
111775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
111875d3a19aSMatthew G. Knepley #if 1
111975d3a19aSMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
112075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
112175d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
112275d3a19aSMatthew G. Knepley       }
112375d3a19aSMatthew G. Knepley #endif
112475d3a19aSMatthew G. Knepley       /* D triangle */
112575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
112675d3a19aSMatthew G. Knepley       orntNew[0] = 0;
112775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
112875d3a19aSMatthew G. Knepley       orntNew[1] = 0;
112975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
113075d3a19aSMatthew G. Knepley       orntNew[2] = 0;
113175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
113275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
113375d3a19aSMatthew G. Knepley #if 1
113475d3a19aSMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
113575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
113675d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
113775d3a19aSMatthew G. Knepley       }
113875d3a19aSMatthew G. Knepley #endif
113975d3a19aSMatthew G. Knepley     }
114075d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
114175d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1142785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
114375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
114475d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
114575d3a19aSMatthew G. Knepley 
114675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
114775d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1148297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
114975d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
115075d3a19aSMatthew G. Knepley 
115175d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
115275d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
115375d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
115475d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
115575d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
115675d3a19aSMatthew G. Knepley #if 1
115775d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
115875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
115975d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
116075d3a19aSMatthew G. Knepley         }
116175d3a19aSMatthew G. Knepley #endif
116275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
116375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
116475d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
116575d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
116675d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1167297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
116875d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
116975d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
117075d3a19aSMatthew G. Knepley           }
1171297d2bf4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
117275d3a19aSMatthew G. Knepley         }
117375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
117475d3a19aSMatthew G. Knepley #if 1
117575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
117675d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
117775d3a19aSMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
117875d3a19aSMatthew G. Knepley         }
117975d3a19aSMatthew G. Knepley #endif
118075d3a19aSMatthew G. Knepley       }
118175d3a19aSMatthew G. Knepley     }
118275d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
118375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
118475d3a19aSMatthew G. Knepley       const PetscInt *cone;
118575d3a19aSMatthew G. Knepley 
118675d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
118775d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
118875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
118975d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
119075d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
119175d3a19aSMatthew G. Knepley 
119275d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
119375d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
119475d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
119575d3a19aSMatthew G. Knepley #if 1
119675d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
119775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
119875d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
119975d3a19aSMatthew G. Knepley         }
120075d3a19aSMatthew G. Knepley #endif
120175d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
120275d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
120375d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
120475d3a19aSMatthew G. Knepley #if 1
120575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
120675d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
120775d3a19aSMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
120875d3a19aSMatthew G. Knepley         }
120975d3a19aSMatthew G. Knepley #endif
121075d3a19aSMatthew G. Knepley       }
121175d3a19aSMatthew G. Knepley     }
121275d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
121375d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
121475d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
121575d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
121675d3a19aSMatthew G. Knepley       PetscInt        size, s;
121775d3a19aSMatthew G. Knepley 
121875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
121975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
122075d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
122175d3a19aSMatthew G. Knepley         PetscInt r = 0;
122275d3a19aSMatthew G. Knepley 
122375d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
122475d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
122575d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
122675d3a19aSMatthew G. Knepley       }
122775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
122875d3a19aSMatthew G. Knepley #if 1
122975d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
123075d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
123175d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
123275d3a19aSMatthew G. Knepley       }
123375d3a19aSMatthew G. Knepley #endif
123475d3a19aSMatthew G. Knepley     }
123575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
123675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
123775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
123875d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
123975d3a19aSMatthew G. Knepley       PetscInt        size, s;
124075d3a19aSMatthew G. Knepley 
124175d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
124275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
124375d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
124475d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
124575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
124675d3a19aSMatthew G. Knepley         PetscInt r = 0;
124775d3a19aSMatthew G. Knepley 
124875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
124975d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
125075d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
125175d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
125275d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
125375d3a19aSMatthew G. Knepley       }
125475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
125575d3a19aSMatthew G. Knepley #if 1
125675d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
125775d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
125875d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
125975d3a19aSMatthew G. Knepley       }
126075d3a19aSMatthew G. Knepley #endif
126175d3a19aSMatthew G. Knepley     }
126275d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
126375d3a19aSMatthew G. Knepley     break;
126475d3a19aSMatthew G. Knepley   case 2:
126575d3a19aSMatthew G. Knepley     /* Hex 2D */
126675d3a19aSMatthew G. Knepley     /*
126775d3a19aSMatthew G. Knepley      3---------2---------2
126875d3a19aSMatthew G. Knepley      |         |         |
126975d3a19aSMatthew G. Knepley      |    D    2    C    |
127075d3a19aSMatthew G. Knepley      |         |         |
127175d3a19aSMatthew G. Knepley      3----3----0----1----1
127275d3a19aSMatthew G. Knepley      |         |         |
127375d3a19aSMatthew G. Knepley      |    A    0    B    |
127475d3a19aSMatthew G. Knepley      |         |         |
127575d3a19aSMatthew G. Knepley      0---------0---------1
127675d3a19aSMatthew G. Knepley      */
127775d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
127875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
127975d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
128075d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
128175d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
128275d3a19aSMatthew G. Knepley 
128375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
128475d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
128575d3a19aSMatthew G. Knepley       /* A quad */
128675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
128775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
128875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
128975d3a19aSMatthew G. Knepley       orntNew[1] = 0;
129075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
129175d3a19aSMatthew G. Knepley       orntNew[2] = -2;
129275d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
129375d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
129475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
129575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
129675d3a19aSMatthew G. Knepley #if 1
129775d3a19aSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
129875d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
129975d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
130075d3a19aSMatthew G. Knepley       }
130175d3a19aSMatthew G. Knepley #endif
130275d3a19aSMatthew G. Knepley       /* B quad */
130375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
130475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
130575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
130675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
130775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
130875d3a19aSMatthew G. Knepley       orntNew[2] = 0;
130975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
131075d3a19aSMatthew G. Knepley       orntNew[3] = -2;
131175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
131275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
131375d3a19aSMatthew G. Knepley #if 1
131475d3a19aSMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
131575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
131675d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
131775d3a19aSMatthew G. Knepley       }
131875d3a19aSMatthew G. Knepley #endif
131975d3a19aSMatthew G. Knepley       /* C quad */
132075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
132175d3a19aSMatthew G. Knepley       orntNew[0] = -2;
132275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
132375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
132475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
132575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
132675d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
132775d3a19aSMatthew G. Knepley       orntNew[3] = 0;
132875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
132975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
133075d3a19aSMatthew G. Knepley #if 1
133175d3a19aSMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
133275d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
133375d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
133475d3a19aSMatthew G. Knepley       }
133575d3a19aSMatthew G. Knepley #endif
133675d3a19aSMatthew G. Knepley       /* D quad */
133775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
133875d3a19aSMatthew G. Knepley       orntNew[0] = 0;
133975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
134075d3a19aSMatthew G. Knepley       orntNew[1] = -2;
134175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
134275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
134375d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
134475d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
134575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
134675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
134775d3a19aSMatthew G. Knepley #if 1
134875d3a19aSMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
134975d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
135075d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
135175d3a19aSMatthew G. Knepley       }
135275d3a19aSMatthew G. Knepley #endif
135375d3a19aSMatthew G. Knepley     }
135475d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
135575d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1356785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
135775d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
135875d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
135975d3a19aSMatthew G. Knepley 
136075d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
136175d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1362455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
136375d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
136475d3a19aSMatthew G. Knepley 
136575d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
136675d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
136775d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
136875d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
136975d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
137075d3a19aSMatthew G. Knepley #if 1
137175d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
137275d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
137375d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
137475d3a19aSMatthew G. Knepley         }
137575d3a19aSMatthew G. Knepley #endif
137675d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
137775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
137875d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
137975d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
138075d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1381455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
138275d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
138375d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
138475d3a19aSMatthew G. Knepley           }
1385455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
138675d3a19aSMatthew G. Knepley         }
138775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
138875d3a19aSMatthew G. Knepley #if 1
138975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
139075d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
139175d3a19aSMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
139275d3a19aSMatthew G. Knepley         }
139375d3a19aSMatthew G. Knepley #endif
139475d3a19aSMatthew G. Knepley       }
139575d3a19aSMatthew G. Knepley     }
139675d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
139775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
139875d3a19aSMatthew G. Knepley       const PetscInt *cone;
139975d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
140075d3a19aSMatthew G. Knepley 
140175d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
140275d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
140375d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
140475d3a19aSMatthew G. Knepley 
140575d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
140675d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
140775d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
140875d3a19aSMatthew G. Knepley #if 1
140975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
141075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
141175d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
141275d3a19aSMatthew G. Knepley         }
141375d3a19aSMatthew G. Knepley #endif
141475d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
141575d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
141675d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
141775d3a19aSMatthew G. Knepley #if 1
141875d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
141975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
142075d3a19aSMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
142175d3a19aSMatthew G. Knepley         }
142275d3a19aSMatthew G. Knepley #endif
142375d3a19aSMatthew G. Knepley       }
142475d3a19aSMatthew G. Knepley     }
142575d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
142675d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
142775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
142875d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
142975d3a19aSMatthew G. Knepley       PetscInt        size, s;
143075d3a19aSMatthew G. Knepley 
143175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
143275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
143375d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
143475d3a19aSMatthew G. Knepley         PetscInt r = 0;
143575d3a19aSMatthew G. Knepley 
143675d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
143775d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
143875d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
143975d3a19aSMatthew G. Knepley       }
144075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
144175d3a19aSMatthew G. Knepley #if 1
144275d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
144375d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
144475d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
144575d3a19aSMatthew G. Knepley       }
144675d3a19aSMatthew G. Knepley #endif
144775d3a19aSMatthew G. Knepley     }
144875d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
144975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
145075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
145175d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
145275d3a19aSMatthew G. Knepley       PetscInt        size, s;
145375d3a19aSMatthew G. Knepley 
145475d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
145575d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
145675d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
145775d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
145875d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
145975d3a19aSMatthew G. Knepley         PetscInt r = 0;
146075d3a19aSMatthew G. Knepley 
146175d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
146275d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
146375d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
146475d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
146575d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
146675d3a19aSMatthew G. Knepley       }
146775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
146875d3a19aSMatthew G. Knepley #if 1
146975d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
147075d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
147175d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
147275d3a19aSMatthew G. Knepley       }
147375d3a19aSMatthew G. Knepley #endif
147475d3a19aSMatthew G. Knepley     }
147575d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
147675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
147775d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
147875d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
147975d3a19aSMatthew G. Knepley 
148075d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
148175d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
148275d3a19aSMatthew G. Knepley       }
148375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
148475d3a19aSMatthew G. Knepley     }
1485da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
148675d3a19aSMatthew G. Knepley     break;
148775d3a19aSMatthew G. Knepley   case 3:
1488149f48fdSMatthew G. Knepley     /* Hybrid Simplicial 2D */
148975d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
149075d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
149175d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
149275d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
1493149f48fdSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
149475d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
149575d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
149675d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
149775d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
149875d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
149975d3a19aSMatthew G. Knepley 
150075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
150175d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
150275d3a19aSMatthew G. Knepley       /* A triangle */
150375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
150475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
150575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
150675d3a19aSMatthew G. Knepley       orntNew[1] = -2;
150775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
150875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
150975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
151075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
151175d3a19aSMatthew G. Knepley #if 1
1512149f48fdSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+0, cStartNew, cMaxNew);
151375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1514149f48fdSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
151575d3a19aSMatthew G. Knepley       }
151675d3a19aSMatthew G. Knepley #endif
151775d3a19aSMatthew G. Knepley       /* B triangle */
151875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
151975d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
152075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
152175d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
152275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
152375d3a19aSMatthew G. Knepley       orntNew[2] = -2;
152475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
152575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
152675d3a19aSMatthew G. Knepley #if 1
1527a97b51b8SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew);
152875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1529a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
153075d3a19aSMatthew G. Knepley       }
153175d3a19aSMatthew G. Knepley #endif
153275d3a19aSMatthew G. Knepley       /* C triangle */
153375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
153475d3a19aSMatthew G. Knepley       orntNew[0] = -2;
153575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
153675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
153775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
153875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
153975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
154075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
154175d3a19aSMatthew G. Knepley #if 1
1542a97b51b8SMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew);
154375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1544a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
154575d3a19aSMatthew G. Knepley       }
154675d3a19aSMatthew G. Knepley #endif
154775d3a19aSMatthew G. Knepley       /* D triangle */
154875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
154975d3a19aSMatthew G. Knepley       orntNew[0] = 0;
155075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
155175d3a19aSMatthew G. Knepley       orntNew[1] = 0;
155275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
155375d3a19aSMatthew G. Knepley       orntNew[2] = 0;
155475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
155575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
155675d3a19aSMatthew G. Knepley #if 1
1557a97b51b8SMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew);
155875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1559a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
156075d3a19aSMatthew G. Knepley       }
156175d3a19aSMatthew G. Knepley #endif
156275d3a19aSMatthew G. Knepley     }
156375d3a19aSMatthew G. Knepley     /*
156475d3a19aSMatthew G. Knepley      2----3----3
156575d3a19aSMatthew G. Knepley      |         |
156675d3a19aSMatthew G. Knepley      |    B    |
156775d3a19aSMatthew G. Knepley      |         |
156875d3a19aSMatthew G. Knepley      0----4--- 1
156975d3a19aSMatthew G. Knepley      |         |
157075d3a19aSMatthew G. Knepley      |    A    |
157175d3a19aSMatthew G. Knepley      |         |
157275d3a19aSMatthew G. Knepley      0----2----1
157375d3a19aSMatthew G. Knepley      */
157475d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
157575d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
157675d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
157775d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
1578ea00e70eSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4], r;
157975d3a19aSMatthew G. Knepley 
158075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
158175d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1582ea00e70eSMatthew G. Knepley       r    = (ornt[0] < 0 ? 1 : 0);
158375d3a19aSMatthew G. Knepley       /* A quad */
1584ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + r;
158575d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
1586ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + r;
158775d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
1588ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax);
1589ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
1590ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
1591ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
159275d3a19aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
159375d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
159475d3a19aSMatthew G. Knepley #if 1
159575d3a19aSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
159675d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
159775d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
159875d3a19aSMatthew G. Knepley       }
159975d3a19aSMatthew G. Knepley #endif
160075d3a19aSMatthew G. Knepley       /* B quad */
1601ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + 1-r;
160275d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
1603ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + 1-r;
160475d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
1605ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
1606ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
1607ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax);
1608ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
160975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
161075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
161175d3a19aSMatthew G. Knepley #if 1
161275d3a19aSMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
161375d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
161475d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
161575d3a19aSMatthew G. Knepley       }
161675d3a19aSMatthew G. Knepley #endif
161775d3a19aSMatthew G. Knepley     }
161875d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
161975d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1620785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
162175d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
162275d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
162375d3a19aSMatthew G. Knepley 
162475d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
162575d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1626297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
162775d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
162875d3a19aSMatthew G. Knepley 
162975d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
163075d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
163175d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
163275d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
163375d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
163475d3a19aSMatthew G. Knepley #if 1
163575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
163675d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
163775d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
163875d3a19aSMatthew G. Knepley         }
163975d3a19aSMatthew G. Knepley #endif
164075d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
164175d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
164275d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
164375d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
164475d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1645297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1646ea00e70eSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == f) break;
1647ea00e70eSMatthew G. Knepley           if (support[s] >= cMax) {
1648ea00e70eSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r);
1649ea00e70eSMatthew G. Knepley           } else {
1650297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
165175d3a19aSMatthew G. Knepley           }
165275d3a19aSMatthew G. Knepley         }
165375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
165475d3a19aSMatthew G. Knepley #if 1
165575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
165675d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
165775d3a19aSMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
165875d3a19aSMatthew G. Knepley         }
165975d3a19aSMatthew G. Knepley #endif
166075d3a19aSMatthew G. Knepley       }
166175d3a19aSMatthew G. Knepley     }
166275d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
166375d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
166475d3a19aSMatthew G. Knepley       const PetscInt *cone;
166575d3a19aSMatthew G. Knepley 
166675d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
166775d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
166875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
166975d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
167075d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
167175d3a19aSMatthew G. Knepley 
167275d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
167375d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
167475d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
167575d3a19aSMatthew G. Knepley #if 1
167675d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
167775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
167875d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
167975d3a19aSMatthew G. Knepley         }
168075d3a19aSMatthew G. Knepley #endif
168175d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
168275d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
168375d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
168475d3a19aSMatthew G. Knepley #if 1
168575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
168675d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
168775d3a19aSMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
168875d3a19aSMatthew G. Knepley         }
168975d3a19aSMatthew G. Knepley #endif
169075d3a19aSMatthew G. Knepley       }
169175d3a19aSMatthew G. Knepley     }
169275d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
169375d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
169475d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
1695ea00e70eSMatthew G. Knepley       const PetscInt *cone, *ornt;
169675d3a19aSMatthew G. Knepley       const PetscInt *support;
169775d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
169875d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
169975d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
170075d3a19aSMatthew G. Knepley 
170175d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
170275d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
170375d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
170475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
170575d3a19aSMatthew G. Knepley #if 1
170675d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
170775d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
170875d3a19aSMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
170975d3a19aSMatthew G. Knepley       }
171075d3a19aSMatthew G. Knepley #endif
171175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
171275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
171375d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
171475d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1715ea00e70eSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
171675d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
171775d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
171875d3a19aSMatthew G. Knepley         }
1719ea00e70eSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r);
172075d3a19aSMatthew G. Knepley       }
172175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
172275d3a19aSMatthew G. Knepley #if 1
172375d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
172475d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
172575d3a19aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
172675d3a19aSMatthew G. Knepley       }
172775d3a19aSMatthew G. Knepley #endif
172875d3a19aSMatthew G. Knepley     }
172975d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
173075d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
173175d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
173275d3a19aSMatthew G. Knepley       const PetscInt *cone;
173375d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
173475d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
173575d3a19aSMatthew G. Knepley 
173675d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
173775d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
173875d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
173975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
174075d3a19aSMatthew G. Knepley #if 1
174175d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
174275d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
174375d3a19aSMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
174475d3a19aSMatthew G. Knepley       }
174575d3a19aSMatthew G. Knepley #endif
174675d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
174775d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
174875d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
174975d3a19aSMatthew G. Knepley #if 1
175075d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
175175d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
175275d3a19aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
175375d3a19aSMatthew G. Knepley       }
175475d3a19aSMatthew G. Knepley #endif
175575d3a19aSMatthew G. Knepley     }
175675d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
175775d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
175875d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
175975d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
176075d3a19aSMatthew G. Knepley       PetscInt        size, s;
176175d3a19aSMatthew G. Knepley 
176275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
176375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
176475d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
176575d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
176675d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
176775d3a19aSMatthew G. Knepley         } else {
176875d3a19aSMatthew G. Knepley           PetscInt r = 0;
176975d3a19aSMatthew G. Knepley 
177075d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
177175d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
177275d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
177375d3a19aSMatthew G. Knepley         }
177475d3a19aSMatthew G. Knepley       }
177575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
177675d3a19aSMatthew G. Knepley #if 1
177775d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
177875d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
177975d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
178075d3a19aSMatthew G. Knepley       }
178175d3a19aSMatthew G. Knepley #endif
178275d3a19aSMatthew G. Knepley     }
178375d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
178475d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
178575d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
178675d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
178775d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
178875d3a19aSMatthew G. Knepley 
178975d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
179075d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
179175d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
179275d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
179375d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
179475d3a19aSMatthew G. Knepley         PetscInt r = 0;
179575d3a19aSMatthew G. Knepley 
179675d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
179775d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
179875d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
179975d3a19aSMatthew G. Knepley 
180075d3a19aSMatthew G. Knepley           newSize += 1;
180175d3a19aSMatthew G. Knepley         } else {
180275d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
180375d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
180475d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
180575d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
180675d3a19aSMatthew G. Knepley 
180775d3a19aSMatthew G. Knepley           newSize += 2;
180875d3a19aSMatthew G. Knepley         }
180975d3a19aSMatthew G. Knepley       }
181075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
181175d3a19aSMatthew G. Knepley #if 1
181275d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
181375d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
181475d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
181575d3a19aSMatthew G. Knepley       }
181675d3a19aSMatthew G. Knepley #endif
181775d3a19aSMatthew G. Knepley     }
181875d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
181975d3a19aSMatthew G. Knepley     break;
1820a97b51b8SMatthew G. Knepley   case 4:
1821a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
1822a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
1823a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
1824a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
1825a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
1826a97b51b8SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
1827a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
1828a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
1829a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
1830a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
1831a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1832a97b51b8SMatthew G. Knepley 
1833a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1834a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1835a97b51b8SMatthew G. Knepley       /* A quad */
1836a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1837a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1838a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
1839a97b51b8SMatthew G. Knepley       orntNew[1] = 0;
1840a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
1841a97b51b8SMatthew G. Knepley       orntNew[2] = -2;
1842a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
1843a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
1844a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1845a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1846a97b51b8SMatthew G. Knepley #if 1
1847a97b51b8SMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+0, cStartNew, cMaxNew);
1848a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1849a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
1850a97b51b8SMatthew G. Knepley       }
1851a97b51b8SMatthew G. Knepley #endif
1852a97b51b8SMatthew G. Knepley       /* B quad */
1853a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1854a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1855a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1856a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1857a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
1858a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
1859a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
1860a97b51b8SMatthew G. Knepley       orntNew[3] = -2;
1861a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1862a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1863a97b51b8SMatthew G. Knepley #if 1
1864a97b51b8SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew);
1865a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1866a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
1867a97b51b8SMatthew G. Knepley       }
1868a97b51b8SMatthew G. Knepley #endif
1869a97b51b8SMatthew G. Knepley       /* C quad */
1870a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
1871a97b51b8SMatthew G. Knepley       orntNew[0] = -2;
1872a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1873a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1874a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
1875a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
1876a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
1877a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
1878a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1879a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1880a97b51b8SMatthew G. Knepley #if 1
1881a97b51b8SMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew);
1882a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1883a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
1884a97b51b8SMatthew G. Knepley       }
1885a97b51b8SMatthew G. Knepley #endif
1886a97b51b8SMatthew G. Knepley       /* D quad */
1887a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
1888a97b51b8SMatthew G. Knepley       orntNew[0] = 0;
1889a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
1890a97b51b8SMatthew G. Knepley       orntNew[1] = -2;
1891a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
1892a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
1893a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
1894a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
1895a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1896a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1897a97b51b8SMatthew G. Knepley #if 1
1898a97b51b8SMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew);
1899a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1900a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
1901a97b51b8SMatthew G. Knepley       }
1902a97b51b8SMatthew G. Knepley #endif
1903a97b51b8SMatthew G. Knepley     }
1904a97b51b8SMatthew G. Knepley     /*
1905a97b51b8SMatthew G. Knepley      2----3----3
1906a97b51b8SMatthew G. Knepley      |         |
1907a97b51b8SMatthew G. Knepley      |    B    |
1908a97b51b8SMatthew G. Knepley      |         |
1909a97b51b8SMatthew G. Knepley      0----4--- 1
1910a97b51b8SMatthew G. Knepley      |         |
1911a97b51b8SMatthew G. Knepley      |    A    |
1912a97b51b8SMatthew G. Knepley      |         |
1913a97b51b8SMatthew G. Knepley      0----2----1
1914a97b51b8SMatthew G. Knepley      */
1915a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
1916a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
1917a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
1918a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
1919a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1920a97b51b8SMatthew G. Knepley 
1921a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1922a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1923a97b51b8SMatthew G. Knepley       /* A quad */
1924a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1925a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1926a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1927a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1928a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax);
1929a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
1930a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
1931a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
1932a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1933a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1934a97b51b8SMatthew G. Knepley #if 1
1935a97b51b8SMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
1936a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1937a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1938a97b51b8SMatthew G. Knepley       }
1939a97b51b8SMatthew G. Knepley #endif
1940a97b51b8SMatthew G. Knepley       /* B quad */
1941a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1942a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1943a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1944a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1945a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
1946a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
1947a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax);
1948a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
1949a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1950a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1951a97b51b8SMatthew G. Knepley #if 1
1952a97b51b8SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
1953a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1954a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
1955a97b51b8SMatthew G. Knepley       }
1956a97b51b8SMatthew G. Knepley #endif
1957a97b51b8SMatthew G. Knepley     }
1958a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
1959a97b51b8SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1960a97b51b8SMatthew G. Knepley     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
1961a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
1962a97b51b8SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
1963a97b51b8SMatthew G. Knepley 
1964a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
1965a97b51b8SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1966a97b51b8SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
1967a97b51b8SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
1968a97b51b8SMatthew G. Knepley 
1969a97b51b8SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
1970a97b51b8SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
1971a97b51b8SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
1972a97b51b8SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
1973a97b51b8SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1974a97b51b8SMatthew G. Knepley #if 1
1975a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1976a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
1977a97b51b8SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
1978a97b51b8SMatthew G. Knepley         }
1979a97b51b8SMatthew G. Knepley #endif
1980a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
1981a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1982a97b51b8SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
1983a97b51b8SMatthew G. Knepley           if (support[s] >= cMax) {
1984a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
1985a97b51b8SMatthew G. Knepley           } else {
1986a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
1987a97b51b8SMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1988a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1989a97b51b8SMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
1990a97b51b8SMatthew G. Knepley               if (cone[c] == f) break;
1991a97b51b8SMatthew G. Knepley             }
1992a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
1993a97b51b8SMatthew G. Knepley           }
1994a97b51b8SMatthew G. Knepley         }
1995a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1996a97b51b8SMatthew G. Knepley #if 1
1997a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
1998a97b51b8SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
1999a97b51b8SMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
2000a97b51b8SMatthew G. Knepley         }
2001a97b51b8SMatthew G. Knepley #endif
2002a97b51b8SMatthew G. Knepley       }
2003a97b51b8SMatthew G. Knepley     }
2004a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
2005a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2006a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2007a97b51b8SMatthew G. Knepley 
2008a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2009a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2010a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2011a97b51b8SMatthew G. Knepley         PetscInt       coneNew[2], supportNew[2];
2012a97b51b8SMatthew G. Knepley 
2013a97b51b8SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2014a97b51b8SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fMax    - fStart) + (c - cStart);
2015a97b51b8SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2016a97b51b8SMatthew G. Knepley #if 1
2017a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2018a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2019a97b51b8SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2020a97b51b8SMatthew G. Knepley         }
2021a97b51b8SMatthew G. Knepley #endif
2022a97b51b8SMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
2023a97b51b8SMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
2024a97b51b8SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2025a97b51b8SMatthew G. Knepley #if 1
2026a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2027a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2028a97b51b8SMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2029a97b51b8SMatthew G. Knepley         }
2030a97b51b8SMatthew G. Knepley #endif
2031a97b51b8SMatthew G. Knepley       }
2032a97b51b8SMatthew G. Knepley     }
2033a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
2034a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
2035a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
2036a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2037a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2038a97b51b8SMatthew G. Knepley       PetscInt        size, s, r;
2039a97b51b8SMatthew G. Knepley 
2040a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2041a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
2042a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
2043a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2044a97b51b8SMatthew G. Knepley #if 1
2045a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2046a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2047a97b51b8SMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2048a97b51b8SMatthew G. Knepley       }
2049a97b51b8SMatthew G. Knepley #endif
2050a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2051a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2052a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2053a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2054a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r) {
2055a97b51b8SMatthew G. Knepley           if (cone[r+2] == f) break;
2056a97b51b8SMatthew G. Knepley         }
2057a97b51b8SMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2058a97b51b8SMatthew G. Knepley       }
2059a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2060a97b51b8SMatthew G. Knepley #if 1
2061a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2062a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2063a97b51b8SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2064a97b51b8SMatthew G. Knepley       }
2065a97b51b8SMatthew G. Knepley #endif
2066a97b51b8SMatthew G. Knepley     }
2067a97b51b8SMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
2068a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2069a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
2070a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2071a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2072a97b51b8SMatthew G. Knepley 
2073a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2074a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
2075a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
2076a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2077a97b51b8SMatthew G. Knepley #if 1
2078a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2079a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2080a97b51b8SMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2081a97b51b8SMatthew G. Knepley       }
2082a97b51b8SMatthew G. Knepley #endif
2083a97b51b8SMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
2084a97b51b8SMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
2085a97b51b8SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2086a97b51b8SMatthew G. Knepley #if 1
2087a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2088a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2089a97b51b8SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2090a97b51b8SMatthew G. Knepley       }
2091a97b51b8SMatthew G. Knepley #endif
2092a97b51b8SMatthew G. Knepley     }
2093a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
2094a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2095a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2096a97b51b8SMatthew G. Knepley       const PetscInt *support, *cone;
2097a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2098a97b51b8SMatthew G. Knepley 
2099a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2100a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2101a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2102a97b51b8SMatthew G. Knepley         if (support[s] >= fMax) {
2103a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax);
2104a97b51b8SMatthew G. Knepley         } else {
2105a97b51b8SMatthew G. Knepley           PetscInt r = 0;
2106a97b51b8SMatthew G. Knepley 
2107a97b51b8SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2108a97b51b8SMatthew G. Knepley           if (cone[1] == v) r = 1;
2109a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2110a97b51b8SMatthew G. Knepley         }
2111a97b51b8SMatthew G. Knepley       }
2112a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2113a97b51b8SMatthew G. Knepley #if 1
2114a97b51b8SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
2115a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2116a97b51b8SMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
2117a97b51b8SMatthew G. Knepley       }
2118a97b51b8SMatthew G. Knepley #endif
2119a97b51b8SMatthew G. Knepley     }
2120a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
2121a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2122a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
2123a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2124a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2125a97b51b8SMatthew G. Knepley 
2126a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2127a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2128a97b51b8SMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2129a97b51b8SMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2130a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2131a97b51b8SMatthew G. Knepley         PetscInt r = 0;
2132a97b51b8SMatthew G. Knepley 
2133a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2134a97b51b8SMatthew G. Knepley         if (support[s] >= cMax) {
2135a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax);
2136a97b51b8SMatthew G. Knepley         } else {
2137a97b51b8SMatthew G. Knepley           if      (cone[1] == f) r = 1;
2138a97b51b8SMatthew G. Knepley           else if (cone[2] == f) r = 2;
2139a97b51b8SMatthew G. Knepley           else if (cone[3] == f) r = 3;
2140a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r;
2141a97b51b8SMatthew G. Knepley         }
2142a97b51b8SMatthew G. Knepley       }
2143a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2144a97b51b8SMatthew G. Knepley #if 1
2145a97b51b8SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
2146a97b51b8SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
2147a97b51b8SMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
2148a97b51b8SMatthew G. Knepley       }
2149a97b51b8SMatthew G. Knepley #endif
2150a97b51b8SMatthew G. Knepley     }
2151a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
2152a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2153a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
2154a97b51b8SMatthew G. Knepley       PetscInt       supportNew[4];
2155a97b51b8SMatthew G. Knepley 
2156a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2157a97b51b8SMatthew G. Knepley         supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2158a97b51b8SMatthew G. Knepley       }
2159a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2160a97b51b8SMatthew G. Knepley     }
2161a97b51b8SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2162a97b51b8SMatthew G. Knepley     break;
2163b5da9499SMatthew G. Knepley   case 5:
2164b5da9499SMatthew G. Knepley     /* Simplicial 3D */
2165b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
2166b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
2167b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2168b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
2169b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2170b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2171b5da9499SMatthew G. Knepley 
2172b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2173b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2174b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
2175518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
2176b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2177518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
2178b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2179518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
2180b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2181b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2182b5da9499SMatthew G. Knepley       orntNew[3] = 0;
2183b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2184b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2185b5da9499SMatthew G. Knepley #if 1
2186b5da9499SMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
2187b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2188b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2189b5da9499SMatthew G. Knepley       }
2190b5da9499SMatthew G. Knepley #endif
2191b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
2192518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
2193b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2194518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
2195b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2196b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2197b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2198518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
2199b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2200b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2201b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2202b5da9499SMatthew G. Knepley #if 1
2203b5da9499SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
2204b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2205b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2206b5da9499SMatthew G. Knepley       }
2207b5da9499SMatthew G. Knepley #endif
2208b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
2209518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
2210b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2211b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2212b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2213518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
2214b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2215518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
2216b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2217b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2218b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2219b5da9499SMatthew G. Knepley #if 1
2220b5da9499SMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
2221b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2222b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2223b5da9499SMatthew G. Knepley       }
2224b5da9499SMatthew G. Knepley #endif
2225b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
2226b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2227b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2228518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
2229b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2230518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
2231b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2232518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
2233b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2234b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2235b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2236b5da9499SMatthew G. Knepley #if 1
2237b5da9499SMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
2238b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2239b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2240b5da9499SMatthew G. Knepley       }
2241b5da9499SMatthew G. Knepley #endif
2242b5da9499SMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
2243b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2244b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2245fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
2246db2c6090SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
2247fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2248fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
2249fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2250fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
2251b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
2252b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
2253b5da9499SMatthew G. Knepley #if 1
2254b5da9499SMatthew G. Knepley       if ((newp+4 < cStartNew) || (newp+4 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cEndNew);
2255b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2256b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2257b5da9499SMatthew G. Knepley       }
2258b5da9499SMatthew G. Knepley #endif
2259b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
2260b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2261b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2262fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2263fac4ab25SMatthew G. Knepley       orntNew[1] = 1;
2264fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
2265b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2266fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
2267db2c6090SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
2268b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
2269b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
2270b5da9499SMatthew G. Knepley #if 1
2271b5da9499SMatthew G. Knepley       if ((newp+5 < cStartNew) || (newp+5 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cEndNew);
2272b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2273b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2274b5da9499SMatthew G. Knepley       }
2275b5da9499SMatthew G. Knepley #endif
2276b5da9499SMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
2277b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2278b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2279fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
2280db2c6090SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
2281fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2282fac4ab25SMatthew G. Knepley       orntNew[2] = -3;
2283fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
2284fac4ab25SMatthew G. Knepley       orntNew[3] = -2;
2285b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
2286b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
2287b5da9499SMatthew G. Knepley #if 1
2288b5da9499SMatthew G. Knepley       if ((newp+6 < cStartNew) || (newp+6 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cEndNew);
2289b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2290b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2291b5da9499SMatthew G. Knepley       }
2292b5da9499SMatthew G. Knepley #endif
2293b5da9499SMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
2294b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2295b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2296fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2297b5da9499SMatthew G. Knepley       orntNew[1] = -3;
2298fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
2299db2c6090SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
2300fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2301fac4ab25SMatthew G. Knepley       orntNew[3] = -3;
2302b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
2303b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
2304b5da9499SMatthew G. Knepley #if 1
2305b5da9499SMatthew G. Knepley       if ((newp+7 < cStartNew) || (newp+7 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cEndNew);
2306b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2307b5da9499SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
2308b5da9499SMatthew G. Knepley       }
2309b5da9499SMatthew G. Knepley #endif
2310b5da9499SMatthew G. Knepley     }
2311b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
2312b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2313785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
2314b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2315b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
2316b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2317b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
2318b5da9499SMatthew G. Knepley 
2319b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2320b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
2321b5da9499SMatthew G. Knepley       /* A triangle */
2322b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
2323b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2324b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2325b5da9499SMatthew G. Knepley       orntNew[1] = -2;
2326b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
2327b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2328b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2329b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2330b5da9499SMatthew G. Knepley #if 1
2331b5da9499SMatthew G. Knepley       if ((newp+0 < fStartNew) || (newp+0 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+0, fStartNew, fEndNew);
2332b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2333b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2334b5da9499SMatthew G. Knepley       }
2335b5da9499SMatthew G. Knepley #endif
2336b5da9499SMatthew G. Knepley       /* B triangle */
2337b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
2338b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2339b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
2340b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2341b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2342b5da9499SMatthew G. Knepley       orntNew[2] = -2;
2343b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2344b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2345b5da9499SMatthew G. Knepley #if 1
2346b5da9499SMatthew G. Knepley       if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fEndNew);
2347b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2348b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2349b5da9499SMatthew G. Knepley       }
2350b5da9499SMatthew G. Knepley #endif
2351b5da9499SMatthew G. Knepley       /* C triangle */
2352b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2353b5da9499SMatthew G. Knepley       orntNew[0] = -2;
2354b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
2355b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2356b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
2357b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2358b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2359b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2360b5da9499SMatthew G. Knepley #if 1
2361b5da9499SMatthew G. Knepley       if ((newp+2 < fStartNew) || (newp+2 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+2, fStartNew, fEndNew);
2362b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2363b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2364b5da9499SMatthew G. Knepley       }
2365b5da9499SMatthew G. Knepley #endif
2366b5da9499SMatthew G. Knepley       /* D triangle */
2367b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2368b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2369b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2370b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2371b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2372b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2373b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2374b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2375b5da9499SMatthew G. Knepley #if 1
2376b5da9499SMatthew G. Knepley       if ((newp+3 < fStartNew) || (newp+3 >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+3, fStartNew, fEndNew);
2377b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2378b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2379b5da9499SMatthew G. Knepley       }
2380b5da9499SMatthew G. Knepley #endif
2381b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2382b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2383b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2384b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2385219f7b90SMatthew G. Knepley           PetscInt subf;
2386b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2387b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2388b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2389b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2390b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
2391b5da9499SMatthew G. Knepley           }
2392219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
2393219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
2394b5da9499SMatthew G. Knepley         }
2395b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
2396b5da9499SMatthew G. Knepley #if 1
23979ddff745SMatthew G. Knepley         if ((newp+r < fStartNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fEndNew);
2398b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2399b5da9499SMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
2400b5da9499SMatthew G. Knepley         }
2401b5da9499SMatthew G. Knepley #endif
2402b5da9499SMatthew G. Knepley       }
2403b5da9499SMatthew G. Knepley     }
2404b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
2405b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2406b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
2407b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2408b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
2409b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
2410b5da9499SMatthew G. Knepley 
2411b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2412b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2413b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
24144bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2415b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
24164bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2417b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
24184bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
2419b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2420b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2421b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2422b5da9499SMatthew G. Knepley #if 1
2423b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2424b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2425b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2426b5da9499SMatthew G. Knepley       }
2427b5da9499SMatthew G. Knepley #endif
2428b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
2429b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
2430b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2431b5da9499SMatthew G. Knepley #if 1
2432b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2433b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2434b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2435b5da9499SMatthew G. Knepley       }
2436b5da9499SMatthew G. Knepley #endif
2437b5da9499SMatthew G. Knepley       ++newp;
2438b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
24394bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2440b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
24414bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
2442b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
24434bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2444b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2445b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2446b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2447b5da9499SMatthew G. Knepley #if 1
24484bb260e2SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2449b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2450b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2451b5da9499SMatthew G. Knepley       }
2452b5da9499SMatthew G. Knepley #endif
2453b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
2454b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
2455b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2456b5da9499SMatthew G. Knepley #if 1
2457b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2458b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2459b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2460b5da9499SMatthew G. Knepley       }
2461b5da9499SMatthew G. Knepley #endif
2462b5da9499SMatthew G. Knepley       ++newp;
2463b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
24644bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
2465b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
24664bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2467b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
24684bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
2469b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
2470b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2471b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2472b5da9499SMatthew G. Knepley #if 1
2473b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2474b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2475b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2476b5da9499SMatthew G. Knepley       }
2477b5da9499SMatthew G. Knepley #endif
2478b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
2479b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2480b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2481b5da9499SMatthew G. Knepley #if 1
2482b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2483b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2484b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2485b5da9499SMatthew G. Knepley       }
2486b5da9499SMatthew G. Knepley #endif
2487b5da9499SMatthew G. Knepley       ++newp;
2488b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
24894bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
2490b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
24914bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2492b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
24934bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2494b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2495b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2496b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2497b5da9499SMatthew G. Knepley #if 1
2498b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2499b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2500b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2501b5da9499SMatthew G. Knepley       }
2502b5da9499SMatthew G. Knepley #endif
2503b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
2504b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2505b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2506b5da9499SMatthew G. Knepley #if 1
2507b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2508b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2509b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2510b5da9499SMatthew G. Knepley       }
2511b5da9499SMatthew G. Knepley #endif
2512b5da9499SMatthew G. Knepley       ++newp;
2513b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
25144bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2515b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
2516b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
25174bb260e2SMatthew G. Knepley       orntNew[1] = -2;
25184bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2519b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2520b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2521b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2522b5da9499SMatthew G. Knepley #if 1
2523b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2524b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2525b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2526b5da9499SMatthew G. Knepley       }
2527b5da9499SMatthew G. Knepley #endif
2528b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2529b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2530b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2531b5da9499SMatthew G. Knepley #if 1
2532b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2533b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2534b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2535b5da9499SMatthew G. Knepley       }
2536b5da9499SMatthew G. Knepley #endif
2537b5da9499SMatthew G. Knepley       ++newp;
2538b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
25394bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2540b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2541b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
25424bb260e2SMatthew G. Knepley       orntNew[1] = 0;
25434bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
25442baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
2545b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2546b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2547b5da9499SMatthew G. Knepley #if 1
2548b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2549b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2550b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2551b5da9499SMatthew G. Knepley       }
2552b5da9499SMatthew G. Knepley #endif
2553b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2554b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2555b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2556b5da9499SMatthew G. Knepley #if 1
2557b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2558b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2559b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2560b5da9499SMatthew G. Knepley       }
2561b5da9499SMatthew G. Knepley #endif
2562b5da9499SMatthew G. Knepley       ++newp;
2563b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
25644bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2565b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
2566b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2567fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
25684bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2569b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
2570b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2571b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2572b5da9499SMatthew G. Knepley #if 1
2573b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2574b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2575b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2576b5da9499SMatthew G. Knepley       }
2577b5da9499SMatthew G. Knepley #endif
2578b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2579b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2580b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2581b5da9499SMatthew G. Knepley #if 1
2582b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2583b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2584b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2585b5da9499SMatthew G. Knepley       }
2586b5da9499SMatthew G. Knepley #endif
2587b5da9499SMatthew G. Knepley       ++newp;
2588b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
25894bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2590b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
25914bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2592b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
2593b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
25944bb260e2SMatthew G. Knepley       orntNew[2] = -2;
2595b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2596b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2597b5da9499SMatthew G. Knepley #if 1
2598b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2599b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2600b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
2601b5da9499SMatthew G. Knepley       }
2602b5da9499SMatthew G. Knepley #endif
2603b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2604b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2605b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2606b5da9499SMatthew G. Knepley #if 1
2607b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2608b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2609b5da9499SMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
2610b5da9499SMatthew G. Knepley       }
2611b5da9499SMatthew G. Knepley #endif
2612b5da9499SMatthew G. Knepley       ++newp;
2613b5da9499SMatthew G. Knepley     }
2614b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
2615b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2616b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
2617b5da9499SMatthew G. Knepley 
2618b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2619b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
2620b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2621b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2622b5da9499SMatthew G. Knepley 
2623b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
2624b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2625b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2626b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2627b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2628b5da9499SMatthew G. Knepley #if 1
2629b5da9499SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
2630b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2631b5da9499SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2632b5da9499SMatthew G. Knepley         }
2633b5da9499SMatthew G. Knepley #endif
2634b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
2635b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2636b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2637b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2638b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2639b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2640b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2641b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
2642b5da9499SMatthew G. Knepley           }
2643b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
2644b5da9499SMatthew G. Knepley         }
2645b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2646b5da9499SMatthew G. Knepley #if 1
2647b5da9499SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
2648b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2649b5da9499SMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
2650b5da9499SMatthew G. Knepley         }
2651b5da9499SMatthew G. Knepley #endif
2652b5da9499SMatthew G. Knepley       }
2653b5da9499SMatthew G. Knepley     }
265486f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
2655b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2656b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2657b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
2658b5da9499SMatthew G. Knepley 
2659b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2660b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2661b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
2662b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
2663b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
2664b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
2665b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
2666b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
2667b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
2668b5da9499SMatthew G. Knepley 
2669b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2670b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
2671b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
2672b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2673b5da9499SMatthew G. Knepley #if 1
2674b5da9499SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
2675b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2676b5da9499SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2677b5da9499SMatthew G. Knepley         }
2678b5da9499SMatthew G. Knepley #endif
2679b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
2680b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
2681b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2682b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2683b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2684b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2685b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
268686f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
26879ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
2688b5da9499SMatthew G. Knepley           if (er == eint[c]) {
2689b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
2690b5da9499SMatthew G. Knepley           } else {
2691b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
2692b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
2693b5da9499SMatthew G. Knepley           }
2694b5da9499SMatthew G. Knepley         }
2695b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2696b5da9499SMatthew G. Knepley #if 1
2697b5da9499SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
2698b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
2699b5da9499SMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
2700b5da9499SMatthew G. Knepley         }
2701b5da9499SMatthew G. Knepley #endif
2702b5da9499SMatthew G. Knepley       }
2703b5da9499SMatthew G. Knepley     }
2704b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
2705b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2706b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2707b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
27084a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
2709b5da9499SMatthew G. Knepley 
2710b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2711b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2712b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
271342525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
2714b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2715b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
271642525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
2717b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2718b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2719b5da9499SMatthew G. Knepley #if 1
2720b5da9499SMatthew G. Knepley       if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
2721b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2722b5da9499SMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
2723b5da9499SMatthew G. Knepley       }
2724b5da9499SMatthew G. Knepley #endif
2725b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
2726b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
2727b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
2728b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
2729b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2730b5da9499SMatthew G. Knepley #if 1
2731b5da9499SMatthew G. Knepley       if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
2732b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2733b5da9499SMatthew G. Knepley         if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew);
2734b5da9499SMatthew G. Knepley       }
2735b5da9499SMatthew G. Knepley #endif
2736b5da9499SMatthew G. Knepley     }
2737b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
2738b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2739b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2740b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
2741b5da9499SMatthew G. Knepley       PetscInt        size, s;
2742b5da9499SMatthew G. Knepley 
2743b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2744b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2745b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2746b5da9499SMatthew G. Knepley         PetscInt r = 0;
2747b5da9499SMatthew G. Knepley 
2748b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2749b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
2750b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
2751b5da9499SMatthew G. Knepley       }
2752b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2753b5da9499SMatthew G. Knepley #if 1
2754b5da9499SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
2755b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2756b5da9499SMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
2757b5da9499SMatthew G. Knepley       }
2758b5da9499SMatthew G. Knepley #endif
2759b5da9499SMatthew G. Knepley     }
2760b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
2761b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2762b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
2763b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
2764b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
2765b5da9499SMatthew G. Knepley 
2766b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
2767b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2768b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
2769b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
2770b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2771b5da9499SMatthew G. Knepley         PetscInt r = 0;
2772b5da9499SMatthew G. Knepley 
2773b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2774b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2775b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
2776b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
2777b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
2778b5da9499SMatthew G. Knepley       }
2779b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2780b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
2781b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
2782b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
2783b5da9499SMatthew G. Knepley 
2784b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
2785b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
2786b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2787b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
2788b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
278942525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
2790b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
2791b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2792b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
279342525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
279442525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
2795b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
2796b5da9499SMatthew G. Knepley         }
2797b5da9499SMatthew G. Knepley       }
2798b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2799b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2800b5da9499SMatthew G. Knepley #if 1
2801b5da9499SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
2802b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
2803b5da9499SMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
2804b5da9499SMatthew G. Knepley       }
2805b5da9499SMatthew G. Knepley #endif
2806b5da9499SMatthew G. Knepley     }
2807b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2808b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
2809b5da9499SMatthew G. Knepley     break;
28106ce3c06aSMatthew G. Knepley   case 7:
28116ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
28126ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
28136ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
28146ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
28156ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
28166ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
28176ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
28186ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
28196ce3c06aSMatthew G. Knepley 
28206ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
28216ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
28226ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
28236ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
28246ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
28256ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
28266ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
28276ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
28286ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
28296ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
28306ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
28316ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
28326ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
28336ce3c06aSMatthew G. Knepley #if 1
28346ce3c06aSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cMaxNew);
28356ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
28366ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
28376ce3c06aSMatthew G. Knepley       }
28386ce3c06aSMatthew G. Knepley #endif
28396ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
28406ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
28416ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
28426ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
28436ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
28446ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
28456ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
28466ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
28476ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
28486ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
28496ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
28506ce3c06aSMatthew G. Knepley #if 1
28516ce3c06aSMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cMaxNew);
28526ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
28536ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
28546ce3c06aSMatthew G. Knepley       }
28556ce3c06aSMatthew G. Knepley #endif
28566ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
28576ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
28586ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
28596ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
28606ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
28616ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
28626ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
28636ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
28646ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
28656ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
28666ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
28676ce3c06aSMatthew G. Knepley #if 1
28686ce3c06aSMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cMaxNew);
28696ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
28706ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
28716ce3c06aSMatthew G. Knepley       }
28726ce3c06aSMatthew G. Knepley #endif
28736ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
28746ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
28756ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
28766ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
28776ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
28786ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
28796ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
28806ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
28816ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
28826ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
28836ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
28846ce3c06aSMatthew G. Knepley #if 1
28856ce3c06aSMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cMaxNew);
28866ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
28876ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
28886ce3c06aSMatthew G. Knepley       }
28896ce3c06aSMatthew G. Knepley #endif
28906ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
28916ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
28926ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
28939ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
28949ddff745SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
28959ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
28969ddff745SMatthew G. Knepley       orntNew[2] = 0;
28979ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
28989ddff745SMatthew G. Knepley       orntNew[3] = 2;
28996ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
29006ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
29016ce3c06aSMatthew G. Knepley #if 1
29026ce3c06aSMatthew G. Knepley       if ((newp+4 < cStartNew) || (newp+4 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cMaxNew);
29036ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29046ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
29056ce3c06aSMatthew G. Knepley       }
29066ce3c06aSMatthew G. Knepley #endif
29076ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
29086ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
29096ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
29109ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
29119ddff745SMatthew G. Knepley       orntNew[1] = 1;
29129ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
29136ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
29149ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
29159ddff745SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
29166ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
29176ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
29186ce3c06aSMatthew G. Knepley #if 1
29196ce3c06aSMatthew G. Knepley       if ((newp+5 < cStartNew) || (newp+5 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cMaxNew);
29206ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29216ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
29226ce3c06aSMatthew G. Knepley       }
29236ce3c06aSMatthew G. Knepley #endif
29246ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
29256ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
29266ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
29279ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
29289ddff745SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
29299ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
29309ddff745SMatthew G. Knepley       orntNew[2] = -3;
29319ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
29329ddff745SMatthew G. Knepley       orntNew[3] = -2;
29336ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
29346ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
29356ce3c06aSMatthew G. Knepley #if 1
29366ce3c06aSMatthew G. Knepley       if ((newp+6 < cStartNew) || (newp+6 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cMaxNew);
29376ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29386ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
29396ce3c06aSMatthew G. Knepley       }
29406ce3c06aSMatthew G. Knepley #endif
29416ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
29426ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
29436ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
29449ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
29456ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
29469ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
29479ddff745SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
29489ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
29499ddff745SMatthew G. Knepley       orntNew[3] = -3;
29506ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
29516ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
29526ce3c06aSMatthew G. Knepley #if 1
29536ce3c06aSMatthew G. Knepley       if ((newp+7 < cStartNew) || (newp+7 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cMaxNew);
29546ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29556ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
29566ce3c06aSMatthew G. Knepley       }
29576ce3c06aSMatthew G. Knepley #endif
29586ce3c06aSMatthew G. Knepley     }
29596ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
29606ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
29616ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
2962d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
29633b61eb6dSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5], o, of, i;
29646ce3c06aSMatthew G. Knepley 
29656ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
29666ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2967d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
2968084f9c62SMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
29696ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
29706ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
29716ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
29726ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
29736ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
2974084f9c62SMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? -1 : 1;
29753b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], r)       + 2;
29763b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)]       - fMax)*2 + (o*of < 0 ? 1 : 0);
29773b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
29783b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2;
29793b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
29803b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
29813b61eb6dSMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
29823b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2;
29833b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (o*of < 0 ? 0 : 1);
29843b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
29856ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
29866ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
29876ce3c06aSMatthew G. Knepley #if 1
29886ce3c06aSMatthew G. Knepley         if ((newp+r < cMaxNew) || (newp+r >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+r, cMaxNew, cEndNew);
29896ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
29906ce3c06aSMatthew G. Knepley           if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
29916ce3c06aSMatthew G. Knepley         }
29926ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
29936ce3c06aSMatthew G. Knepley           if ((coneNew[p] < fMaxNew)   || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew);
29946ce3c06aSMatthew G. Knepley         }
29956ce3c06aSMatthew G. Knepley #endif
29966ce3c06aSMatthew G. Knepley       }
29976ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
29986ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
29996ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
30006ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
30013b61eb6dSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
30026ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
30033b61eb6dSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
30046ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
30053b61eb6dSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
30066ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
30076ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
30086ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
30096ce3c06aSMatthew G. Knepley #if 1
30106ce3c06aSMatthew G. Knepley       if ((newp+3 < cMaxNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+3, cMaxNew, cEndNew);
30116ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
30126ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
30136ce3c06aSMatthew G. Knepley       }
30146ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
30156ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fMaxNew)   || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew);
30166ce3c06aSMatthew G. Knepley       }
30176ce3c06aSMatthew G. Knepley #endif
30186ce3c06aSMatthew G. Knepley     }
30196ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
30206ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3021785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
30226ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
30236ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
30246ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
30256ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
30266ce3c06aSMatthew G. Knepley 
30276ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
30286ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
30296ce3c06aSMatthew G. Knepley       /* A triangle */
30306ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
30316ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
30326ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
30336ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
30346ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
30356ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
30366ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
30376ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
30386ce3c06aSMatthew G. Knepley #if 1
30396ce3c06aSMatthew G. Knepley       if ((newp+0 < fStartNew) || (newp+0 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+0, fStartNew, fMaxNew);
30406ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
30416ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
30426ce3c06aSMatthew G. Knepley       }
30436ce3c06aSMatthew G. Knepley #endif
30446ce3c06aSMatthew G. Knepley       /* B triangle */
30456ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
30466ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
30476ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
30486ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
30496ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
30506ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
30516ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
30526ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
30536ce3c06aSMatthew G. Knepley #if 1
30546ce3c06aSMatthew G. Knepley       if ((newp+1 < fStartNew) || (newp+1 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fMaxNew);
30556ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
30566ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
30576ce3c06aSMatthew G. Knepley       }
30586ce3c06aSMatthew G. Knepley #endif
30596ce3c06aSMatthew G. Knepley       /* C triangle */
30606ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
30616ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
30626ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
30636ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
30646ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
30656ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
30666ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
30676ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
30686ce3c06aSMatthew G. Knepley #if 1
30696ce3c06aSMatthew G. Knepley       if ((newp+2 < fStartNew) || (newp+2 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+2, fStartNew, fMaxNew);
30706ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
30716ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
30726ce3c06aSMatthew G. Knepley       }
30736ce3c06aSMatthew G. Knepley #endif
30746ce3c06aSMatthew G. Knepley       /* D triangle */
30756ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
30766ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
30776ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
30786ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
30796ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
30806ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
30816ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
30826ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
30836ce3c06aSMatthew G. Knepley #if 1
30846ce3c06aSMatthew G. Knepley       if ((newp+3 < fStartNew) || (newp+3 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+3, fStartNew, fMaxNew);
30856ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
30866ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
30876ce3c06aSMatthew G. Knepley       }
30886ce3c06aSMatthew G. Knepley #endif
30896ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
30906ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
30916ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
30926ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
30939ddff745SMatthew G. Knepley           PetscInt subf;
30946ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
30956ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
30966ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
30976ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
30986ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
30996ce3c06aSMatthew G. Knepley           }
31009ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
31016ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
31029ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
31036ce3c06aSMatthew G. Knepley           } else {
31049ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
31056ce3c06aSMatthew G. Knepley           }
31066ce3c06aSMatthew G. Knepley         }
31076ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
31086ce3c06aSMatthew G. Knepley #if 1
31099ddff745SMatthew G. Knepley         if ((newp+r < fStartNew) || (newp+r >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fMaxNew);
31106ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
31116ce3c06aSMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
31126ce3c06aSMatthew G. Knepley         }
31136ce3c06aSMatthew G. Knepley #endif
31146ce3c06aSMatthew G. Knepley       }
31156ce3c06aSMatthew G. Knepley     }
31166ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
31176ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
31186ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
31196ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
31206ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
31216ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
31226ce3c06aSMatthew G. Knepley 
31236ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
31246ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
31256ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
31269ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
31276ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
31289ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
31296ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
31309ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
31316ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
31326ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
31336ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
31346ce3c06aSMatthew G. Knepley #if 1
31356ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
31366ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31376ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
31386ce3c06aSMatthew G. Knepley       }
31396ce3c06aSMatthew G. Knepley #endif
31406ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
31416ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
31426ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
31436ce3c06aSMatthew G. Knepley #if 1
31446ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
31456ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
31466ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
31476ce3c06aSMatthew G. Knepley       }
31486ce3c06aSMatthew G. Knepley #endif
31496ce3c06aSMatthew G. Knepley       ++newp;
31506ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
31519ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
31526ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
31539ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
31546ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
31559ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
31566ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
31576ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
31586ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
31596ce3c06aSMatthew G. Knepley #if 1
31606ce3c06aSMatthew G. Knepley       if ((newp+1 < fStartNew) || (newp+1 >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fMaxNew);
31616ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31626ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
31636ce3c06aSMatthew G. Knepley       }
31646ce3c06aSMatthew G. Knepley #endif
31656ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
31666ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
31676ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
31686ce3c06aSMatthew G. Knepley #if 1
31696ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
31706ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
31716ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
31726ce3c06aSMatthew G. Knepley       }
31736ce3c06aSMatthew G. Knepley #endif
31746ce3c06aSMatthew G. Knepley       ++newp;
31756ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
31769ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
31776ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
31789ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
31796ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
31809ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
31816ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
31826ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
31836ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
31846ce3c06aSMatthew G. Knepley #if 1
31856ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
31866ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31876ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
31886ce3c06aSMatthew G. Knepley       }
31896ce3c06aSMatthew G. Knepley #endif
31906ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
31916ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
31926ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
31936ce3c06aSMatthew G. Knepley #if 1
31946ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
31956ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
31966ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
31976ce3c06aSMatthew G. Knepley       }
31986ce3c06aSMatthew G. Knepley #endif
31996ce3c06aSMatthew G. Knepley       ++newp;
32006ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
32019ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
32026ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
32039ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
32046ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
32059ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
32066ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
32076ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32086ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32096ce3c06aSMatthew G. Knepley #if 1
32106ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
32116ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32126ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
32136ce3c06aSMatthew G. Knepley       }
32146ce3c06aSMatthew G. Knepley #endif
32156ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
32166ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
32176ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32186ce3c06aSMatthew G. Knepley #if 1
32196ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
32206ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32216ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
32226ce3c06aSMatthew G. Knepley       }
32236ce3c06aSMatthew G. Knepley #endif
32246ce3c06aSMatthew G. Knepley       ++newp;
32256ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
32269ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
32276ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
32286ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
32299ddff745SMatthew G. Knepley       orntNew[1] = -2;
32309ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
32316ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
32326ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32336ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32346ce3c06aSMatthew G. Knepley #if 1
32356ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
32366ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32376ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
32386ce3c06aSMatthew G. Knepley       }
32396ce3c06aSMatthew G. Knepley #endif
32406ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
32416ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
32426ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32436ce3c06aSMatthew G. Knepley #if 1
32446ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
32456ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32466ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
32476ce3c06aSMatthew G. Knepley       }
32486ce3c06aSMatthew G. Knepley #endif
32496ce3c06aSMatthew G. Knepley       ++newp;
32506ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
32519ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
32526ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
32536ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
32549ddff745SMatthew G. Knepley       orntNew[1] = 0;
32559ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
32569ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
32576ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32586ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32596ce3c06aSMatthew G. Knepley #if 1
32606ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
32616ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32626ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
32636ce3c06aSMatthew G. Knepley       }
32646ce3c06aSMatthew G. Knepley #endif
32656ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
32666ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
32676ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32686ce3c06aSMatthew G. Knepley #if 1
32696ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
32706ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32716ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
32726ce3c06aSMatthew G. Knepley       }
32736ce3c06aSMatthew G. Knepley #endif
32746ce3c06aSMatthew G. Knepley       ++newp;
32756ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
32769ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
32776ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
32786ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
32799ddff745SMatthew G. Knepley       orntNew[1] = 0;
32809ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
32816ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
32826ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32836ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32846ce3c06aSMatthew G. Knepley #if 1
32856ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
32866ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32876ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
32886ce3c06aSMatthew G. Knepley       }
32896ce3c06aSMatthew G. Knepley #endif
32906ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
32916ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
32926ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32936ce3c06aSMatthew G. Knepley #if 1
32946ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
32956ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32966ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
32976ce3c06aSMatthew G. Knepley       }
32986ce3c06aSMatthew G. Knepley #endif
32996ce3c06aSMatthew G. Knepley       ++newp;
33006ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
33019ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
33026ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
33039ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
33046ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
33056ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
33069ddff745SMatthew G. Knepley       orntNew[2] = -2;
33076ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33086ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33096ce3c06aSMatthew G. Knepley #if 1
33106ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
33116ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33126ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
33136ce3c06aSMatthew G. Knepley       }
33146ce3c06aSMatthew G. Knepley #endif
33156ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
33166ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
33176ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33186ce3c06aSMatthew G. Knepley #if 1
33196ce3c06aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
33206ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
33216ce3c06aSMatthew G. Knepley         if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
33226ce3c06aSMatthew G. Knepley       }
33236ce3c06aSMatthew G. Knepley #endif
33246ce3c06aSMatthew G. Knepley       ++newp;
33256ce3c06aSMatthew G. Knepley     }
33266ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
33276ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
33286ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
33296ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
33306ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
33316ce3c06aSMatthew G. Knepley 
33326ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
33336ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
33346ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
33356ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
33366ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
33376ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
33386ce3c06aSMatthew G. Knepley 
33396ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
33406ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
33416ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
33426ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
33436ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
33446ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
33456ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
33466ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
33476ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33486ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33496ce3c06aSMatthew G. Knepley #if 1
33506ce3c06aSMatthew G. Knepley         if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew);
33516ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
33526ce3c06aSMatthew G. Knepley           if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
33536ce3c06aSMatthew G. Knepley         }
33546ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
33556ce3c06aSMatthew G. Knepley           if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew);
33566ce3c06aSMatthew G. Knepley         }
33576ce3c06aSMatthew G. Knepley #endif
33586ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
3359d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
3360084f9c62SMatthew G. Knepley           PetscInt        o, of;
33616ce3c06aSMatthew G. Knepley 
33626ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
33636ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
3364084f9c62SMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
33656ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
33666ce3c06aSMatthew G. Knepley           if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]);
3367d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
3368084f9c62SMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
3369084f9c62SMatthew G. Knepley           supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3;
33706ce3c06aSMatthew G. Knepley         }
33716ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33726ce3c06aSMatthew G. Knepley #if 1
33736ce3c06aSMatthew G. Knepley         if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew);
33746ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
33756ce3c06aSMatthew G. Knepley           if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew);
33766ce3c06aSMatthew G. Knepley         }
33776ce3c06aSMatthew G. Knepley #endif
33786ce3c06aSMatthew G. Knepley       }
33796ce3c06aSMatthew G. Knepley     }
33806ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
33816ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
33826ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
33836ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
33846ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
33856ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
33866ce3c06aSMatthew G. Knepley 
33876ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
33886ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
33896ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3390b598a9d5SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
33916ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
3392b598a9d5SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
33936ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
3394b598a9d5SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
33956ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
3396b598a9d5SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r]       - fMax);
33976ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
33986ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
33996ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
34006ce3c06aSMatthew G. Knepley #if 1
34016ce3c06aSMatthew G. Knepley         if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew);
34026ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34036ce3c06aSMatthew G. Knepley           if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
34046ce3c06aSMatthew G. Knepley         }
34056ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
34066ce3c06aSMatthew G. Knepley           if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew);
34076ce3c06aSMatthew G. Knepley         }
34086ce3c06aSMatthew G. Knepley #endif
34096ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
34106ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
34116ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
34126ce3c06aSMatthew G. Knepley #if 1
34136ce3c06aSMatthew G. Knepley         if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew);
34146ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34156ce3c06aSMatthew G. Knepley           if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew);
34166ce3c06aSMatthew G. Knepley         }
34176ce3c06aSMatthew G. Knepley #endif
34186ce3c06aSMatthew G. Knepley       }
34196ce3c06aSMatthew G. Knepley     }
34206ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
34216ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
34226ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
34236ce3c06aSMatthew G. Knepley 
34246ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
34256ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
34266ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
34276ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
34286ce3c06aSMatthew G. Knepley 
34296ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
34306ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
34316ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
34326ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
34336ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34346ce3c06aSMatthew G. Knepley #if 1
34356ce3c06aSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
34366ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34376ce3c06aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
34386ce3c06aSMatthew G. Knepley         }
34396ce3c06aSMatthew G. Knepley #endif
34406ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
34416ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
34426ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
34436ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
34446ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
34456ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
34466ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
34476ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
34486ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
34496ce3c06aSMatthew G. Knepley           } else {
34506ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
34516ce3c06aSMatthew G. Knepley           }
34526ce3c06aSMatthew G. Knepley         }
34536ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
34546ce3c06aSMatthew G. Knepley #if 1
34556ce3c06aSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
34566ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
34576ce3c06aSMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid face [%d, %d)", supportRef[p], fStartNew, fEndNew);
34586ce3c06aSMatthew G. Knepley         }
34596ce3c06aSMatthew G. Knepley #endif
34606ce3c06aSMatthew G. Knepley       }
34616ce3c06aSMatthew G. Knepley     }
34626ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
34636ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
34646ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
34656ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
34666ce3c06aSMatthew G. Knepley 
34676ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
34686ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
34696ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
34706ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
34716ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
34726ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
34736ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
34746ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
34756ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
34766ce3c06aSMatthew G. Knepley 
34776ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
34786ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
34796ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
34806ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34816ce3c06aSMatthew G. Knepley #if 1
34826ce3c06aSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
34836ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34846ce3c06aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
34856ce3c06aSMatthew G. Knepley         }
34866ce3c06aSMatthew G. Knepley #endif
34876ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
34886ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
34896ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
34906ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
34916ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
34926ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
34936ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
34946ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
34956ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
34969ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
34976ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
34986ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
34996ce3c06aSMatthew G. Knepley             } else {
35006ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
35016ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
35026ce3c06aSMatthew G. Knepley             }
35036ce3c06aSMatthew G. Knepley           } else {
3504b598a9d5SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
35056ce3c06aSMatthew G. Knepley           }
35066ce3c06aSMatthew G. Knepley         }
35076ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35086ce3c06aSMatthew G. Knepley #if 1
35096ce3c06aSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
35106ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
35116ce3c06aSMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid face [%d, %d)", supportRef[p], fStartNew, fEndNew);
35126ce3c06aSMatthew G. Knepley         }
35136ce3c06aSMatthew G. Knepley #endif
35146ce3c06aSMatthew G. Knepley       }
35156ce3c06aSMatthew G. Knepley     }
35166ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
35176ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
35186ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
35196ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
35206ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
35216ce3c06aSMatthew G. Knepley 
35226ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
35236ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
35246ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
35256ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
35266ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
35276ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
35286ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
35296ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
35306ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35316ce3c06aSMatthew G. Knepley #if 1
35326ce3c06aSMatthew G. Knepley       if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
35336ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
35346ce3c06aSMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
35356ce3c06aSMatthew G. Knepley       }
35366ce3c06aSMatthew G. Knepley #endif
35376ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
35386ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
35396ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
35406ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
35416ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
35426ce3c06aSMatthew G. Knepley #if 1
35436ce3c06aSMatthew G. Knepley       if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
35446ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
35456ce3c06aSMatthew G. Knepley         if ((supportNew[p] < fStartNew) || (supportNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fMaxNew);
35466ce3c06aSMatthew G. Knepley       }
35476ce3c06aSMatthew G. Knepley #endif
35486ce3c06aSMatthew G. Knepley     }
35496ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
35506ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
35516ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
35526ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
35536ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
35546ce3c06aSMatthew G. Knepley 
35556ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
35566ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
35576ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
35586ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
35596ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
35606ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35616ce3c06aSMatthew G. Knepley #if 1
35626ce3c06aSMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
35636ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
35646ce3c06aSMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
35656ce3c06aSMatthew G. Knepley       }
35666ce3c06aSMatthew G. Knepley #endif
35676ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
35686ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
35696ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
35706ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
35716ce3c06aSMatthew G. Knepley         if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]);
35726ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
35736ce3c06aSMatthew G. Knepley       }
35746ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35756ce3c06aSMatthew G. Knepley #if 1
35766ce3c06aSMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
35776ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
35786ce3c06aSMatthew G. Knepley         if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
35796ce3c06aSMatthew G. Knepley       }
35806ce3c06aSMatthew G. Knepley #endif
35816ce3c06aSMatthew G. Knepley     }
35826ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
35836ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
35846ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
3585623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
35866ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
35876ce3c06aSMatthew G. Knepley 
35886ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
35896ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
35906ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
35916ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
35926ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
35936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35946ce3c06aSMatthew G. Knepley #if 1
35956ce3c06aSMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
35966ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
35976ce3c06aSMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
35986ce3c06aSMatthew G. Knepley       }
35996ce3c06aSMatthew G. Knepley #endif
36006ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
36016ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
36026ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36036ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
36046ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
3605623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
36066ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
36076ce3c06aSMatthew G. Knepley         if ((c < 2) || (c >= csize)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Hybrid face %d is not in cone of hybrid cell %d", f, support[s]);
3608b598a9d5SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
3609b598a9d5SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
36106ce3c06aSMatthew G. Knepley       }
36116ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36126ce3c06aSMatthew G. Knepley #if 1
36136ce3c06aSMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
36146ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
36156ce3c06aSMatthew G. Knepley         if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
36166ce3c06aSMatthew G. Knepley       }
36176ce3c06aSMatthew G. Knepley #endif
36186ce3c06aSMatthew G. Knepley     }
36196ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
36206ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
36216ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
36226ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
36236ce3c06aSMatthew G. Knepley       PetscInt        size, s;
36246ce3c06aSMatthew G. Knepley 
36256ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
36266ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
36276ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36286ce3c06aSMatthew G. Knepley         PetscInt r = 0;
36296ce3c06aSMatthew G. Knepley 
36306ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36316ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
36326ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
36336ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
36346ce3c06aSMatthew G. Knepley       }
36356ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36366ce3c06aSMatthew G. Knepley #if 1
36376ce3c06aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
36386ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
36396ce3c06aSMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
36406ce3c06aSMatthew G. Knepley       }
36416ce3c06aSMatthew G. Knepley #endif
36426ce3c06aSMatthew G. Knepley     }
36436ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
36446ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
36456ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
36466ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
36476ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
36486ce3c06aSMatthew G. Knepley 
36496ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
36506ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
36516ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
36526ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
36536ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36546ce3c06aSMatthew G. Knepley         PetscInt r = 0;
36556ce3c06aSMatthew G. Knepley 
36566ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
36576ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
36586ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36596ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
36606ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
36616ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
36626ce3c06aSMatthew G. Knepley           faceSize += 2;
36636ce3c06aSMatthew G. Knepley         } else {
36646ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
36656ce3c06aSMatthew G. Knepley           ++faceSize;
36666ce3c06aSMatthew G. Knepley         }
36676ce3c06aSMatthew G. Knepley       }
36686ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
36696ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
36706ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
36716ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
36726ce3c06aSMatthew G. Knepley 
36736ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
36746ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
36756ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
36766ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
36776ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
36786ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
36796ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
36806ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
36816ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
36826ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
36836ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
36846ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
36856ce3c06aSMatthew G. Knepley         }
36866ce3c06aSMatthew G. Knepley       }
36876ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
36886ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36896ce3c06aSMatthew G. Knepley #if 1
36906ce3c06aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
36916ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
36926ce3c06aSMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior or hybrid edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
36936ce3c06aSMatthew G. Knepley       }
36946ce3c06aSMatthew G. Knepley #endif
36956ce3c06aSMatthew G. Knepley     }
36966ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
36976ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
36986ce3c06aSMatthew G. Knepley     break;
36992eabf88fSMatthew G. Knepley   case 6:
37002eabf88fSMatthew G. Knepley     /* Hex 3D */
37012eabf88fSMatthew G. Knepley     /*
37022eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
37032eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
37042eabf88fSMatthew G. Knepley      |         |         |       |         |         |
37052eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
37062eabf88fSMatthew G. Knepley      |         |         |       |         |         |
37072eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
37082eabf88fSMatthew G. Knepley      |         |         |       |         |         |
37092eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
37102eabf88fSMatthew G. Knepley      |         |         |       |         |         |
37112eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
37122eabf88fSMatthew G. Knepley      */
37132eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
37142eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
37152eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
37162eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
37172eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
37182eabf88fSMatthew G. Knepley 
37192eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
37202eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
37212eabf88fSMatthew G. Knepley       /* A hex */
3722e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
37232eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
37242eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
37252eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3726e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
37272eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
37282eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
37292eabf88fSMatthew G. Knepley       orntNew[3] = 0;
37302eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
37312eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3732e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
37332eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
37342eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
37352eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
37362eabf88fSMatthew G. Knepley #if 1
37372eabf88fSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
37382eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
37392eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
37402eabf88fSMatthew G. Knepley       }
37412eabf88fSMatthew G. Knepley #endif
37422eabf88fSMatthew G. Knepley       /* B hex */
3743e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
37442eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
37452eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
37462eabf88fSMatthew G. Knepley       orntNew[1] = 0;
37472eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
3748a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3749e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
37502eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
37512eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
37522eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3753e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
37542eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
37552eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
37562eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
37572eabf88fSMatthew G. Knepley #if 1
37582eabf88fSMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
37592eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
37602eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
37612eabf88fSMatthew G. Knepley       }
37622eabf88fSMatthew G. Knepley #endif
37632eabf88fSMatthew G. Knepley       /* C hex */
3764e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
37652eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
37662eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
37672eabf88fSMatthew G. Knepley       orntNew[1] = 0;
37682eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3769a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3770e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
37712eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3772e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
37732eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
37742eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
3775a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
37762eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
37772eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
37782eabf88fSMatthew G. Knepley #if 1
37792eabf88fSMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
37802eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
37812eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
37822eabf88fSMatthew G. Knepley       }
37832eabf88fSMatthew G. Knepley #endif
37842eabf88fSMatthew G. Knepley       /* D hex */
3785e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
37862eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
37872eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
37882eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3789e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
37902eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
37912eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3792a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3793e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
37942eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
37952eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
3796a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
37972eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
37982eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
37992eabf88fSMatthew G. Knepley #if 1
38002eabf88fSMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
38012eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38022eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
38032eabf88fSMatthew G. Knepley       }
38042eabf88fSMatthew G. Knepley #endif
38052eabf88fSMatthew G. Knepley       /* E hex */
38062eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
3807a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3808e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
38092eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3810e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
38112eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
38122eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
38132eabf88fSMatthew G. Knepley       orntNew[3] = 0;
38142eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3815a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
3816e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
38172eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3818b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
3819b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
38202eabf88fSMatthew G. Knepley #if 1
3821b164cbf2SMatthew G. Knepley       if ((newp+4 < cStartNew) || (newp+4 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cEndNew);
38222eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38232eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
38242eabf88fSMatthew G. Knepley       }
38252eabf88fSMatthew G. Knepley #endif
38262eabf88fSMatthew G. Knepley       /* F hex */
38272eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
3828a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3829e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
38302eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3831e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
38322eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
38332eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3834a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
3835e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
38362eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
38372eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3838a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
3839b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
3840b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
38412eabf88fSMatthew G. Knepley #if 1
3842b164cbf2SMatthew G. Knepley       if ((newp+5 < cStartNew) || (newp+5 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cEndNew);
38432eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38442eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
38452eabf88fSMatthew G. Knepley       }
38462eabf88fSMatthew G. Knepley #endif
38472eabf88fSMatthew G. Knepley       /* G hex */
38482eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
3849a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3850e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
38512eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
38522eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3853a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
3854e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
38552eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3856e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
38572eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
38582eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3859a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
3860b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
3861b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
38622eabf88fSMatthew G. Knepley #if 1
3863b164cbf2SMatthew G. Knepley       if ((newp+6 < cStartNew) || (newp+6 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cEndNew);
38642eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38652eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
38662eabf88fSMatthew G. Knepley       }
38672eabf88fSMatthew G. Knepley #endif
38682eabf88fSMatthew G. Knepley       /* H hex */
38692eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
3870a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3871e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
38722eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
38732eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
3874a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3875e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
38762eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
38772eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3878a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
3879e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
38802eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3881b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
3882b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
38832eabf88fSMatthew G. Knepley #if 1
3884b164cbf2SMatthew G. Knepley       if ((newp+7 < cStartNew) || (newp+7 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cEndNew);
38852eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38862eabf88fSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
38872eabf88fSMatthew G. Knepley       }
38882eabf88fSMatthew G. Knepley #endif
38892eabf88fSMatthew G. Knepley     }
38902eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
38912eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3892785e854fSJed Brown     ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
38932eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
38942eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
3895aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
38962eabf88fSMatthew G. Knepley         const PetscInt  newCells[24] = {0, 1, 2, 3,  4, 5, 6, 7,  0, 3, 5, 4,  2, 1, 7, 6,  3, 2, 6, 5,  0, 4, 7, 1};
38972eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
38982eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3899aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
39002eabf88fSMatthew G. Knepley 
39012eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3902aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
3903a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
3904a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
3905a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
3906a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
3907a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
3908a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
3909a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
3910a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
39112eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3912aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
39132eabf88fSMatthew G. Knepley #if 1
39142eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
39152eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
39162eabf88fSMatthew G. Knepley           if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
39172eabf88fSMatthew G. Knepley         }
39182eabf88fSMatthew G. Knepley #endif
39192eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
39202eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
39212eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
39222eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
39232eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
39242eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
39252eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
39262eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
39272eabf88fSMatthew G. Knepley           }
3928a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
39292eabf88fSMatthew G. Knepley         }
39302eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
39312eabf88fSMatthew G. Knepley #if 1
39322eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
39332eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
39342eabf88fSMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
39352eabf88fSMatthew G. Knepley         }
39362eabf88fSMatthew G. Knepley #endif
39372eabf88fSMatthew G. Knepley       }
39382eabf88fSMatthew G. Knepley     }
39392eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
39402eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
39412eabf88fSMatthew G. Knepley       const PetscInt  newCells[24] = {0, 3,  2, 3,  1, 2,  0, 1,  4, 5,  5, 6,  6, 7,  4, 7,  0, 4,  3, 5,  2, 6,  1, 7};
3942afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
3943afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
39442eabf88fSMatthew G. Knepley 
39452eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3946afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3947afb2665bSMatthew G. Knepley       /* A-D face */
3948afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
3949a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
3950a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3951a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3952afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3953a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3954a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3955a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
3956afb2665bSMatthew G. Knepley       orntNew[3] = -2;
39572eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3958afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
39592eabf88fSMatthew G. Knepley #if 1
39602eabf88fSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
39612eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
39622eabf88fSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
39632eabf88fSMatthew G. Knepley       }
39642eabf88fSMatthew G. Knepley #endif
3965afb2665bSMatthew G. Knepley       /* C-D face */
3966afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
3967a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
3968a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3969a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3970afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3971a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3972a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3973a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
3974afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3975afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3976afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3977afb2665bSMatthew G. Knepley #if 1
3978afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3979afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3980afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3981afb2665bSMatthew G. Knepley       }
3982afb2665bSMatthew G. Knepley #endif
3983afb2665bSMatthew G. Knepley       /* B-C face */
3984afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
3985afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
3986afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3987afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
3988afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3989afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3990afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3991afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3992afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3993afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3994afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3995afb2665bSMatthew G. Knepley #if 1
3996afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
3997afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3998afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
3999afb2665bSMatthew G. Knepley       }
4000afb2665bSMatthew G. Knepley #endif
4001afb2665bSMatthew G. Knepley       /* A-B face */
4002afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
4003afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
4004afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4005afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
4006afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4007afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4008afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4009afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4010afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4011afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4012afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4013afb2665bSMatthew G. Knepley #if 1
4014afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4015afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4016afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4017afb2665bSMatthew G. Knepley       }
4018afb2665bSMatthew G. Knepley #endif
4019afb2665bSMatthew G. Knepley       /* E-F face */
4020afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
4021a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4022afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4023a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
4024a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4025a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
4026afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4027a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4028a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4029afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4030afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4031afb2665bSMatthew G. Knepley #if 1
4032afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4033afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4034afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4035afb2665bSMatthew G. Knepley       }
4036afb2665bSMatthew G. Knepley #endif
4037afb2665bSMatthew G. Knepley       /* F-G face */
4038afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
4039a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4040afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4041a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
4042a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4043a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
4044afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4045a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4046a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4047afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4048afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4049afb2665bSMatthew G. Knepley #if 1
4050afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4051afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4052afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4053afb2665bSMatthew G. Knepley       }
4054afb2665bSMatthew G. Knepley #endif
4055afb2665bSMatthew G. Knepley       /* G-H face */
4056afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
4057afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
4058afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4059afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
4060afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4061afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4062afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4063afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4064afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4065afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4066afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4067afb2665bSMatthew G. Knepley #if 1
4068afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4069afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4070afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4071afb2665bSMatthew G. Knepley       }
4072afb2665bSMatthew G. Knepley #endif
4073afb2665bSMatthew G. Knepley       /* E-H face */
4074afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
4075a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4076afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4077a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
4078a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4079a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
4080afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4081a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4082a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4083afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4084afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4085afb2665bSMatthew G. Knepley #if 1
4086afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4087afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4088afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4089afb2665bSMatthew G. Knepley       }
4090afb2665bSMatthew G. Knepley #endif
4091afb2665bSMatthew G. Knepley       /* A-E face */
4092afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
4093a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
4094a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4095a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4096afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4097a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4098a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4099a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
4100afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4101afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4102afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4103afb2665bSMatthew G. Knepley #if 1
4104afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4105afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4106afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4107afb2665bSMatthew G. Knepley       }
4108afb2665bSMatthew G. Knepley #endif
4109afb2665bSMatthew G. Knepley       /* D-F face */
4110afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
4111afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
4112afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4113afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
4114afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4115afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4116afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4117afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4118afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4119afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4120afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4121afb2665bSMatthew G. Knepley #if 1
4122afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4123afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4124afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4125afb2665bSMatthew G. Knepley       }
4126afb2665bSMatthew G. Knepley #endif
4127afb2665bSMatthew G. Knepley       /* C-G face */
4128afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
4129a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4130afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4131a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
4132a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4133a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
4134afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4135a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4136a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4137afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4138afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4139afb2665bSMatthew G. Knepley #if 1
4140afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4141afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4142afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4143afb2665bSMatthew G. Knepley       }
4144afb2665bSMatthew G. Knepley #endif
4145afb2665bSMatthew G. Knepley       /* B-H face */
4146afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
4147a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4148a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4149a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4150a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4151a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
4152a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4153a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
4154a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4155afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4156afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4157afb2665bSMatthew G. Knepley #if 1
4158afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4159afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4160afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4161afb2665bSMatthew G. Knepley       }
4162afb2665bSMatthew G. Knepley #endif
4163afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
4164afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
41652eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
41662eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
41672eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
41682eabf88fSMatthew G. Knepley #if 1
41692eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
41702eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
41712eabf88fSMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
41722eabf88fSMatthew G. Knepley         }
41732eabf88fSMatthew G. Knepley #endif
41742eabf88fSMatthew G. Knepley       }
41752eabf88fSMatthew G. Knepley     }
41762eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
41772eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
41782eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
41792eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
41802eabf88fSMatthew G. Knepley 
41812eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
41822eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
41832eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
41842eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
41852eabf88fSMatthew G. Knepley 
41862eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
41872eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
41882eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
41892eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
41902eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
41912eabf88fSMatthew G. Knepley #if 1
41922eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
41932eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
41942eabf88fSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
41952eabf88fSMatthew G. Knepley         }
41962eabf88fSMatthew G. Knepley #endif
41972eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
41982eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
41992eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
42002eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
42012eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
42022eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
42032eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
42042eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
42052eabf88fSMatthew G. Knepley           }
42062eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
42072eabf88fSMatthew G. Knepley         }
42082eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
42092eabf88fSMatthew G. Knepley #if 1
42102eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
42112eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
42122eabf88fSMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
42132eabf88fSMatthew G. Knepley         }
42142eabf88fSMatthew G. Knepley #endif
42152eabf88fSMatthew G. Knepley       }
42162eabf88fSMatthew G. Knepley     }
42172eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
42182eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
42196b852384SMatthew G. Knepley       const PetscInt  newFaces[24] = {3, 2, 1, 0,  4, 5, 6, 7,  0, 9, 4, 8,  2, 11, 6, 10,  1, 10, 5, 9,  8, 7, 11, 3};
42202eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
42216b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
42222eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
42232eabf88fSMatthew G. Knepley 
42242eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
42252eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
42262eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
42272eabf88fSMatthew G. Knepley 
42282eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
42292eabf88fSMatthew G. Knepley         coneNew[1] = newv;
42302eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
42312eabf88fSMatthew G. Knepley #if 1
42322eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
42332eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
42342eabf88fSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
42352eabf88fSMatthew G. Knepley         }
42362eabf88fSMatthew G. Knepley #endif
42372eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
42382eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
42392eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
42402eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
42412eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
42426b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
42436b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
42446b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
42452eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
4246a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
42472eabf88fSMatthew G. Knepley         }
42482eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
42492eabf88fSMatthew G. Knepley #if 1
42502eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
42512eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
42522eabf88fSMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
42532eabf88fSMatthew G. Knepley         }
42542eabf88fSMatthew G. Knepley #endif
42552eabf88fSMatthew G. Knepley       }
42562eabf88fSMatthew G. Knepley     }
42572eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
42582eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
42592eabf88fSMatthew G. Knepley       const PetscInt  newFaces[24] = {0, 1, 2, 3,  4, 5, 6, 7,  0, 9, 4, 8,  2, 11, 6, 10,  1, 10, 5, 9,  3, 8, 7, 11};
42602eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
42612eabf88fSMatthew G. Knepley       const PetscInt *cone;
42622eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
42632eabf88fSMatthew G. Knepley 
42642eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
42652eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
42662eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
42672eabf88fSMatthew G. Knepley 
42682eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
42692eabf88fSMatthew G. Knepley         coneNew[1] = newv;
42702eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
42712eabf88fSMatthew G. Knepley #if 1
42722eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
42732eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
42742eabf88fSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
42752eabf88fSMatthew G. Knepley         }
42762eabf88fSMatthew G. Knepley #endif
42772eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
42782eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
42792eabf88fSMatthew G. Knepley #if 1
42802eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
42812eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
42822eabf88fSMatthew G. Knepley           if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew);
42832eabf88fSMatthew G. Knepley         }
42842eabf88fSMatthew G. Knepley #endif
42852eabf88fSMatthew G. Knepley       }
42862eabf88fSMatthew G. Knepley     }
42872eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
42882eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
42892eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
42902eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
42912eabf88fSMatthew G. Knepley       PetscInt        size, s;
42922eabf88fSMatthew G. Knepley 
42932eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
42942eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
42952eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
42962eabf88fSMatthew G. Knepley         PetscInt r = 0;
42972eabf88fSMatthew G. Knepley 
42982eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
42992eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
43002eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
43012eabf88fSMatthew G. Knepley       }
43022eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
43032eabf88fSMatthew G. Knepley #if 1
43042eabf88fSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
43052eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
43062eabf88fSMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
43072eabf88fSMatthew G. Knepley       }
43082eabf88fSMatthew G. Knepley #endif
43092eabf88fSMatthew G. Knepley     }
43102eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
43112eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
43122eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
43132eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
43142eabf88fSMatthew G. Knepley       PetscInt        size, s;
43152eabf88fSMatthew G. Knepley 
43162eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
43172eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
43182eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
43192eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
43202eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
43212eabf88fSMatthew G. Knepley         PetscInt r;
43222eabf88fSMatthew G. Knepley 
43232eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4324a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
43252eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
43262eabf88fSMatthew G. Knepley       }
43272eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
43282eabf88fSMatthew G. Knepley #if 1
43292eabf88fSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
43302eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
43312eabf88fSMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
43322eabf88fSMatthew G. Knepley       }
43332eabf88fSMatthew G. Knepley #endif
43342eabf88fSMatthew G. Knepley     }
43352eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
43362eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
43372eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
43382eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
43392eabf88fSMatthew G. Knepley       PetscInt        size, s;
43402eabf88fSMatthew G. Knepley 
43412eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
43422eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
43430793999aSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 +  (f - fStart)*4 + r;
43442eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
43452eabf88fSMatthew G. Knepley         PetscInt r;
43462eabf88fSMatthew G. Knepley 
43472eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
43482eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
43492eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
43502eabf88fSMatthew G. Knepley       }
43512eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
43522eabf88fSMatthew G. Knepley #if 1
43532eabf88fSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
43542eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
43552eabf88fSMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
43562eabf88fSMatthew G. Knepley       }
43572eabf88fSMatthew G. Knepley #endif
43582eabf88fSMatthew G. Knepley     }
43592eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
43602eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
43612eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
43622eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
43632eabf88fSMatthew G. Knepley 
43642eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
43652eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
43662eabf88fSMatthew G. Knepley       }
43672eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
43682eabf88fSMatthew G. Knepley     }
4369da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
43702eabf88fSMatthew G. Knepley     break;
437127fcede3SMatthew G. Knepley   case 8:
437227fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
437327fcede3SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
437427fcede3SMatthew G. Knepley     /*
437527fcede3SMatthew G. Knepley      Bottom (viewed from top)    Top
437627fcede3SMatthew G. Knepley      1---------2---------2       7---------2---------6
437727fcede3SMatthew G. Knepley      |         |         |       |         |         |
437827fcede3SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
437927fcede3SMatthew G. Knepley      |         |         |       |         |         |
438027fcede3SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
438127fcede3SMatthew G. Knepley      |         |         |       |         |         |
438227fcede3SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
438327fcede3SMatthew G. Knepley      |         |         |       |         |         |
438427fcede3SMatthew G. Knepley      0---------0---------3       4---------0---------5
438527fcede3SMatthew G. Knepley      */
438627fcede3SMatthew G. Knepley     /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
438727fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
438827fcede3SMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
438927fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
439027fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
439127fcede3SMatthew G. Knepley 
439227fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
439327fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
439427fcede3SMatthew G. Knepley       /* A hex */
439527fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
439627fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
439727fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
439827fcede3SMatthew G. Knepley       orntNew[1] = 0;
439927fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
440027fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
440127fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
440227fcede3SMatthew G. Knepley       orntNew[3] = 0;
440327fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
440427fcede3SMatthew G. Knepley       orntNew[4] = 0;
440527fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
440627fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
440727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
440827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
440927fcede3SMatthew G. Knepley #if 1
441027fcede3SMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cMaxNew);
441127fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
441227fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
441327fcede3SMatthew G. Knepley       }
441427fcede3SMatthew G. Knepley #endif
441527fcede3SMatthew G. Knepley       /* B hex */
441627fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
441727fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
441827fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
441927fcede3SMatthew G. Knepley       orntNew[1] = 0;
442027fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
442127fcede3SMatthew G. Knepley       orntNew[2] = -1;
442227fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
442327fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
442427fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
442527fcede3SMatthew G. Knepley       orntNew[4] = 0;
442627fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
442727fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
442827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
442927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
443027fcede3SMatthew G. Knepley #if 1
443127fcede3SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cMaxNew);
443227fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
443327fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
443427fcede3SMatthew G. Knepley       }
443527fcede3SMatthew G. Knepley #endif
443627fcede3SMatthew G. Knepley       /* C hex */
443727fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
443827fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
443927fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
444027fcede3SMatthew G. Knepley       orntNew[1] = 0;
444127fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
444227fcede3SMatthew G. Knepley       orntNew[2] = -1;
444327fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
444427fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
444527fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
444627fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
444727fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
444827fcede3SMatthew G. Knepley       orntNew[5] = -4;
444927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
445027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
445127fcede3SMatthew G. Knepley #if 1
445227fcede3SMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cMaxNew);
445327fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
445427fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
445527fcede3SMatthew G. Knepley       }
445627fcede3SMatthew G. Knepley #endif
445727fcede3SMatthew G. Knepley       /* D hex */
445827fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
445927fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
446027fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
446127fcede3SMatthew G. Knepley       orntNew[1] = 0;
446227fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
446327fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
446427fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
446527fcede3SMatthew G. Knepley       orntNew[3] = 0;
446627fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
446727fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
446827fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
446927fcede3SMatthew G. Knepley       orntNew[5] = -4;
447027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
447127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
447227fcede3SMatthew G. Knepley #if 1
447327fcede3SMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cMaxNew);
447427fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
447527fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
447627fcede3SMatthew G. Knepley       }
447727fcede3SMatthew G. Knepley #endif
447827fcede3SMatthew G. Knepley       /* E hex */
447927fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
448027fcede3SMatthew G. Knepley       orntNew[0] = -4;
448127fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
448227fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
448327fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
448427fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
448527fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
448627fcede3SMatthew G. Knepley       orntNew[3] = 0;
448727fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
448827fcede3SMatthew G. Knepley       orntNew[4] = -1;
448927fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
449027fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
449127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
449227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
449327fcede3SMatthew G. Knepley #if 1
449427fcede3SMatthew G. Knepley       if ((newp+4 < cStartNew) || (newp+4 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cMaxNew);
449527fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
449627fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
449727fcede3SMatthew G. Knepley       }
449827fcede3SMatthew G. Knepley #endif
449927fcede3SMatthew G. Knepley       /* F hex */
450027fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
450127fcede3SMatthew G. Knepley       orntNew[0] = -4;
450227fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
450327fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
450427fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
450527fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
450627fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
450727fcede3SMatthew G. Knepley       orntNew[3] = -1;
450827fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
450927fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
451027fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
451127fcede3SMatthew G. Knepley       orntNew[5] = 1;
451227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
451327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
451427fcede3SMatthew G. Knepley #if 1
451527fcede3SMatthew G. Knepley       if ((newp+5 < cStartNew) || (newp+5 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cMaxNew);
451627fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
451727fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
451827fcede3SMatthew G. Knepley       }
451927fcede3SMatthew G. Knepley #endif
452027fcede3SMatthew G. Knepley       /* G hex */
452127fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
452227fcede3SMatthew G. Knepley       orntNew[0] = -4;
452327fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
452427fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
452527fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
452627fcede3SMatthew G. Knepley       orntNew[2] = 0;
452727fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
452827fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
452927fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
453027fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
453127fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
453227fcede3SMatthew G. Knepley       orntNew[5] = -3;
453327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
453427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
453527fcede3SMatthew G. Knepley #if 1
453627fcede3SMatthew G. Knepley       if ((newp+6 < cStartNew) || (newp+6 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cMaxNew);
453727fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
453827fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
453927fcede3SMatthew G. Knepley       }
454027fcede3SMatthew G. Knepley #endif
454127fcede3SMatthew G. Knepley       /* H hex */
454227fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
454327fcede3SMatthew G. Knepley       orntNew[0] = -4;
454427fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
454527fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
454627fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
454727fcede3SMatthew G. Knepley       orntNew[2] = -1;
454827fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
454927fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
455027fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
455127fcede3SMatthew G. Knepley       orntNew[4] = 3;
455227fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
455327fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
455427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
455527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
455627fcede3SMatthew G. Knepley #if 1
455727fcede3SMatthew G. Knepley       if ((newp+7 < cStartNew) || (newp+7 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cMaxNew);
455827fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
455927fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
456027fcede3SMatthew G. Knepley       }
456127fcede3SMatthew G. Knepley #endif
456227fcede3SMatthew G. Knepley     }
456327fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces: Front, Back, Sides */
456427fcede3SMatthew G. Knepley     /*
456527fcede3SMatthew G. Knepley      3---------2---------2
456627fcede3SMatthew G. Knepley      |         |         |
456727fcede3SMatthew G. Knepley      |    D    2    C    |
456827fcede3SMatthew G. Knepley      |         |         |
456927fcede3SMatthew G. Knepley      3----3----0----1----1
457027fcede3SMatthew G. Knepley      |         |         |
457127fcede3SMatthew G. Knepley      |    A    0    B    |
457227fcede3SMatthew G. Knepley      |         |         |
457327fcede3SMatthew G. Knepley      0---------0---------1
457427fcede3SMatthew G. Knepley      */
457527fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
457627fcede3SMatthew G. Knepley       const PetscInt  newp = (cMax - cStart)*8 + (c - cMax)*4;
457727fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
4578d273725eSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6], o, of, i;
457927fcede3SMatthew G. Knepley 
458027fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
458127fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
458227fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
4583d273725eSMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
458427fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
458527fcede3SMatthew G. Knepley         PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
458627fcede3SMatthew G. Knepley         PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
4587d273725eSMatthew G. Knepley         PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4);
458827fcede3SMatthew G. Knepley         if (ornt[0] != ornt[1]) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent ordering for matching ends of hybrid cell %d: %d != %d", c, ornt[0], ornt[1]);
458927fcede3SMatthew G. Knepley         coneNew[0]         = fStartNew + (cone[0] - fStart)*4 + subfA;
459027fcede3SMatthew G. Knepley         orntNew[0]         = ornt[0];
459127fcede3SMatthew G. Knepley         coneNew[1]         = fStartNew + (cone[1] - fStart)*4 + subfA;
459227fcede3SMatthew G. Knepley         orntNew[1]         = ornt[0];
4593d273725eSMatthew G. Knepley         of = fornt[edgeA] < 0 ? -1 : 1;
4594d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], r) + 2;
4595d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0);
4596d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeA];
4597d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2;
4598d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeA;
4599d273725eSMatthew G. Knepley         orntNew[i] = 0;
4600d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2;
4601d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeB;
4602d273725eSMatthew G. Knepley         orntNew[i] = -2;
4603d273725eSMatthew G. Knepley         of = fornt[edgeB] < 0 ? -1 : 1;
4604d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2;
4605d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1);
4606d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeB];
460727fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
460827fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
460927fcede3SMatthew G. Knepley #if 1
461027fcede3SMatthew G. Knepley         if ((newp+r < cMaxNew) || (newp+r >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+r, cMaxNew, cEndNew);
461127fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
461227fcede3SMatthew G. Knepley           if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
461327fcede3SMatthew G. Knepley         }
461427fcede3SMatthew G. Knepley         for (p = 2; p < 6; ++p) {
461527fcede3SMatthew G. Knepley           if ((coneNew[p] < fMaxNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew);
461627fcede3SMatthew G. Knepley         }
461727fcede3SMatthew G. Knepley #endif
461827fcede3SMatthew G. Knepley       }
461927fcede3SMatthew G. Knepley     }
462027fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
462127fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
462227fcede3SMatthew G. Knepley     ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
462327fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
462427fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
462527fcede3SMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
462627fcede3SMatthew G. Knepley         const PetscInt  newCells[24] = {0, 1, 2, 3,  4, 5, 6, 7,  0, 3, 5, 4,  2, 1, 7, 6,  3, 2, 6, 5,  0, 4, 7, 1};
462727fcede3SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
462827fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
462927fcede3SMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
463027fcede3SMatthew G. Knepley 
463127fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
463227fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
463327fcede3SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
463427fcede3SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
463527fcede3SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
463627fcede3SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
463727fcede3SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
463827fcede3SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
463927fcede3SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
464027fcede3SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
464127fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
464227fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
464327fcede3SMatthew G. Knepley #if 1
464427fcede3SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
464527fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
464627fcede3SMatthew G. Knepley           if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
464727fcede3SMatthew G. Knepley         }
464827fcede3SMatthew G. Knepley #endif
464927fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
465027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
465127fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
465227fcede3SMatthew G. Knepley           PetscInt subf;
465327fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
465427fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
465527fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
465627fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
465727fcede3SMatthew G. Knepley             if (cone[c] == f) break;
465827fcede3SMatthew G. Knepley           }
465927fcede3SMatthew G. Knepley           subf = GetQuadSubfaceInverse_Static(ornt[c], r);
466027fcede3SMatthew G. Knepley           if (support[s] < cMax) {
466127fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
466227fcede3SMatthew G. Knepley           } else {
466327fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax       - cStart)*8 + (support[s] - cMax)*4 + subf;
466427fcede3SMatthew G. Knepley           }
466527fcede3SMatthew G. Knepley         }
466627fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
466727fcede3SMatthew G. Knepley #if 1
466827fcede3SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
466927fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
467027fcede3SMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
467127fcede3SMatthew G. Knepley         }
467227fcede3SMatthew G. Knepley #endif
467327fcede3SMatthew G. Knepley       }
467427fcede3SMatthew G. Knepley     }
4675d273725eSMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
467627fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
467727fcede3SMatthew G. Knepley       const PetscInt  newCells[24] = {0, 3,  2, 3,  1, 2,  0, 1,  4, 5,  5, 6,  6, 7,  4, 7,  0, 4,  3, 5,  2, 6,  1, 7};
467827fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
467927fcede3SMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
468027fcede3SMatthew G. Knepley 
468127fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
468227fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
468327fcede3SMatthew G. Knepley       /* A-D face */
468427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
468527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
468627fcede3SMatthew G. Knepley       orntNew[0] = 0;
468727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
468827fcede3SMatthew G. Knepley       orntNew[1] = 0;
468927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
469027fcede3SMatthew G. Knepley       orntNew[2] = -2;
469127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
469227fcede3SMatthew G. Knepley       orntNew[3] = -2;
469327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
469427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
469527fcede3SMatthew G. Knepley #if 1
469627fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
469727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
469827fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
469927fcede3SMatthew G. Knepley       }
470027fcede3SMatthew G. Knepley #endif
470127fcede3SMatthew G. Knepley       /* C-D face */
470227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
470327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
470427fcede3SMatthew G. Knepley       orntNew[0] = 0;
470527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
470627fcede3SMatthew G. Knepley       orntNew[1] = 0;
470727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
470827fcede3SMatthew G. Knepley       orntNew[2] = -2;
470927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
471027fcede3SMatthew G. Knepley       orntNew[3] = -2;
471127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
471227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
471327fcede3SMatthew G. Knepley #if 1
471427fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
471527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
471627fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
471727fcede3SMatthew G. Knepley       }
471827fcede3SMatthew G. Knepley #endif
471927fcede3SMatthew G. Knepley       /* B-C face */
472027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
472127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
472227fcede3SMatthew G. Knepley       orntNew[0] = -2;
472327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
472427fcede3SMatthew G. Knepley       orntNew[1] = 0;
472527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
472627fcede3SMatthew G. Knepley       orntNew[2] = 0;
472727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
472827fcede3SMatthew G. Knepley       orntNew[3] = -2;
472927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
473027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
473127fcede3SMatthew G. Knepley #if 1
473227fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
473327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
473427fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
473527fcede3SMatthew G. Knepley       }
473627fcede3SMatthew G. Knepley #endif
473727fcede3SMatthew G. Knepley       /* A-B face */
473827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
473927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
474027fcede3SMatthew G. Knepley       orntNew[0] = -2;
474127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
474227fcede3SMatthew G. Knepley       orntNew[1] = 0;
474327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
474427fcede3SMatthew G. Knepley       orntNew[2] = 0;
474527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
474627fcede3SMatthew G. Knepley       orntNew[3] = -2;
474727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
474827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
474927fcede3SMatthew G. Knepley #if 1
475027fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
475127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
475227fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
475327fcede3SMatthew G. Knepley       }
475427fcede3SMatthew G. Knepley #endif
475527fcede3SMatthew G. Knepley       /* E-F face */
475627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
475727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
475827fcede3SMatthew G. Knepley       orntNew[0] = -2;
475927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
476027fcede3SMatthew G. Knepley       orntNew[1] = -2;
476127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
476227fcede3SMatthew G. Knepley       orntNew[2] = 0;
476327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
476427fcede3SMatthew G. Knepley       orntNew[3] = 0;
476527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
476627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
476727fcede3SMatthew G. Knepley #if 1
476827fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
476927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
477027fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
477127fcede3SMatthew G. Knepley       }
477227fcede3SMatthew G. Knepley #endif
477327fcede3SMatthew G. Knepley       /* F-G face */
477427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
477527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
477627fcede3SMatthew G. Knepley       orntNew[0] = -2;
477727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
477827fcede3SMatthew G. Knepley       orntNew[1] = -2;
477927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
478027fcede3SMatthew G. Knepley       orntNew[2] = 0;
478127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
478227fcede3SMatthew G. Knepley       orntNew[3] = 0;
478327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
478427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
478527fcede3SMatthew G. Knepley #if 1
478627fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
478727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
478827fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
478927fcede3SMatthew G. Knepley       }
479027fcede3SMatthew G. Knepley #endif
479127fcede3SMatthew G. Knepley       /* G-H face */
479227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
479327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
479427fcede3SMatthew G. Knepley       orntNew[0] = -2;
479527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
479627fcede3SMatthew G. Knepley       orntNew[1] = 0;
479727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
479827fcede3SMatthew G. Knepley       orntNew[2] = 0;
479927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
480027fcede3SMatthew G. Knepley       orntNew[3] = -2;
480127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
480227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
480327fcede3SMatthew G. Knepley #if 1
480427fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
480527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
480627fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
480727fcede3SMatthew G. Knepley       }
480827fcede3SMatthew G. Knepley #endif
480927fcede3SMatthew G. Knepley       /* E-H face */
481027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
481127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
481227fcede3SMatthew G. Knepley       orntNew[0] = -2;
481327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
481427fcede3SMatthew G. Knepley       orntNew[1] = -2;
481527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
481627fcede3SMatthew G. Knepley       orntNew[2] = 0;
481727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
481827fcede3SMatthew G. Knepley       orntNew[3] = 0;
481927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
482027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
482127fcede3SMatthew G. Knepley #if 1
482227fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
482327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
482427fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
482527fcede3SMatthew G. Knepley       }
482627fcede3SMatthew G. Knepley #endif
482727fcede3SMatthew G. Knepley       /* A-E face */
482827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
482927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
483027fcede3SMatthew G. Knepley       orntNew[0] = 0;
483127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
483227fcede3SMatthew G. Knepley       orntNew[1] = 0;
483327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
483427fcede3SMatthew G. Knepley       orntNew[2] = -2;
483527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
483627fcede3SMatthew G. Knepley       orntNew[3] = -2;
483727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
483827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
483927fcede3SMatthew G. Knepley #if 1
484027fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
484127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
484227fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
484327fcede3SMatthew G. Knepley       }
484427fcede3SMatthew G. Knepley #endif
484527fcede3SMatthew G. Knepley       /* D-F face */
484627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
484727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
484827fcede3SMatthew G. Knepley       orntNew[0] = -2;
484927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
485027fcede3SMatthew G. Knepley       orntNew[1] = 0;
485127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
485227fcede3SMatthew G. Knepley       orntNew[2] = 0;
485327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
485427fcede3SMatthew G. Knepley       orntNew[3] = -2;
485527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
485627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
485727fcede3SMatthew G. Knepley #if 1
485827fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
485927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
486027fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
486127fcede3SMatthew G. Knepley       }
486227fcede3SMatthew G. Knepley #endif
486327fcede3SMatthew G. Knepley       /* C-G face */
486427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
486527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
486627fcede3SMatthew G. Knepley       orntNew[0] = -2;
486727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
486827fcede3SMatthew G. Knepley       orntNew[1] = -2;
486927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
487027fcede3SMatthew G. Knepley       orntNew[2] = 0;
487127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
487227fcede3SMatthew G. Knepley       orntNew[3] = 0;
487327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
487427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
487527fcede3SMatthew G. Knepley #if 1
487627fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
487727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
487827fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
487927fcede3SMatthew G. Knepley       }
488027fcede3SMatthew G. Knepley #endif
488127fcede3SMatthew G. Knepley       /* B-H face */
488227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
488327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
488427fcede3SMatthew G. Knepley       orntNew[0] = 0;
488527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
488627fcede3SMatthew G. Knepley       orntNew[1] = -2;
488727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
488827fcede3SMatthew G. Knepley       orntNew[2] = -2;
488927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
489027fcede3SMatthew G. Knepley       orntNew[3] = 0;
489127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
489227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
489327fcede3SMatthew G. Knepley #if 1
489427fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
489527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
489627fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
489727fcede3SMatthew G. Knepley       }
489827fcede3SMatthew G. Knepley #endif
489927fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
490027fcede3SMatthew G. Knepley         newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
490127fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
490227fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
490327fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
490427fcede3SMatthew G. Knepley #if 1
490527fcede3SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
490627fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
490727fcede3SMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew);
490827fcede3SMatthew G. Knepley         }
490927fcede3SMatthew G. Knepley #endif
491027fcede3SMatthew G. Knepley       }
491127fcede3SMatthew G. Knepley     }
491227fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
491327fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
491427fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
491527fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
491627fcede3SMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
491727fcede3SMatthew G. Knepley 
491827fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
491927fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
492027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
492127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
492227fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
492327fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
492427fcede3SMatthew G. Knepley 
492527fcede3SMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
492627fcede3SMatthew G. Knepley         orntNew[0]   = ornt[0];
492727fcede3SMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
492827fcede3SMatthew G. Knepley         orntNew[1]   = ornt[1];
492927fcede3SMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
493027fcede3SMatthew G. Knepley         orntNew[2+r] = 0;
493127fcede3SMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd      - eMax) + (f - fMax);
493227fcede3SMatthew G. Knepley         orntNew[3-r] = 0;
493327fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
493427fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
493527fcede3SMatthew G. Knepley #if 1
493627fcede3SMatthew G. Knepley         if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew);
493727fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
493827fcede3SMatthew G. Knepley           if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
493927fcede3SMatthew G. Knepley         }
494027fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
494127fcede3SMatthew G. Knepley           if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew);
494227fcede3SMatthew G. Knepley         }
494327fcede3SMatthew G. Knepley #endif
494427fcede3SMatthew G. Knepley         for (s = 0; s < size; ++s) {
494527fcede3SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
4946d273725eSMatthew G. Knepley           PetscInt        o, of;
494727fcede3SMatthew G. Knepley 
494827fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
494927fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
4950d273725eSMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
495127fcede3SMatthew G. Knepley           for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
495227fcede3SMatthew G. Knepley           if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]);
495327fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
4954d273725eSMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
4955d273725eSMatthew G. Knepley           supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4;
495627fcede3SMatthew G. Knepley         }
495727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
495827fcede3SMatthew G. Knepley #if 1
495927fcede3SMatthew G. Knepley         if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew);
496027fcede3SMatthew G. Knepley         for (p = 0; p < size; ++p) {
496127fcede3SMatthew G. Knepley           if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew);
496227fcede3SMatthew G. Knepley         }
496327fcede3SMatthew G. Knepley #endif
496427fcede3SMatthew G. Knepley       }
496527fcede3SMatthew G. Knepley     }
496627fcede3SMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
496727fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
496827fcede3SMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
496927fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
497027fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
497127fcede3SMatthew G. Knepley       PetscInt        supportNew[2];
497227fcede3SMatthew G. Knepley 
497327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
497427fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
497527fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
4976d273725eSMatthew G. Knepley #if 0
497727fcede3SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
497827fcede3SMatthew G. Knepley         orntNew[0] = 0;
497927fcede3SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
498027fcede3SMatthew G. Knepley         orntNew[1] = 0;
498127fcede3SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
498227fcede3SMatthew G. Knepley         orntNew[2] = 0;
498327fcede3SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd                                   - fMax) + (c - cMax);
498427fcede3SMatthew G. Knepley         orntNew[3] = 0;
4985d273725eSMatthew G. Knepley #else
4986d273725eSMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r;
4987d273725eSMatthew G. Knepley         orntNew[0] = 0;
4988d273725eSMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r;
4989d273725eSMatthew G. Knepley         orntNew[1] = 0;
4990d273725eSMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax);
4991d273725eSMatthew G. Knepley         orntNew[2] = 0;
4992d273725eSMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd      - fMax) + (c - cMax);
4993d273725eSMatthew G. Knepley         orntNew[3] = 0;
4994d273725eSMatthew G. Knepley #endif
499527fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
499627fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
499727fcede3SMatthew G. Knepley #if 1
499827fcede3SMatthew G. Knepley         if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew);
499927fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
500027fcede3SMatthew G. Knepley           if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
500127fcede3SMatthew G. Knepley         }
500227fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
500327fcede3SMatthew G. Knepley           if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew);
500427fcede3SMatthew G. Knepley         }
500527fcede3SMatthew G. Knepley #endif
500627fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
500727fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
500827fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
500927fcede3SMatthew G. Knepley #if 1
501027fcede3SMatthew G. Knepley         if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew);
501127fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
501227fcede3SMatthew G. Knepley           if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew);
501327fcede3SMatthew G. Knepley         }
501427fcede3SMatthew G. Knepley #endif
501527fcede3SMatthew G. Knepley       }
501627fcede3SMatthew G. Knepley     }
501727fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
501827fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
501927fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
502027fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
502127fcede3SMatthew G. Knepley 
502227fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
502327fcede3SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
502427fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
502527fcede3SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
502627fcede3SMatthew G. Knepley 
502727fcede3SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
502827fcede3SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
502927fcede3SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
503027fcede3SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
503127fcede3SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
503227fcede3SMatthew G. Knepley #if 1
503327fcede3SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
503427fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
503527fcede3SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
503627fcede3SMatthew G. Knepley         }
503727fcede3SMatthew G. Knepley #endif
503827fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
503927fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
504027fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
504127fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
504227fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
504327fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
504427fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
504527fcede3SMatthew G. Knepley             if (cone[c] == e) break;
504627fcede3SMatthew G. Knepley           }
504727fcede3SMatthew G. Knepley           if (support[s] < fMax) {
504827fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
504927fcede3SMatthew G. Knepley           } else {
505027fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
505127fcede3SMatthew G. Knepley           }
505227fcede3SMatthew G. Knepley         }
505327fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
505427fcede3SMatthew G. Knepley #if 1
505527fcede3SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
505627fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
505727fcede3SMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
505827fcede3SMatthew G. Knepley         }
505927fcede3SMatthew G. Knepley #endif
506027fcede3SMatthew G. Knepley       }
506127fcede3SMatthew G. Knepley     }
506227fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
506327fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
506427fcede3SMatthew G. Knepley       const PetscInt  newFaces[24] = {3, 2, 1, 0,  4, 5, 6, 7,  0, 9, 4, 8,  2, 11, 6, 10,  1, 10, 5, 9,  8, 7, 11, 3};
506527fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
506627fcede3SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
506727fcede3SMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
506827fcede3SMatthew G. Knepley 
506927fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
507027fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
507127fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
507227fcede3SMatthew G. Knepley 
507327fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
507427fcede3SMatthew G. Knepley         coneNew[1] = newv;
507527fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
507627fcede3SMatthew G. Knepley #if 1
507727fcede3SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
507827fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
507927fcede3SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
508027fcede3SMatthew G. Knepley         }
508127fcede3SMatthew G. Knepley #endif
508227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
508327fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
508427fcede3SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
508527fcede3SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
508627fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
508727fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
508827fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
508927fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
509027fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
509127fcede3SMatthew G. Knepley           if (support[s] < cMax) {
509227fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
509327fcede3SMatthew G. Knepley           } else {
5094d273725eSMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r;
509527fcede3SMatthew G. Knepley           }
509627fcede3SMatthew G. Knepley         }
509727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
509827fcede3SMatthew G. Knepley #if 1
509927fcede3SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
510027fcede3SMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
510127fcede3SMatthew G. Knepley           if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
510227fcede3SMatthew G. Knepley         }
510327fcede3SMatthew G. Knepley #endif
510427fcede3SMatthew G. Knepley       }
510527fcede3SMatthew G. Knepley     }
510627fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
510727fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
510827fcede3SMatthew G. Knepley       const PetscInt  newFaces[24] = {0, 1, 2, 3,  4, 5, 6, 7,  0, 9, 4, 8,  2, 11, 6, 10,  1, 10, 5, 9,  3, 8, 7, 11};
510927fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
511027fcede3SMatthew G. Knepley       const PetscInt *cone;
511127fcede3SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
511227fcede3SMatthew G. Knepley 
511327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
511427fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
511527fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
511627fcede3SMatthew G. Knepley 
511727fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
511827fcede3SMatthew G. Knepley         coneNew[1] = newv;
511927fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
512027fcede3SMatthew G. Knepley #if 1
512127fcede3SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
512227fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
512327fcede3SMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
512427fcede3SMatthew G. Knepley         }
512527fcede3SMatthew G. Knepley #endif
512627fcede3SMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
512727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
512827fcede3SMatthew G. Knepley #if 1
512927fcede3SMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew);
513027fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
513127fcede3SMatthew G. Knepley           if ((supportNew[p] < fStartNew) || (supportNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fMaxNew);
513227fcede3SMatthew G. Knepley         }
513327fcede3SMatthew G. Knepley #endif
513427fcede3SMatthew G. Knepley       }
513527fcede3SMatthew G. Knepley     }
513627fcede3SMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
513727fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
513827fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
513927fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
514027fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
514127fcede3SMatthew G. Knepley 
514227fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
514327fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
514427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
514527fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
514627fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
514727fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
514827fcede3SMatthew G. Knepley #if 1
514927fcede3SMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
515027fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
515127fcede3SMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
515227fcede3SMatthew G. Knepley       }
515327fcede3SMatthew G. Knepley #endif
515427fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
515527fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
515627fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
515727fcede3SMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
515827fcede3SMatthew G. Knepley         if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]);
515927fcede3SMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
516027fcede3SMatthew G. Knepley       }
516127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
516227fcede3SMatthew G. Knepley #if 1
516327fcede3SMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
516427fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
516527fcede3SMatthew G. Knepley         if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
516627fcede3SMatthew G. Knepley       }
516727fcede3SMatthew G. Knepley #endif
516827fcede3SMatthew G. Knepley     }
516927fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
517027fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
517127fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
517227fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
517327fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
517427fcede3SMatthew G. Knepley 
517527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
517627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
517727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
517827fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
517927fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
518027fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
518127fcede3SMatthew G. Knepley #if 1
518227fcede3SMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
518327fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
518427fcede3SMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
518527fcede3SMatthew G. Knepley       }
518627fcede3SMatthew G. Knepley #endif
518727fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
518827fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
518927fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
519027fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
519127fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
519227fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
519327fcede3SMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
519427fcede3SMatthew G. Knepley         if ((c < 2) || (c >= csize)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Hybrid face %d is not in cone of hybrid cell %d", f, support[s]);
5195d273725eSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2;
519627fcede3SMatthew G. Knepley       }
519727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
519827fcede3SMatthew G. Knepley #if 1
519927fcede3SMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
520027fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
520127fcede3SMatthew G. Knepley         if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
520227fcede3SMatthew G. Knepley       }
520327fcede3SMatthew G. Knepley #endif
520427fcede3SMatthew G. Knepley     }
520527fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
520627fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
520727fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
520827fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
520927fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size;
521027fcede3SMatthew G. Knepley 
521127fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
521227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr);
521327fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr);
521427fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
521527fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
521627fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
521727fcede3SMatthew G. Knepley #if 1
521827fcede3SMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
521927fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
522027fcede3SMatthew G. Knepley         if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
522127fcede3SMatthew G. Knepley       }
522227fcede3SMatthew G. Knepley #endif
522327fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
522427fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
522527fcede3SMatthew G. Knepley       supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
522627fcede3SMatthew G. Knepley       supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
522727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
522827fcede3SMatthew G. Knepley #if 1
522927fcede3SMatthew G. Knepley       if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew);
523027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
523127fcede3SMatthew G. Knepley         if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew);
523227fcede3SMatthew G. Knepley       }
523327fcede3SMatthew G. Knepley #endif
523427fcede3SMatthew G. Knepley     }
523527fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
523627fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
523727fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
523827fcede3SMatthew G. Knepley       const PetscInt *support, *cone;
523927fcede3SMatthew G. Knepley       PetscInt        size, s;
524027fcede3SMatthew G. Knepley 
524127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
524227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
524327fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
524427fcede3SMatthew G. Knepley         PetscInt r = 0;
524527fcede3SMatthew G. Knepley 
524627fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
524727fcede3SMatthew G. Knepley         if (cone[1] == v) r = 1;
524827fcede3SMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
524927fcede3SMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
525027fcede3SMatthew G. Knepley       }
525127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
525227fcede3SMatthew G. Knepley #if 1
525327fcede3SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
525427fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
525527fcede3SMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
525627fcede3SMatthew G. Knepley       }
525727fcede3SMatthew G. Knepley #endif
525827fcede3SMatthew G. Knepley     }
525927fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
526027fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
526127fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
526227fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
526327fcede3SMatthew G. Knepley       PetscInt        size, s;
526427fcede3SMatthew G. Knepley 
526527fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
526627fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
526727fcede3SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
526827fcede3SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
526927fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
527027fcede3SMatthew G. Knepley         PetscInt r;
527127fcede3SMatthew G. Knepley 
527227fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
527327fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
527427fcede3SMatthew G. Knepley         if (support[s] < fMax) {
527527fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
527627fcede3SMatthew G. Knepley         } else {
527727fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
527827fcede3SMatthew G. Knepley         }
527927fcede3SMatthew G. Knepley       }
528027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
528127fcede3SMatthew G. Knepley #if 1
528227fcede3SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
528327fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
528427fcede3SMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
528527fcede3SMatthew G. Knepley       }
528627fcede3SMatthew G. Knepley #endif
528727fcede3SMatthew G. Knepley     }
528827fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
528927fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
529027fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
529127fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
529227fcede3SMatthew G. Knepley       PetscInt        size, s;
529327fcede3SMatthew G. Knepley 
529427fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
529527fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
529627fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 +  (f - fStart)*4 + r;
529727fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
529827fcede3SMatthew G. Knepley         PetscInt r;
529927fcede3SMatthew G. Knepley 
530027fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
530127fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
530227fcede3SMatthew G. Knepley         if (support[s] < cMax) {
530327fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
530427fcede3SMatthew G. Knepley         } else {
530527fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax       - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
530627fcede3SMatthew G. Knepley         }
530727fcede3SMatthew G. Knepley       }
530827fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
530927fcede3SMatthew G. Knepley #if 1
531027fcede3SMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
531127fcede3SMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
531227fcede3SMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
531327fcede3SMatthew G. Knepley       }
531427fcede3SMatthew G. Knepley #endif
531527fcede3SMatthew G. Knepley     }
531627fcede3SMatthew G. Knepley     /* Cell vertices have 6 supports */
531727fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
531827fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
531927fcede3SMatthew G. Knepley       PetscInt       supportNew[6];
532027fcede3SMatthew G. Knepley 
532127fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
532227fcede3SMatthew G. Knepley         supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
532327fcede3SMatthew G. Knepley       }
532427fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
532527fcede3SMatthew G. Knepley     }
532627fcede3SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
532727fcede3SMatthew G. Knepley     break;
532875d3a19aSMatthew G. Knepley   default:
532975d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
533075d3a19aSMatthew G. Knepley   }
533175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
533275d3a19aSMatthew G. Knepley }
533375d3a19aSMatthew G. Knepley 
533475d3a19aSMatthew G. Knepley #undef __FUNCT__
533575d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates"
533686150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
533775d3a19aSMatthew G. Knepley {
533875d3a19aSMatthew G. Knepley   PetscSection   coordSection, coordSectionNew;
533975d3a19aSMatthew G. Knepley   Vec            coordinates, coordinatesNew;
534075d3a19aSMatthew G. Knepley   PetscScalar   *coords, *coordsNew;
53413478d7aaSMatthew G. Knepley   const PetscInt numVertices = depthSize ? depthSize[0] : 0;
5342f1d7821bSLawrence Mitchell   PetscInt       spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
534375d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
534475d3a19aSMatthew G. Knepley 
534575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
534675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
534775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
5348b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
534975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
535075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
535127fcede3SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr);
53523478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);}
535375d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);
5354f719d809SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
5355f1d7821bSLawrence Mitchell   ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr);
535675d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
535775d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
5358f1d7821bSLawrence Mitchell   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr);
53593478d7aaSMatthew G. Knepley   ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
536027fcede3SMatthew G. Knepley   if (cMax < 0) cMax = cEnd;
536175d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
5362b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
5363f1d7821bSLawrence Mitchell   /* All vertices have the spaceDim coordinates */
53643478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
5365f1d7821bSLawrence Mitchell     ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr);
5366f1d7821bSLawrence Mitchell     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr);
536775d3a19aSMatthew G. Knepley   }
536875d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
5369f719d809SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr);
537075d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
537175d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
537275d3a19aSMatthew G. Knepley   ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr);
537375d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
537475d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
537560b9e8a1SMatthew G. Knepley   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
537660b9e8a1SMatthew G. Knepley   ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr);
537775d3a19aSMatthew G. Knepley   ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr);
537875d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
537975d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
5380b5da9499SMatthew G. Knepley   switch (refiner) {
53813478d7aaSMatthew G. Knepley   case 0: break;
5382b5da9499SMatthew G. Knepley   case 6: /* Hex 3D */
5383d856d60fSMatthew G. Knepley   case 8: /* Hybrid Hex 3D */
5384b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
5385d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
538627fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
5387b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
5388b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
5389b5da9499SMatthew G. Knepley 
5390b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5391b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
5392b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
5393b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
5394b5da9499SMatthew G. Knepley       }
5395b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
5396b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
5397b5da9499SMatthew G. Knepley       }
5398b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5399f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
5400f1d7821bSLawrence Mitchell       for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
5401f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
5402b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5403b5da9499SMatthew G. Knepley     }
5404b5da9499SMatthew G. Knepley   case 2: /* Hex 2D */
5405a97b51b8SMatthew G. Knepley   case 4: /* Hybrid Hex 2D */
5406b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
540727fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
5408f1d7821bSLawrence Mitchell       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (spaceDim > 2 ? (fMax - fStart) : 0);
5409b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
5410b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
5411b5da9499SMatthew G. Knepley 
5412b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5413b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
5414b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
5415b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
5416b5da9499SMatthew G. Knepley       }
5417b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
5418b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
5419b5da9499SMatthew G. Knepley       }
5420b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5421f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
5422f1d7821bSLawrence Mitchell       for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
5423f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
5424b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5425b5da9499SMatthew G. Knepley     }
5426b5da9499SMatthew G. Knepley   case 1: /* Simplicial 2D */
5427b5da9499SMatthew G. Knepley   case 3: /* Hybrid Simplicial 2D */
5428b5da9499SMatthew G. Knepley   case 5: /* Simplicial 3D */
54296ce3c06aSMatthew G. Knepley   case 7: /* Hybrid Simplicial 3D */
5430b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
5431b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
5432b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
5433b5da9499SMatthew G. Knepley       const PetscInt *cone;
5434b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
5435b5da9499SMatthew G. Knepley 
5436b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
5437b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
5438b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
5439b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
5440b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
5441b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5442f1d7821bSLawrence Mitchell       ierr = DMPlexLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr);
5443f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
5444a96104c9SMatthew G. Knepley         coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]);
5445b5da9499SMatthew G. Knepley       }
5446b5da9499SMatthew G. Knepley     }
544775d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
544875d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
544975d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
545075d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
545175d3a19aSMatthew G. Knepley 
545275d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
545375d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5454f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
545575d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
545675d3a19aSMatthew G. Knepley       }
545775d3a19aSMatthew G. Knepley     }
5458b5da9499SMatthew G. Knepley     break;
5459b5da9499SMatthew G. Knepley   default:
5460b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
546175d3a19aSMatthew G. Knepley   }
546275d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
546375d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
546475d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
546575d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
546675d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
5467a96104c9SMatthew G. Knepley   if (dm->maxCell) {
5468a96104c9SMatthew G. Knepley     const PetscReal *maxCell, *L;
5469a96104c9SMatthew G. Knepley     ierr = DMGetPeriodicity(dm,  &maxCell, &L);CHKERRQ(ierr);
5470a96104c9SMatthew G. Knepley     ierr = DMSetPeriodicity(rdm,  maxCell,  L);CHKERRQ(ierr);
5471a96104c9SMatthew G. Knepley   }
547275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
547375d3a19aSMatthew G. Knepley }
547475d3a19aSMatthew G. Knepley 
547575d3a19aSMatthew G. Knepley #undef __FUNCT__
547675d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF"
547786150812SJed Brown static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
547875d3a19aSMatthew G. Knepley {
547975d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
548075d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
548175d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
548275d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
548375d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
548475d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
548575d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
548675d3a19aSMatthew G. Knepley 
548775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
548875d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
5489785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
549075d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
549175d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
549275d3a19aSMatthew G. Knepley   }
549375d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
5494785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &ranksNew);CHKERRQ(ierr);
5495785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &localPointsNew);CHKERRQ(ierr);
5496785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
549775d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
549875d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
549975d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
550075d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
550175d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
550275d3a19aSMatthew G. Knepley   }
550375d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
550475d3a19aSMatthew G. Knepley   ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);
550575d3a19aSMatthew G. Knepley   ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
550675d3a19aSMatthew G. Knepley   ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
550775d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
550875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
550975d3a19aSMatthew G. Knepley }
551075d3a19aSMatthew G. Knepley 
551175d3a19aSMatthew G. Knepley #undef __FUNCT__
551275d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF"
551386150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
551475d3a19aSMatthew G. Knepley {
551575d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
551675d3a19aSMatthew G. Knepley   IS                 processRanks;
551775d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
551875d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
551975d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
552075d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
552175d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
552275d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
552375d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
55247ba685a0SMatthew G. Knepley   PetscInt           depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
55257ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
552675d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
552775d3a19aSMatthew G. Knepley 
552875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
552975d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
553075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
553175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
553275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
553375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
553475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
553575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
5536*add09238SMatthew G. Knepley   cMax = cMax < 0 ? cEnd : cMax;
5537*add09238SMatthew G. Knepley   fMax = fMax < 0 ? fEnd : fMax;
5538*add09238SMatthew G. Knepley   eMax = eMax < 0 ? eEnd : eMax;
55393478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
554075d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
554175d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
5542*add09238SMatthew G. Knepley   /* Calculate size of new SF */
554375d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
554475d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
554575d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
554675d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
554775d3a19aSMatthew G. Knepley 
554875d3a19aSMatthew G. Knepley     switch (refiner) {
554975d3a19aSMatthew G. Knepley     case 1:
5550a97b51b8SMatthew G. Knepley     case 3:
5551a97b51b8SMatthew G. Knepley       /* Hybrid Simplicial 2D */
5552a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5553a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
5554a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5555a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5556a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
5557a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5558a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5559a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
5560a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5561a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5562a97b51b8SMatthew G. Knepley         /* Interior cells add new cells and interior faces */
5563a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 3;
5564a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
5565a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
5566a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5567a97b51b8SMatthew G. Knepley       }
5568a97b51b8SMatthew G. Knepley       break;
556975d3a19aSMatthew G. Knepley     case 2:
5570a97b51b8SMatthew G. Knepley     case 4:
5571a97b51b8SMatthew G. Knepley       /* Hybrid Hex 2D */
5572a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5573a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
5574a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5575a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5576a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
5577a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5578a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5579a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
5580a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5581a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5582a97b51b8SMatthew G. Knepley         /* Interior cells add new cells, interior faces, and vertex */
5583a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
5584a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
5585a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
5586a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5587a97b51b8SMatthew G. Knepley       }
5588a97b51b8SMatthew G. Knepley       break;
5589b5da9499SMatthew G. Knepley     case 5:
55906ce3c06aSMatthew G. Knepley     case 7:
55916ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
55926ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
55936ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
55946ce3c06aSMatthew G. Knepley         ++numLeavesNew;
55956ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
55966ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
55976ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
55986ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
55996ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
56006ce3c06aSMatthew G. Knepley         ++numLeavesNew;
56016ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
56026ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
56036ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
56046ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
56056ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
56066ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
56076ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
56086ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
56096ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
56106ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
56116ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
56126ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
56136ce3c06aSMatthew G. Knepley       }
56146ce3c06aSMatthew G. Knepley       break;
56152eabf88fSMatthew G. Knepley     case 6:
561627fcede3SMatthew G. Knepley     case 8:
561727fcede3SMatthew G. Knepley       /* Hybrid Hex 3D */
561827fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
561927fcede3SMatthew G. Knepley         /* Old vertices stay the same */
562027fcede3SMatthew G. Knepley         ++numLeavesNew;
562127fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
562227fcede3SMatthew G. Knepley         /* Interior edges add new edges, and vertex */
562327fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
562427fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
562527fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
562627fcede3SMatthew G. Knepley         ++numLeavesNew;
562727fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
562827fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
562927fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
563027fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
563127fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
563227fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
563327fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
563427fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
563527fcede3SMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
563627fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
563727fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
563827fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
563927fcede3SMatthew G. Knepley       }
564027fcede3SMatthew G. Knepley       break;
564175d3a19aSMatthew G. Knepley     default:
564275d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
564375d3a19aSMatthew G. Knepley     }
564475d3a19aSMatthew G. Knepley   }
564575d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
564675d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
564775d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
5648dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
5649dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
565075d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
565175d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
565275d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
565375d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
565475d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
565575d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
565675d3a19aSMatthew G. Knepley   }
565775d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
565875d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
565975d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
566075d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
566175d3a19aSMatthew G. Knepley 
566275d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
566375d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
566475d3a19aSMatthew G. Knepley 
566575d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
566675d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
566775d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
566875d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
566975d3a19aSMatthew G. Knepley 
567075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
567175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
567275d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
567375d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
56740252e7f5SMatthew G. Knepley     rdepthMaxOld[n*(depth+1)+depth]   = rdepthMaxOld[n*(depth+1)+depth]   < 0 ? rdepthSizeOld[n*(depth+1)+depth]  +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth];
56750252e7f5SMatthew G. Knepley     rdepthMaxOld[n*(depth+1)+depth-1] = rdepthMaxOld[n*(depth+1)+depth-1] < 0 ? rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n]: rdepthMaxOld[n*(depth+1)+depth-1];
56760252e7f5SMatthew G. Knepley     rdepthMaxOld[n*(depth+1)+1]       = rdepthMaxOld[n*(depth+1)+1]       < 0 ? rdepthSizeOld[n*(depth+1)+1]      +reStart[n]: rdepthMaxOld[n*(depth+1)+1];
567775d3a19aSMatthew G. Knepley   }
567875d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
567975d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
568075d3a19aSMatthew G. Knepley   /* Calculate new point SF */
5681785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew,    &localPointsNew);CHKERRQ(ierr);
5682785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
568375d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
568475d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
568575d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
568675d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
568775d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
568875d3a19aSMatthew G. Knepley 
568975d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
569075d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
569175d3a19aSMatthew G. Knepley     switch (refiner) {
569275d3a19aSMatthew G. Knepley     case 1:
569375d3a19aSMatthew G. Knepley     case 3:
569475d3a19aSMatthew G. Knepley       /* Hybrid simplicial 2D */
569575d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
569675d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
569775d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
569875d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
569975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
570075d3a19aSMatthew G. Knepley         ++m;
570175d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
570275d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
570375d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
570475d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
570575d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
570675d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
570775d3a19aSMatthew G. Knepley         }
5708*add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
5709*add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
5710*add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5711*add09238SMatthew G. Knepley         ++m;
571275d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
571375d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
571475d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
571575d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
571675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
571775d3a19aSMatthew G. Knepley         ++m;
571875d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
571975d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
572075d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
572175d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
572275d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
572375d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
572475d3a19aSMatthew G. Knepley         }
572575d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
572675d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
572775d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
572875d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
572975d3a19aSMatthew G. Knepley         }
5730*add09238SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
573175d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
573275d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
573375d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
573475d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
573575d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
573675d3a19aSMatthew G. Knepley         }
573775d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
573875d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*3 + (rp - rdepthMaxOld[n*(depth+1)+depth]);
573975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
574075d3a19aSMatthew G. Knepley         ++m;
574175d3a19aSMatthew G. Knepley       }
574275d3a19aSMatthew G. Knepley       break;
5743*add09238SMatthew G. Knepley     case 2:
5744a97b51b8SMatthew G. Knepley     case 4:
5745a97b51b8SMatthew G. Knepley       /* Hybrid Hex 2D */
5746a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5747a97b51b8SMatthew G. Knepley         /* Old vertices stay the same */
5748a97b51b8SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
5749a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5750a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5751a97b51b8SMatthew G. Knepley         ++m;
5752a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5753a97b51b8SMatthew G. Knepley         /* Old interior faces add new faces and vertex */
5754a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5755a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
5756a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
5757a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5758a97b51b8SMatthew G. Knepley         }
5759*add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
5760*add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
5761*add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5762*add09238SMatthew G. Knepley         ++m;
5763a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5764a97b51b8SMatthew G. Knepley         /* Old hybrid faces stay the same */
5765a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
5766a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
5767a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5768a97b51b8SMatthew G. Knepley         ++m;
5769a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5770a97b51b8SMatthew G. Knepley         /* Old interior cells add new cells, interior faces, and vertex */
5771a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5772a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
5773a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5774a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5775a97b51b8SMatthew G. Knepley         }
5776a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5777a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*4     + r;
5778a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r;
5779a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5780a97b51b8SMatthew G. Knepley         }
5781*add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)               + (fMax                              - fStart)     + (p  - cStart);
5782*add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0]  + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]);
5783*add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5784*add09238SMatthew G. Knepley         ++m;
5785a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5786a97b51b8SMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
5787a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5788a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
5789a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5790a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5791a97b51b8SMatthew G. Knepley         }
5792a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*4     + (p  - cMax);
5793a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth]);
5794a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5795a97b51b8SMatthew G. Knepley         ++m;
5796a97b51b8SMatthew G. Knepley       }
5797a97b51b8SMatthew G. Knepley       break;
5798b5da9499SMatthew G. Knepley     case 5:
57996ce3c06aSMatthew G. Knepley     case 7:
58006ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
58016ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
58026ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
58036ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
58046ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
58056ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
58066ce3c06aSMatthew G. Knepley         ++m;
58076ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
58086ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
58096ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
58106ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
58116ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
58126ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
58136ce3c06aSMatthew G. Knepley         }
58146ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
58156ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
58166ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
58176ce3c06aSMatthew G. Knepley         ++m;
58186ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
58196ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
58206ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
58217d5cd7d5SMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rp - rdepthMaxOld[n*(depth+1)+1]);
58226ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
58236ce3c06aSMatthew G. Knepley         ++m;
58246ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
58256ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
58266ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
58276ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
58286ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
58296ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
58306ce3c06aSMatthew G. Knepley         }
58316ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
58326ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
58336ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
58346ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
58356ce3c06aSMatthew G. Knepley         }
58366ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
58376ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
58386ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5839899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
5840899f98d0SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r;
58416ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
58426ce3c06aSMatthew G. Knepley         }
58437d5cd7d5SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (eEnd                                    - eMax)                        + (p  - fMax);
58447d5cd7d5SMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
58456ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
584609b1338fSMatthew G. Knepley         ++m;
58476ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
58486ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
58496ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
58506ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
58516ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
58526ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
58536ce3c06aSMatthew G. Knepley         }
58546ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
58556ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
58566ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
58576ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
58586ce3c06aSMatthew G. Knepley         }
58596ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + r;
58606ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rp - rcStart[n])*1 + r;
58616ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
586209b1338fSMatthew G. Knepley         ++m;
58636ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
58646ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
58656ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
58666ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
58676ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
58686ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
58696ce3c06aSMatthew G. Knepley         }
58706ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
5871899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*3                            + r;
5872899f98d0SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r;
58736ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
58746ce3c06aSMatthew G. Knepley         }
58756ce3c06aSMatthew G. Knepley       }
58766ce3c06aSMatthew G. Knepley       break;
58772eabf88fSMatthew G. Knepley     case 6:
587827fcede3SMatthew G. Knepley     case 8:
587927fcede3SMatthew G. Knepley       /* Hybrid Hex 3D */
588027fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
588127fcede3SMatthew G. Knepley         /* Interior vertices stay the same */
588227fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
588327fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
588427fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
588527fcede3SMatthew G. Knepley         ++m;
588627fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
588727fcede3SMatthew G. Knepley         /* Interior edges add new edges and vertex */
588827fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
588927fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
589027fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
589127fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
589227fcede3SMatthew G. Knepley         }
589327fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
589427fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
589527fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
589627fcede3SMatthew G. Knepley         ++m;
589727fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
589827fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
589927fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (p  - eMax);
5900d2701f60SMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rp - rdepthMaxOld[n*(depth+1)+1]);
590127fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
590227fcede3SMatthew G. Knepley         ++m;
590327fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
590427fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
590527fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
590627fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
590727fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
590827fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
590927fcede3SMatthew G. Knepley         }
591027fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
591127fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*4     + r;
591227fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
591327fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
591427fcede3SMatthew G. Knepley         }
591527fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eMax                        - eStart)     + (p  - fStart);
591627fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
591727fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
591827fcede3SMatthew G. Knepley         ++m;
591927fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
592027fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
592127fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5922d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (p  - fMax)*2                              + r;
5923d2701f60SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*12 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r;
592427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
592527fcede3SMatthew G. Knepley         }
5926d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (p  - fMax);
5927d2701f60SMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
592827fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
592927fcede3SMatthew G. Knepley         ++m;
593027fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
593127fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
593227fcede3SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
593327fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
593427fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
593527fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
593627fcede3SMatthew G. Knepley         }
593727fcede3SMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
593827fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*12     + r;
593927fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
594027fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
594127fcede3SMatthew G. Knepley         }
594227fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
594327fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (p  - cStart)*6     + r;
594427fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*6 + r;
594527fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
594627fcede3SMatthew G. Knepley         }
594727fcede3SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
594827fcede3SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eMax                        - eStart)     + (fMax                              - fStart)     + (p  - cStart)     + r;
594927fcede3SMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r;
595027fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
595127fcede3SMatthew G. Knepley         }
595227fcede3SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
595327fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
595427fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
595527fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
595627fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
595727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
595827fcede3SMatthew G. Knepley         }
595927fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5960d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (fEnd                                          - fMax)*2                              + (p  - cMax)*4                            + r;
5961d2701f60SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*12 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
596227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
596327fcede3SMatthew G. Knepley         }
5964d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (fEnd                                          - fMax)                              + (p  - cMax);
5965d2701f60SMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]);
596627fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
596727fcede3SMatthew G. Knepley         ++m;
596827fcede3SMatthew G. Knepley       }
596927fcede3SMatthew G. Knepley       break;
597075d3a19aSMatthew G. Knepley     default:
597175d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
597275d3a19aSMatthew G. Knepley     }
597375d3a19aSMatthew G. Knepley   }
597409b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
597575d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
597675d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
5977ba3c3d50SMatthew G. Knepley   {
5978ba3c3d50SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
5979ba3c3d50SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
5980ba3c3d50SMatthew G. Knepley 
5981ba3c3d50SMatthew G. Knepley     /* SF needs sorted leaves to correct calculate Gather */
5982ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr);
5983ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr);
5984ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr);
5985ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) idx[i] = i;
5986ba3c3d50SMatthew G. Knepley     ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr);
5987ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
5988ba3c3d50SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
5989ba3c3d50SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
5990ba3c3d50SMatthew G. Knepley     }
5991ba3c3d50SMatthew G. Knepley     ltmp            = localPointsNew;
5992ba3c3d50SMatthew G. Knepley     localPointsNew  = lp;
5993ba3c3d50SMatthew G. Knepley     rtmp            = remotePointsNew;
5994ba3c3d50SMatthew G. Knepley     remotePointsNew = rp;
5995ba3c3d50SMatthew G. Knepley     ierr = PetscFree(idx);CHKERRQ(ierr);
5996ba3c3d50SMatthew G. Knepley     ierr = PetscFree(ltmp);CHKERRQ(ierr);
5997ba3c3d50SMatthew G. Knepley     ierr = PetscFree(rtmp);CHKERRQ(ierr);
5998ba3c3d50SMatthew G. Knepley   }
599975d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
600075d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
600106a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
600275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
600375d3a19aSMatthew G. Knepley }
600475d3a19aSMatthew G. Knepley 
600575d3a19aSMatthew G. Knepley #undef __FUNCT__
600675d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels"
600786150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
600875d3a19aSMatthew G. Knepley {
600975d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
60107ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
60117ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
601275d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
601375d3a19aSMatthew G. Knepley 
601475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
601575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
601675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
601775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
601875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
6019d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
60203478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
602175d3a19aSMatthew G. Knepley   ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
602275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
602375d3a19aSMatthew G. Knepley   switch (refiner) {
60243478d7aaSMatthew G. Knepley   case 0: break;
602558b8852aSMatthew G. Knepley   case 7:
602658b8852aSMatthew G. Knepley   case 8:
602758b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
602875d3a19aSMatthew G. Knepley   case 3:
602958b8852aSMatthew G. Knepley   case 4:
603075d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
603175d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
603275d3a19aSMatthew G. Knepley   }
603375d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
603475d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
603575d3a19aSMatthew G. Knepley     const char     *lname;
603675d3a19aSMatthew G. Knepley     PetscBool       isDepth;
603775d3a19aSMatthew G. Knepley     IS              valueIS;
603875d3a19aSMatthew G. Knepley     const PetscInt *values;
603975d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
604075d3a19aSMatthew G. Knepley 
604175d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr);
604275d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
604375d3a19aSMatthew G. Knepley     if (isDepth) continue;
604475d3a19aSMatthew G. Knepley     ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr);
604575d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr);
604675d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
604775d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
604875d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
604975d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
605075d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
605175d3a19aSMatthew G. Knepley       IS              pointIS;
605275d3a19aSMatthew G. Knepley       const PetscInt *points;
605375d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
605475d3a19aSMatthew G. Knepley 
605575d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
605675d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
605775d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
605875d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
605975d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
606075d3a19aSMatthew G. Knepley         switch (refiner) {
606175d3a19aSMatthew G. Knepley         case 1:
606275d3a19aSMatthew G. Knepley           /* Simplicial 2D */
606375d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
606475d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
606575d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
606675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
606775d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
606875d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
606975d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
607075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
607175d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
607275d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
607375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
607475d3a19aSMatthew G. Knepley             }
607575d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
607675d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
607775d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
607875d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
607975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
608075d3a19aSMatthew G. Knepley             }
608175d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
608275d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
608375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
608475d3a19aSMatthew G. Knepley             }
608575d3a19aSMatthew G. Knepley           }
608675d3a19aSMatthew G. Knepley           break;
608775d3a19aSMatthew G. Knepley         case 2:
608875d3a19aSMatthew G. Knepley           /* Hex 2D */
608975d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
609075d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
609175d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
609275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
609375d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
609475d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
609575d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
609675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
609775d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
609875d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
609975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
610075d3a19aSMatthew G. Knepley             }
610175d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
610275d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
610375d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
610475d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
610575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
610675d3a19aSMatthew G. Knepley             }
610775d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
610875d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
610975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
611075d3a19aSMatthew G. Knepley             }
611175d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
611275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
611375d3a19aSMatthew G. Knepley           }
611475d3a19aSMatthew G. Knepley           break;
611575d3a19aSMatthew G. Knepley         case 3:
611675d3a19aSMatthew G. Knepley           /* Hybrid simplicial 2D */
611775d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
611875d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
611975d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
612075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
612175d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
612275d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
612375d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
612475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
612575d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
612675d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
612775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
612875d3a19aSMatthew G. Knepley             }
612975d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
613075d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
613175d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
613275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
613375d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
613475d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
613575d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
613675d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
613775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
613875d3a19aSMatthew G. Knepley             }
613975d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
614075d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
614175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
614275d3a19aSMatthew G. Knepley             }
614375d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
614475d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
614575d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
614675d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
614775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
614875d3a19aSMatthew G. Knepley             }
614975d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
615075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
615175d3a19aSMatthew G. Knepley           }
615275d3a19aSMatthew G. Knepley           break;
6153a97b51b8SMatthew G. Knepley         case 4:
6154a97b51b8SMatthew G. Knepley           /* Hybrid Hex 2D */
6155a97b51b8SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
6156a97b51b8SMatthew G. Knepley             /* Old vertices stay the same */
6157a97b51b8SMatthew G. Knepley             newp = vStartNew + (p - vStart);
6158a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6159a97b51b8SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
6160a97b51b8SMatthew G. Knepley             /* Old interior faces add new faces and vertex */
6161a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
6162a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6163a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6164a97b51b8SMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
6165a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6166a97b51b8SMatthew G. Knepley             }
6167a97b51b8SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
6168a97b51b8SMatthew G. Knepley             /* Old hybrid faces stay the same */
6169a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
6170a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6171a97b51b8SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
6172a97b51b8SMatthew G. Knepley             /* Old interior cells add new cells, interior faces, and vertex */
6173a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6174a97b51b8SMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
6175a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6176a97b51b8SMatthew G. Knepley             }
6177a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6178a97b51b8SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
6179a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6180a97b51b8SMatthew G. Knepley             }
6181a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
6182a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6183a97b51b8SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
6184a97b51b8SMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
6185a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6186a97b51b8SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
6187a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6188a97b51b8SMatthew G. Knepley             }
6189a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
6190a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6191a97b51b8SMatthew G. Knepley           }
6192a97b51b8SMatthew G. Knepley           break;
6193b5da9499SMatthew G. Knepley         case 5:
6194b5da9499SMatthew G. Knepley           /* Simplicial 3D */
6195b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
6196b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
6197b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
6198b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6199b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
6200b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
6201b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6202b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
6203b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6204b5da9499SMatthew G. Knepley             }
6205b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
6206b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6207b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
6208b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
6209b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6210b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
6211b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6212b5da9499SMatthew G. Knepley             }
6213b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
6214b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
6215b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6216b5da9499SMatthew G. Knepley             }
6217b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
6218b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
6219b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
6220b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
6221b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6222b5da9499SMatthew G. Knepley             }
6223b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
6224b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
6225b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6226b5da9499SMatthew G. Knepley             }
6227b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
6228b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
6229b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6230b5da9499SMatthew G. Knepley             }
6231b5da9499SMatthew G. Knepley           }
6232b5da9499SMatthew G. Knepley           break;
62336ce3c06aSMatthew G. Knepley         case 7:
62346ce3c06aSMatthew G. Knepley           /* Hybrid Simplicial 3D */
62356ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
62366ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
62376ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
62386ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62396ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
62406ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
62416ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
62426ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
62436ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62446ce3c06aSMatthew G. Knepley             }
62456ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
62466ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62476ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
62486ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
62496ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
62506ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62516ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
62526ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
62536ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
62546ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
62556ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62566ce3c06aSMatthew G. Knepley             }
62576ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
62586ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
62596ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62606ce3c06aSMatthew G. Knepley             }
62616ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
62626ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
62636ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
62646ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
62656ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62666ce3c06aSMatthew G. Knepley             }
62676ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
62686ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62696ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
62706ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
62716ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
62726ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
62736ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62746ce3c06aSMatthew G. Knepley             }
62756ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
62766ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
62776ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62786ce3c06aSMatthew G. Knepley             }
62796ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
62806ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
628158b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
62826ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
62836ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
62846ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
62856ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62866ce3c06aSMatthew G. Knepley             }
62876ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
62886ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
62896ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
62906ce3c06aSMatthew G. Knepley             }
62916ce3c06aSMatthew G. Knepley           }
62926ce3c06aSMatthew G. Knepley           break;
62932eabf88fSMatthew G. Knepley         case 6:
62942eabf88fSMatthew G. Knepley           /* Hex 3D */
62952eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
62962eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
62972eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
62982eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
629919d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
63002eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
63012eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
63022eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
63032eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63042eabf88fSMatthew G. Knepley             }
63052eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
63062eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63072eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
63082eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
63092eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
63102eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
63112eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63122eabf88fSMatthew G. Knepley             }
63132eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
63142eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
63152eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63162eabf88fSMatthew G. Knepley             }
63172eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
63182eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63192eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
63202eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
63212eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
63222eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
63232eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63242eabf88fSMatthew G. Knepley             }
63252eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
63262eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
63272eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63282eabf88fSMatthew G. Knepley             }
63292eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
63302eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
63312eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63322eabf88fSMatthew G. Knepley             }
63332eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
63342eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63352eabf88fSMatthew G. Knepley           }
63362eabf88fSMatthew G. Knepley           break;
633727fcede3SMatthew G. Knepley         case 8:
633827fcede3SMatthew G. Knepley           /* Hybrid Hex 3D */
633927fcede3SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
634027fcede3SMatthew G. Knepley             /* Interior vertices stay the same */
634127fcede3SMatthew G. Knepley             newp = vStartNew + (p - vStart);
634227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
634327fcede3SMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
634427fcede3SMatthew G. Knepley             /* Interior edges add new edges and vertex */
634527fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
634627fcede3SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
634727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
634827fcede3SMatthew G. Knepley             }
634927fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
635027fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
635127fcede3SMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
635227fcede3SMatthew G. Knepley             /* Hybrid edges stay the same */
635327fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
635427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
635527fcede3SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
635627fcede3SMatthew G. Knepley             /* Interior faces add new faces, edges, and vertex */
635727fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
635827fcede3SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
635927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
636027fcede3SMatthew G. Knepley             }
636127fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
636227fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
636327fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
636427fcede3SMatthew G. Knepley             }
636527fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
636627fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
636727fcede3SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
636827fcede3SMatthew G. Knepley             /* Hybrid faces add new faces and edges */
636927fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
637027fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
637127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
637227fcede3SMatthew G. Knepley             }
637327fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
637427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
637527fcede3SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
637627fcede3SMatthew G. Knepley             /* Interior cells add new cells, faces, edges, and vertex */
637727fcede3SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
637827fcede3SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
637927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
638027fcede3SMatthew G. Knepley             }
638127fcede3SMatthew G. Knepley             for (r = 0; r < 12; ++r) {
638227fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
638327fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
638427fcede3SMatthew G. Knepley             }
638527fcede3SMatthew G. Knepley             for (r = 0; r < 6; ++r) {
638627fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
638727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
638827fcede3SMatthew G. Knepley             }
638927fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
639027fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
639127fcede3SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
639227fcede3SMatthew G. Knepley             /* Hybrid cells add new cells, faces, and edges */
639327fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
639427fcede3SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
639527fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
639627fcede3SMatthew G. Knepley             }
639727fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
639827fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
639927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
640027fcede3SMatthew G. Knepley             }
640127fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
640227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
640327fcede3SMatthew G. Knepley           }
640427fcede3SMatthew G. Knepley           break;
640575d3a19aSMatthew G. Knepley         default:
640675d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
640775d3a19aSMatthew G. Knepley         }
640875d3a19aSMatthew G. Knepley       }
640975d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
641075d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
641175d3a19aSMatthew G. Knepley     }
641275d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
641375d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
641475d3a19aSMatthew G. Knepley     if (0) {
641575d3a19aSMatthew G. Knepley       ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr);
641675d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
641775d3a19aSMatthew G. Knepley       ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
641875d3a19aSMatthew G. Knepley     }
641975d3a19aSMatthew G. Knepley   }
642075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
642175d3a19aSMatthew G. Knepley }
642275d3a19aSMatthew G. Knepley 
642375d3a19aSMatthew G. Knepley #undef __FUNCT__
6424509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexRefineUniform_Internal"
642575d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
6426509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
642775d3a19aSMatthew G. Knepley {
642875d3a19aSMatthew G. Knepley   DM             rdm;
642975d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
643075d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
643175d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
643275d3a19aSMatthew G. Knepley 
643375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
643475d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
643575d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
643675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
643775d3a19aSMatthew G. Knepley   ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr);
643875d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
643975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
6440785e854fSJed Brown   ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr);
644175d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
644275d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
644375d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
644475d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
644575d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
644675d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
644775d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
644875d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
644975d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
645075d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
645175d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
645275d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
645375d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
645475d3a19aSMatthew G. Knepley   /* Step 6: Set coordinates for vertices */
645575d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
645675d3a19aSMatthew G. Knepley   /* Step 7: Create pointSF */
645775d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
645875d3a19aSMatthew G. Knepley   /* Step 8: Create labels */
645975d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
646075d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
646175d3a19aSMatthew G. Knepley 
646275d3a19aSMatthew G. Knepley   *dmRefined = rdm;
646375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
646475d3a19aSMatthew G. Knepley }
646575d3a19aSMatthew G. Knepley 
646675d3a19aSMatthew G. Knepley #undef __FUNCT__
64672389894bSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateCoarsePointIS"
64682389894bSMatthew G. Knepley /*@
64692389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
64702389894bSMatthew G. Knepley 
64712389894bSMatthew G. Knepley   Input Parameter:
64722389894bSMatthew G. Knepley . dm - The coarse DM
64732389894bSMatthew G. Knepley 
64742389894bSMatthew G. Knepley   Output Parameter:
64752389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
64762389894bSMatthew G. Knepley 
64772389894bSMatthew G. Knepley   Level: developer
64782389894bSMatthew G. Knepley 
64792389894bSMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS()
64802389894bSMatthew G. Knepley @*/
64812389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
64822389894bSMatthew G. Knepley {
64832389894bSMatthew G. Knepley   CellRefiner    cellRefiner;
64842389894bSMatthew G. Knepley   PetscInt      *depthSize, *fpoints;
64852389894bSMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
64862389894bSMatthew G. Knepley   PetscInt       depth, pStart, pEnd, p, vStart, vEnd, v;
64872389894bSMatthew G. Knepley   PetscErrorCode ierr;
64882389894bSMatthew G. Knepley 
64892389894bSMatthew G. Knepley   PetscFunctionBegin;
64902389894bSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
64912389894bSMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
64922389894bSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
64932389894bSMatthew G. Knepley   ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr);
64942389894bSMatthew G. Knepley   ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr);
64952389894bSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
64962389894bSMatthew G. Knepley   if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
64972389894bSMatthew G. Knepley   ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr);
64982389894bSMatthew G. Knepley   for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
64992389894bSMatthew G. Knepley   switch (cellRefiner) {
65002389894bSMatthew G. Knepley   case 1: /* Simplicial 2D */
65012389894bSMatthew G. Knepley   case 3: /* Hybrid simplicial 2D */
65022389894bSMatthew G. Knepley   case 2: /* Hex 2D */
65032389894bSMatthew G. Knepley   case 4: /* Hybrid Hex 2D */
65042389894bSMatthew G. Knepley   case 5: /* Simplicial 3D */
65052389894bSMatthew G. Knepley   case 7: /* Hybrid Simplicial 3D */
65062389894bSMatthew G. Knepley   case 6: /* Hex 3D */
65072389894bSMatthew G. Knepley   case 8: /* Hybrid Hex 3D */
65082389894bSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart);
65092389894bSMatthew G. Knepley     break;
65102389894bSMatthew G. Knepley   default:
65112389894bSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner);
65122389894bSMatthew G. Knepley   }
65132389894bSMatthew G. Knepley   ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr);
65142389894bSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
65152389894bSMatthew G. Knepley   PetscFunctionReturn(0);
65162389894bSMatthew G. Knepley }
65172389894bSMatthew G. Knepley 
65182389894bSMatthew G. Knepley #undef __FUNCT__
651975d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform"
65200e2b6761SMatthew G. Knepley /*@
65210e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
65220e2b6761SMatthew G. Knepley 
65230e2b6761SMatthew G. Knepley   Input Parameters:
65240e2b6761SMatthew G. Knepley + dm - The DM
65250e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
65260e2b6761SMatthew G. Knepley 
65270e2b6761SMatthew G. Knepley   Level: developer
65280e2b6761SMatthew G. Knepley 
65290e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
65300e2b6761SMatthew G. Knepley @*/
653175d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
653275d3a19aSMatthew G. Knepley {
653375d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
653475d3a19aSMatthew G. Knepley 
653575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
653675d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
653775d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
653875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
653975d3a19aSMatthew G. Knepley }
654075d3a19aSMatthew G. Knepley 
654175d3a19aSMatthew G. Knepley #undef __FUNCT__
654275d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform"
65430e2b6761SMatthew G. Knepley /*@
65440e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
65450e2b6761SMatthew G. Knepley 
65460e2b6761SMatthew G. Knepley   Input Parameter:
65470e2b6761SMatthew G. Knepley . dm - The DM
65480e2b6761SMatthew G. Knepley 
65490e2b6761SMatthew G. Knepley   Output Parameter:
65500e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
65510e2b6761SMatthew G. Knepley 
65520e2b6761SMatthew G. Knepley   Level: developer
65530e2b6761SMatthew G. Knepley 
65540e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
65550e2b6761SMatthew G. Knepley @*/
655675d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
655775d3a19aSMatthew G. Knepley {
655875d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
655975d3a19aSMatthew G. Knepley 
656075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
656175d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
656275d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
656375d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
656475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
656575d3a19aSMatthew G. Knepley }
656675d3a19aSMatthew G. Knepley 
656775d3a19aSMatthew G. Knepley #undef __FUNCT__
656875d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit"
65690e2b6761SMatthew G. Knepley /*@
65700e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
65710e2b6761SMatthew G. Knepley 
65720e2b6761SMatthew G. Knepley   Input Parameters:
65730e2b6761SMatthew G. Knepley + dm - The DM
65740e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
65750e2b6761SMatthew G. Knepley 
65760e2b6761SMatthew G. Knepley   Level: developer
65770e2b6761SMatthew G. Knepley 
65780e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
65790e2b6761SMatthew G. Knepley @*/
658075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
658175d3a19aSMatthew G. Knepley {
658275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
658375d3a19aSMatthew G. Knepley 
658475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
658575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
658675d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
658775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
658875d3a19aSMatthew G. Knepley }
658975d3a19aSMatthew G. Knepley 
659075d3a19aSMatthew G. Knepley #undef __FUNCT__
659175d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit"
65920e2b6761SMatthew G. Knepley /*@
65930e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
65940e2b6761SMatthew G. Knepley 
65950e2b6761SMatthew G. Knepley   Input Parameter:
65960e2b6761SMatthew G. Knepley . dm - The DM
65970e2b6761SMatthew G. Knepley 
65980e2b6761SMatthew G. Knepley   Output Parameter:
65990e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
66000e2b6761SMatthew G. Knepley 
66010e2b6761SMatthew G. Knepley   Level: developer
66020e2b6761SMatthew G. Knepley 
66030e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
66040e2b6761SMatthew G. Knepley @*/
660575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
660675d3a19aSMatthew G. Knepley {
660775d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
660875d3a19aSMatthew G. Knepley 
660975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
661075d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
661175d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
661275d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
661375d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
661475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
661575d3a19aSMatthew G. Knepley }
661675d3a19aSMatthew G. Knepley 
661775d3a19aSMatthew G. Knepley #undef __FUNCT__
6618509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Internal"
6619509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
662075d3a19aSMatthew G. Knepley {
66213478d7aaSMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax;
662275d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
662375d3a19aSMatthew G. Knepley 
662475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
662575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
66263478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
66273478d7aaSMatthew G. Knepley   if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);}
662875d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
662975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr);
663075d3a19aSMatthew G. Knepley   switch (dim) {
663175d3a19aSMatthew G. Knepley   case 2:
663275d3a19aSMatthew G. Knepley     switch (coneSize) {
663375d3a19aSMatthew G. Knepley     case 3:
663475d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 3; /* Hybrid */
663575d3a19aSMatthew G. Knepley       else *cellRefiner = 1; /* Triangular */
663675d3a19aSMatthew G. Knepley       break;
663775d3a19aSMatthew G. Knepley     case 4:
663875d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 4; /* Hybrid */
663975d3a19aSMatthew G. Knepley       else *cellRefiner = 2; /* Quadrilateral */
664075d3a19aSMatthew G. Knepley       break;
664175d3a19aSMatthew G. Knepley     default:
664275d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
664375d3a19aSMatthew G. Knepley     }
664475d3a19aSMatthew G. Knepley     break;
6645b5da9499SMatthew G. Knepley   case 3:
6646b5da9499SMatthew G. Knepley     switch (coneSize) {
6647b5da9499SMatthew G. Knepley     case 4:
6648b5da9499SMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 7; /* Hybrid */
6649b5da9499SMatthew G. Knepley       else *cellRefiner = 5; /* Tetrahedral */
6650b5da9499SMatthew G. Knepley       break;
66512eabf88fSMatthew G. Knepley     case 6:
66522eabf88fSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 8; /* Hybrid */
66532eabf88fSMatthew G. Knepley       else *cellRefiner = 6; /* hexahedral */
66542eabf88fSMatthew G. Knepley       break;
6655b5da9499SMatthew G. Knepley     default:
6656b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
6657b5da9499SMatthew G. Knepley     }
6658b5da9499SMatthew G. Knepley     break;
665975d3a19aSMatthew G. Knepley   default:
666075d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
666175d3a19aSMatthew G. Knepley   }
666275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
666375d3a19aSMatthew G. Knepley }
6664