xref: /petsc/src/dm/impls/plex/plexrefine.c (revision bed052ea5faea526473af9f209327cf55d85a03e)
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__
29*bed052eaSMatthew G. Knepley #define __FUNCT__ "CellRefinerGetAffineTransforms_Internal"
30*bed052eaSMatthew G. Knepley /* Gets the affine map from the original cell to each subcell */
31*bed052eaSMatthew G. Knepley PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
32*bed052eaSMatthew G. Knepley {
33*bed052eaSMatthew G. Knepley   PetscReal     *v = NULL, *j = NULL, *invj = NULL, detJ;
34*bed052eaSMatthew G. Knepley   PetscInt       dim, s;
35*bed052eaSMatthew G. Knepley   PetscErrorCode ierr;
36*bed052eaSMatthew G. Knepley 
37*bed052eaSMatthew G. Knepley   PetscFunctionBegin;
38*bed052eaSMatthew G. Knepley   switch (refiner) {
39*bed052eaSMatthew G. Knepley   case 0: break;
40*bed052eaSMatthew G. Knepley   case 1:
41*bed052eaSMatthew G. Knepley     dim  = 2;
42*bed052eaSMatthew G. Knepley     if (numSubcells) *numSubcells = 4;
43*bed052eaSMatthew G. Knepley     if (v0) {
44*bed052eaSMatthew G. Knepley       ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr);
45*bed052eaSMatthew G. Knepley       /* A */
46*bed052eaSMatthew G. Knepley       v[0+0] = -1.0; v[0+1] = -1.0;
47*bed052eaSMatthew G. Knepley       j[0+0] =  0.5; j[0+1] =  0.0;
48*bed052eaSMatthew G. Knepley       j[0+2] =  0.0; j[0+3] =  0.5;
49*bed052eaSMatthew G. Knepley       /* B */
50*bed052eaSMatthew G. Knepley       v[2+0] =  0.0; v[2+1] = -1.0;
51*bed052eaSMatthew G. Knepley       j[4+0] =  0.5; j[4+1] =  0.0;
52*bed052eaSMatthew G. Knepley       j[4+2] =  0.0; j[4+3] =  0.5;
53*bed052eaSMatthew G. Knepley       /* C */
54*bed052eaSMatthew G. Knepley       v[4+0] = -1.0; v[4+1] =  0.0;
55*bed052eaSMatthew G. Knepley       j[8+0] =  0.5; j[8+1] =  0.0;
56*bed052eaSMatthew G. Knepley       j[8+2] =  0.0; j[8+3] =  0.5;
57*bed052eaSMatthew G. Knepley       /* D */
58*bed052eaSMatthew G. Knepley       v[6+0]  =  0.0; v[6+1]  = -1.0;
59*bed052eaSMatthew G. Knepley       j[12+0] =  0.0; j[12+1] = -0.5;
60*bed052eaSMatthew G. Knepley       j[12+2] =  0.5; j[12+3] =  0.5;
61*bed052eaSMatthew G. Knepley       for (s = 0; s < 4; ++s) {
62*bed052eaSMatthew G. Knepley         DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
63*bed052eaSMatthew G. Knepley         DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
64*bed052eaSMatthew G. Knepley       }
65*bed052eaSMatthew G. Knepley     }
66*bed052eaSMatthew G. Knepley     break;
67*bed052eaSMatthew G. Knepley   default:
68*bed052eaSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
69*bed052eaSMatthew G. Knepley   }
70*bed052eaSMatthew G. Knepley   if (v0) {*v0 = v; *jac = j; *invjac = invj;}
71*bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
72*bed052eaSMatthew G. Knepley }
73*bed052eaSMatthew G. Knepley 
74*bed052eaSMatthew G. Knepley #undef __FUNCT__
75*bed052eaSMatthew G. Knepley #define __FUNCT__ "CellRefinerRestoreAffineTransforms_Internal"
76*bed052eaSMatthew G. Knepley PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
77*bed052eaSMatthew G. Knepley {
78*bed052eaSMatthew G. Knepley   PetscErrorCode ierr;
79*bed052eaSMatthew G. Knepley 
80*bed052eaSMatthew G. Knepley   PetscFunctionBegin;
81*bed052eaSMatthew G. Knepley   ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr);
82*bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
83*bed052eaSMatthew G. Knepley }
84*bed052eaSMatthew G. Knepley 
85*bed052eaSMatthew 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 */
11775d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + cEnd - cStart + fEnd - fStart; /* 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;
121b5da9499SMatthew G. Knepley   case 5:
122b5da9499SMatthew G. Knepley     /* Simplicial 3D */
123b5da9499SMatthew G. Knepley     depthSize[0] =    vEnd - vStart  +    eEnd - eStart;                    /* Add a vertex on every edge */
124b5da9499SMatthew 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 */
125b5da9499SMatthew G. Knepley     depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart);                   /* Every face split into 4 faces and 8 faces are added for each cell */
126b5da9499SMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                       /* Every cell split into 8 cells */
127b5da9499SMatthew G. Knepley     break;
128b5da9499SMatthew G. Knepley   case 7:
129b5da9499SMatthew G. Knepley     /* Hybrid Simplicial 3D */
130b5da9499SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
1316ce3c06aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
132b5da9499SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
133dae4404aSMatthew G. Knepley     /* Tetrahedra */
134dae4404aSMatthew G. Knepley     depthSize[0]  =    vEnd - vStart  +    eMax - eStart;                    /* Add a vertex on every interior edge */
135dae4404aSMatthew 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 */
136dae4404aSMatthew G. Knepley     depthSize[2]  = 4*(fMax - fStart) + 8*(cMax - cStart);                   /* Every interior face split into 4 faces, 8 faces added for each interior cell */
137dae4404aSMatthew G. Knepley     depthSize[3]  = 8*(cMax - cStart);                                       /* Every interior cell split into 8 cells */
138dae4404aSMatthew G. Knepley     /* Triangular Prisms */
139dae4404aSMatthew G. Knepley     depthSize[0] += 0;                                                       /* No hybrid vertices */
140dae4404aSMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax);                     /* Every hybrid edge remains, 1 edge for every hybrid face */
1416ce3c06aSMatthew 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 */
142dae4404aSMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                         /* Every hybrid cell split into 4 cells */
143b5da9499SMatthew G. Knepley     break;
1446ce3c06aSMatthew G. Knepley   case 6:
1456ce3c06aSMatthew G. Knepley     /* Hex 3D */
1466ce3c06aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
1476ce3c06aSMatthew 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 */
1486ce3c06aSMatthew 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 */
1496ce3c06aSMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                             /* Every cell split into 8 cells */
1506ce3c06aSMatthew G. Knepley     break;
15127fcede3SMatthew G. Knepley   case 8:
15227fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
15327fcede3SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
15427fcede3SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
15527fcede3SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
15627fcede3SMatthew G. Knepley     /* Hexahedra */
15727fcede3SMatthew G. Knepley     depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
15827fcede3SMatthew 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 */
15927fcede3SMatthew 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 */
16027fcede3SMatthew G. Knepley     depthSize[3] = 8*(cMax - cStart);                                             /* Every cell split into 8 cells */
16127fcede3SMatthew G. Knepley     /* Quadrilateral Prisms */
16227fcede3SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
16327fcede3SMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax)   +   (cEnd - cMax);      /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
16427fcede3SMatthew 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 */
16527fcede3SMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                              /* Every hybrid cell split into 4 cells */
16627fcede3SMatthew G. Knepley     break;
16775d3a19aSMatthew G. Knepley   default:
16875d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
16975d3a19aSMatthew G. Knepley   }
17075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
17175d3a19aSMatthew G. Knepley }
17275d3a19aSMatthew G. Knepley 
17342525629SMatthew G. Knepley /* Return triangle edge for orientation o, if it is r for o == 0 */
17442525629SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
175518a8359SMatthew G. Knepley   return (o < 0 ? 2-(o+r) : o+r)%3;
176518a8359SMatthew G. Knepley }
177de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
178de65f515SMatthew G. Knepley   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
179de65f515SMatthew G. Knepley }
180518a8359SMatthew G. Knepley 
181518a8359SMatthew G. Knepley /* Return triangle subface for orientation o, if it is r for o == 0 */
182518a8359SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
1834bae88c7SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%3;
18442525629SMatthew G. Knepley }
185de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
186de65f515SMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 3+s-o)%3;
187de65f515SMatthew G. Knepley }
18842525629SMatthew G. Knepley 
189431647a4SMatthew G. Knepley /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */
190431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) {
191431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+r) : o+r)%3;
192431647a4SMatthew G. Knepley }
193431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) {
194431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+s) : 3+s-o)%3;
195431647a4SMatthew G. Knepley }
196431647a4SMatthew G. Knepley 
19742525629SMatthew G. Knepley 
198e3f8b1d6SMatthew G. Knepley /* Return quad edge for orientation o, if it is r for o == 0 */
199e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
200e3f8b1d6SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%4;
201e3f8b1d6SMatthew G. Knepley }
202d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
203d6d937efSMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 4+s-o)%4;
204d6d937efSMatthew G. Knepley }
205e3f8b1d6SMatthew G. Knepley 
206e3f8b1d6SMatthew G. Knepley /* Return quad subface for orientation o, if it is r for o == 0 */
207e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
2084bae88c7SMatthew G. Knepley   return (o < 0 ? 4-(o+r) : o+r)%4;
20942525629SMatthew G. Knepley }
210d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
211d6d937efSMatthew G. Knepley   return (o < 0 ? 4-(o+s) : 4+s-o)%4;
212d6d937efSMatthew G. Knepley }
21342525629SMatthew G. Knepley 
21475d3a19aSMatthew G. Knepley #undef __FUNCT__
21575d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetConeSizes"
21686150812SJed Brown static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
21775d3a19aSMatthew G. Knepley {
218b5da9499SMatthew 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;
21975d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
22075d3a19aSMatthew G. Knepley 
22175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
22275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
22375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
22475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
22575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
22675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
22775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
2283478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
22975d3a19aSMatthew G. Knepley   switch (refiner) {
2303478d7aaSMatthew G. Knepley   case 0: break;
23175d3a19aSMatthew G. Knepley   case 1:
23275d3a19aSMatthew G. Knepley     /* Simplicial 2D */
23375d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
23475d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
23575d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
23675d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
23775d3a19aSMatthew G. Knepley 
23875d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
23975d3a19aSMatthew G. Knepley       }
24075d3a19aSMatthew G. Knepley     }
24175d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
24275d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
24375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
24475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
24575d3a19aSMatthew G. Knepley         PetscInt       size;
24675d3a19aSMatthew G. Knepley 
24775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
24875d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
24975d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
25075d3a19aSMatthew G. Knepley       }
25175d3a19aSMatthew G. Knepley     }
25275d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
25375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
25475d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
25575d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
25675d3a19aSMatthew G. Knepley 
25775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
25875d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
25975d3a19aSMatthew G. Knepley       }
26075d3a19aSMatthew G. Knepley     }
26175d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
26275d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
26375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
26475d3a19aSMatthew G. Knepley       PetscInt       size;
26575d3a19aSMatthew G. Knepley 
26675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
26775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
26875d3a19aSMatthew G. Knepley     }
26975d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
27075d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
27175d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
27275d3a19aSMatthew G. Knepley       PetscInt       size;
27375d3a19aSMatthew G. Knepley 
27475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
27575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
27675d3a19aSMatthew G. Knepley     }
27775d3a19aSMatthew G. Knepley     break;
27875d3a19aSMatthew G. Knepley   case 2:
27975d3a19aSMatthew G. Knepley     /* Hex 2D */
28075d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
28175d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
28275d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
28375d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
28475d3a19aSMatthew G. Knepley 
28575d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
28675d3a19aSMatthew G. Knepley       }
28775d3a19aSMatthew G. Knepley     }
28875d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
28975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
29075d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
29175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
29275d3a19aSMatthew G. Knepley         PetscInt       size;
29375d3a19aSMatthew G. Knepley 
29475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
29575d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
29675d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
29775d3a19aSMatthew G. Knepley       }
29875d3a19aSMatthew G. Knepley     }
29975d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
30075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
30175d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
30275d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
30375d3a19aSMatthew G. Knepley 
30475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
30575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
30675d3a19aSMatthew G. Knepley       }
30775d3a19aSMatthew G. Knepley     }
30875d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
30975d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
31075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
31175d3a19aSMatthew G. Knepley       PetscInt       size;
31275d3a19aSMatthew G. Knepley 
31375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
31475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
31575d3a19aSMatthew G. Knepley     }
31675d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
31775d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
31875d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
31975d3a19aSMatthew G. Knepley       PetscInt       size;
32075d3a19aSMatthew G. Knepley 
32175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
32275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
32375d3a19aSMatthew G. Knepley     }
32475d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
32575d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
32675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
32775d3a19aSMatthew G. Knepley 
32875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
32975d3a19aSMatthew G. Knepley     }
33075d3a19aSMatthew G. Knepley     break;
33175d3a19aSMatthew G. Knepley   case 3:
332d963de37SMatthew G. Knepley     /* Hybrid Simplicial 2D */
33375d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
33475d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
33575d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
33675d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
33775d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
33875d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
33975d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
34075d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
34175d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
34275d3a19aSMatthew G. Knepley 
34375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
34475d3a19aSMatthew G. Knepley       }
34575d3a19aSMatthew G. Knepley     }
34675d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
34775d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
34875d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
34975d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
35075d3a19aSMatthew G. Knepley 
35175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
35275d3a19aSMatthew G. Knepley       }
35375d3a19aSMatthew G. Knepley     }
35475d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
35575d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
35675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
35775d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
35875d3a19aSMatthew G. Knepley         PetscInt       size;
35975d3a19aSMatthew G. Knepley 
36075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
36175d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
36275d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
36375d3a19aSMatthew G. Knepley       }
36475d3a19aSMatthew G. Knepley     }
36575d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
36675d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
36775d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
36875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
36975d3a19aSMatthew G. Knepley 
37075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
37175d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
37275d3a19aSMatthew G. Knepley       }
37375d3a19aSMatthew G. Knepley     }
37475d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
37575d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
37675d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
37775d3a19aSMatthew G. Knepley       PetscInt       size;
37875d3a19aSMatthew G. Knepley 
37975d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
38075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
38175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
38275d3a19aSMatthew G. Knepley     }
38375d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
38475d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
38575d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
38675d3a19aSMatthew G. Knepley 
38775d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
38875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
38975d3a19aSMatthew G. Knepley     }
39075d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
39175d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
39275d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
39375d3a19aSMatthew G. Knepley       PetscInt       size;
39475d3a19aSMatthew G. Knepley 
39575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
39675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
39775d3a19aSMatthew G. Knepley     }
39875d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
39975d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
40075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
40175d3a19aSMatthew G. Knepley       const PetscInt *support;
40275d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
40375d3a19aSMatthew G. Knepley 
40475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
40575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
40675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
40775d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
40875d3a19aSMatthew G. Knepley         else newSize += 2;
40975d3a19aSMatthew G. Knepley       }
41075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
41175d3a19aSMatthew G. Knepley     }
41275d3a19aSMatthew G. Knepley     break;
413b5da9499SMatthew G. Knepley   case 5:
414b5da9499SMatthew G. Knepley     /* Simplicial 3D */
415b5da9499SMatthew G. Knepley     /* All cells have 4 faces */
416b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
417b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
418dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
419b5da9499SMatthew G. Knepley 
420b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
421b5da9499SMatthew G. Knepley       }
422b5da9499SMatthew G. Knepley     }
423b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
424b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
425b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
426b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
427b5da9499SMatthew G. Knepley         PetscInt       size;
428b5da9499SMatthew G. Knepley 
429b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
430b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
431b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
432b5da9499SMatthew G. Knepley       }
433b5da9499SMatthew G. Knepley     }
4349ddff745SMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
435b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
436b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
437b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
438b5da9499SMatthew G. Knepley 
439b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
440b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
441b5da9499SMatthew G. Knepley       }
442b5da9499SMatthew G. Knepley     }
443b5da9499SMatthew G. Knepley     /* Split edges have 2 vertices and the same faces */
444b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
445b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
446b5da9499SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
447b5da9499SMatthew G. Knepley         PetscInt       size;
448b5da9499SMatthew G. Knepley 
449b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
450b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
451b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
452b5da9499SMatthew G. Knepley       }
453b5da9499SMatthew G. Knepley     }
454b5da9499SMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
455b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
456b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
457b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
458b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
459b5da9499SMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
460b5da9499SMatthew G. Knepley 
461b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
462b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
463b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
464b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
465b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
466b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
467b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
468b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
46986f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
4709ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
471b5da9499SMatthew G. Knepley           if (er == eint[c]) {
472b5da9499SMatthew G. Knepley             intFaces += 1;
473b5da9499SMatthew G. Knepley           } else {
474b5da9499SMatthew G. Knepley             intFaces += 2;
475b5da9499SMatthew G. Knepley           }
476b5da9499SMatthew G. Knepley         }
477b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
478b5da9499SMatthew G. Knepley       }
479b5da9499SMatthew G. Knepley     }
4809ddff745SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
481b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
482b5da9499SMatthew G. Knepley       const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
483b5da9499SMatthew G. Knepley 
484b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
485b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
486b5da9499SMatthew G. Knepley     }
487b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
488b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
489b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
490b5da9499SMatthew G. Knepley       PetscInt       size;
491b5da9499SMatthew G. Knepley 
492b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
493b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
494b5da9499SMatthew G. Knepley     }
495b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
496b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
497b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
498b5da9499SMatthew G. Knepley       PetscInt       size, *star = NULL, starSize, s, cellSize = 0;
499b5da9499SMatthew G. Knepley 
500b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
501b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
502b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
503b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
504b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
505b5da9499SMatthew G. Knepley 
506b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
507b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
508b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
509b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
510b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
51142525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
512b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
513b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
514b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
51542525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
51642525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
517b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
518b5da9499SMatthew G. Knepley         }
519b5da9499SMatthew G. Knepley       }
520b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
521b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr);
522b5da9499SMatthew G. Knepley     }
523b5da9499SMatthew G. Knepley     break;
524dae4404aSMatthew G. Knepley   case 7:
5256ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
5266ce3c06aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
5276ce3c06aSMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
528dae4404aSMatthew G. Knepley     /* Interior cells have 4 faces */
529dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
530dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
531dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
532dae4404aSMatthew G. Knepley 
533dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
534dae4404aSMatthew G. Knepley       }
535dae4404aSMatthew G. Knepley     }
536dae4404aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
537dae4404aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
538dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
539dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
540dae4404aSMatthew G. Knepley 
541dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr);
542dae4404aSMatthew G. Knepley       }
543dae4404aSMatthew G. Knepley     }
5446ce3c06aSMatthew G. Knepley     /* Interior split faces have 3 edges and the same cells as the parent */
545dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
546dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
547dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
548dae4404aSMatthew G. Knepley         PetscInt       size;
549dae4404aSMatthew G. Knepley 
550dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
551dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
552dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
553dae4404aSMatthew G. Knepley       }
554dae4404aSMatthew G. Knepley     }
555dae4404aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
556dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
557dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
558dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
559dae4404aSMatthew G. Knepley 
560dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
561dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
562dae4404aSMatthew G. Knepley       }
563dae4404aSMatthew G. Knepley     }
5646ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
5656ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
5666ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
5676ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
5686ce3c06aSMatthew G. Knepley         PetscInt       size;
5696ce3c06aSMatthew G. Knepley 
5706ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
5716ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
5726ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
5736ce3c06aSMatthew G. Knepley       }
5746ce3c06aSMatthew G. Knepley     }
5756ce3c06aSMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
5766ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
5776ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
5786ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
5796ce3c06aSMatthew G. Knepley 
5806ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
5816ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
5826ce3c06aSMatthew G. Knepley       }
5836ce3c06aSMatthew G. Knepley     }
5846ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces */
585dae4404aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
586dae4404aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
587dae4404aSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
588dae4404aSMatthew G. Knepley         PetscInt       size;
589dae4404aSMatthew G. Knepley 
590dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
591dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
592dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
593dae4404aSMatthew G. Knepley       }
594dae4404aSMatthew G. Knepley     }
5956ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
596dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
597dae4404aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
598dae4404aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
599dae4404aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
600dae4404aSMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
601dae4404aSMatthew G. Knepley 
602dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
603dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
604dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
605dae4404aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
606dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
607dae4404aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
608dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
609dae4404aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
6106ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
611dae4404aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
6129ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
613dae4404aSMatthew G. Knepley             if (er == eint[c]) {
614dae4404aSMatthew G. Knepley               intFaces += 1;
615dae4404aSMatthew G. Knepley             } else {
616dae4404aSMatthew G. Knepley               intFaces += 2;
617dae4404aSMatthew G. Knepley             }
6186ce3c06aSMatthew G. Knepley           } else {
6196ce3c06aSMatthew G. Knepley             intFaces += 1;
6206ce3c06aSMatthew G. Knepley           }
621dae4404aSMatthew G. Knepley         }
622dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
623dae4404aSMatthew G. Knepley       }
624dae4404aSMatthew G. Knepley     }
6256ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
626dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
627dae4404aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
628dae4404aSMatthew G. Knepley 
629dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
630dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
631dae4404aSMatthew G. Knepley     }
6326ce3c06aSMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
633dae4404aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
6346ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
6356ce3c06aSMatthew G. Knepley       PetscInt       size;
6366ce3c06aSMatthew G. Knepley 
6376ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6386ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
6396ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6406ce3c06aSMatthew G. Knepley     }
6416ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
6426ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
6436ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
644dae4404aSMatthew G. Knepley       PetscInt       size;
645dae4404aSMatthew G. Knepley 
646dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
647dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
6486ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr);
649dae4404aSMatthew G. Knepley     }
6506ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
651dae4404aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
652dae4404aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
653dae4404aSMatthew G. Knepley       PetscInt       size;
654dae4404aSMatthew G. Knepley 
655dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
656dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
657dae4404aSMatthew G. Knepley     }
6586ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
6596ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
6606ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
661dae4404aSMatthew G. Knepley       const PetscInt *support;
6626ce3c06aSMatthew G. Knepley       PetscInt        size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
663dae4404aSMatthew G. Knepley 
6646ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
6656ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
666dae4404aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
6676ce3c06aSMatthew G. Knepley         if (support[s] < fMax) faceSize += 2;
6686ce3c06aSMatthew G. Knepley         else                   faceSize += 1;
669dae4404aSMatthew G. Knepley       }
6706ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
6716ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
6726ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
6736ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
6746ce3c06aSMatthew G. Knepley 
6756ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
6766ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
6776ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
6786ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
6796ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
6806ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
6816ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
6826ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
6836ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
6846ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
6856ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
6866ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
6876ce3c06aSMatthew G. Knepley         }
6886ce3c06aSMatthew G. Knepley       }
6896ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
6906ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr);
691dae4404aSMatthew G. Knepley     }
692dae4404aSMatthew G. Knepley     break;
6932eabf88fSMatthew G. Knepley   case 6:
6942eabf88fSMatthew G. Knepley     /* Hex 3D */
6952eabf88fSMatthew G. Knepley     /* All cells have 6 faces */
6962eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6972eabf88fSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
6982eabf88fSMatthew G. Knepley         const PetscInt newp = (c - cStart)*8 + r;
6992eabf88fSMatthew G. Knepley 
7002eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
7012eabf88fSMatthew G. Knepley       }
7022eabf88fSMatthew G. Knepley     }
7032eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
7042eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
7052eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
7062eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
7072eabf88fSMatthew G. Knepley         PetscInt       size;
7082eabf88fSMatthew G. Knepley 
7092eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
7102eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
7112eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
7122eabf88fSMatthew G. Knepley       }
7132eabf88fSMatthew G. Knepley     }
7142eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
7152eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
7162eabf88fSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
7172eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
7182eabf88fSMatthew G. Knepley 
7192eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
7202eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
7212eabf88fSMatthew G. Knepley       }
7222eabf88fSMatthew G. Knepley     }
7232eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
7242eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
7252eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
7262eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
7272eabf88fSMatthew G. Knepley         PetscInt       size;
7282eabf88fSMatthew G. Knepley 
7292eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
7302eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
7312eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
7322eabf88fSMatthew G. Knepley       }
7332eabf88fSMatthew G. Knepley     }
7342eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
7352eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
7362eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
7372eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
7382eabf88fSMatthew G. Knepley         PetscInt       size;
7392eabf88fSMatthew G. Knepley 
7402eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
7412eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
7422eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
7432eabf88fSMatthew G. Knepley       }
7442eabf88fSMatthew G. Knepley     }
7452eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
7462eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
7472eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
7482eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
7492eabf88fSMatthew G. Knepley 
7502eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
7512eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
7522eabf88fSMatthew G. Knepley       }
7532eabf88fSMatthew G. Knepley     }
7542eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
7552eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
7562eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
7572eabf88fSMatthew G. Knepley       PetscInt       size;
7582eabf88fSMatthew G. Knepley 
7592eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
7602eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
7612eabf88fSMatthew G. Knepley     }
7622eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
7632eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
7642eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
7652eabf88fSMatthew G. Knepley       PetscInt       size;
7662eabf88fSMatthew G. Knepley 
7672eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
7682eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
7692eabf88fSMatthew G. Knepley     }
7702eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
7712eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
7722eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
7732eabf88fSMatthew G. Knepley       PetscInt       size;
7742eabf88fSMatthew G. Knepley 
7752eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
7762eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
7772eabf88fSMatthew G. Knepley     }
7782eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
7792eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
7802eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
7812eabf88fSMatthew G. Knepley 
7822eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
7832eabf88fSMatthew G. Knepley     }
7842eabf88fSMatthew G. Knepley     break;
78527fcede3SMatthew G. Knepley   case 8:
78627fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
78727fcede3SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
78827fcede3SMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
78927fcede3SMatthew G. Knepley     /* Interior cells have 6 faces */
79027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
79127fcede3SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
79227fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
79327fcede3SMatthew G. Knepley 
79427fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
79527fcede3SMatthew G. Knepley       }
79627fcede3SMatthew G. Knepley     }
79727fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces */
79827fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
79927fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
80027fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
80127fcede3SMatthew G. Knepley 
80227fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
80327fcede3SMatthew G. Knepley       }
80427fcede3SMatthew G. Knepley     }
80527fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
80627fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
80727fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
80827fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
80927fcede3SMatthew G. Knepley         PetscInt       size;
81027fcede3SMatthew G. Knepley 
81127fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
81227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
81327fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
81427fcede3SMatthew G. Knepley       }
81527fcede3SMatthew G. Knepley     }
81627fcede3SMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
81727fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
81827fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
81927fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
82027fcede3SMatthew G. Knepley 
82127fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
82227fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
82327fcede3SMatthew G. Knepley       }
82427fcede3SMatthew G. Knepley     }
82527fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
82627fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
82727fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
82827fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
82927fcede3SMatthew G. Knepley         PetscInt       size;
83027fcede3SMatthew G. Knepley 
83127fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
83227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
83327fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
83427fcede3SMatthew G. Knepley       }
83527fcede3SMatthew G. Knepley     }
83627fcede3SMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
83727fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
83827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
83927fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
84027fcede3SMatthew G. Knepley 
84127fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
84227fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
84327fcede3SMatthew G. Knepley       }
84427fcede3SMatthew G. Knepley     }
84527fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
84627fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
84727fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
84827fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
84927fcede3SMatthew G. Knepley         PetscInt       size;
85027fcede3SMatthew G. Knepley 
85127fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
85227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
85327fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
85427fcede3SMatthew G. Knepley       }
85527fcede3SMatthew G. Knepley     }
85627fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
85727fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
85827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
85927fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
86027fcede3SMatthew G. Knepley         PetscInt       size;
86127fcede3SMatthew G. Knepley 
86227fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
86327fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
86427fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
86527fcede3SMatthew G. Knepley       }
86627fcede3SMatthew G. Knepley     }
86727fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
86827fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
86927fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
87027fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
87127fcede3SMatthew G. Knepley 
87227fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
87327fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
87427fcede3SMatthew G. Knepley       }
87527fcede3SMatthew G. Knepley     }
87627fcede3SMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
87727fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
87827fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
87927fcede3SMatthew G. Knepley       PetscInt       size;
88027fcede3SMatthew G. Knepley 
88127fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
88227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
88327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
88427fcede3SMatthew G. Knepley     }
88527fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
88627fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
88727fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
88827fcede3SMatthew G. Knepley       PetscInt       size;
88927fcede3SMatthew G. Knepley 
89027fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
89127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
89227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
89327fcede3SMatthew G. Knepley     }
89427fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
89527fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
89627fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
89727fcede3SMatthew G. Knepley 
89827fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
89927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
90027fcede3SMatthew G. Knepley     }
90127fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
90227fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
90327fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
90427fcede3SMatthew G. Knepley       PetscInt       size;
90527fcede3SMatthew G. Knepley 
90627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
90727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
90827fcede3SMatthew G. Knepley     }
90927fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
91027fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
91127fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
91227fcede3SMatthew G. Knepley       PetscInt       size;
91327fcede3SMatthew G. Knepley 
91427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
91527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
91627fcede3SMatthew G. Knepley     }
91727fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
91827fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
91927fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
92027fcede3SMatthew G. Knepley       PetscInt       size;
92127fcede3SMatthew G. Knepley 
92227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
92327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
92427fcede3SMatthew G. Knepley     }
92527fcede3SMatthew G. Knepley     /* Interior cell vertices have 6 supports */
92627fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
92727fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
92827fcede3SMatthew G. Knepley 
92927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
93027fcede3SMatthew G. Knepley     }
93127fcede3SMatthew G. Knepley     break;
93275d3a19aSMatthew G. Knepley   default:
93375d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
93475d3a19aSMatthew G. Knepley   }
93575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
93675d3a19aSMatthew G. Knepley }
93775d3a19aSMatthew G. Knepley 
93875d3a19aSMatthew G. Knepley #undef __FUNCT__
93975d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCones"
94086150812SJed Brown static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
94175d3a19aSMatthew G. Knepley {
942b5da9499SMatthew G. Knepley   const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
9436ce3c06aSMatthew G. Knepley   PetscInt        cStart,    cEnd,    cMax,    vStart,    vEnd, vMax, fStart,    fEnd,    fMax,    eStart,    eEnd,    eMax;
9446ce3c06aSMatthew G. Knepley   PetscInt        cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew,    fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
9456ce3c06aSMatthew G. Knepley   PetscInt        depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
94675d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
94775d3a19aSMatthew G. Knepley 
94875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
94975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
95075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
95175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
95275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
95375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
95475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
9553478d7aaSMatthew G. Knepley   if (refiner) {
95675d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
95775d3a19aSMatthew G. Knepley     ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
9583478d7aaSMatthew G. Knepley   }
95975d3a19aSMatthew G. Knepley   switch (refiner) {
9603478d7aaSMatthew G. Knepley   case 0: break;
96175d3a19aSMatthew G. Knepley   case 1:
96275d3a19aSMatthew G. Knepley     /* Simplicial 2D */
96375d3a19aSMatthew G. Knepley     /*
96475d3a19aSMatthew G. Knepley      2
96575d3a19aSMatthew G. Knepley      |\
96675d3a19aSMatthew G. Knepley      | \
96775d3a19aSMatthew G. Knepley      |  \
96875d3a19aSMatthew G. Knepley      |   \
96975d3a19aSMatthew G. Knepley      | C  \
97075d3a19aSMatthew G. Knepley      |     \
97175d3a19aSMatthew G. Knepley      |      \
97275d3a19aSMatthew G. Knepley      2---1---1
97375d3a19aSMatthew G. Knepley      |\  D  / \
97475d3a19aSMatthew G. Knepley      | 2   0   \
97575d3a19aSMatthew G. Knepley      |A \ /  B  \
97675d3a19aSMatthew G. Knepley      0---0-------1
97775d3a19aSMatthew G. Knepley      */
97875d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
97975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
98075d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
98175d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
98275d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
98375d3a19aSMatthew G. Knepley 
98475d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
98575d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
98675d3a19aSMatthew G. Knepley       /* A triangle */
98775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
98875d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
98975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
99075d3a19aSMatthew G. Knepley       orntNew[1] = -2;
99175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
99275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
99375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
99475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
99575d3a19aSMatthew G. Knepley #if 1
99675d3a19aSMatthew 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);
99775d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
99875d3a19aSMatthew 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);
99975d3a19aSMatthew G. Knepley       }
100075d3a19aSMatthew G. Knepley #endif
100175d3a19aSMatthew G. Knepley       /* B triangle */
100275d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
100375d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
100475d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
100575d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
100675d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
100775d3a19aSMatthew G. Knepley       orntNew[2] = -2;
100875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
100975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
101075d3a19aSMatthew G. Knepley #if 1
101175d3a19aSMatthew 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);
101275d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
101375d3a19aSMatthew 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);
101475d3a19aSMatthew G. Knepley       }
101575d3a19aSMatthew G. Knepley #endif
101675d3a19aSMatthew G. Knepley       /* C triangle */
101775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
101875d3a19aSMatthew G. Knepley       orntNew[0] = -2;
101975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
102075d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
102175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
102275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
102375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
102475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
102575d3a19aSMatthew G. Knepley #if 1
102675d3a19aSMatthew 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);
102775d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
102875d3a19aSMatthew 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);
102975d3a19aSMatthew G. Knepley       }
103075d3a19aSMatthew G. Knepley #endif
103175d3a19aSMatthew G. Knepley       /* D triangle */
103275d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
103375d3a19aSMatthew G. Knepley       orntNew[0] = 0;
103475d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
103575d3a19aSMatthew G. Knepley       orntNew[1] = 0;
103675d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
103775d3a19aSMatthew G. Knepley       orntNew[2] = 0;
103875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
103975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
104075d3a19aSMatthew G. Knepley #if 1
104175d3a19aSMatthew 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);
104275d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
104375d3a19aSMatthew 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);
104475d3a19aSMatthew G. Knepley       }
104575d3a19aSMatthew G. Knepley #endif
104675d3a19aSMatthew G. Knepley     }
104775d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
104875d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1049785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
105075d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
105175d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
105275d3a19aSMatthew G. Knepley 
105375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
105475d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1055297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
105675d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
105775d3a19aSMatthew G. Knepley 
105875d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
105975d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
106075d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
106175d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
106275d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
106375d3a19aSMatthew G. Knepley #if 1
106475d3a19aSMatthew 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);
106575d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
106675d3a19aSMatthew 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);
106775d3a19aSMatthew G. Knepley         }
106875d3a19aSMatthew G. Knepley #endif
106975d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
107075d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
107175d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
107275d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
107375d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1074297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
107575d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
107675d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
107775d3a19aSMatthew G. Knepley           }
1078297d2bf4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
107975d3a19aSMatthew G. Knepley         }
108075d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
108175d3a19aSMatthew G. Knepley #if 1
108275d3a19aSMatthew 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);
108375d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
108475d3a19aSMatthew 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);
108575d3a19aSMatthew G. Knepley         }
108675d3a19aSMatthew G. Knepley #endif
108775d3a19aSMatthew G. Knepley       }
108875d3a19aSMatthew G. Knepley     }
108975d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
109075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
109175d3a19aSMatthew G. Knepley       const PetscInt *cone;
109275d3a19aSMatthew G. Knepley 
109375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
109475d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
109575d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
109675d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
109775d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
109875d3a19aSMatthew G. Knepley 
109975d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
110075d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
110175d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
110275d3a19aSMatthew G. Knepley #if 1
110375d3a19aSMatthew 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);
110475d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
110575d3a19aSMatthew 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);
110675d3a19aSMatthew G. Knepley         }
110775d3a19aSMatthew G. Knepley #endif
110875d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
110975d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
111075d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
111175d3a19aSMatthew G. Knepley #if 1
111275d3a19aSMatthew 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);
111375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
111475d3a19aSMatthew 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);
111575d3a19aSMatthew G. Knepley         }
111675d3a19aSMatthew G. Knepley #endif
111775d3a19aSMatthew G. Knepley       }
111875d3a19aSMatthew G. Knepley     }
111975d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
112075d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
112175d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
112275d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
112375d3a19aSMatthew G. Knepley       PetscInt        size, s;
112475d3a19aSMatthew G. Knepley 
112575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
112675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
112775d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
112875d3a19aSMatthew G. Knepley         PetscInt r = 0;
112975d3a19aSMatthew G. Knepley 
113075d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
113175d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
113275d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
113375d3a19aSMatthew G. Knepley       }
113475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
113575d3a19aSMatthew G. Knepley #if 1
113675d3a19aSMatthew 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);
113775d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
113875d3a19aSMatthew 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);
113975d3a19aSMatthew G. Knepley       }
114075d3a19aSMatthew G. Knepley #endif
114175d3a19aSMatthew G. Knepley     }
114275d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
114375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
114475d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
114575d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
114675d3a19aSMatthew G. Knepley       PetscInt        size, s;
114775d3a19aSMatthew G. Knepley 
114875d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
114975d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
115075d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
115175d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
115275d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
115375d3a19aSMatthew G. Knepley         PetscInt r = 0;
115475d3a19aSMatthew G. Knepley 
115575d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
115675d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
115775d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
115875d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
115975d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
116075d3a19aSMatthew G. Knepley       }
116175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
116275d3a19aSMatthew G. Knepley #if 1
116375d3a19aSMatthew 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);
116475d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
116575d3a19aSMatthew 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);
116675d3a19aSMatthew G. Knepley       }
116775d3a19aSMatthew G. Knepley #endif
116875d3a19aSMatthew G. Knepley     }
116975d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
117075d3a19aSMatthew G. Knepley     break;
117175d3a19aSMatthew G. Knepley   case 2:
117275d3a19aSMatthew G. Knepley     /* Hex 2D */
117375d3a19aSMatthew G. Knepley     /*
117475d3a19aSMatthew G. Knepley      3---------2---------2
117575d3a19aSMatthew G. Knepley      |         |         |
117675d3a19aSMatthew G. Knepley      |    D    2    C    |
117775d3a19aSMatthew G. Knepley      |         |         |
117875d3a19aSMatthew G. Knepley      3----3----0----1----1
117975d3a19aSMatthew G. Knepley      |         |         |
118075d3a19aSMatthew G. Knepley      |    A    0    B    |
118175d3a19aSMatthew G. Knepley      |         |         |
118275d3a19aSMatthew G. Knepley      0---------0---------1
118375d3a19aSMatthew G. Knepley      */
118475d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
118575d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
118675d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
118775d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
118875d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
118975d3a19aSMatthew G. Knepley 
119075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
119175d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
119275d3a19aSMatthew G. Knepley       /* A quad */
119375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
119475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
119575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
119675d3a19aSMatthew G. Knepley       orntNew[1] = 0;
119775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
119875d3a19aSMatthew G. Knepley       orntNew[2] = -2;
119975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
120075d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
120175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
120275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
120375d3a19aSMatthew G. Knepley #if 1
120475d3a19aSMatthew 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);
120575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
120675d3a19aSMatthew 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);
120775d3a19aSMatthew G. Knepley       }
120875d3a19aSMatthew G. Knepley #endif
120975d3a19aSMatthew G. Knepley       /* B quad */
121075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
121175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
121275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
121375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
121475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
121575d3a19aSMatthew G. Knepley       orntNew[2] = 0;
121675d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
121775d3a19aSMatthew G. Knepley       orntNew[3] = -2;
121875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
121975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
122075d3a19aSMatthew G. Knepley #if 1
122175d3a19aSMatthew 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);
122275d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
122375d3a19aSMatthew 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);
122475d3a19aSMatthew G. Knepley       }
122575d3a19aSMatthew G. Knepley #endif
122675d3a19aSMatthew G. Knepley       /* C quad */
122775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
122875d3a19aSMatthew G. Knepley       orntNew[0] = -2;
122975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
123075d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
123175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
123275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
123375d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
123475d3a19aSMatthew G. Knepley       orntNew[3] = 0;
123575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
123675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
123775d3a19aSMatthew G. Knepley #if 1
123875d3a19aSMatthew 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);
123975d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
124075d3a19aSMatthew 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);
124175d3a19aSMatthew G. Knepley       }
124275d3a19aSMatthew G. Knepley #endif
124375d3a19aSMatthew G. Knepley       /* D quad */
124475d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
124575d3a19aSMatthew G. Knepley       orntNew[0] = 0;
124675d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
124775d3a19aSMatthew G. Knepley       orntNew[1] = -2;
124875d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
124975d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
125075d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
125175d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
125275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
125375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
125475d3a19aSMatthew G. Knepley #if 1
125575d3a19aSMatthew 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);
125675d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
125775d3a19aSMatthew 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);
125875d3a19aSMatthew G. Knepley       }
125975d3a19aSMatthew G. Knepley #endif
126075d3a19aSMatthew G. Knepley     }
126175d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
126275d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1263785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
126475d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
126575d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
126675d3a19aSMatthew G. Knepley 
126775d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
126875d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1269455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
127075d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
127175d3a19aSMatthew G. Knepley 
127275d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
127375d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
127475d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
127575d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
127675d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
127775d3a19aSMatthew G. Knepley #if 1
127875d3a19aSMatthew 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);
127975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
128075d3a19aSMatthew 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);
128175d3a19aSMatthew G. Knepley         }
128275d3a19aSMatthew G. Knepley #endif
128375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
128475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
128575d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
128675d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
128775d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1288455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
128975d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
129075d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
129175d3a19aSMatthew G. Knepley           }
1292455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
129375d3a19aSMatthew G. Knepley         }
129475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
129575d3a19aSMatthew G. Knepley #if 1
129675d3a19aSMatthew 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);
129775d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
129875d3a19aSMatthew 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);
129975d3a19aSMatthew G. Knepley         }
130075d3a19aSMatthew G. Knepley #endif
130175d3a19aSMatthew G. Knepley       }
130275d3a19aSMatthew G. Knepley     }
130375d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
130475d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
130575d3a19aSMatthew G. Knepley       const PetscInt *cone;
130675d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
130775d3a19aSMatthew G. Knepley 
130875d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
130975d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
131075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
131175d3a19aSMatthew G. Knepley 
131275d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
131375d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
131475d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
131575d3a19aSMatthew G. Knepley #if 1
131675d3a19aSMatthew 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);
131775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
131875d3a19aSMatthew 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);
131975d3a19aSMatthew G. Knepley         }
132075d3a19aSMatthew G. Knepley #endif
132175d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
132275d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
132375d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
132475d3a19aSMatthew G. Knepley #if 1
132575d3a19aSMatthew 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);
132675d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
132775d3a19aSMatthew 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);
132875d3a19aSMatthew G. Knepley         }
132975d3a19aSMatthew G. Knepley #endif
133075d3a19aSMatthew G. Knepley       }
133175d3a19aSMatthew G. Knepley     }
133275d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
133375d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
133475d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
133575d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
133675d3a19aSMatthew G. Knepley       PetscInt        size, s;
133775d3a19aSMatthew G. Knepley 
133875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
133975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
134075d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
134175d3a19aSMatthew G. Knepley         PetscInt r = 0;
134275d3a19aSMatthew G. Knepley 
134375d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
134475d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
134575d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
134675d3a19aSMatthew G. Knepley       }
134775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
134875d3a19aSMatthew G. Knepley #if 1
134975d3a19aSMatthew 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);
135075d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
135175d3a19aSMatthew 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);
135275d3a19aSMatthew G. Knepley       }
135375d3a19aSMatthew G. Knepley #endif
135475d3a19aSMatthew G. Knepley     }
135575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
135675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
135775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
135875d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
135975d3a19aSMatthew G. Knepley       PetscInt        size, s;
136075d3a19aSMatthew G. Knepley 
136175d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
136275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
136375d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
136475d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
136575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
136675d3a19aSMatthew G. Knepley         PetscInt r = 0;
136775d3a19aSMatthew G. Knepley 
136875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
136975d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
137075d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
137175d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
137275d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
137375d3a19aSMatthew G. Knepley       }
137475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
137575d3a19aSMatthew G. Knepley #if 1
137675d3a19aSMatthew 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);
137775d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
137875d3a19aSMatthew 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);
137975d3a19aSMatthew G. Knepley       }
138075d3a19aSMatthew G. Knepley #endif
138175d3a19aSMatthew G. Knepley     }
138275d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
138375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
138475d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
138575d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
138675d3a19aSMatthew G. Knepley 
138775d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
138875d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
138975d3a19aSMatthew G. Knepley       }
139075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
139175d3a19aSMatthew G. Knepley     }
1392da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
139375d3a19aSMatthew G. Knepley     break;
139475d3a19aSMatthew G. Knepley   case 3:
139575d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
139675d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
139775d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
139875d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
139975d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
140075d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
140175d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
140275d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
140375d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
140475d3a19aSMatthew G. Knepley 
140575d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
140675d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
140775d3a19aSMatthew G. Knepley       /* A triangle */
140875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
140975d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
141075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
141175d3a19aSMatthew G. Knepley       orntNew[1] = -2;
141275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
141375d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
141475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
141575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
141675d3a19aSMatthew G. Knepley #if 1
141775d3a19aSMatthew 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);
141875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
141975d3a19aSMatthew 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);
142075d3a19aSMatthew G. Knepley       }
142175d3a19aSMatthew G. Knepley #endif
142275d3a19aSMatthew G. Knepley       /* B triangle */
142375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
142475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
142575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
142675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
142775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
142875d3a19aSMatthew G. Knepley       orntNew[2] = -2;
142975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
143075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
143175d3a19aSMatthew G. Knepley #if 1
143275d3a19aSMatthew 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);
143375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
143475d3a19aSMatthew 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);
143575d3a19aSMatthew G. Knepley       }
143675d3a19aSMatthew G. Knepley #endif
143775d3a19aSMatthew G. Knepley       /* C triangle */
143875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
143975d3a19aSMatthew G. Knepley       orntNew[0] = -2;
144075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
144175d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
144275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
144375d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
144475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
144575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
144675d3a19aSMatthew G. Knepley #if 1
144775d3a19aSMatthew 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);
144875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
144975d3a19aSMatthew 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);
145075d3a19aSMatthew G. Knepley       }
145175d3a19aSMatthew G. Knepley #endif
145275d3a19aSMatthew G. Knepley       /* D triangle */
145375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
145475d3a19aSMatthew G. Knepley       orntNew[0] = 0;
145575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
145675d3a19aSMatthew G. Knepley       orntNew[1] = 0;
145775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
145875d3a19aSMatthew G. Knepley       orntNew[2] = 0;
145975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
146075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
146175d3a19aSMatthew G. Knepley #if 1
146275d3a19aSMatthew 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);
146375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
146475d3a19aSMatthew 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);
146575d3a19aSMatthew G. Knepley       }
146675d3a19aSMatthew G. Knepley #endif
146775d3a19aSMatthew G. Knepley     }
146875d3a19aSMatthew G. Knepley     /*
146975d3a19aSMatthew G. Knepley      2----3----3
147075d3a19aSMatthew G. Knepley      |         |
147175d3a19aSMatthew G. Knepley      |    B    |
147275d3a19aSMatthew G. Knepley      |         |
147375d3a19aSMatthew G. Knepley      0----4--- 1
147475d3a19aSMatthew G. Knepley      |         |
147575d3a19aSMatthew G. Knepley      |    A    |
147675d3a19aSMatthew G. Knepley      |         |
147775d3a19aSMatthew G. Knepley      0----2----1
147875d3a19aSMatthew G. Knepley      */
147975d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
148075d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
148175d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
148275d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
148375d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
148475d3a19aSMatthew G. Knepley 
148575d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
148675d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
148775d3a19aSMatthew G. Knepley       /* A quad */
148875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
148975d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
149075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
149175d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
149275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2] - fMax);
149375d3a19aSMatthew G. Knepley       orntNew[2] = 0;
149475d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
149575d3a19aSMatthew G. Knepley       orntNew[3] = 0;
149675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
149775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
149875d3a19aSMatthew G. Knepley #if 1
149975d3a19aSMatthew 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);
150075d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
150175d3a19aSMatthew 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);
150275d3a19aSMatthew G. Knepley       }
150375d3a19aSMatthew G. Knepley #endif
150475d3a19aSMatthew G. Knepley       /* B quad */
150575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
150675d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
150775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
150875d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
150975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
151075d3a19aSMatthew G. Knepley       orntNew[2] = 0;
151175d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3] - fMax);
151275d3a19aSMatthew G. Knepley       orntNew[3] = 0;
151375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
151475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
151575d3a19aSMatthew G. Knepley #if 1
151675d3a19aSMatthew 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);
151775d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
151875d3a19aSMatthew 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);
151975d3a19aSMatthew G. Knepley       }
152075d3a19aSMatthew G. Knepley #endif
152175d3a19aSMatthew G. Knepley     }
152275d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
152375d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1524785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
152575d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
152675d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
152775d3a19aSMatthew G. Knepley 
152875d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
152975d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1530297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
153175d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
153275d3a19aSMatthew G. Knepley 
153375d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
153475d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
153575d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
153675d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
153775d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
153875d3a19aSMatthew G. Knepley #if 1
153975d3a19aSMatthew 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);
154075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
154175d3a19aSMatthew 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);
154275d3a19aSMatthew G. Knepley         }
154375d3a19aSMatthew G. Knepley #endif
154475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
154575d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
154675d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
154775d3a19aSMatthew G. Knepley           if (support[s] >= cMax) {
154875d3a19aSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
154975d3a19aSMatthew G. Knepley           } else {
155075d3a19aSMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
155175d3a19aSMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1552297d2bf4SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
155375d3a19aSMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
155475d3a19aSMatthew G. Knepley               if (cone[c] == f) break;
155575d3a19aSMatthew G. Knepley             }
1556297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
155775d3a19aSMatthew G. Knepley           }
155875d3a19aSMatthew G. Knepley         }
155975d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
156075d3a19aSMatthew G. Knepley #if 1
156175d3a19aSMatthew 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);
156275d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
156375d3a19aSMatthew 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);
156475d3a19aSMatthew G. Knepley         }
156575d3a19aSMatthew G. Knepley #endif
156675d3a19aSMatthew G. Knepley       }
156775d3a19aSMatthew G. Knepley     }
156875d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
156975d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
157075d3a19aSMatthew G. Knepley       const PetscInt *cone;
157175d3a19aSMatthew G. Knepley 
157275d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
157375d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
157475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
157575d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
157675d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
157775d3a19aSMatthew G. Knepley 
157875d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
157975d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
158075d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
158175d3a19aSMatthew G. Knepley #if 1
158275d3a19aSMatthew 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);
158375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
158475d3a19aSMatthew 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);
158575d3a19aSMatthew G. Knepley         }
158675d3a19aSMatthew G. Knepley #endif
158775d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
158875d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
158975d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
159075d3a19aSMatthew G. Knepley #if 1
159175d3a19aSMatthew 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);
159275d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
159375d3a19aSMatthew 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);
159475d3a19aSMatthew G. Knepley         }
159575d3a19aSMatthew G. Knepley #endif
159675d3a19aSMatthew G. Knepley       }
159775d3a19aSMatthew G. Knepley     }
159875d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
159975d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
160075d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
160175d3a19aSMatthew G. Knepley       const PetscInt *cone;
160275d3a19aSMatthew G. Knepley       const PetscInt *support;
160375d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
160475d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
160575d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
160675d3a19aSMatthew G. Knepley 
160775d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
160875d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
160975d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
161075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
161175d3a19aSMatthew G. Knepley #if 1
161275d3a19aSMatthew 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);
161375d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
161475d3a19aSMatthew 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);
161575d3a19aSMatthew G. Knepley       }
161675d3a19aSMatthew G. Knepley #endif
161775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
161875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
161975d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
162075d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
162175d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
162275d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
162375d3a19aSMatthew G. Knepley         }
162475d3a19aSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
162575d3a19aSMatthew G. Knepley       }
162675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
162775d3a19aSMatthew G. Knepley #if 1
162875d3a19aSMatthew 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);
162975d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
163075d3a19aSMatthew 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);
163175d3a19aSMatthew G. Knepley       }
163275d3a19aSMatthew G. Knepley #endif
163375d3a19aSMatthew G. Knepley     }
163475d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
163575d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
163675d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
163775d3a19aSMatthew G. Knepley       const PetscInt *cone;
163875d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
163975d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
164075d3a19aSMatthew G. Knepley 
164175d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
164275d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
164375d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
164475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
164575d3a19aSMatthew G. Knepley #if 1
164675d3a19aSMatthew 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);
164775d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
164875d3a19aSMatthew 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);
164975d3a19aSMatthew G. Knepley       }
165075d3a19aSMatthew G. Knepley #endif
165175d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
165275d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
165375d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
165775d3a19aSMatthew 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);
165875d3a19aSMatthew G. Knepley       }
165975d3a19aSMatthew G. Knepley #endif
166075d3a19aSMatthew G. Knepley     }
166175d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
166275d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
166375d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
166475d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
166575d3a19aSMatthew G. Knepley       PetscInt        size, s;
166675d3a19aSMatthew G. Knepley 
166775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
166875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
166975d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
167075d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
167175d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
167275d3a19aSMatthew G. Knepley         } else {
167375d3a19aSMatthew G. Knepley           PetscInt r = 0;
167475d3a19aSMatthew G. Knepley 
167575d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
167675d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
167775d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
167875d3a19aSMatthew G. Knepley         }
167975d3a19aSMatthew G. Knepley       }
168075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
168175d3a19aSMatthew G. Knepley #if 1
168275d3a19aSMatthew 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);
168375d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
168475d3a19aSMatthew 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);
168575d3a19aSMatthew G. Knepley       }
168675d3a19aSMatthew G. Knepley #endif
168775d3a19aSMatthew G. Knepley     }
168875d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
168975d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
169075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
169175d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
169275d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
169375d3a19aSMatthew G. Knepley 
169475d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
169575d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
169675d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
169775d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
169875d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
169975d3a19aSMatthew G. Knepley         PetscInt r = 0;
170075d3a19aSMatthew G. Knepley 
170175d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
170275d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
170375d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
170475d3a19aSMatthew G. Knepley 
170575d3a19aSMatthew G. Knepley           newSize += 1;
170675d3a19aSMatthew G. Knepley         } else {
170775d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
170875d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
170975d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
171075d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
171175d3a19aSMatthew G. Knepley 
171275d3a19aSMatthew G. Knepley           newSize += 2;
171375d3a19aSMatthew G. Knepley         }
171475d3a19aSMatthew G. Knepley       }
171575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
171675d3a19aSMatthew G. Knepley #if 1
171775d3a19aSMatthew 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);
171875d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
171975d3a19aSMatthew 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);
172075d3a19aSMatthew G. Knepley       }
172175d3a19aSMatthew G. Knepley #endif
172275d3a19aSMatthew G. Knepley     }
172375d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
172475d3a19aSMatthew G. Knepley     break;
1725b5da9499SMatthew G. Knepley   case 5:
1726b5da9499SMatthew G. Knepley     /* Simplicial 3D */
1727b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
1728b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
1729b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
1730b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
1731b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
1732b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1733b5da9499SMatthew G. Knepley 
1734b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1735b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1736b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
1737518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
1738b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1739518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
1740b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1741518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
1742b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1743b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
1744b5da9499SMatthew G. Knepley       orntNew[3] = 0;
1745b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1746b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1747b5da9499SMatthew G. Knepley #if 1
1748b5da9499SMatthew 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);
1749b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1750b5da9499SMatthew 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);
1751b5da9499SMatthew G. Knepley       }
1752b5da9499SMatthew G. Knepley #endif
1753b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
1754518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
1755b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1756518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
1757b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1758b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
1759b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1760518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
1761b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1762b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1763b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1764b5da9499SMatthew G. Knepley #if 1
1765b5da9499SMatthew 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);
1766b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1767b5da9499SMatthew 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);
1768b5da9499SMatthew G. Knepley       }
1769b5da9499SMatthew G. Knepley #endif
1770b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
1771518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
1772b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1773b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
1774b5da9499SMatthew G. Knepley       orntNew[1] = 0;
1775518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
1776b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1777518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
1778b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1779b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1780b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1781b5da9499SMatthew G. Knepley #if 1
1782b5da9499SMatthew 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);
1783b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1784b5da9499SMatthew 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);
1785b5da9499SMatthew G. Knepley       }
1786b5da9499SMatthew G. Knepley #endif
1787b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
1788b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
1789b5da9499SMatthew G. Knepley       orntNew[0] = 0;
1790518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
1791b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1792518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
1793b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1794518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
1795b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1796b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1797b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1798b5da9499SMatthew G. Knepley #if 1
1799b5da9499SMatthew 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);
1800b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1801b5da9499SMatthew 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);
1802b5da9499SMatthew G. Knepley       }
1803b5da9499SMatthew G. Knepley #endif
1804b5da9499SMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
1805b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
1806b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1807fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
1808db2c6090SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
1809fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
1810fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
1811fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
1812fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
1813b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
1814b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
1815b5da9499SMatthew G. Knepley #if 1
1816b5da9499SMatthew 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);
1817b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1818b5da9499SMatthew 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);
1819b5da9499SMatthew G. Knepley       }
1820b5da9499SMatthew G. Knepley #endif
1821b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
1822b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
1823b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1824fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
1825fac4ab25SMatthew G. Knepley       orntNew[1] = 1;
1826fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
1827b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1828fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
1829db2c6090SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
1830b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
1831b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
1832b5da9499SMatthew G. Knepley #if 1
1833b5da9499SMatthew 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);
1834b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1835b5da9499SMatthew 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);
1836b5da9499SMatthew G. Knepley       }
1837b5da9499SMatthew G. Knepley #endif
1838b5da9499SMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
1839b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
1840b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1841fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
1842db2c6090SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
1843fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
1844fac4ab25SMatthew G. Knepley       orntNew[2] = -3;
1845fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
1846fac4ab25SMatthew G. Knepley       orntNew[3] = -2;
1847b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
1848b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
1849b5da9499SMatthew G. Knepley #if 1
1850b5da9499SMatthew 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);
1851b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1852b5da9499SMatthew 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);
1853b5da9499SMatthew G. Knepley       }
1854b5da9499SMatthew G. Knepley #endif
1855b5da9499SMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
1856b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
1857b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1858fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
1859b5da9499SMatthew G. Knepley       orntNew[1] = -3;
1860fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
1861db2c6090SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
1862fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
1863fac4ab25SMatthew G. Knepley       orntNew[3] = -3;
1864b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
1865b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
1866b5da9499SMatthew G. Knepley #if 1
1867b5da9499SMatthew 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);
1868b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1869b5da9499SMatthew 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);
1870b5da9499SMatthew G. Knepley       }
1871b5da9499SMatthew G. Knepley #endif
1872b5da9499SMatthew G. Knepley     }
1873b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
1874b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1875785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
1876b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
1877b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
1878b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
1879b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
1880b5da9499SMatthew G. Knepley 
1881b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
1882b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
1883b5da9499SMatthew G. Knepley       /* A triangle */
1884b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
1885b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1886b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
1887b5da9499SMatthew G. Knepley       orntNew[1] = -2;
1888b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
1889b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1890b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1891b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1892b5da9499SMatthew G. Knepley #if 1
1893b5da9499SMatthew 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);
1894b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1895b5da9499SMatthew 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);
1896b5da9499SMatthew G. Knepley       }
1897b5da9499SMatthew G. Knepley #endif
1898b5da9499SMatthew G. Knepley       /* B triangle */
1899b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
1900b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1901b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
1902b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1903b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
1904b5da9499SMatthew G. Knepley       orntNew[2] = -2;
1905b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1906b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1907b5da9499SMatthew G. Knepley #if 1
1908b5da9499SMatthew 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);
1909b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1910b5da9499SMatthew 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);
1911b5da9499SMatthew G. Knepley       }
1912b5da9499SMatthew G. Knepley #endif
1913b5da9499SMatthew G. Knepley       /* C triangle */
1914b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
1915b5da9499SMatthew G. Knepley       orntNew[0] = -2;
1916b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
1917b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1918b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
1919b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1920b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1921b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1922b5da9499SMatthew G. Knepley #if 1
1923b5da9499SMatthew 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);
1924b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1925b5da9499SMatthew 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);
1926b5da9499SMatthew G. Knepley       }
1927b5da9499SMatthew G. Knepley #endif
1928b5da9499SMatthew G. Knepley       /* D triangle */
1929b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
1930b5da9499SMatthew G. Knepley       orntNew[0] = 0;
1931b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
1932b5da9499SMatthew G. Knepley       orntNew[1] = 0;
1933b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
1934b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1935b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1936b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1937b5da9499SMatthew G. Knepley #if 1
1938b5da9499SMatthew 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);
1939b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1940b5da9499SMatthew 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);
1941b5da9499SMatthew G. Knepley       }
1942b5da9499SMatthew G. Knepley #endif
1943b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
1944b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1945b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
1946b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
1947219f7b90SMatthew G. Knepley           PetscInt subf;
1948b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
1949b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1950b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1951b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
1952b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
1953b5da9499SMatthew G. Knepley           }
1954219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
1955219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
1956b5da9499SMatthew G. Knepley         }
1957b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
1958b5da9499SMatthew G. Knepley #if 1
19599ddff745SMatthew 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);
1960b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
1961b5da9499SMatthew 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);
1962b5da9499SMatthew G. Knepley         }
1963b5da9499SMatthew G. Knepley #endif
1964b5da9499SMatthew G. Knepley       }
1965b5da9499SMatthew G. Knepley     }
1966b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
1967b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
1968b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
1969b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
1970b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
1971b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
1972b5da9499SMatthew G. Knepley 
1973b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1974b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1975b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
19764bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
1977b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
19784bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
1979b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
19804bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
1981b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
1982b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1983b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1984b5da9499SMatthew G. Knepley #if 1
1985b5da9499SMatthew 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);
1986b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1987b5da9499SMatthew 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);
1988b5da9499SMatthew G. Knepley       }
1989b5da9499SMatthew G. Knepley #endif
1990b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
1991b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
1992b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1993b5da9499SMatthew G. Knepley #if 1
1994b5da9499SMatthew 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);
1995b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1996b5da9499SMatthew 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);
1997b5da9499SMatthew G. Knepley       }
1998b5da9499SMatthew G. Knepley #endif
1999b5da9499SMatthew G. Knepley       ++newp;
2000b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
20014bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2002b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
20034bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
2004b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
20054bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2006b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2007b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2008b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2009b5da9499SMatthew G. Knepley #if 1
20104bb260e2SMatthew 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);
2011b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2012b5da9499SMatthew 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);
2013b5da9499SMatthew G. Knepley       }
2014b5da9499SMatthew G. Knepley #endif
2015b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
2016b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
2017b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2018b5da9499SMatthew G. Knepley #if 1
2019b5da9499SMatthew 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);
2020b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2021b5da9499SMatthew 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);
2022b5da9499SMatthew G. Knepley       }
2023b5da9499SMatthew G. Knepley #endif
2024b5da9499SMatthew G. Knepley       ++newp;
2025b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
20264bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
2027b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
20284bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2029b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
20304bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
2031b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
2032b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2033b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2034b5da9499SMatthew G. Knepley #if 1
2035b5da9499SMatthew 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);
2036b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2037b5da9499SMatthew 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);
2038b5da9499SMatthew G. Knepley       }
2039b5da9499SMatthew G. Knepley #endif
2040b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
2041b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2042b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2043b5da9499SMatthew G. Knepley #if 1
2044b5da9499SMatthew 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);
2045b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2046b5da9499SMatthew 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);
2047b5da9499SMatthew G. Knepley       }
2048b5da9499SMatthew G. Knepley #endif
2049b5da9499SMatthew G. Knepley       ++newp;
2050b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
20514bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
2052b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
20534bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2054b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
20554bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2056b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2057b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2058b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2059b5da9499SMatthew G. Knepley #if 1
2060b5da9499SMatthew 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);
2061b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2062b5da9499SMatthew 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);
2063b5da9499SMatthew G. Knepley       }
2064b5da9499SMatthew G. Knepley #endif
2065b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
2066b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2067b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2068b5da9499SMatthew G. Knepley #if 1
2069b5da9499SMatthew 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);
2070b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2071b5da9499SMatthew 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);
2072b5da9499SMatthew G. Knepley       }
2073b5da9499SMatthew G. Knepley #endif
2074b5da9499SMatthew G. Knepley       ++newp;
2075b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
20764bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2077b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
2078b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
20794bb260e2SMatthew G. Knepley       orntNew[1] = -2;
20804bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2081b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2082b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2083b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2084b5da9499SMatthew G. Knepley #if 1
2085b5da9499SMatthew 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);
2086b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2087b5da9499SMatthew 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);
2088b5da9499SMatthew G. Knepley       }
2089b5da9499SMatthew G. Knepley #endif
2090b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2091b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2092b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2093b5da9499SMatthew G. Knepley #if 1
2094b5da9499SMatthew 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);
2095b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2096b5da9499SMatthew 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);
2097b5da9499SMatthew G. Knepley       }
2098b5da9499SMatthew G. Knepley #endif
2099b5da9499SMatthew G. Knepley       ++newp;
2100b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
21014bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2102b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2103b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
21044bb260e2SMatthew G. Knepley       orntNew[1] = 0;
21054bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
21062baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
2107b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2108b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2109b5da9499SMatthew G. Knepley #if 1
2110b5da9499SMatthew 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);
2111b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2112b5da9499SMatthew 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);
2113b5da9499SMatthew G. Knepley       }
2114b5da9499SMatthew G. Knepley #endif
2115b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2116b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2117b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2118b5da9499SMatthew G. Knepley #if 1
2119b5da9499SMatthew 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);
2120b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2121b5da9499SMatthew 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);
2122b5da9499SMatthew G. Knepley       }
2123b5da9499SMatthew G. Knepley #endif
2124b5da9499SMatthew G. Knepley       ++newp;
2125b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
21264bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2127b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
2128b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2129fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
21304bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2131b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
2132b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2133b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2134b5da9499SMatthew G. Knepley #if 1
2135b5da9499SMatthew 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);
2136b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2137b5da9499SMatthew 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);
2138b5da9499SMatthew G. Knepley       }
2139b5da9499SMatthew G. Knepley #endif
2140b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2141b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2142b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2143b5da9499SMatthew G. Knepley #if 1
2144b5da9499SMatthew 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);
2145b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2146b5da9499SMatthew 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);
2147b5da9499SMatthew G. Knepley       }
2148b5da9499SMatthew G. Knepley #endif
2149b5da9499SMatthew G. Knepley       ++newp;
2150b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
21514bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2152b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
21534bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2154b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
2155b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
21564bb260e2SMatthew G. Knepley       orntNew[2] = -2;
2157b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2158b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2159b5da9499SMatthew G. Knepley #if 1
2160b5da9499SMatthew 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);
2161b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2162b5da9499SMatthew 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);
2163b5da9499SMatthew G. Knepley       }
2164b5da9499SMatthew G. Knepley #endif
2165b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2166b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2167b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2168b5da9499SMatthew G. Knepley #if 1
2169b5da9499SMatthew 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);
2170b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2171b5da9499SMatthew 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);
2172b5da9499SMatthew G. Knepley       }
2173b5da9499SMatthew G. Knepley #endif
2174b5da9499SMatthew G. Knepley       ++newp;
2175b5da9499SMatthew G. Knepley     }
2176b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
2177b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2178b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
2179b5da9499SMatthew G. Knepley 
2180b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2181b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
2182b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2183b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2184b5da9499SMatthew G. Knepley 
2185b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
2186b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2187b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2188b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2189b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2190b5da9499SMatthew G. Knepley #if 1
2191b5da9499SMatthew 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);
2192b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2193b5da9499SMatthew 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);
2194b5da9499SMatthew G. Knepley         }
2195b5da9499SMatthew G. Knepley #endif
2196b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
2197b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2198b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2199b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2200b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2201b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2202b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2203b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
2204b5da9499SMatthew G. Knepley           }
2205b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
2206b5da9499SMatthew G. Knepley         }
2207b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2208b5da9499SMatthew G. Knepley #if 1
2209b5da9499SMatthew 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);
2210b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2211b5da9499SMatthew 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);
2212b5da9499SMatthew G. Knepley         }
2213b5da9499SMatthew G. Knepley #endif
2214b5da9499SMatthew G. Knepley       }
2215b5da9499SMatthew G. Knepley     }
221686f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
2217b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2218b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2219b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
2220b5da9499SMatthew G. Knepley 
2221b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2222b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2223b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
2224b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
2225b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
2226b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
2227b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
2228b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
2229b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
2230b5da9499SMatthew G. Knepley 
2231b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2232b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
2233b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
2234b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2235b5da9499SMatthew G. Knepley #if 1
2236b5da9499SMatthew 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);
2237b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2238b5da9499SMatthew 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);
2239b5da9499SMatthew G. Knepley         }
2240b5da9499SMatthew G. Knepley #endif
2241b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
2242b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
2243b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2244b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2245b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2246b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2247b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
224886f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
22499ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
2250b5da9499SMatthew G. Knepley           if (er == eint[c]) {
2251b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
2252b5da9499SMatthew G. Knepley           } else {
2253b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
2254b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
2255b5da9499SMatthew G. Knepley           }
2256b5da9499SMatthew G. Knepley         }
2257b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2258b5da9499SMatthew G. Knepley #if 1
2259b5da9499SMatthew 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);
2260b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
2261b5da9499SMatthew 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);
2262b5da9499SMatthew G. Knepley         }
2263b5da9499SMatthew G. Knepley #endif
2264b5da9499SMatthew G. Knepley       }
2265b5da9499SMatthew G. Knepley     }
2266b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
2267b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2268b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2269b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
22704a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
2271b5da9499SMatthew G. Knepley 
2272b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2273b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2274b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
227542525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
2276b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2277b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
227842525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
2279b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2280b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2281b5da9499SMatthew G. Knepley #if 1
2282b5da9499SMatthew 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);
2283b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2284b5da9499SMatthew 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);
2285b5da9499SMatthew G. Knepley       }
2286b5da9499SMatthew G. Knepley #endif
2287b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
2288b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
2289b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
2290b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
2291b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2292b5da9499SMatthew G. Knepley #if 1
2293b5da9499SMatthew 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);
2294b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2295b5da9499SMatthew 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);
2296b5da9499SMatthew G. Knepley       }
2297b5da9499SMatthew G. Knepley #endif
2298b5da9499SMatthew G. Knepley     }
2299b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
2300b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2301b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2302b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
2303b5da9499SMatthew G. Knepley       PetscInt        size, s;
2304b5da9499SMatthew G. Knepley 
2305b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2306b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2307b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2308b5da9499SMatthew G. Knepley         PetscInt r = 0;
2309b5da9499SMatthew G. Knepley 
2310b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2311b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
2312b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
2313b5da9499SMatthew G. Knepley       }
2314b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2315b5da9499SMatthew G. Knepley #if 1
2316b5da9499SMatthew 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);
2317b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2318b5da9499SMatthew 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);
2319b5da9499SMatthew G. Knepley       }
2320b5da9499SMatthew G. Knepley #endif
2321b5da9499SMatthew G. Knepley     }
2322b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
2323b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2324b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
2325b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
2326b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
2327b5da9499SMatthew G. Knepley 
2328b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
2329b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2330b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
2331b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
2332b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2333b5da9499SMatthew G. Knepley         PetscInt r = 0;
2334b5da9499SMatthew G. Knepley 
2335b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2336b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2337b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
2338b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
2339b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
2340b5da9499SMatthew G. Knepley       }
2341b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2342b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
2343b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
2344b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
2345b5da9499SMatthew G. Knepley 
2346b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
2347b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
2348b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2349b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
2350b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
235142525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
2352b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
2353b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2354b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
235542525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
235642525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
2357b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
2358b5da9499SMatthew G. Knepley         }
2359b5da9499SMatthew G. Knepley       }
2360b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2361b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2362b5da9499SMatthew G. Knepley #if 1
2363b5da9499SMatthew 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);
2364b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
2365b5da9499SMatthew 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);
2366b5da9499SMatthew G. Knepley       }
2367b5da9499SMatthew G. Knepley #endif
2368b5da9499SMatthew G. Knepley     }
2369b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2370b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
2371b5da9499SMatthew G. Knepley     break;
23726ce3c06aSMatthew G. Knepley   case 7:
23736ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
23746ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
23756ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
23766ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
23776ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
23786ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
23796ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
23806ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
23816ce3c06aSMatthew G. Knepley 
23826ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
23836ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
23846ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
23856ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
23866ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
23876ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
23886ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
23896ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
23906ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
23916ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
23926ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
23936ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
23946ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
23956ce3c06aSMatthew G. Knepley #if 1
23966ce3c06aSMatthew 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);
23976ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
23986ce3c06aSMatthew 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);
23996ce3c06aSMatthew G. Knepley       }
24006ce3c06aSMatthew G. Knepley #endif
24016ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
24026ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
24036ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
24046ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
24056ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
24066ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
24076ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
24086ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
24096ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
24106ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
24116ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
24126ce3c06aSMatthew G. Knepley #if 1
24136ce3c06aSMatthew 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);
24146ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
24156ce3c06aSMatthew 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);
24166ce3c06aSMatthew G. Knepley       }
24176ce3c06aSMatthew G. Knepley #endif
24186ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
24196ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
24206ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
24216ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
24226ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
24236ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
24246ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
24256ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
24266ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
24276ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
24286ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
24296ce3c06aSMatthew G. Knepley #if 1
24306ce3c06aSMatthew 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);
24316ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
24326ce3c06aSMatthew 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);
24336ce3c06aSMatthew G. Knepley       }
24346ce3c06aSMatthew G. Knepley #endif
24356ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
24366ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
24376ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
24386ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
24396ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
24406ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
24416ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
24426ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
24436ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
24446ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
24456ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
24466ce3c06aSMatthew G. Knepley #if 1
24476ce3c06aSMatthew 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);
24486ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
24496ce3c06aSMatthew 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);
24506ce3c06aSMatthew G. Knepley       }
24516ce3c06aSMatthew G. Knepley #endif
24526ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
24536ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
24546ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
24559ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
24569ddff745SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
24579ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
24589ddff745SMatthew G. Knepley       orntNew[2] = 0;
24599ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
24609ddff745SMatthew G. Knepley       orntNew[3] = 2;
24616ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
24626ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
24636ce3c06aSMatthew G. Knepley #if 1
24646ce3c06aSMatthew 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);
24656ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
24666ce3c06aSMatthew 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);
24676ce3c06aSMatthew G. Knepley       }
24686ce3c06aSMatthew G. Knepley #endif
24696ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
24706ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
24716ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
24729ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
24739ddff745SMatthew G. Knepley       orntNew[1] = 1;
24749ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
24756ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
24769ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
24779ddff745SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
24786ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
24796ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
24806ce3c06aSMatthew G. Knepley #if 1
24816ce3c06aSMatthew 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);
24826ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
24836ce3c06aSMatthew 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);
24846ce3c06aSMatthew G. Knepley       }
24856ce3c06aSMatthew G. Knepley #endif
24866ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
24876ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
24886ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
24899ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
24909ddff745SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
24919ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
24929ddff745SMatthew G. Knepley       orntNew[2] = -3;
24939ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
24949ddff745SMatthew G. Knepley       orntNew[3] = -2;
24956ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
24966ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
24976ce3c06aSMatthew G. Knepley #if 1
24986ce3c06aSMatthew 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);
24996ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
25006ce3c06aSMatthew 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);
25016ce3c06aSMatthew G. Knepley       }
25026ce3c06aSMatthew G. Knepley #endif
25036ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
25046ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
25056ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
25069ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
25076ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
25089ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
25099ddff745SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
25109ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
25119ddff745SMatthew G. Knepley       orntNew[3] = -3;
25126ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
25136ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
25146ce3c06aSMatthew G. Knepley #if 1
25156ce3c06aSMatthew 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);
25166ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
25176ce3c06aSMatthew 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);
25186ce3c06aSMatthew G. Knepley       }
25196ce3c06aSMatthew G. Knepley #endif
25206ce3c06aSMatthew G. Knepley     }
25216ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
25226ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
25236ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
2524d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
25256ce3c06aSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5];
25266ce3c06aSMatthew G. Knepley 
25276ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
25286ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2529d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
25306ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
25316ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
25326ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
25336ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
25346ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
2535d3a1cc75SMatthew G. Knepley         coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? 0 : 1);
25366ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
2537d3a1cc75SMatthew G. Knepley         coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)]       - fMax)*2 + (fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? 1 : 0);
25386ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
25396ce3c06aSMatthew G. Knepley         coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
25406ce3c06aSMatthew G. Knepley         orntNew[4] = 0;
25416ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
25426ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
25436ce3c06aSMatthew G. Knepley #if 1
25446ce3c06aSMatthew 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);
25456ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
25466ce3c06aSMatthew 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);
25476ce3c06aSMatthew G. Knepley         }
25486ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
25496ce3c06aSMatthew 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);
25506ce3c06aSMatthew G. Knepley         }
25516ce3c06aSMatthew G. Knepley #endif
25526ce3c06aSMatthew G. Knepley       }
25536ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
25546ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
25556ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
25566ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
25576ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
25586ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
25596ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
25606ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
25616ce3c06aSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
25626ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
25636ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
25646ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
25656ce3c06aSMatthew G. Knepley #if 1
25666ce3c06aSMatthew 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);
25676ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
25686ce3c06aSMatthew 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);
25696ce3c06aSMatthew G. Knepley       }
25706ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
25716ce3c06aSMatthew 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);
25726ce3c06aSMatthew G. Knepley       }
25736ce3c06aSMatthew G. Knepley #endif
25746ce3c06aSMatthew G. Knepley     }
25756ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
25766ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2577785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
25786ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
25796ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
25806ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
25816ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
25826ce3c06aSMatthew G. Knepley 
25836ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
25846ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
25856ce3c06aSMatthew G. Knepley       /* A triangle */
25866ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
25876ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
25886ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
25896ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
25906ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
25916ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
25926ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
25936ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
25946ce3c06aSMatthew G. Knepley #if 1
25956ce3c06aSMatthew 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);
25966ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25976ce3c06aSMatthew 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);
25986ce3c06aSMatthew G. Knepley       }
25996ce3c06aSMatthew G. Knepley #endif
26006ce3c06aSMatthew G. Knepley       /* B triangle */
26016ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
26026ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
26036ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
26046ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
26056ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
26066ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
26076ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
26086ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
26096ce3c06aSMatthew G. Knepley #if 1
26106ce3c06aSMatthew 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);
26116ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26126ce3c06aSMatthew 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);
26136ce3c06aSMatthew G. Knepley       }
26146ce3c06aSMatthew G. Knepley #endif
26156ce3c06aSMatthew G. Knepley       /* C triangle */
26166ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
26176ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
26186ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
26196ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
26206ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
26216ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
26226ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
26236ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
26246ce3c06aSMatthew G. Knepley #if 1
26256ce3c06aSMatthew 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);
26266ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26276ce3c06aSMatthew 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);
26286ce3c06aSMatthew G. Knepley       }
26296ce3c06aSMatthew G. Knepley #endif
26306ce3c06aSMatthew G. Knepley       /* D triangle */
26316ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
26326ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
26336ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
26346ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
26356ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
26366ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
26376ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
26386ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
26396ce3c06aSMatthew G. Knepley #if 1
26406ce3c06aSMatthew 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);
26416ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26426ce3c06aSMatthew 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);
26436ce3c06aSMatthew G. Knepley       }
26446ce3c06aSMatthew G. Knepley #endif
26456ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
26466ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
26476ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
26486ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
26499ddff745SMatthew G. Knepley           PetscInt subf;
26506ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
26516ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
26526ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
26536ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
26546ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
26556ce3c06aSMatthew G. Knepley           }
26569ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
26576ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
26589ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
26596ce3c06aSMatthew G. Knepley           } else {
26609ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
26616ce3c06aSMatthew G. Knepley           }
26626ce3c06aSMatthew G. Knepley         }
26636ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
26646ce3c06aSMatthew G. Knepley #if 1
26659ddff745SMatthew 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);
26666ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
26676ce3c06aSMatthew 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);
26686ce3c06aSMatthew G. Knepley         }
26696ce3c06aSMatthew G. Knepley #endif
26706ce3c06aSMatthew G. Knepley       }
26716ce3c06aSMatthew G. Knepley     }
26726ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
26736ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
26746ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
26756ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
26766ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
26776ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
26786ce3c06aSMatthew G. Knepley 
26796ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
26806ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
26816ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
26829ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
26836ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
26849ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
26856ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
26869ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
26876ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
26886ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
26896ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
26906ce3c06aSMatthew G. Knepley #if 1
26916ce3c06aSMatthew 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);
26926ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26936ce3c06aSMatthew 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);
26946ce3c06aSMatthew G. Knepley       }
26956ce3c06aSMatthew G. Knepley #endif
26966ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
26976ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
26986ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
26996ce3c06aSMatthew G. Knepley #if 1
27006ce3c06aSMatthew 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);
27016ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
27026ce3c06aSMatthew 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);
27036ce3c06aSMatthew G. Knepley       }
27046ce3c06aSMatthew G. Knepley #endif
27056ce3c06aSMatthew G. Knepley       ++newp;
27066ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
27079ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
27086ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
27099ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
27106ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
27119ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
27126ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
27136ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27146ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
27156ce3c06aSMatthew G. Knepley #if 1
27166ce3c06aSMatthew 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);
27176ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
27186ce3c06aSMatthew 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);
27196ce3c06aSMatthew G. Knepley       }
27206ce3c06aSMatthew G. Knepley #endif
27216ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
27226ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
27236ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
27246ce3c06aSMatthew G. Knepley #if 1
27256ce3c06aSMatthew 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);
27266ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
27276ce3c06aSMatthew 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);
27286ce3c06aSMatthew G. Knepley       }
27296ce3c06aSMatthew G. Knepley #endif
27306ce3c06aSMatthew G. Knepley       ++newp;
27316ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
27329ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
27336ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
27349ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
27356ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
27369ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
27376ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
27386ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27396ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
27406ce3c06aSMatthew G. Knepley #if 1
27416ce3c06aSMatthew 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);
27426ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
27436ce3c06aSMatthew 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);
27446ce3c06aSMatthew G. Knepley       }
27456ce3c06aSMatthew G. Knepley #endif
27466ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
27476ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
27486ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
27496ce3c06aSMatthew G. Knepley #if 1
27506ce3c06aSMatthew 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);
27516ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
27526ce3c06aSMatthew 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);
27536ce3c06aSMatthew G. Knepley       }
27546ce3c06aSMatthew G. Knepley #endif
27556ce3c06aSMatthew G. Knepley       ++newp;
27566ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
27579ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
27586ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
27599ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
27606ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
27619ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
27626ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
27636ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27646ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
27656ce3c06aSMatthew G. Knepley #if 1
27666ce3c06aSMatthew 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);
27676ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
27686ce3c06aSMatthew 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);
27696ce3c06aSMatthew G. Knepley       }
27706ce3c06aSMatthew G. Knepley #endif
27716ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
27726ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
27736ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
27746ce3c06aSMatthew G. Knepley #if 1
27756ce3c06aSMatthew 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);
27766ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
27776ce3c06aSMatthew 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);
27786ce3c06aSMatthew G. Knepley       }
27796ce3c06aSMatthew G. Knepley #endif
27806ce3c06aSMatthew G. Knepley       ++newp;
27816ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
27829ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
27836ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
27846ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
27859ddff745SMatthew G. Knepley       orntNew[1] = -2;
27869ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
27876ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
27886ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27896ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
27906ce3c06aSMatthew G. Knepley #if 1
27916ce3c06aSMatthew 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);
27926ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
27936ce3c06aSMatthew 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);
27946ce3c06aSMatthew G. Knepley       }
27956ce3c06aSMatthew G. Knepley #endif
27966ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
27976ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
27986ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
27996ce3c06aSMatthew G. Knepley #if 1
28006ce3c06aSMatthew 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);
28016ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
28026ce3c06aSMatthew 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);
28036ce3c06aSMatthew G. Knepley       }
28046ce3c06aSMatthew G. Knepley #endif
28056ce3c06aSMatthew G. Knepley       ++newp;
28066ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
28079ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
28086ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
28096ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
28109ddff745SMatthew G. Knepley       orntNew[1] = 0;
28119ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
28129ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
28136ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
28146ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
28156ce3c06aSMatthew G. Knepley #if 1
28166ce3c06aSMatthew 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);
28176ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
28186ce3c06aSMatthew 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);
28196ce3c06aSMatthew G. Knepley       }
28206ce3c06aSMatthew G. Knepley #endif
28216ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
28226ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
28236ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
28246ce3c06aSMatthew G. Knepley #if 1
28256ce3c06aSMatthew 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);
28266ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
28276ce3c06aSMatthew 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);
28286ce3c06aSMatthew G. Knepley       }
28296ce3c06aSMatthew G. Knepley #endif
28306ce3c06aSMatthew G. Knepley       ++newp;
28316ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
28329ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
28336ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
28346ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
28359ddff745SMatthew G. Knepley       orntNew[1] = 0;
28369ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
28376ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
28386ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
28396ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
28406ce3c06aSMatthew G. Knepley #if 1
28416ce3c06aSMatthew 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);
28426ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
28436ce3c06aSMatthew 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);
28446ce3c06aSMatthew G. Knepley       }
28456ce3c06aSMatthew G. Knepley #endif
28466ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
28476ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
28486ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
28496ce3c06aSMatthew G. Knepley #if 1
28506ce3c06aSMatthew 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);
28516ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
28526ce3c06aSMatthew 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);
28536ce3c06aSMatthew G. Knepley       }
28546ce3c06aSMatthew G. Knepley #endif
28556ce3c06aSMatthew G. Knepley       ++newp;
28566ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
28579ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
28586ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
28599ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
28606ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
28616ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
28629ddff745SMatthew G. Knepley       orntNew[2] = -2;
28636ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
28646ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
28656ce3c06aSMatthew G. Knepley #if 1
28666ce3c06aSMatthew 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);
28676ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
28686ce3c06aSMatthew 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);
28696ce3c06aSMatthew G. Knepley       }
28706ce3c06aSMatthew G. Knepley #endif
28716ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
28726ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
28736ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
28746ce3c06aSMatthew G. Knepley #if 1
28756ce3c06aSMatthew 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);
28766ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
28776ce3c06aSMatthew 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);
28786ce3c06aSMatthew G. Knepley       }
28796ce3c06aSMatthew G. Knepley #endif
28806ce3c06aSMatthew G. Knepley       ++newp;
28816ce3c06aSMatthew G. Knepley     }
28826ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
28836ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
28846ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
28856ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
28866ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
28876ce3c06aSMatthew G. Knepley 
28886ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
28896ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
28906ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
28916ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
28926ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
28936ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
28946ce3c06aSMatthew G. Knepley 
28956ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
28966ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
28976ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
28986ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
28996ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
29006ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
29016ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
29026ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
29036ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
29046ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
29056ce3c06aSMatthew G. Knepley #if 1
29066ce3c06aSMatthew 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);
29076ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
29086ce3c06aSMatthew 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);
29096ce3c06aSMatthew G. Knepley         }
29106ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
29116ce3c06aSMatthew 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);
29126ce3c06aSMatthew G. Knepley         }
29136ce3c06aSMatthew G. Knepley #endif
29146ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
2915d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
29166ce3c06aSMatthew G. Knepley 
29176ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
29186ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
29196ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
29206ce3c06aSMatthew 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]);
2921d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
2922d3a1cc75SMatthew G. Knepley           supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%3;
29236ce3c06aSMatthew G. Knepley         }
29246ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
29256ce3c06aSMatthew G. Knepley #if 1
29266ce3c06aSMatthew 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);
29276ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
29286ce3c06aSMatthew 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);
29296ce3c06aSMatthew G. Knepley         }
29306ce3c06aSMatthew G. Knepley #endif
29316ce3c06aSMatthew G. Knepley       }
29326ce3c06aSMatthew G. Knepley     }
29336ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
29346ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
29356ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
29366ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
29376ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
29386ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
29396ce3c06aSMatthew G. Knepley 
29406ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
29416ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
29426ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
29436ce3c06aSMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], (r+2)%3);
29446ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
29456ce3c06aSMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], (r+2)%3);
29466ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
29476ce3c06aSMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], (r+2)%3)] - fMax);
29486ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
29496ce3c06aSMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], r)]       - fMax);
29506ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
29516ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
29526ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
29536ce3c06aSMatthew G. Knepley #if 1
29546ce3c06aSMatthew 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);
29556ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
29566ce3c06aSMatthew 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);
29576ce3c06aSMatthew G. Knepley         }
29586ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
29596ce3c06aSMatthew 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);
29606ce3c06aSMatthew G. Knepley         }
29616ce3c06aSMatthew G. Knepley #endif
29626ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
29636ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
29646ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
29656ce3c06aSMatthew G. Knepley #if 1
29666ce3c06aSMatthew 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);
29676ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
29686ce3c06aSMatthew 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);
29696ce3c06aSMatthew G. Knepley         }
29706ce3c06aSMatthew G. Knepley #endif
29716ce3c06aSMatthew G. Knepley       }
29726ce3c06aSMatthew G. Knepley     }
29736ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
29746ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
29756ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
29766ce3c06aSMatthew G. Knepley 
29776ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
29786ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
29796ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
29806ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
29816ce3c06aSMatthew G. Knepley 
29826ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
29836ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
29846ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
29856ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
29866ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
29876ce3c06aSMatthew G. Knepley #if 1
29886ce3c06aSMatthew 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);
29896ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
29906ce3c06aSMatthew 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);
29916ce3c06aSMatthew G. Knepley         }
29926ce3c06aSMatthew G. Knepley #endif
29936ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
29946ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
29956ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
29966ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
29976ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
29986ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
29996ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
30006ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
30016ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
30026ce3c06aSMatthew G. Knepley           } else {
30036ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
30046ce3c06aSMatthew G. Knepley           }
30056ce3c06aSMatthew G. Knepley         }
30066ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
30076ce3c06aSMatthew G. Knepley #if 1
30086ce3c06aSMatthew 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);
30096ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
30106ce3c06aSMatthew 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);
30116ce3c06aSMatthew G. Knepley         }
30126ce3c06aSMatthew G. Knepley #endif
30136ce3c06aSMatthew G. Knepley       }
30146ce3c06aSMatthew G. Knepley     }
30156ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
30166ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
30176ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
30186ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
30196ce3c06aSMatthew G. Knepley 
30206ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
30216ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
30226ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
30236ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
30246ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
30256ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
30266ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
30276ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
30286ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
30296ce3c06aSMatthew G. Knepley 
30306ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
30316ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
30326ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
30336ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
30346ce3c06aSMatthew G. Knepley #if 1
30356ce3c06aSMatthew 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);
30366ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
30376ce3c06aSMatthew 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);
30386ce3c06aSMatthew G. Knepley         }
30396ce3c06aSMatthew G. Knepley #endif
30406ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
30416ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
30426ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
30436ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
30446ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
30456ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
30466ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
30476ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
30486ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
30499ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
30506ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
30516ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
30526ce3c06aSMatthew G. Knepley             } else {
30536ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
30546ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
30556ce3c06aSMatthew G. Knepley             }
30566ce3c06aSMatthew G. Knepley           } else {
3057e515e2ddSMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(ornt[c], r) + 1)%3;
30586ce3c06aSMatthew G. Knepley           }
30596ce3c06aSMatthew G. Knepley         }
30606ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
30616ce3c06aSMatthew G. Knepley #if 1
30626ce3c06aSMatthew 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);
30636ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
30646ce3c06aSMatthew 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);
30656ce3c06aSMatthew G. Knepley         }
30666ce3c06aSMatthew G. Knepley #endif
30676ce3c06aSMatthew G. Knepley       }
30686ce3c06aSMatthew G. Knepley     }
30696ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
30706ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
30716ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
30726ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
30736ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
30746ce3c06aSMatthew G. Knepley 
30756ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
30766ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
30776ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
30786ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
30796ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
30806ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
30816ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
30826ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
30836ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
30846ce3c06aSMatthew G. Knepley #if 1
30856ce3c06aSMatthew 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);
30866ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
30876ce3c06aSMatthew 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);
30886ce3c06aSMatthew G. Knepley       }
30896ce3c06aSMatthew G. Knepley #endif
30906ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
30916ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
30926ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
30936ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
30946ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
30956ce3c06aSMatthew G. Knepley #if 1
30966ce3c06aSMatthew 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);
30976ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30986ce3c06aSMatthew 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);
30996ce3c06aSMatthew G. Knepley       }
31006ce3c06aSMatthew G. Knepley #endif
31016ce3c06aSMatthew G. Knepley     }
31026ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
31036ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
31046ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
31056ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
31066ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
31076ce3c06aSMatthew G. Knepley 
31086ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
31096ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
31106ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
31116ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
31126ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
31136ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
31146ce3c06aSMatthew G. Knepley #if 1
31156ce3c06aSMatthew 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);
31166ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
31176ce3c06aSMatthew 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);
31186ce3c06aSMatthew G. Knepley       }
31196ce3c06aSMatthew G. Knepley #endif
31206ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
31216ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
31226ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
31236ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
31246ce3c06aSMatthew 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]);
31256ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
31266ce3c06aSMatthew G. Knepley       }
31276ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
31286ce3c06aSMatthew G. Knepley #if 1
31296ce3c06aSMatthew 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);
31306ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
31316ce3c06aSMatthew 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);
31326ce3c06aSMatthew G. Knepley       }
31336ce3c06aSMatthew G. Knepley #endif
31346ce3c06aSMatthew G. Knepley     }
31356ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
31366ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
31376ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
3138623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
31396ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
31406ce3c06aSMatthew G. Knepley 
31416ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
31426ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
31436ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
31446ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
31456ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
31466ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
31476ce3c06aSMatthew G. Knepley #if 1
31486ce3c06aSMatthew 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);
31496ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
31506ce3c06aSMatthew 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);
31516ce3c06aSMatthew G. Knepley       }
31526ce3c06aSMatthew G. Knepley #endif
31536ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
31546ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
31556ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
31566ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
31576ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
3158623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
31596ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
31606ce3c06aSMatthew 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]);
3161623f4348SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + GetTriSubfaceInverse_Static(cornt[0], c-2);
3162623f4348SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(cornt[0], c-2) + 1)%3;
31636ce3c06aSMatthew G. Knepley       }
31646ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
31656ce3c06aSMatthew G. Knepley #if 1
31666ce3c06aSMatthew 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);
31676ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
31686ce3c06aSMatthew 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);
31696ce3c06aSMatthew G. Knepley       }
31706ce3c06aSMatthew G. Knepley #endif
31716ce3c06aSMatthew G. Knepley     }
31726ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
31736ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
31746ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
31756ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
31766ce3c06aSMatthew G. Knepley       PetscInt        size, s;
31776ce3c06aSMatthew G. Knepley 
31786ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
31796ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
31806ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
31816ce3c06aSMatthew G. Knepley         PetscInt r = 0;
31826ce3c06aSMatthew G. Knepley 
31836ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
31846ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
31856ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
31866ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
31876ce3c06aSMatthew G. Knepley       }
31886ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
31896ce3c06aSMatthew G. Knepley #if 1
31906ce3c06aSMatthew 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);
31916ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
31926ce3c06aSMatthew 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);
31936ce3c06aSMatthew G. Knepley       }
31946ce3c06aSMatthew G. Knepley #endif
31956ce3c06aSMatthew G. Knepley     }
31966ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
31976ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
31986ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
31996ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
32006ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
32016ce3c06aSMatthew G. Knepley 
32026ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
32036ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
32046ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
32056ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
32066ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
32076ce3c06aSMatthew G. Knepley         PetscInt r = 0;
32086ce3c06aSMatthew G. Knepley 
32096ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
32106ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
32116ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
32126ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
32136ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
32146ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
32156ce3c06aSMatthew G. Knepley           faceSize += 2;
32166ce3c06aSMatthew G. Knepley         } else {
32176ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
32186ce3c06aSMatthew G. Knepley           ++faceSize;
32196ce3c06aSMatthew G. Knepley         }
32206ce3c06aSMatthew G. Knepley       }
32216ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
32226ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
32236ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
32246ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
32256ce3c06aSMatthew G. Knepley 
32266ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
32276ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
32286ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
32296ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
32306ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
32316ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
32326ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
32336ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
32346ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
32356ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
32366ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
32376ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
32386ce3c06aSMatthew G. Knepley         }
32396ce3c06aSMatthew G. Knepley       }
32406ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
32416ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
32426ce3c06aSMatthew G. Knepley #if 1
32436ce3c06aSMatthew 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);
32446ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
32456ce3c06aSMatthew 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);
32466ce3c06aSMatthew G. Knepley       }
32476ce3c06aSMatthew G. Knepley #endif
32486ce3c06aSMatthew G. Knepley     }
32496ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
32506ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
32516ce3c06aSMatthew G. Knepley     break;
32522eabf88fSMatthew G. Knepley   case 6:
32532eabf88fSMatthew G. Knepley     /* Hex 3D */
32542eabf88fSMatthew G. Knepley     /*
32552eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
32562eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
32572eabf88fSMatthew G. Knepley      |         |         |       |         |         |
32582eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
32592eabf88fSMatthew G. Knepley      |         |         |       |         |         |
32602eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
32612eabf88fSMatthew G. Knepley      |         |         |       |         |         |
32622eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
32632eabf88fSMatthew G. Knepley      |         |         |       |         |         |
32642eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
32652eabf88fSMatthew G. Knepley      */
32662eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
32672eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
32682eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
32692eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
32702eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
32712eabf88fSMatthew G. Knepley 
32722eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
32732eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
32742eabf88fSMatthew G. Knepley       /* A hex */
3275e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
32762eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
32772eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
32782eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3279e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
32802eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
32812eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
32822eabf88fSMatthew G. Knepley       orntNew[3] = 0;
32832eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
32842eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3285e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
32862eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
32872eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
32882eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
32892eabf88fSMatthew G. Knepley #if 1
32902eabf88fSMatthew 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);
32912eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
32922eabf88fSMatthew 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);
32932eabf88fSMatthew G. Knepley       }
32942eabf88fSMatthew G. Knepley #endif
32952eabf88fSMatthew G. Knepley       /* B hex */
3296e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
32972eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
32982eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
32992eabf88fSMatthew G. Knepley       orntNew[1] = 0;
33002eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
3301a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3302e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
33032eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
33042eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
33052eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3306e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
33072eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
33082eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
33092eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
33102eabf88fSMatthew G. Knepley #if 1
33112eabf88fSMatthew 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);
33122eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33132eabf88fSMatthew 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);
33142eabf88fSMatthew G. Knepley       }
33152eabf88fSMatthew G. Knepley #endif
33162eabf88fSMatthew G. Knepley       /* C hex */
3317e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
33182eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
33192eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
33202eabf88fSMatthew G. Knepley       orntNew[1] = 0;
33212eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3322a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3323e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
33242eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3325e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
33262eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
33272eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
3328a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
33292eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
33302eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
33312eabf88fSMatthew G. Knepley #if 1
33322eabf88fSMatthew 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);
33332eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33342eabf88fSMatthew 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);
33352eabf88fSMatthew G. Knepley       }
33362eabf88fSMatthew G. Knepley #endif
33372eabf88fSMatthew G. Knepley       /* D hex */
3338e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
33392eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
33402eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
33412eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3342e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
33432eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
33442eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3345a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3346e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
33472eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
33482eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
3349a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
33502eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
33512eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
33522eabf88fSMatthew G. Knepley #if 1
33532eabf88fSMatthew 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);
33542eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33552eabf88fSMatthew 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);
33562eabf88fSMatthew G. Knepley       }
33572eabf88fSMatthew G. Knepley #endif
33582eabf88fSMatthew G. Knepley       /* E hex */
33592eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
3360a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3361e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
33622eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3363e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
33642eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
33652eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
33662eabf88fSMatthew G. Knepley       orntNew[3] = 0;
33672eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3368a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
3369e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
33702eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3371b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
3372b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
33732eabf88fSMatthew G. Knepley #if 1
3374b164cbf2SMatthew 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);
33752eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33762eabf88fSMatthew 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);
33772eabf88fSMatthew G. Knepley       }
33782eabf88fSMatthew G. Knepley #endif
33792eabf88fSMatthew G. Knepley       /* F hex */
33802eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
3381a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3382e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
33832eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3384e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
33852eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
33862eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3387a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
3388e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
33892eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
33902eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3391a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
3392b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
3393b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
33942eabf88fSMatthew G. Knepley #if 1
3395b164cbf2SMatthew 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);
33962eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33972eabf88fSMatthew 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);
33982eabf88fSMatthew G. Knepley       }
33992eabf88fSMatthew G. Knepley #endif
34002eabf88fSMatthew G. Knepley       /* G hex */
34012eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
3402a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3403e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
34042eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
34052eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3406a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
3407e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
34082eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3409e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
34102eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
34112eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3412a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
3413b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
3414b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
34152eabf88fSMatthew G. Knepley #if 1
3416b164cbf2SMatthew 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);
34172eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
34182eabf88fSMatthew 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);
34192eabf88fSMatthew G. Knepley       }
34202eabf88fSMatthew G. Knepley #endif
34212eabf88fSMatthew G. Knepley       /* H hex */
34222eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
3423a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3424e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
34252eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
34262eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
3427a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3428e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
34292eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
34302eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3431a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
3432e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
34332eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3434b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
3435b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
34362eabf88fSMatthew G. Knepley #if 1
3437b164cbf2SMatthew 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);
34382eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
34392eabf88fSMatthew 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);
34402eabf88fSMatthew G. Knepley       }
34412eabf88fSMatthew G. Knepley #endif
34422eabf88fSMatthew G. Knepley     }
34432eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
34442eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3445785e854fSJed Brown     ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
34462eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
34472eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
3448aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
34492eabf88fSMatthew 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};
34502eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
34512eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3452aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
34532eabf88fSMatthew G. Knepley 
34542eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3455aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
3456a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
3457a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
3458a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
3459a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
3460a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
3461a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
3462a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
3463a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
34642eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3465aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
34662eabf88fSMatthew G. Knepley #if 1
34672eabf88fSMatthew 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);
34682eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
34692eabf88fSMatthew 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);
34702eabf88fSMatthew G. Knepley         }
34712eabf88fSMatthew G. Knepley #endif
34722eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
34732eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
34742eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
34752eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
34762eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
34772eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
34782eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
34792eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
34802eabf88fSMatthew G. Knepley           }
3481a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
34822eabf88fSMatthew G. Knepley         }
34832eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
34842eabf88fSMatthew G. Knepley #if 1
34852eabf88fSMatthew 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);
34862eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
34872eabf88fSMatthew 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);
34882eabf88fSMatthew G. Knepley         }
34892eabf88fSMatthew G. Knepley #endif
34902eabf88fSMatthew G. Knepley       }
34912eabf88fSMatthew G. Knepley     }
34922eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
34932eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
34942eabf88fSMatthew 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};
3495afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
3496afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
34972eabf88fSMatthew G. Knepley 
34982eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3499afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3500afb2665bSMatthew G. Knepley       /* A-D face */
3501afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
3502a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
3503a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3504a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3505afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3506a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3507a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3508a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
3509afb2665bSMatthew G. Knepley       orntNew[3] = -2;
35102eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3511afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
35122eabf88fSMatthew G. Knepley #if 1
35132eabf88fSMatthew 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);
35142eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
35152eabf88fSMatthew 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);
35162eabf88fSMatthew G. Knepley       }
35172eabf88fSMatthew G. Knepley #endif
3518afb2665bSMatthew G. Knepley       /* C-D face */
3519afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
3520a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
3521a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3522a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3523afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3524a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3525a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3526a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
3527afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3528afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3529afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3530afb2665bSMatthew G. Knepley #if 1
3531afb2665bSMatthew 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);
3532afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3533afb2665bSMatthew 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);
3534afb2665bSMatthew G. Knepley       }
3535afb2665bSMatthew G. Knepley #endif
3536afb2665bSMatthew G. Knepley       /* B-C face */
3537afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
3538afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
3539afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3540afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
3541afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3542afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3543afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3544afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3545afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3546afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3547afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3548afb2665bSMatthew G. Knepley #if 1
3549afb2665bSMatthew 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);
3550afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3551afb2665bSMatthew 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);
3552afb2665bSMatthew G. Knepley       }
3553afb2665bSMatthew G. Knepley #endif
3554afb2665bSMatthew G. Knepley       /* A-B face */
3555afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
3556afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
3557afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3558afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
3559afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3560afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3561afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3562afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3563afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3564afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3565afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3566afb2665bSMatthew G. Knepley #if 1
3567afb2665bSMatthew 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);
3568afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3569afb2665bSMatthew 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);
3570afb2665bSMatthew G. Knepley       }
3571afb2665bSMatthew G. Knepley #endif
3572afb2665bSMatthew G. Knepley       /* E-F face */
3573afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
3574a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3575afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3576a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
3577a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3578a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
3579afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3580a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3581a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3582afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3583afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3584afb2665bSMatthew G. Knepley #if 1
3585afb2665bSMatthew 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);
3586afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3587afb2665bSMatthew 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);
3588afb2665bSMatthew G. Knepley       }
3589afb2665bSMatthew G. Knepley #endif
3590afb2665bSMatthew G. Knepley       /* F-G face */
3591afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
3592a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3593afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3594a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
3595a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3596a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
3597afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3598a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3599a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3600afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3601afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3602afb2665bSMatthew G. Knepley #if 1
3603afb2665bSMatthew 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);
3604afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3605afb2665bSMatthew 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);
3606afb2665bSMatthew G. Knepley       }
3607afb2665bSMatthew G. Knepley #endif
3608afb2665bSMatthew G. Knepley       /* G-H face */
3609afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
3610afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
3611afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3612afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
3613afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3614afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3615afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3616afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3617afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3618afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3619afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3620afb2665bSMatthew G. Knepley #if 1
3621afb2665bSMatthew 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);
3622afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3623afb2665bSMatthew 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);
3624afb2665bSMatthew G. Knepley       }
3625afb2665bSMatthew G. Knepley #endif
3626afb2665bSMatthew G. Knepley       /* E-H face */
3627afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
3628a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3629afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3630a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
3631a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3632a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
3633afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3634a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3635a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3636afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3637afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3638afb2665bSMatthew G. Knepley #if 1
3639afb2665bSMatthew 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);
3640afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3641afb2665bSMatthew 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);
3642afb2665bSMatthew G. Knepley       }
3643afb2665bSMatthew G. Knepley #endif
3644afb2665bSMatthew G. Knepley       /* A-E face */
3645afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
3646a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
3647a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3648a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3649afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3650a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3651a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3652a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
3653afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3654afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3655afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3656afb2665bSMatthew G. Knepley #if 1
3657afb2665bSMatthew 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);
3658afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3659afb2665bSMatthew 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);
3660afb2665bSMatthew G. Knepley       }
3661afb2665bSMatthew G. Knepley #endif
3662afb2665bSMatthew G. Knepley       /* D-F face */
3663afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
3664afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
3665afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3666afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
3667afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3668afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3669afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3670afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3671afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3672afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3673afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3674afb2665bSMatthew G. Knepley #if 1
3675afb2665bSMatthew 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);
3676afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3677afb2665bSMatthew 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);
3678afb2665bSMatthew G. Knepley       }
3679afb2665bSMatthew G. Knepley #endif
3680afb2665bSMatthew G. Knepley       /* C-G face */
3681afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
3682a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3683afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3684a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
3685a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3686a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
3687afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3688a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3689a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3690afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3691afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3692afb2665bSMatthew G. Knepley #if 1
3693afb2665bSMatthew 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);
3694afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3695afb2665bSMatthew 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);
3696afb2665bSMatthew G. Knepley       }
3697afb2665bSMatthew G. Knepley #endif
3698afb2665bSMatthew G. Knepley       /* B-H face */
3699afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
3700a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3701a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3702a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3703a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3704a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
3705a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3706a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
3707a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3708afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3709afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3710afb2665bSMatthew G. Knepley #if 1
3711afb2665bSMatthew 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);
3712afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3713afb2665bSMatthew 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);
3714afb2665bSMatthew G. Knepley       }
3715afb2665bSMatthew G. Knepley #endif
3716afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
3717afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
37182eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
37192eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
37202eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37212eabf88fSMatthew G. Knepley #if 1
37222eabf88fSMatthew 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);
37232eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
37242eabf88fSMatthew 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);
37252eabf88fSMatthew G. Knepley         }
37262eabf88fSMatthew G. Knepley #endif
37272eabf88fSMatthew G. Knepley       }
37282eabf88fSMatthew G. Knepley     }
37292eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
37302eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
37312eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
37322eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
37332eabf88fSMatthew G. Knepley 
37342eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
37352eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
37362eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
37372eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
37382eabf88fSMatthew G. Knepley 
37392eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
37402eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
37412eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
37422eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
37432eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37442eabf88fSMatthew G. Knepley #if 1
37452eabf88fSMatthew 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);
37462eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
37472eabf88fSMatthew 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);
37482eabf88fSMatthew G. Knepley         }
37492eabf88fSMatthew G. Knepley #endif
37502eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
37512eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
37522eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
37532eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
37542eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
37552eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
37562eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
37572eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
37582eabf88fSMatthew G. Knepley           }
37592eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
37602eabf88fSMatthew G. Knepley         }
37612eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37622eabf88fSMatthew G. Knepley #if 1
37632eabf88fSMatthew 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);
37642eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
37652eabf88fSMatthew 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);
37662eabf88fSMatthew G. Knepley         }
37672eabf88fSMatthew G. Knepley #endif
37682eabf88fSMatthew G. Knepley       }
37692eabf88fSMatthew G. Knepley     }
37702eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
37712eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
37726b852384SMatthew 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};
37732eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
37746b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
37752eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
37762eabf88fSMatthew G. Knepley 
37772eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
37782eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
37792eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
37802eabf88fSMatthew G. Knepley 
37812eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
37822eabf88fSMatthew G. Knepley         coneNew[1] = newv;
37832eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37842eabf88fSMatthew G. Knepley #if 1
37852eabf88fSMatthew 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);
37862eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
37872eabf88fSMatthew 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);
37882eabf88fSMatthew G. Knepley         }
37892eabf88fSMatthew G. Knepley #endif
37902eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
37912eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
37922eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
37932eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
37942eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
37956b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
37966b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
37976b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
37982eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
3799a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
38002eabf88fSMatthew G. Knepley         }
38012eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
38022eabf88fSMatthew G. Knepley #if 1
38032eabf88fSMatthew 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);
38042eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
38052eabf88fSMatthew 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);
38062eabf88fSMatthew G. Knepley         }
38072eabf88fSMatthew G. Knepley #endif
38082eabf88fSMatthew G. Knepley       }
38092eabf88fSMatthew G. Knepley     }
38102eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
38112eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
38122eabf88fSMatthew 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};
38132eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
38142eabf88fSMatthew G. Knepley       const PetscInt *cone;
38152eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
38162eabf88fSMatthew G. Knepley 
38172eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
38182eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
38192eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
38202eabf88fSMatthew G. Knepley 
38212eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
38222eabf88fSMatthew G. Knepley         coneNew[1] = newv;
38232eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
38242eabf88fSMatthew G. Knepley #if 1
38252eabf88fSMatthew 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);
38262eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
38272eabf88fSMatthew 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);
38282eabf88fSMatthew G. Knepley         }
38292eabf88fSMatthew G. Knepley #endif
38302eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
38312eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38322eabf88fSMatthew G. Knepley #if 1
38332eabf88fSMatthew 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);
38342eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
38352eabf88fSMatthew 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);
38362eabf88fSMatthew G. Knepley         }
38372eabf88fSMatthew G. Knepley #endif
38382eabf88fSMatthew G. Knepley       }
38392eabf88fSMatthew G. Knepley     }
38402eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
38412eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
38422eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
38432eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
38442eabf88fSMatthew G. Knepley       PetscInt        size, s;
38452eabf88fSMatthew G. Knepley 
38462eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
38472eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
38482eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
38492eabf88fSMatthew G. Knepley         PetscInt r = 0;
38502eabf88fSMatthew G. Knepley 
38512eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
38522eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
38532eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
38542eabf88fSMatthew G. Knepley       }
38552eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
38562eabf88fSMatthew G. Knepley #if 1
38572eabf88fSMatthew 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);
38582eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
38592eabf88fSMatthew 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);
38602eabf88fSMatthew G. Knepley       }
38612eabf88fSMatthew G. Knepley #endif
38622eabf88fSMatthew G. Knepley     }
38632eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
38642eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
38652eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
38662eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
38672eabf88fSMatthew G. Knepley       PetscInt        size, s;
38682eabf88fSMatthew G. Knepley 
38692eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
38702eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
38712eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
38722eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
38732eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
38742eabf88fSMatthew G. Knepley         PetscInt r;
38752eabf88fSMatthew G. Knepley 
38762eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3877a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
38782eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
38792eabf88fSMatthew G. Knepley       }
38802eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
38812eabf88fSMatthew G. Knepley #if 1
38822eabf88fSMatthew 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);
38832eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
38842eabf88fSMatthew 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);
38852eabf88fSMatthew G. Knepley       }
38862eabf88fSMatthew G. Knepley #endif
38872eabf88fSMatthew G. Knepley     }
38882eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
38892eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
38902eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
38912eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
38922eabf88fSMatthew G. Knepley       PetscInt        size, s;
38932eabf88fSMatthew G. Knepley 
38942eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
38952eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
38960793999aSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 +  (f - fStart)*4 + r;
38972eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
38982eabf88fSMatthew G. Knepley         PetscInt r;
38992eabf88fSMatthew G. Knepley 
39002eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
39012eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
39022eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
39032eabf88fSMatthew G. Knepley       }
39042eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
39052eabf88fSMatthew G. Knepley #if 1
39062eabf88fSMatthew 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);
39072eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
39082eabf88fSMatthew 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);
39092eabf88fSMatthew G. Knepley       }
39102eabf88fSMatthew G. Knepley #endif
39112eabf88fSMatthew G. Knepley     }
39122eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
39132eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
39142eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
39152eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
39162eabf88fSMatthew G. Knepley 
39172eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
39182eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
39192eabf88fSMatthew G. Knepley       }
39202eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
39212eabf88fSMatthew G. Knepley     }
3922da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
39232eabf88fSMatthew G. Knepley     break;
392427fcede3SMatthew G. Knepley   case 8:
392527fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
392627fcede3SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
392727fcede3SMatthew G. Knepley     /*
392827fcede3SMatthew G. Knepley      Bottom (viewed from top)    Top
392927fcede3SMatthew G. Knepley      1---------2---------2       7---------2---------6
393027fcede3SMatthew G. Knepley      |         |         |       |         |         |
393127fcede3SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
393227fcede3SMatthew G. Knepley      |         |         |       |         |         |
393327fcede3SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
393427fcede3SMatthew G. Knepley      |         |         |       |         |         |
393527fcede3SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
393627fcede3SMatthew G. Knepley      |         |         |       |         |         |
393727fcede3SMatthew G. Knepley      0---------0---------3       4---------0---------5
393827fcede3SMatthew G. Knepley      */
393927fcede3SMatthew G. Knepley     /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
394027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
394127fcede3SMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
394227fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
394327fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
394427fcede3SMatthew G. Knepley 
394527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
394627fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
394727fcede3SMatthew G. Knepley       /* A hex */
394827fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
394927fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
395027fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
395127fcede3SMatthew G. Knepley       orntNew[1] = 0;
395227fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
395327fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
395427fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
395527fcede3SMatthew G. Knepley       orntNew[3] = 0;
395627fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
395727fcede3SMatthew G. Knepley       orntNew[4] = 0;
395827fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
395927fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
396027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
396127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
396227fcede3SMatthew G. Knepley #if 1
396327fcede3SMatthew 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);
396427fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
396527fcede3SMatthew 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);
396627fcede3SMatthew G. Knepley       }
396727fcede3SMatthew G. Knepley #endif
396827fcede3SMatthew G. Knepley       /* B hex */
396927fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
397027fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
397127fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
397227fcede3SMatthew G. Knepley       orntNew[1] = 0;
397327fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
397427fcede3SMatthew G. Knepley       orntNew[2] = -1;
397527fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
397627fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
397727fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
397827fcede3SMatthew G. Knepley       orntNew[4] = 0;
397927fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
398027fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
398127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
398227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
398327fcede3SMatthew G. Knepley #if 1
398427fcede3SMatthew 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);
398527fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
398627fcede3SMatthew 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);
398727fcede3SMatthew G. Knepley       }
398827fcede3SMatthew G. Knepley #endif
398927fcede3SMatthew G. Knepley       /* C hex */
399027fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
399127fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
399227fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
399327fcede3SMatthew G. Knepley       orntNew[1] = 0;
399427fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
399527fcede3SMatthew G. Knepley       orntNew[2] = -1;
399627fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
399727fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
399827fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
399927fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
400027fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
400127fcede3SMatthew G. Knepley       orntNew[5] = -4;
400227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
400327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
400427fcede3SMatthew G. Knepley #if 1
400527fcede3SMatthew 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);
400627fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
400727fcede3SMatthew 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);
400827fcede3SMatthew G. Knepley       }
400927fcede3SMatthew G. Knepley #endif
401027fcede3SMatthew G. Knepley       /* D hex */
401127fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
401227fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
401327fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
401427fcede3SMatthew G. Knepley       orntNew[1] = 0;
401527fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
401627fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
401727fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
401827fcede3SMatthew G. Knepley       orntNew[3] = 0;
401927fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
402027fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
402127fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
402227fcede3SMatthew G. Knepley       orntNew[5] = -4;
402327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
402427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
402527fcede3SMatthew G. Knepley #if 1
402627fcede3SMatthew 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);
402727fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
402827fcede3SMatthew 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);
402927fcede3SMatthew G. Knepley       }
403027fcede3SMatthew G. Knepley #endif
403127fcede3SMatthew G. Knepley       /* E hex */
403227fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
403327fcede3SMatthew G. Knepley       orntNew[0] = -4;
403427fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
403527fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
403627fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
403727fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
403827fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
403927fcede3SMatthew G. Knepley       orntNew[3] = 0;
404027fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
404127fcede3SMatthew G. Knepley       orntNew[4] = -1;
404227fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
404327fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
404427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
404527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
404627fcede3SMatthew G. Knepley #if 1
404727fcede3SMatthew 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);
404827fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
404927fcede3SMatthew 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);
405027fcede3SMatthew G. Knepley       }
405127fcede3SMatthew G. Knepley #endif
405227fcede3SMatthew G. Knepley       /* F hex */
405327fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
405427fcede3SMatthew G. Knepley       orntNew[0] = -4;
405527fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
405627fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
405727fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
405827fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
405927fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
406027fcede3SMatthew G. Knepley       orntNew[3] = -1;
406127fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
406227fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
406327fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
406427fcede3SMatthew G. Knepley       orntNew[5] = 1;
406527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
406627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
406727fcede3SMatthew G. Knepley #if 1
406827fcede3SMatthew 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);
406927fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
407027fcede3SMatthew 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);
407127fcede3SMatthew G. Knepley       }
407227fcede3SMatthew G. Knepley #endif
407327fcede3SMatthew G. Knepley       /* G hex */
407427fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
407527fcede3SMatthew G. Knepley       orntNew[0] = -4;
407627fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
407727fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
407827fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
407927fcede3SMatthew G. Knepley       orntNew[2] = 0;
408027fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
408127fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
408227fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
408327fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
408427fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
408527fcede3SMatthew G. Knepley       orntNew[5] = -3;
408627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
408727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
408827fcede3SMatthew G. Knepley #if 1
408927fcede3SMatthew 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);
409027fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
409127fcede3SMatthew 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);
409227fcede3SMatthew G. Knepley       }
409327fcede3SMatthew G. Knepley #endif
409427fcede3SMatthew G. Knepley       /* H hex */
409527fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
409627fcede3SMatthew G. Knepley       orntNew[0] = -4;
409727fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
409827fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
409927fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
410027fcede3SMatthew G. Knepley       orntNew[2] = -1;
410127fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
410227fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
410327fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
410427fcede3SMatthew G. Knepley       orntNew[4] = 3;
410527fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
410627fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
410727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
410827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
410927fcede3SMatthew G. Knepley #if 1
411027fcede3SMatthew 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);
411127fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
411227fcede3SMatthew 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);
411327fcede3SMatthew G. Knepley       }
411427fcede3SMatthew G. Knepley #endif
411527fcede3SMatthew G. Knepley     }
411627fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces: Front, Back, Sides */
411727fcede3SMatthew G. Knepley     /*
411827fcede3SMatthew G. Knepley      3---------2---------2
411927fcede3SMatthew G. Knepley      |         |         |
412027fcede3SMatthew G. Knepley      |    D    2    C    |
412127fcede3SMatthew G. Knepley      |         |         |
412227fcede3SMatthew G. Knepley      3----3----0----1----1
412327fcede3SMatthew G. Knepley      |         |         |
412427fcede3SMatthew G. Knepley      |    A    0    B    |
412527fcede3SMatthew G. Knepley      |         |         |
412627fcede3SMatthew G. Knepley      0---------0---------1
412727fcede3SMatthew G. Knepley      */
412827fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
412927fcede3SMatthew G. Knepley       const PetscInt  newp = (cMax - cStart)*8 + (c - cMax)*4;
413027fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
413127fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
413227fcede3SMatthew G. Knepley 
413327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
413427fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
413527fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
413627fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
413727fcede3SMatthew G. Knepley         PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
413827fcede3SMatthew G. Knepley         PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
413927fcede3SMatthew G. Knepley         PetscInt edgeB = (edgeA+3)%4;
414027fcede3SMatthew 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]);
414127fcede3SMatthew G. Knepley         coneNew[0]         = fStartNew + (cone[0] - fStart)*4 + subfA;
414227fcede3SMatthew G. Knepley         orntNew[0]         = ornt[0];
414327fcede3SMatthew G. Knepley         coneNew[1]         = fStartNew + (cone[1] - fStart)*4 + subfA;
414427fcede3SMatthew G. Knepley         orntNew[1]         = ornt[0];
414527fcede3SMatthew G. Knepley         coneNew[(r+0)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeA+2] - fMax)*2 + (fornt[edgeA] < 0 ? 1 : 0);
414627fcede3SMatthew G. Knepley         orntNew[(r+0)%4+2] = ornt[edgeA];
414727fcede3SMatthew G. Knepley         coneNew[(r+1)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeA;
414827fcede3SMatthew G. Knepley         orntNew[(r+1)%4+2] = 0;
414927fcede3SMatthew G. Knepley         coneNew[(r+2)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeB;
415027fcede3SMatthew G. Knepley         orntNew[(r+2)%4+2] = -2;
415127fcede3SMatthew G. Knepley         coneNew[(r+3)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeB+2] - fMax)*2 + (fornt[edgeB] < 0 ? 0 : 1);
415227fcede3SMatthew G. Knepley         orntNew[(r+3)%4+2] = ornt[edgeB];
415327fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
415427fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
415527fcede3SMatthew G. Knepley #if 1
415627fcede3SMatthew 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);
415727fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
415827fcede3SMatthew 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);
415927fcede3SMatthew G. Knepley         }
416027fcede3SMatthew G. Knepley         for (p = 2; p < 6; ++p) {
416127fcede3SMatthew 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);
416227fcede3SMatthew G. Knepley         }
416327fcede3SMatthew G. Knepley #endif
416427fcede3SMatthew G. Knepley       }
416527fcede3SMatthew G. Knepley     }
416627fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
416727fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
416827fcede3SMatthew G. Knepley     ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
416927fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
417027fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
417127fcede3SMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
417227fcede3SMatthew 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};
417327fcede3SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
417427fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
417527fcede3SMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
417627fcede3SMatthew G. Knepley 
417727fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
417827fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
417927fcede3SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
418027fcede3SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
418127fcede3SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
418227fcede3SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
418327fcede3SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
418427fcede3SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
418527fcede3SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
418627fcede3SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
418727fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
418827fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
418927fcede3SMatthew G. Knepley #if 1
419027fcede3SMatthew 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);
419127fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
419227fcede3SMatthew 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);
419327fcede3SMatthew G. Knepley         }
419427fcede3SMatthew G. Knepley #endif
419527fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
419627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
419727fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
419827fcede3SMatthew G. Knepley           PetscInt subf;
419927fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
420027fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
420127fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
420227fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
420327fcede3SMatthew G. Knepley             if (cone[c] == f) break;
420427fcede3SMatthew G. Knepley           }
420527fcede3SMatthew G. Knepley           subf = GetQuadSubfaceInverse_Static(ornt[c], r);
420627fcede3SMatthew G. Knepley           if (support[s] < cMax) {
420727fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
420827fcede3SMatthew G. Knepley           } else {
420927fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax       - cStart)*8 + (support[s] - cMax)*4 + subf;
421027fcede3SMatthew G. Knepley           }
421127fcede3SMatthew G. Knepley         }
421227fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
421327fcede3SMatthew G. Knepley #if 1
421427fcede3SMatthew 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);
421527fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
421627fcede3SMatthew 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);
421727fcede3SMatthew G. Knepley         }
421827fcede3SMatthew G. Knepley #endif
421927fcede3SMatthew G. Knepley       }
422027fcede3SMatthew G. Knepley     }
422127fcede3SMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
422227fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
422327fcede3SMatthew 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};
422427fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
422527fcede3SMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
422627fcede3SMatthew G. Knepley 
422727fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
422827fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
422927fcede3SMatthew G. Knepley       /* A-D face */
423027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
423127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
423227fcede3SMatthew G. Knepley       orntNew[0] = 0;
423327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
423427fcede3SMatthew G. Knepley       orntNew[1] = 0;
423527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
423627fcede3SMatthew G. Knepley       orntNew[2] = -2;
423727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
423827fcede3SMatthew G. Knepley       orntNew[3] = -2;
423927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
424027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
424127fcede3SMatthew G. Knepley #if 1
424227fcede3SMatthew 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);
424327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
424427fcede3SMatthew 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);
424527fcede3SMatthew G. Knepley       }
424627fcede3SMatthew G. Knepley #endif
424727fcede3SMatthew G. Knepley       /* C-D face */
424827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
424927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
425027fcede3SMatthew G. Knepley       orntNew[0] = 0;
425127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
425227fcede3SMatthew G. Knepley       orntNew[1] = 0;
425327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
425427fcede3SMatthew G. Knepley       orntNew[2] = -2;
425527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
425627fcede3SMatthew G. Knepley       orntNew[3] = -2;
425727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
425827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
425927fcede3SMatthew G. Knepley #if 1
426027fcede3SMatthew 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);
426127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
426227fcede3SMatthew 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);
426327fcede3SMatthew G. Knepley       }
426427fcede3SMatthew G. Knepley #endif
426527fcede3SMatthew G. Knepley       /* B-C face */
426627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
426727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
426827fcede3SMatthew G. Knepley       orntNew[0] = -2;
426927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
427027fcede3SMatthew G. Knepley       orntNew[1] = 0;
427127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
427227fcede3SMatthew G. Knepley       orntNew[2] = 0;
427327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
427427fcede3SMatthew G. Knepley       orntNew[3] = -2;
427527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
427627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
427727fcede3SMatthew G. Knepley #if 1
427827fcede3SMatthew 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);
427927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
428027fcede3SMatthew 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);
428127fcede3SMatthew G. Knepley       }
428227fcede3SMatthew G. Knepley #endif
428327fcede3SMatthew G. Knepley       /* A-B face */
428427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
428527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
428627fcede3SMatthew G. Knepley       orntNew[0] = -2;
428727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
428827fcede3SMatthew G. Knepley       orntNew[1] = 0;
428927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
429027fcede3SMatthew G. Knepley       orntNew[2] = 0;
429127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
429227fcede3SMatthew G. Knepley       orntNew[3] = -2;
429327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
429427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
429527fcede3SMatthew G. Knepley #if 1
429627fcede3SMatthew 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);
429727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
429827fcede3SMatthew 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);
429927fcede3SMatthew G. Knepley       }
430027fcede3SMatthew G. Knepley #endif
430127fcede3SMatthew G. Knepley       /* E-F face */
430227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
430327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
430427fcede3SMatthew G. Knepley       orntNew[0] = -2;
430527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
430627fcede3SMatthew G. Knepley       orntNew[1] = -2;
430727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
430827fcede3SMatthew G. Knepley       orntNew[2] = 0;
430927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
431027fcede3SMatthew G. Knepley       orntNew[3] = 0;
431127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
431227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
431327fcede3SMatthew G. Knepley #if 1
431427fcede3SMatthew 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);
431527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
431627fcede3SMatthew 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);
431727fcede3SMatthew G. Knepley       }
431827fcede3SMatthew G. Knepley #endif
431927fcede3SMatthew G. Knepley       /* F-G face */
432027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
432127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
432227fcede3SMatthew G. Knepley       orntNew[0] = -2;
432327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
432427fcede3SMatthew G. Knepley       orntNew[1] = -2;
432527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
432627fcede3SMatthew G. Knepley       orntNew[2] = 0;
432727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
432827fcede3SMatthew G. Knepley       orntNew[3] = 0;
432927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
433027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
433127fcede3SMatthew G. Knepley #if 1
433227fcede3SMatthew 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);
433327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
433427fcede3SMatthew 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);
433527fcede3SMatthew G. Knepley       }
433627fcede3SMatthew G. Knepley #endif
433727fcede3SMatthew G. Knepley       /* G-H face */
433827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
433927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
434027fcede3SMatthew G. Knepley       orntNew[0] = -2;
434127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
434227fcede3SMatthew G. Knepley       orntNew[1] = 0;
434327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
434427fcede3SMatthew G. Knepley       orntNew[2] = 0;
434527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
434627fcede3SMatthew G. Knepley       orntNew[3] = -2;
434727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
434827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
434927fcede3SMatthew G. Knepley #if 1
435027fcede3SMatthew 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);
435127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
435227fcede3SMatthew 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);
435327fcede3SMatthew G. Knepley       }
435427fcede3SMatthew G. Knepley #endif
435527fcede3SMatthew G. Knepley       /* E-H face */
435627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
435727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
435827fcede3SMatthew G. Knepley       orntNew[0] = -2;
435927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
436027fcede3SMatthew G. Knepley       orntNew[1] = -2;
436127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
436227fcede3SMatthew G. Knepley       orntNew[2] = 0;
436327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
436427fcede3SMatthew G. Knepley       orntNew[3] = 0;
436527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
436627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
436727fcede3SMatthew G. Knepley #if 1
436827fcede3SMatthew 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);
436927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
437027fcede3SMatthew 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);
437127fcede3SMatthew G. Knepley       }
437227fcede3SMatthew G. Knepley #endif
437327fcede3SMatthew G. Knepley       /* A-E face */
437427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
437527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
437627fcede3SMatthew G. Knepley       orntNew[0] = 0;
437727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
437827fcede3SMatthew G. Knepley       orntNew[1] = 0;
437927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
438027fcede3SMatthew G. Knepley       orntNew[2] = -2;
438127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
438227fcede3SMatthew G. Knepley       orntNew[3] = -2;
438327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
438427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
438527fcede3SMatthew G. Knepley #if 1
438627fcede3SMatthew 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);
438727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
438827fcede3SMatthew 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);
438927fcede3SMatthew G. Knepley       }
439027fcede3SMatthew G. Knepley #endif
439127fcede3SMatthew G. Knepley       /* D-F face */
439227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
439327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
439427fcede3SMatthew G. Knepley       orntNew[0] = -2;
439527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
439627fcede3SMatthew G. Knepley       orntNew[1] = 0;
439727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
439827fcede3SMatthew G. Knepley       orntNew[2] = 0;
439927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
440027fcede3SMatthew G. Knepley       orntNew[3] = -2;
440127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
440227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
440327fcede3SMatthew G. Knepley #if 1
440427fcede3SMatthew 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);
440527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
440627fcede3SMatthew 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);
440727fcede3SMatthew G. Knepley       }
440827fcede3SMatthew G. Knepley #endif
440927fcede3SMatthew G. Knepley       /* C-G face */
441027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
441127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
441227fcede3SMatthew G. Knepley       orntNew[0] = -2;
441327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
441427fcede3SMatthew G. Knepley       orntNew[1] = -2;
441527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
441627fcede3SMatthew G. Knepley       orntNew[2] = 0;
441727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
441827fcede3SMatthew G. Knepley       orntNew[3] = 0;
441927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
442027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
442127fcede3SMatthew G. Knepley #if 1
442227fcede3SMatthew 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);
442327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
442427fcede3SMatthew 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);
442527fcede3SMatthew G. Knepley       }
442627fcede3SMatthew G. Knepley #endif
442727fcede3SMatthew G. Knepley       /* B-H face */
442827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
442927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
443027fcede3SMatthew G. Knepley       orntNew[0] = 0;
443127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
443227fcede3SMatthew G. Knepley       orntNew[1] = -2;
443327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
443427fcede3SMatthew G. Knepley       orntNew[2] = -2;
443527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
443627fcede3SMatthew G. Knepley       orntNew[3] = 0;
443727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
443827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
443927fcede3SMatthew G. Knepley #if 1
444027fcede3SMatthew 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);
444127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
444227fcede3SMatthew 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);
444327fcede3SMatthew G. Knepley       }
444427fcede3SMatthew G. Knepley #endif
444527fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
444627fcede3SMatthew G. Knepley         newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
444727fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
444827fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
444927fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
445027fcede3SMatthew G. Knepley #if 1
445127fcede3SMatthew 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);
445227fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
445327fcede3SMatthew 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);
445427fcede3SMatthew G. Knepley         }
445527fcede3SMatthew G. Knepley #endif
445627fcede3SMatthew G. Knepley       }
445727fcede3SMatthew G. Knepley     }
445827fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
445927fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
446027fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
446127fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
446227fcede3SMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
446327fcede3SMatthew G. Knepley 
446427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
446527fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
446627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
446727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
446827fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
446927fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
447027fcede3SMatthew G. Knepley 
447127fcede3SMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
447227fcede3SMatthew G. Knepley         orntNew[0]   = ornt[0];
447327fcede3SMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
447427fcede3SMatthew G. Knepley         orntNew[1]   = ornt[1];
447527fcede3SMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
447627fcede3SMatthew G. Knepley         orntNew[2+r] = 0;
447727fcede3SMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd      - eMax) + (f - fMax);
447827fcede3SMatthew G. Knepley         orntNew[3-r] = 0;
447927fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
448027fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
448127fcede3SMatthew G. Knepley #if 1
448227fcede3SMatthew 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);
448327fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
448427fcede3SMatthew 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);
448527fcede3SMatthew G. Knepley         }
448627fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
448727fcede3SMatthew 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);
448827fcede3SMatthew G. Knepley         }
448927fcede3SMatthew G. Knepley #endif
449027fcede3SMatthew G. Knepley         for (s = 0; s < size; ++s) {
449127fcede3SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
449227fcede3SMatthew G. Knepley 
449327fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
449427fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
449527fcede3SMatthew G. Knepley           for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
449627fcede3SMatthew 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]);
449727fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
449827fcede3SMatthew G. Knepley           supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%4;
449927fcede3SMatthew G. Knepley         }
450027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
450127fcede3SMatthew G. Knepley #if 1
450227fcede3SMatthew 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);
450327fcede3SMatthew G. Knepley         for (p = 0; p < size; ++p) {
450427fcede3SMatthew 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);
450527fcede3SMatthew G. Knepley         }
450627fcede3SMatthew G. Knepley #endif
450727fcede3SMatthew G. Knepley       }
450827fcede3SMatthew G. Knepley     }
450927fcede3SMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
451027fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
451127fcede3SMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
451227fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
451327fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
451427fcede3SMatthew G. Knepley       PetscInt        supportNew[2];
451527fcede3SMatthew G. Knepley 
451627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
451727fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
451827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
451927fcede3SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
452027fcede3SMatthew G. Knepley         orntNew[0] = 0;
452127fcede3SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
452227fcede3SMatthew G. Knepley         orntNew[1] = 0;
452327fcede3SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
452427fcede3SMatthew G. Knepley         orntNew[2] = 0;
452527fcede3SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd                                   - fMax) + (c - cMax);
452627fcede3SMatthew G. Knepley         orntNew[3] = 0;
452727fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
452827fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
452927fcede3SMatthew G. Knepley #if 1
453027fcede3SMatthew 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);
453127fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
453227fcede3SMatthew 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);
453327fcede3SMatthew G. Knepley         }
453427fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
453527fcede3SMatthew 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);
453627fcede3SMatthew G. Knepley         }
453727fcede3SMatthew G. Knepley #endif
453827fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
453927fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
454027fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
454127fcede3SMatthew G. Knepley #if 1
454227fcede3SMatthew 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);
454327fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
454427fcede3SMatthew 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);
454527fcede3SMatthew G. Knepley         }
454627fcede3SMatthew G. Knepley #endif
454727fcede3SMatthew G. Knepley       }
454827fcede3SMatthew G. Knepley     }
454927fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
455027fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
455127fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
455227fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
455327fcede3SMatthew G. Knepley 
455427fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
455527fcede3SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
455627fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
455727fcede3SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
455827fcede3SMatthew G. Knepley 
455927fcede3SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
456027fcede3SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
456127fcede3SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
456227fcede3SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
456327fcede3SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
456427fcede3SMatthew G. Knepley #if 1
456527fcede3SMatthew 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);
456627fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
456727fcede3SMatthew 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);
456827fcede3SMatthew G. Knepley         }
456927fcede3SMatthew G. Knepley #endif
457027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
457127fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
457227fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
457327fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
457427fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
457527fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
457627fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
457727fcede3SMatthew G. Knepley             if (cone[c] == e) break;
457827fcede3SMatthew G. Knepley           }
457927fcede3SMatthew G. Knepley           if (support[s] < fMax) {
458027fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
458127fcede3SMatthew G. Knepley           } else {
458227fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
458327fcede3SMatthew G. Knepley           }
458427fcede3SMatthew G. Knepley         }
458527fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
458627fcede3SMatthew G. Knepley #if 1
458727fcede3SMatthew 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);
458827fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
458927fcede3SMatthew 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);
459027fcede3SMatthew G. Knepley         }
459127fcede3SMatthew G. Knepley #endif
459227fcede3SMatthew G. Knepley       }
459327fcede3SMatthew G. Knepley     }
459427fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
459527fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
459627fcede3SMatthew 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};
459727fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
459827fcede3SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
459927fcede3SMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
460027fcede3SMatthew G. Knepley 
460127fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
460227fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
460327fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
460427fcede3SMatthew G. Knepley 
460527fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
460627fcede3SMatthew G. Knepley         coneNew[1] = newv;
460727fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
460827fcede3SMatthew G. Knepley #if 1
460927fcede3SMatthew 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);
461027fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
461127fcede3SMatthew 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);
461227fcede3SMatthew G. Knepley         }
461327fcede3SMatthew G. Knepley #endif
461427fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
461527fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
461627fcede3SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
461727fcede3SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
461827fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
461927fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
462027fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
462127fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
462227fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
462327fcede3SMatthew G. Knepley           if (support[s] < cMax) {
462427fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
462527fcede3SMatthew G. Knepley           } else {
462627fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadEdgeInverse_Static(orntCell[c], r);
462727fcede3SMatthew G. Knepley           }
462827fcede3SMatthew G. Knepley         }
462927fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
463027fcede3SMatthew G. Knepley #if 1
463127fcede3SMatthew 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);
463227fcede3SMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
463327fcede3SMatthew 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);
463427fcede3SMatthew G. Knepley         }
463527fcede3SMatthew G. Knepley #endif
463627fcede3SMatthew G. Knepley       }
463727fcede3SMatthew G. Knepley     }
463827fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
463927fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
464027fcede3SMatthew 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};
464127fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
464227fcede3SMatthew G. Knepley       const PetscInt *cone;
464327fcede3SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
464427fcede3SMatthew G. Knepley 
464527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
464627fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
464727fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
464827fcede3SMatthew G. Knepley 
464927fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
465027fcede3SMatthew G. Knepley         coneNew[1] = newv;
465127fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
465227fcede3SMatthew G. Knepley #if 1
465327fcede3SMatthew 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);
465427fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
465527fcede3SMatthew 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);
465627fcede3SMatthew G. Knepley         }
465727fcede3SMatthew G. Knepley #endif
465827fcede3SMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
465927fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
466027fcede3SMatthew G. Knepley #if 1
466127fcede3SMatthew 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);
466227fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
466327fcede3SMatthew 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);
466427fcede3SMatthew G. Knepley         }
466527fcede3SMatthew G. Knepley #endif
466627fcede3SMatthew G. Knepley       }
466727fcede3SMatthew G. Knepley     }
466827fcede3SMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
466927fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
467027fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
467127fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
467227fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
467327fcede3SMatthew G. Knepley 
467427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
467527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
467627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
467727fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
467827fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
467927fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
468027fcede3SMatthew G. Knepley #if 1
468127fcede3SMatthew 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);
468227fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
468327fcede3SMatthew 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);
468427fcede3SMatthew G. Knepley       }
468527fcede3SMatthew G. Knepley #endif
468627fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
468727fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
468827fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
468927fcede3SMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
469027fcede3SMatthew 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]);
469127fcede3SMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
469227fcede3SMatthew G. Knepley       }
469327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
469427fcede3SMatthew G. Knepley #if 1
469527fcede3SMatthew 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);
469627fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
469727fcede3SMatthew 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);
469827fcede3SMatthew G. Knepley       }
469927fcede3SMatthew G. Knepley #endif
470027fcede3SMatthew G. Knepley     }
470127fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
470227fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
470327fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
470427fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
470527fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
470627fcede3SMatthew G. Knepley 
470727fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
470827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
470927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
471027fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
471127fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
471227fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
471327fcede3SMatthew G. Knepley #if 1
471427fcede3SMatthew 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);
471527fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
471627fcede3SMatthew 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);
471727fcede3SMatthew G. Knepley       }
471827fcede3SMatthew G. Knepley #endif
471927fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
472027fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
472127fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
472227fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
472327fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
472427fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
472527fcede3SMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
472627fcede3SMatthew 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]);
472727fcede3SMatthew G. Knepley         supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadSubfaceInverse_Static(cornt[0], c-2);
472827fcede3SMatthew G. Knepley       }
472927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
473027fcede3SMatthew G. Knepley #if 1
473127fcede3SMatthew 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);
473227fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
473327fcede3SMatthew 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);
473427fcede3SMatthew G. Knepley       }
473527fcede3SMatthew G. Knepley #endif
473627fcede3SMatthew G. Knepley     }
473727fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
473827fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
473927fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
474027fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
474127fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size;
474227fcede3SMatthew G. Knepley 
474327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
474427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr);
474527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr);
474627fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
474727fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
474827fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
474927fcede3SMatthew G. Knepley #if 1
475027fcede3SMatthew 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);
475127fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
475227fcede3SMatthew 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);
475327fcede3SMatthew G. Knepley       }
475427fcede3SMatthew G. Knepley #endif
475527fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
475627fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
475727fcede3SMatthew G. Knepley       supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
475827fcede3SMatthew G. Knepley       supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
475927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
476027fcede3SMatthew G. Knepley #if 1
476127fcede3SMatthew 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);
476227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
476327fcede3SMatthew 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);
476427fcede3SMatthew G. Knepley       }
476527fcede3SMatthew G. Knepley #endif
476627fcede3SMatthew G. Knepley     }
476727fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
476827fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
476927fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
477027fcede3SMatthew G. Knepley       const PetscInt *support, *cone;
477127fcede3SMatthew G. Knepley       PetscInt        size, s;
477227fcede3SMatthew G. Knepley 
477327fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
477427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
477527fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
477627fcede3SMatthew G. Knepley         PetscInt r = 0;
477727fcede3SMatthew G. Knepley 
477827fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
477927fcede3SMatthew G. Knepley         if (cone[1] == v) r = 1;
478027fcede3SMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
478127fcede3SMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
478227fcede3SMatthew G. Knepley       }
478327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
478427fcede3SMatthew G. Knepley #if 1
478527fcede3SMatthew 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);
478627fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
478727fcede3SMatthew 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);
478827fcede3SMatthew G. Knepley       }
478927fcede3SMatthew G. Knepley #endif
479027fcede3SMatthew G. Knepley     }
479127fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
479227fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
479327fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
479427fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
479527fcede3SMatthew G. Knepley       PetscInt        size, s;
479627fcede3SMatthew G. Knepley 
479727fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
479827fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
479927fcede3SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
480027fcede3SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
480127fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
480227fcede3SMatthew G. Knepley         PetscInt r;
480327fcede3SMatthew G. Knepley 
480427fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
480527fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
480627fcede3SMatthew G. Knepley         if (support[s] < fMax) {
480727fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
480827fcede3SMatthew G. Knepley         } else {
480927fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
481027fcede3SMatthew G. Knepley         }
481127fcede3SMatthew G. Knepley       }
481227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
481327fcede3SMatthew G. Knepley #if 1
481427fcede3SMatthew 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);
481527fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
481627fcede3SMatthew 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);
481727fcede3SMatthew G. Knepley       }
481827fcede3SMatthew G. Knepley #endif
481927fcede3SMatthew G. Knepley     }
482027fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
482127fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
482227fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
482327fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
482427fcede3SMatthew G. Knepley       PetscInt        size, s;
482527fcede3SMatthew G. Knepley 
482627fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
482727fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
482827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 +  (f - fStart)*4 + r;
482927fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
483027fcede3SMatthew G. Knepley         PetscInt r;
483127fcede3SMatthew G. Knepley 
483227fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
483327fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
483427fcede3SMatthew G. Knepley         if (support[s] < cMax) {
483527fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
483627fcede3SMatthew G. Knepley         } else {
483727fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax       - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
483827fcede3SMatthew G. Knepley         }
483927fcede3SMatthew G. Knepley       }
484027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
484127fcede3SMatthew G. Knepley #if 1
484227fcede3SMatthew 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);
484327fcede3SMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
484427fcede3SMatthew 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);
484527fcede3SMatthew G. Knepley       }
484627fcede3SMatthew G. Knepley #endif
484727fcede3SMatthew G. Knepley     }
484827fcede3SMatthew G. Knepley     /* Cell vertices have 6 supports */
484927fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
485027fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
485127fcede3SMatthew G. Knepley       PetscInt       supportNew[6];
485227fcede3SMatthew G. Knepley 
485327fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
485427fcede3SMatthew G. Knepley         supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
485527fcede3SMatthew G. Knepley       }
485627fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
485727fcede3SMatthew G. Knepley     }
485827fcede3SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
485927fcede3SMatthew G. Knepley     break;
486075d3a19aSMatthew G. Knepley   default:
486175d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
486275d3a19aSMatthew G. Knepley   }
486375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
486475d3a19aSMatthew G. Knepley }
486575d3a19aSMatthew G. Knepley 
486675d3a19aSMatthew G. Knepley #undef __FUNCT__
486775d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates"
486886150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
486975d3a19aSMatthew G. Knepley {
487075d3a19aSMatthew G. Knepley   PetscSection   coordSection, coordSectionNew;
487175d3a19aSMatthew G. Knepley   Vec            coordinates, coordinatesNew;
487275d3a19aSMatthew G. Knepley   PetscScalar   *coords, *coordsNew;
48733478d7aaSMatthew G. Knepley   const PetscInt numVertices = depthSize ? depthSize[0] : 0;
487427fcede3SMatthew G. Knepley   PetscInt       dim, depth, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
487575d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
487675d3a19aSMatthew G. Knepley 
487775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
487875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
487975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
488075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
4881b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
488275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
488375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
488427fcede3SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr);
48853478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);}
488675d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);
4887f719d809SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
488875d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
488975d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
489075d3a19aSMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr);
48913478d7aaSMatthew G. Knepley   ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
489227fcede3SMatthew G. Knepley   if (cMax < 0) cMax = cEnd;
489375d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
4894b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
489575d3a19aSMatthew G. Knepley   /* All vertices have the dim coordinates */
48963478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
489775d3a19aSMatthew G. Knepley     ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr);
489875d3a19aSMatthew G. Knepley     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr);
489975d3a19aSMatthew G. Knepley   }
490075d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
4901f719d809SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr);
490275d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
490375d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
490475d3a19aSMatthew G. Knepley   ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr);
490575d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
490675d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
490775d3a19aSMatthew G. Knepley   ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr);
490875d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
490975d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
4910b5da9499SMatthew G. Knepley   switch (refiner) {
49113478d7aaSMatthew G. Knepley   case 0: break;
4912b5da9499SMatthew G. Knepley   case 6: /* Hex 3D */
4913d856d60fSMatthew G. Knepley   case 8: /* Hybrid Hex 3D */
4914b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
4915d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
491627fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
4917b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
4918b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
4919b5da9499SMatthew G. Knepley 
4920b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
4921b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
4922b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
4923b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
4924b5da9499SMatthew G. Knepley       }
4925b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
4926b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
4927b5da9499SMatthew G. Knepley       }
4928b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
4929b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
4930b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
4931b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
4932b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
4933b5da9499SMatthew G. Knepley       }
4934b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
4935b5da9499SMatthew G. Knepley     }
4936b5da9499SMatthew G. Knepley   case 2: /* Hex 2D */
4937b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
493827fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
493927fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
4940b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
4941b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
4942b5da9499SMatthew G. Knepley 
4943b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
4944b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
4945b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
4946b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
4947b5da9499SMatthew G. Knepley       }
4948b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
4949b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
4950b5da9499SMatthew G. Knepley       }
4951b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
4952b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
4953b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
4954b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
4955b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
4956b5da9499SMatthew G. Knepley       }
4957b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
4958b5da9499SMatthew G. Knepley     }
4959b5da9499SMatthew G. Knepley   case 1: /* Simplicial 2D */
4960b5da9499SMatthew G. Knepley   case 3: /* Hybrid Simplicial 2D */
4961b5da9499SMatthew G. Knepley   case 5: /* Simplicial 3D */
49626ce3c06aSMatthew G. Knepley   case 7: /* Hybrid Simplicial 3D */
4963b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
4964b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
4965b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
4966b5da9499SMatthew G. Knepley       const PetscInt *cone;
4967b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
4968b5da9499SMatthew G. Knepley 
4969b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
4970b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
4971b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
4972b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
4973b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
4974b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
4975b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
4976b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]);
4977b5da9499SMatthew G. Knepley       }
4978b5da9499SMatthew G. Knepley     }
497975d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
498075d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
498175d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
498275d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
498375d3a19aSMatthew G. Knepley 
498475d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
498575d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
498675d3a19aSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
498775d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
498875d3a19aSMatthew G. Knepley       }
498975d3a19aSMatthew G. Knepley     }
4990b5da9499SMatthew G. Knepley     break;
4991b5da9499SMatthew G. Knepley   default:
4992b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
499375d3a19aSMatthew G. Knepley   }
499475d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
499575d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
499675d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
499775d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
499875d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
499975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
500075d3a19aSMatthew G. Knepley }
500175d3a19aSMatthew G. Knepley 
500275d3a19aSMatthew G. Knepley #undef __FUNCT__
500375d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF"
500486150812SJed Brown static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
500575d3a19aSMatthew G. Knepley {
500675d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
500775d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
500875d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
500975d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
501075d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
501175d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
501275d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
501375d3a19aSMatthew G. Knepley 
501475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
501575d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
5016785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
501775d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
501875d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
501975d3a19aSMatthew G. Knepley   }
502075d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
5021785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &ranksNew);CHKERRQ(ierr);
5022785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &localPointsNew);CHKERRQ(ierr);
5023785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
502475d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
502575d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
502675d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
502775d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
502875d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
502975d3a19aSMatthew G. Knepley   }
503075d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
503175d3a19aSMatthew G. Knepley   ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);
503275d3a19aSMatthew G. Knepley   ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
503375d3a19aSMatthew G. Knepley   ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
503475d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
503575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
503675d3a19aSMatthew G. Knepley }
503775d3a19aSMatthew G. Knepley 
503875d3a19aSMatthew G. Knepley #undef __FUNCT__
503975d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF"
504086150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
504175d3a19aSMatthew G. Knepley {
504275d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
504375d3a19aSMatthew G. Knepley   IS                 processRanks;
504475d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
504575d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
504675d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
504775d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
504875d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
504975d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
505075d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
50517ba685a0SMatthew G. Knepley   PetscInt           depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
50527ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
505375d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
505475d3a19aSMatthew G. Knepley 
505575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
505675d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
505775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
505875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
505975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
506075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
506175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
506275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
50633478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
506475d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
506575d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
506675d3a19aSMatthew G. Knepley   /* Caculate size of new SF */
506775d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
506875d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
506975d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
507075d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
507175d3a19aSMatthew G. Knepley 
507275d3a19aSMatthew G. Knepley     switch (refiner) {
507375d3a19aSMatthew G. Knepley     case 1:
507475d3a19aSMatthew G. Knepley       /* Simplicial 2D */
507575d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
507675d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
507775d3a19aSMatthew G. Knepley         ++numLeavesNew;
507875d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
507975d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
5080d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
508175d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
508275d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
508375d3a19aSMatthew G. Knepley         numLeavesNew += 4 + 3;
508475d3a19aSMatthew G. Knepley       }
508575d3a19aSMatthew G. Knepley       break;
508675d3a19aSMatthew G. Knepley     case 2:
508775d3a19aSMatthew G. Knepley       /* Hex 2D */
508875d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
508975d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
509075d3a19aSMatthew G. Knepley         ++numLeavesNew;
509175d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
509275d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
5093d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
509475d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5095455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
5096455d6cd4SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
509775d3a19aSMatthew G. Knepley       }
509875d3a19aSMatthew G. Knepley       break;
5099b5da9499SMatthew G. Knepley     case 5:
5100b5da9499SMatthew G. Knepley       /* Simplicial 3D */
5101b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5102b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
5103b5da9499SMatthew G. Knepley         ++numLeavesNew;
5104b5da9499SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
5105b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
5106b5da9499SMatthew G. Knepley         numLeavesNew += 2 + 1;
5107b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
5108b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
5109b5da9499SMatthew G. Knepley         numLeavesNew += 4 + 3;
5110b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5111b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
5112b5da9499SMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
5113b5da9499SMatthew G. Knepley       }
5114b5da9499SMatthew G. Knepley       break;
51156ce3c06aSMatthew G. Knepley     case 7:
51166ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
51176ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
51186ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
51196ce3c06aSMatthew G. Knepley         ++numLeavesNew;
51206ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
51216ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
51226ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
51236ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
51246ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
51256ce3c06aSMatthew G. Knepley         ++numLeavesNew;
51266ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
51276ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
51286ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
51296ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
51306ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
51316ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
51326ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
51336ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
51346ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
51356ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
51366ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
51376ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
51386ce3c06aSMatthew G. Knepley       }
51396ce3c06aSMatthew G. Knepley       break;
51402eabf88fSMatthew G. Knepley     case 6:
51412eabf88fSMatthew G. Knepley       /* Hex 3D */
51422eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
51432eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
51442eabf88fSMatthew G. Knepley         ++numLeavesNew;
51452eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
51462eabf88fSMatthew G. Knepley         /* Old edges add new edges, and vertex */
51472eabf88fSMatthew G. Knepley         numLeavesNew += 2 + 1;
51482eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
51492eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
51502eabf88fSMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
51512eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
51522eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
51532eabf88fSMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
51542eabf88fSMatthew G. Knepley       }
51552eabf88fSMatthew G. Knepley       break;
515627fcede3SMatthew G. Knepley     case 8:
515727fcede3SMatthew G. Knepley       /* Hybrid Hex 3D */
515827fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
515927fcede3SMatthew G. Knepley         /* Old vertices stay the same */
516027fcede3SMatthew G. Knepley         ++numLeavesNew;
516127fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
516227fcede3SMatthew G. Knepley         /* Interior edges add new edges, and vertex */
516327fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
516427fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
516527fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
516627fcede3SMatthew G. Knepley         ++numLeavesNew;
516727fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
516827fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
516927fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
517027fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
517127fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
517227fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
517327fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
517427fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
517527fcede3SMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
517627fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
517727fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
517827fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
517927fcede3SMatthew G. Knepley       }
518027fcede3SMatthew G. Knepley       break;
518175d3a19aSMatthew G. Knepley     default:
518275d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
518375d3a19aSMatthew G. Knepley     }
518475d3a19aSMatthew G. Knepley   }
518575d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
518675d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
518775d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
5188dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
5189dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
519075d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
519175d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
519275d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
519375d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
519475d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
519575d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
519675d3a19aSMatthew G. Knepley   }
519775d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
519875d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
519975d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
520075d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
520175d3a19aSMatthew G. Knepley 
520275d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
520375d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
520475d3a19aSMatthew G. Knepley 
520575d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
520675d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
520775d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
520875d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
520975d3a19aSMatthew G. Knepley 
521075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
521175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
521275d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
521375d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
521475d3a19aSMatthew G. Knepley   }
521575d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
521675d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
521775d3a19aSMatthew G. Knepley   /* Calculate new point SF */
5218785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew,    &localPointsNew);CHKERRQ(ierr);
5219785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
522075d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
522175d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
522275d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
522375d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
522475d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
522575d3a19aSMatthew G. Knepley 
522675d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
522775d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
522875d3a19aSMatthew G. Knepley     switch (refiner) {
522975d3a19aSMatthew G. Knepley     case 1:
523075d3a19aSMatthew G. Knepley       /* Simplicial 2D */
523175d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
523275d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
523375d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
523475d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
523575d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
523675d3a19aSMatthew G. Knepley         ++m;
523775d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
523875d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
523975d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
524075d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
524175d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
524275d3a19aSMatthew G. Knepley         ++m;
524375d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
524475d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
524575d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
524675d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
524775d3a19aSMatthew G. Knepley         }
524875d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
524975d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
525075d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
525175d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
525275d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
525375d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
525475d3a19aSMatthew G. Knepley         }
525575d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
525675d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*3     + r;
525775d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
525875d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
525975d3a19aSMatthew G. Knepley         }
526075d3a19aSMatthew G. Knepley       }
526175d3a19aSMatthew G. Knepley       break;
526275d3a19aSMatthew G. Knepley     case 2:
526375d3a19aSMatthew G. Knepley       /* Hex 2D */
526475d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
526575d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
526675d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
526775d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
526875d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
526975d3a19aSMatthew G. Knepley         ++m;
527075d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
527175d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
527275d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
527375d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
527475d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
527575d3a19aSMatthew G. Knepley         ++m;
527675d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
527775d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
527875d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
527975d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
528075d3a19aSMatthew G. Knepley         }
528175d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5282455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
528375d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
528475d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
528575d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
528675d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
528775d3a19aSMatthew G. Knepley         }
528875d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
528975d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*4     + r;
529075d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r;
529175d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
529275d3a19aSMatthew G. Knepley         }
5293455d6cd4SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
5294455d6cd4SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (fEnd - fStart)                    + (p  - cStart)     + r;
5295455d6cd4SMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
5296455d6cd4SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5297455d6cd4SMatthew G. Knepley         }
529875d3a19aSMatthew G. Knepley       }
529975d3a19aSMatthew G. Knepley       break;
530075d3a19aSMatthew G. Knepley     case 3:
530175d3a19aSMatthew G. Knepley       /* Hybrid simplicial 2D */
530275d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
530375d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
530475d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
530575d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
530675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
530775d3a19aSMatthew G. Knepley         ++m;
530875d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
530975d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
531075d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
531175d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
531275d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
531375d3a19aSMatthew G. Knepley         ++m;
531475d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
531575d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
531675d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
531775d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
531875d3a19aSMatthew G. Knepley         }
531975d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
532075d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
532175d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
532275d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
532375d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
532475d3a19aSMatthew G. Knepley         ++m;
532575d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
532675d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
532775d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
532875d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
532975d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
533075d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
533175d3a19aSMatthew G. Knepley         }
533275d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
533375d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
533475d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
533575d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
533675d3a19aSMatthew G. Knepley         }
533775d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
533875d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
533975d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
534075d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
534175d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
534275d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
534375d3a19aSMatthew G. Knepley         }
534475d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
534575d3a19aSMatthew 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]);
534675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
534775d3a19aSMatthew G. Knepley         ++m;
534875d3a19aSMatthew G. Knepley       }
534975d3a19aSMatthew G. Knepley       break;
5350b5da9499SMatthew G. Knepley     case 5:
5351b5da9499SMatthew G. Knepley       /* Simplicial 3D */
5352b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5353b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
5354b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
5355b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5356b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5357b5da9499SMatthew G. Knepley         ++m;
535887fe6628SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
5359b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
5360b5da9499SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5361b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
5362b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
5363b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5364b5da9499SMatthew G. Knepley         }
5365b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
5366b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
5367b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5368b5da9499SMatthew G. Knepley         ++m;
5369b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
5370b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
5371b5da9499SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5372b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
5373b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
5374b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5375b5da9499SMatthew G. Knepley         }
5376b5da9499SMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
5377b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*3     + r;
5378b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r;
5379b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5380b5da9499SMatthew G. Knepley         }
5381b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5382b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
5383b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
5384b5da9499SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
5385b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
5386b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5387b5da9499SMatthew G. Knepley         }
5388b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
5389b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*8     + r;
5390b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r;
5391b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5392b5da9499SMatthew G. Knepley         }
5393b5da9499SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
5394b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*3                    + (p  - cStart)*1     + r;
5395b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r;
5396b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5397b5da9499SMatthew G. Knepley         }
5398b5da9499SMatthew G. Knepley       }
5399b5da9499SMatthew G. Knepley       break;
54006ce3c06aSMatthew G. Knepley     case 7:
54016ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
54026ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
54036ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
54046ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
54056ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
54066ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
54076ce3c06aSMatthew G. Knepley         ++m;
54086ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
54096ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
54106ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
54116ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
54126ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
54136ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54146ce3c06aSMatthew G. Knepley         }
54156ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
54166ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
54176ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
54186ce3c06aSMatthew G. Knepley         ++m;
54196ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
54206ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
54216ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
54226ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[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]);
54236ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
54246ce3c06aSMatthew G. Knepley         ++m;
54256ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
54266ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
54276ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
54286ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
54296ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
54306ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54316ce3c06aSMatthew G. Knepley         }
54326ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
54336ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
54346ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
54356ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54366ce3c06aSMatthew G. Knepley         }
54376ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
54386ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
54396ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5440899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
5441899f98d0SMatthew 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;
54426ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54436ce3c06aSMatthew G. Knepley         }
5444899f98d0SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - fMax);
5445899f98d0SMatthew 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)+depth-1]);
54466ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
544709b1338fSMatthew G. Knepley         ++m;
54486ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
54496ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
54506ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
54516ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
54526ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
54536ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54546ce3c06aSMatthew G. Knepley         }
54556ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
54566ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
54576ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
54586ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54596ce3c06aSMatthew G. Knepley         }
54606ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + r;
54616ce3c06aSMatthew 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;
54626ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
546309b1338fSMatthew G. Knepley         ++m;
54646ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
54656ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
54666ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
54676ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
54686ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
54696ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54706ce3c06aSMatthew G. Knepley         }
54716ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
5472899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*3                            + r;
5473899f98d0SMatthew 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;
54746ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54756ce3c06aSMatthew G. Knepley         }
54766ce3c06aSMatthew G. Knepley       }
54776ce3c06aSMatthew G. Knepley       break;
54782eabf88fSMatthew G. Knepley     case 6:
54792eabf88fSMatthew G. Knepley       /* Hex 3D */
54802eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
54812eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
54822eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
54832eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
54842eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
54852eabf88fSMatthew G. Knepley         ++m;
54862eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
54872eabf88fSMatthew G. Knepley         /* Old edges add new edges and vertex */
54882eabf88fSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
54892eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
54902eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
54912eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54922eabf88fSMatthew G. Knepley         }
54932eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
54942eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
54952eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
54962eabf88fSMatthew G. Knepley         ++m;
54972eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
54982eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
54992eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
55002eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
55012eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
55022eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
55032eabf88fSMatthew G. Knepley         }
55042eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
55052eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*4     + r;
55062eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r;
55072eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
55082eabf88fSMatthew G. Knepley         }
55092eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (p  - fStart);
55102eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]);
55112eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
55122eabf88fSMatthew G. Knepley         ++m;
55132eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
55142eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
55152eabf88fSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
55162eabf88fSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
55172eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
55182eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
55192eabf88fSMatthew G. Knepley         }
55202eabf88fSMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
55212eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*12     + r;
55222eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r;
55232eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
55242eabf88fSMatthew G. Knepley         }
55252eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
55262eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*4                    + (p  - cStart)*6     + r;
55272eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r;
55282eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
55292eabf88fSMatthew G. Knepley         }
55302eabf88fSMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
55312eabf88fSMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eEnd - eStart)              + (fEnd - fStart)                    + (p  - cStart)     + r;
55322eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
55332eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
55342eabf88fSMatthew G. Knepley         }
55352eabf88fSMatthew G. Knepley       }
55362eabf88fSMatthew G. Knepley       break;
553727fcede3SMatthew G. Knepley     case 8:
553827fcede3SMatthew G. Knepley       /* Hybrid Hex 3D */
553927fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
554027fcede3SMatthew G. Knepley         /* Interior vertices stay the same */
554127fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
554227fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
554327fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
554427fcede3SMatthew G. Knepley         ++m;
554527fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
554627fcede3SMatthew G. Knepley         /* Interior edges add new edges and vertex */
554727fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
554827fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
554927fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
555027fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
555127fcede3SMatthew G. Knepley         }
555227fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
555327fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
555427fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
555527fcede3SMatthew G. Knepley         ++m;
555627fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
555727fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
555827fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (p  - eMax);
555927fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[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]);
556027fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
556127fcede3SMatthew G. Knepley         ++m;
556227fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
556327fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
556427fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
556527fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
556627fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
556727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
556827fcede3SMatthew G. Knepley         }
556927fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
557027fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*4     + r;
557127fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
557227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
557327fcede3SMatthew G. Knepley         }
557427fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eMax                        - eStart)     + (p  - fStart);
557527fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
557627fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
557727fcede3SMatthew G. Knepley         ++m;
557827fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
557927fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
558027fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
558127fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
558227fcede3SMatthew 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;
558327fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
558427fcede3SMatthew G. Knepley         }
558527fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (fEnd                                          - fMax);
558627fcede3SMatthew 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)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]);
558727fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
558827fcede3SMatthew G. Knepley         ++m;
558927fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
559027fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
559127fcede3SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
559227fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
559327fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
559427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
559527fcede3SMatthew G. Knepley         }
559627fcede3SMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
559727fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*12     + r;
559827fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
559927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
560027fcede3SMatthew G. Knepley         }
560127fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
560227fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (p  - cStart)*6     + r;
560327fcede3SMatthew 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;
560427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
560527fcede3SMatthew G. Knepley         }
560627fcede3SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
560727fcede3SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eMax                        - eStart)     + (fMax                              - fStart)     + (p  - cStart)     + r;
560827fcede3SMatthew 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;
560927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
561027fcede3SMatthew G. Knepley         }
561127fcede3SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
561227fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
561327fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
561427fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
561527fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
561627fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
561727fcede3SMatthew G. Knepley         }
561827fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
561927fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*4                            + r;
562027fcede3SMatthew 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])*4 + r;
562127fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
562227fcede3SMatthew G. Knepley         }
562327fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (fEnd                                          - fMax)                              + (p  - cMax);
562427fcede3SMatthew 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)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]);
562527fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
562627fcede3SMatthew G. Knepley         ++m;
562727fcede3SMatthew G. Knepley       }
562827fcede3SMatthew G. Knepley       break;
562975d3a19aSMatthew G. Knepley     default:
563075d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
563175d3a19aSMatthew G. Knepley     }
563275d3a19aSMatthew G. Knepley   }
563309b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
563475d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
563575d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
563675d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
563775d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
563806a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
563975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
564075d3a19aSMatthew G. Knepley }
564175d3a19aSMatthew G. Knepley 
564275d3a19aSMatthew G. Knepley #undef __FUNCT__
564375d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels"
564486150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
564575d3a19aSMatthew G. Knepley {
564675d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
56477ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
56487ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
564975d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
565075d3a19aSMatthew G. Knepley 
565175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
565275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
565375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
565475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
565575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
5656d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
56573478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
565875d3a19aSMatthew G. Knepley   ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
565975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
566075d3a19aSMatthew G. Knepley   switch (refiner) {
56613478d7aaSMatthew G. Knepley   case 0: break;
566258b8852aSMatthew G. Knepley   case 7:
566358b8852aSMatthew G. Knepley   case 8:
566458b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
566575d3a19aSMatthew G. Knepley   case 3:
566658b8852aSMatthew G. Knepley   case 4:
566775d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
566875d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
566975d3a19aSMatthew G. Knepley   }
567075d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
567175d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
567275d3a19aSMatthew G. Knepley     const char     *lname;
567375d3a19aSMatthew G. Knepley     PetscBool       isDepth;
567475d3a19aSMatthew G. Knepley     IS              valueIS;
567575d3a19aSMatthew G. Knepley     const PetscInt *values;
567675d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
567775d3a19aSMatthew G. Knepley 
567875d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr);
567975d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
568075d3a19aSMatthew G. Knepley     if (isDepth) continue;
568175d3a19aSMatthew G. Knepley     ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr);
568275d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr);
568375d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
568475d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
568575d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
568675d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
568775d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
568875d3a19aSMatthew G. Knepley       IS              pointIS;
568975d3a19aSMatthew G. Knepley       const PetscInt *points;
569075d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
569175d3a19aSMatthew G. Knepley 
569275d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
569375d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
569475d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
569575d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
569675d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
569775d3a19aSMatthew G. Knepley         switch (refiner) {
569875d3a19aSMatthew G. Knepley         case 1:
569975d3a19aSMatthew G. Knepley           /* Simplicial 2D */
570075d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
570175d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
570275d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
570375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
570475d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
570575d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
570675d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
570775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
570875d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
570975d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
571075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
571175d3a19aSMatthew G. Knepley             }
571275d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
571375d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
571475d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
571575d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
571675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
571775d3a19aSMatthew G. Knepley             }
571875d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
571975d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
572075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
572175d3a19aSMatthew G. Knepley             }
572275d3a19aSMatthew G. Knepley           }
572375d3a19aSMatthew G. Knepley           break;
572475d3a19aSMatthew G. Knepley         case 2:
572575d3a19aSMatthew G. Knepley           /* Hex 2D */
572675d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
572775d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
572875d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
572975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
573075d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
573175d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
573275d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
573375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
573475d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
573575d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
573675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
573775d3a19aSMatthew G. Knepley             }
573875d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
573975d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
574075d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
574175d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
574275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
574375d3a19aSMatthew G. Knepley             }
574475d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
574575d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
574675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
574775d3a19aSMatthew G. Knepley             }
574875d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
574975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
575075d3a19aSMatthew G. Knepley           }
575175d3a19aSMatthew G. Knepley           break;
575275d3a19aSMatthew G. Knepley         case 3:
575375d3a19aSMatthew G. Knepley           /* Hybrid simplicial 2D */
575475d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
575575d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
575675d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
575775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
575875d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
575975d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
576075d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
576175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
576275d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
576375d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
576475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
576575d3a19aSMatthew G. Knepley             }
576675d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
576775d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
576875d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
576975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
577075d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
577175d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
577275d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
577375d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
577475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
577575d3a19aSMatthew G. Knepley             }
577675d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
577775d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
577875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
577975d3a19aSMatthew G. Knepley             }
578075d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
578175d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
578275d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
578375d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
578475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
578575d3a19aSMatthew G. Knepley             }
578675d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
578775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
578875d3a19aSMatthew G. Knepley           }
578975d3a19aSMatthew G. Knepley           break;
5790b5da9499SMatthew G. Knepley         case 5:
5791b5da9499SMatthew G. Knepley           /* Simplicial 3D */
5792b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
5793b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
5794b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
5795b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5796b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
5797b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
5798b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
5799b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
5800b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5801b5da9499SMatthew G. Knepley             }
5802b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
5803b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5804b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
5805b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
5806b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
5807b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
5808b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5809b5da9499SMatthew G. Knepley             }
5810b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
5811b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
5812b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5813b5da9499SMatthew G. Knepley             }
5814b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
5815b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
5816b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
5817b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
5818b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5819b5da9499SMatthew G. Knepley             }
5820b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
5821b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
5822b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5823b5da9499SMatthew G. Knepley             }
5824b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
5825b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
5826b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5827b5da9499SMatthew G. Knepley             }
5828b5da9499SMatthew G. Knepley           }
5829b5da9499SMatthew G. Knepley           break;
58306ce3c06aSMatthew G. Knepley         case 7:
58316ce3c06aSMatthew G. Knepley           /* Hybrid Simplicial 3D */
58326ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
58336ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
58346ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
58356ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58366ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
58376ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
58386ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
58396ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
58406ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58416ce3c06aSMatthew G. Knepley             }
58426ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
58436ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58446ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
58456ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
58466ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
58476ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58486ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
58496ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
58506ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
58516ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
58526ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58536ce3c06aSMatthew G. Knepley             }
58546ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
58556ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
58566ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58576ce3c06aSMatthew G. Knepley             }
58586ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
58596ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
58606ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
58616ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
58626ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58636ce3c06aSMatthew G. Knepley             }
58646ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
58656ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58666ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
58676ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
58686ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
58696ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
58706ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58716ce3c06aSMatthew G. Knepley             }
58726ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
58736ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
58746ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58756ce3c06aSMatthew G. Knepley             }
58766ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
58776ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
587858b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
58796ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
58806ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
58816ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
58826ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58836ce3c06aSMatthew G. Knepley             }
58846ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
58856ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
58866ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58876ce3c06aSMatthew G. Knepley             }
58886ce3c06aSMatthew G. Knepley           }
58896ce3c06aSMatthew G. Knepley           break;
58902eabf88fSMatthew G. Knepley         case 6:
58912eabf88fSMatthew G. Knepley           /* Hex 3D */
58922eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
58932eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
58942eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
58952eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
589619d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
58972eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
58982eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
58992eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
59002eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
59012eabf88fSMatthew G. Knepley             }
59022eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
59032eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
59042eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
59052eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
59062eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
59072eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
59082eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
59092eabf88fSMatthew G. Knepley             }
59102eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
59112eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
59122eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
59132eabf88fSMatthew G. Knepley             }
59142eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
59152eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
59162eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
59172eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
59182eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
59192eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
59202eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
59212eabf88fSMatthew G. Knepley             }
59222eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
59232eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
59242eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
59252eabf88fSMatthew G. Knepley             }
59262eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
59272eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
59282eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
59292eabf88fSMatthew G. Knepley             }
59302eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
59312eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
59322eabf88fSMatthew G. Knepley           }
59332eabf88fSMatthew G. Knepley           break;
593427fcede3SMatthew G. Knepley         case 8:
593527fcede3SMatthew G. Knepley           /* Hybrid Hex 3D */
593627fcede3SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
593727fcede3SMatthew G. Knepley             /* Interior vertices stay the same */
593827fcede3SMatthew G. Knepley             newp = vStartNew + (p - vStart);
593927fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
594027fcede3SMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
594127fcede3SMatthew G. Knepley             /* Interior edges add new edges and vertex */
594227fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
594327fcede3SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
594427fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
594527fcede3SMatthew G. Knepley             }
594627fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
594727fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
594827fcede3SMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
594927fcede3SMatthew G. Knepley             /* Hybrid edges stay the same */
595027fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
595127fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
595227fcede3SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
595327fcede3SMatthew G. Knepley             /* Interior faces add new faces, edges, and vertex */
595427fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
595527fcede3SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
595627fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
595727fcede3SMatthew G. Knepley             }
595827fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
595927fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
596027fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
596127fcede3SMatthew G. Knepley             }
596227fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
596327fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
596427fcede3SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
596527fcede3SMatthew G. Knepley             /* Hybrid faces add new faces and edges */
596627fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
596727fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
596827fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
596927fcede3SMatthew G. Knepley             }
597027fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
597127fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
597227fcede3SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
597327fcede3SMatthew G. Knepley             /* Interior cells add new cells, faces, edges, and vertex */
597427fcede3SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
597527fcede3SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
597627fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
597727fcede3SMatthew G. Knepley             }
597827fcede3SMatthew G. Knepley             for (r = 0; r < 12; ++r) {
597927fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
598027fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
598127fcede3SMatthew G. Knepley             }
598227fcede3SMatthew G. Knepley             for (r = 0; r < 6; ++r) {
598327fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
598427fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
598527fcede3SMatthew G. Knepley             }
598627fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
598727fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
598827fcede3SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
598927fcede3SMatthew G. Knepley             /* Hybrid cells add new cells, faces, and edges */
599027fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
599127fcede3SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
599227fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
599327fcede3SMatthew G. Knepley             }
599427fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
599527fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
599627fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
599727fcede3SMatthew G. Knepley             }
599827fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
599927fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
600027fcede3SMatthew G. Knepley           }
600127fcede3SMatthew G. Knepley           break;
600275d3a19aSMatthew G. Knepley         default:
600375d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
600475d3a19aSMatthew G. Knepley         }
600575d3a19aSMatthew G. Knepley       }
600675d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
600775d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
600875d3a19aSMatthew G. Knepley     }
600975d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
601075d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
601175d3a19aSMatthew G. Knepley     if (0) {
601275d3a19aSMatthew G. Knepley       ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr);
601375d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
601475d3a19aSMatthew G. Knepley       ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
601575d3a19aSMatthew G. Knepley     }
601675d3a19aSMatthew G. Knepley   }
601775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
601875d3a19aSMatthew G. Knepley }
601975d3a19aSMatthew G. Knepley 
602075d3a19aSMatthew G. Knepley #undef __FUNCT__
6021509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexRefineUniform_Internal"
602275d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
6023509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
602475d3a19aSMatthew G. Knepley {
602575d3a19aSMatthew G. Knepley   DM             rdm;
602675d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
602775d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
602875d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
602975d3a19aSMatthew G. Knepley 
603075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
603175d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
603275d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
603375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
603475d3a19aSMatthew G. Knepley   ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr);
603575d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
603675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
6037785e854fSJed Brown   ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr);
603875d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
603975d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
604075d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
604175d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
604275d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
604375d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
604475d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
604575d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
604675d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
604775d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
604875d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
604975d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
605075d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
605175d3a19aSMatthew G. Knepley   /* Step 6: Set coordinates for vertices */
605275d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
605375d3a19aSMatthew G. Knepley   /* Step 7: Create pointSF */
605475d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
605575d3a19aSMatthew G. Knepley   /* Step 8: Create labels */
605675d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
605775d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
605875d3a19aSMatthew G. Knepley 
605975d3a19aSMatthew G. Knepley   *dmRefined = rdm;
606075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
606175d3a19aSMatthew G. Knepley }
606275d3a19aSMatthew G. Knepley 
606375d3a19aSMatthew G. Knepley #undef __FUNCT__
606475d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform"
606575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
606675d3a19aSMatthew G. Knepley {
606775d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
606875d3a19aSMatthew G. Knepley 
606975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
607075d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
607175d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
607275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
607375d3a19aSMatthew G. Knepley }
607475d3a19aSMatthew G. Knepley 
607575d3a19aSMatthew G. Knepley #undef __FUNCT__
607675d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform"
607775d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
607875d3a19aSMatthew G. Knepley {
607975d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
608075d3a19aSMatthew G. Knepley 
608175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
608275d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
608375d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
608475d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
608575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
608675d3a19aSMatthew G. Knepley }
608775d3a19aSMatthew G. Knepley 
608875d3a19aSMatthew G. Knepley #undef __FUNCT__
608975d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit"
609075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
609175d3a19aSMatthew G. Knepley {
609275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
609375d3a19aSMatthew G. Knepley 
609475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
609575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
609675d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
609775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
609875d3a19aSMatthew G. Knepley }
609975d3a19aSMatthew G. Knepley 
610075d3a19aSMatthew G. Knepley #undef __FUNCT__
610175d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit"
610275d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
610375d3a19aSMatthew G. Knepley {
610475d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
610575d3a19aSMatthew G. Knepley 
610675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
610775d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
610875d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
610975d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
611075d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
611175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
611275d3a19aSMatthew G. Knepley }
611375d3a19aSMatthew G. Knepley 
611475d3a19aSMatthew G. Knepley #undef __FUNCT__
6115509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Internal"
6116509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
611775d3a19aSMatthew G. Knepley {
61183478d7aaSMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax;
611975d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
612075d3a19aSMatthew G. Knepley 
612175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
612275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
61233478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
61243478d7aaSMatthew G. Knepley   if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);}
612575d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
612675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr);
612775d3a19aSMatthew G. Knepley   switch (dim) {
612875d3a19aSMatthew G. Knepley   case 2:
612975d3a19aSMatthew G. Knepley     switch (coneSize) {
613075d3a19aSMatthew G. Knepley     case 3:
613175d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 3; /* Hybrid */
613275d3a19aSMatthew G. Knepley       else *cellRefiner = 1; /* Triangular */
613375d3a19aSMatthew G. Knepley       break;
613475d3a19aSMatthew G. Knepley     case 4:
613575d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 4; /* Hybrid */
613675d3a19aSMatthew G. Knepley       else *cellRefiner = 2; /* Quadrilateral */
613775d3a19aSMatthew G. Knepley       break;
613875d3a19aSMatthew G. Knepley     default:
613975d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
614075d3a19aSMatthew G. Knepley     }
614175d3a19aSMatthew G. Knepley     break;
6142b5da9499SMatthew G. Knepley   case 3:
6143b5da9499SMatthew G. Knepley     switch (coneSize) {
6144b5da9499SMatthew G. Knepley     case 4:
6145b5da9499SMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 7; /* Hybrid */
6146b5da9499SMatthew G. Knepley       else *cellRefiner = 5; /* Tetrahedral */
6147b5da9499SMatthew G. Knepley       break;
61482eabf88fSMatthew G. Knepley     case 6:
61492eabf88fSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 8; /* Hybrid */
61502eabf88fSMatthew G. Knepley       else *cellRefiner = 6; /* hexahedral */
61512eabf88fSMatthew G. Knepley       break;
6152b5da9499SMatthew G. Knepley     default:
6153b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
6154b5da9499SMatthew G. Knepley     }
6155b5da9499SMatthew G. Knepley     break;
615675d3a19aSMatthew G. Knepley   default:
615775d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
615875d3a19aSMatthew G. Knepley   }
615975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
616075d3a19aSMatthew G. Knepley }
6161