xref: /petsc/src/dm/impls/plex/plexrefine.c (revision de65f515ffd7817158584230fc1c95bfdec70ffe)
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__
2975d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerGetSizes"
3075d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[])
3175d3a19aSMatthew G. Knepley {
326ce3c06aSMatthew G. Knepley   PetscInt       cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
3375d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
3475d3a19aSMatthew G. Knepley 
3575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
3675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
3775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
3875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
3975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
4075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
4175d3a19aSMatthew G. Knepley   switch (refiner) {
423478d7aaSMatthew G. Knepley   case 0:
433478d7aaSMatthew G. Knepley     break;
4475d3a19aSMatthew G. Knepley   case 1:
4575d3a19aSMatthew G. Knepley     /* Simplicial 2D */
4675d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart;         /* Add a vertex on every face */
4775d3a19aSMatthew 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 */
4875d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                     /* Every cell split into 4 cells */
4975d3a19aSMatthew G. Knepley     break;
5075d3a19aSMatthew G. Knepley   case 3:
51d963de37SMatthew G. Knepley     /* Hybrid Simplicial 2D */
5275d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
5375d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
5475d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart;                                         /* Add a vertex on every face, but not hybrid faces */
5575d3a19aSMatthew 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 */
5675d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax);                                   /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */
5775d3a19aSMatthew G. Knepley     break;
5875d3a19aSMatthew G. Knepley   case 2:
5975d3a19aSMatthew G. Knepley     /* Hex 2D */
6075d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + cEnd - cStart + fEnd - fStart; /* Add a vertex on every face and cell */
6175d3a19aSMatthew 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 */
6275d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                             /* Every cell split into 4 cells */
6375d3a19aSMatthew G. Knepley     break;
64b5da9499SMatthew G. Knepley   case 5:
65b5da9499SMatthew G. Knepley     /* Simplicial 3D */
66b5da9499SMatthew G. Knepley     depthSize[0] =    vEnd - vStart  +    eEnd - eStart;                    /* Add a vertex on every edge */
67b5da9499SMatthew 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 */
68b5da9499SMatthew G. Knepley     depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart);                   /* Every face split into 4 faces and 8 faces are added for each cell */
69b5da9499SMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                       /* Every cell split into 8 cells */
70b5da9499SMatthew G. Knepley     break;
71b5da9499SMatthew G. Knepley   case 7:
72b5da9499SMatthew G. Knepley     /* Hybrid Simplicial 3D */
73b5da9499SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
746ce3c06aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
75b5da9499SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
76dae4404aSMatthew G. Knepley     /* Tetrahedra */
77dae4404aSMatthew G. Knepley     depthSize[0]  =    vEnd - vStart  +    eMax - eStart;                    /* Add a vertex on every interior edge */
78dae4404aSMatthew 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 */
79dae4404aSMatthew G. Knepley     depthSize[2]  = 4*(fMax - fStart) + 8*(cMax - cStart);                   /* Every interior face split into 4 faces, 8 faces added for each interior cell */
80dae4404aSMatthew G. Knepley     depthSize[3]  = 8*(cMax - cStart);                                       /* Every interior cell split into 8 cells */
81dae4404aSMatthew G. Knepley     /* Triangular Prisms */
82dae4404aSMatthew G. Knepley     depthSize[0] += 0;                                                       /* No hybrid vertices */
83dae4404aSMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax);                     /* Every hybrid edge remains, 1 edge for every hybrid face */
846ce3c06aSMatthew 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 */
85dae4404aSMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                         /* Every hybrid cell split into 4 cells */
86b5da9499SMatthew G. Knepley     break;
876ce3c06aSMatthew G. Knepley   case 6:
886ce3c06aSMatthew G. Knepley     /* Hex 3D */
896ce3c06aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
906ce3c06aSMatthew 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 */
916ce3c06aSMatthew 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 */
926ce3c06aSMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                             /* Every cell split into 8 cells */
936ce3c06aSMatthew G. Knepley     break;
9475d3a19aSMatthew G. Knepley   default:
9575d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
9675d3a19aSMatthew G. Knepley   }
9775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
9875d3a19aSMatthew G. Knepley }
9975d3a19aSMatthew G. Knepley 
10042525629SMatthew G. Knepley /* Return triangle edge for orientation o, if it is r for o == 0 */
10142525629SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
102518a8359SMatthew G. Knepley   return (o < 0 ? 2-(o+r) : o+r)%3;
103518a8359SMatthew G. Knepley }
104*de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
105*de65f515SMatthew G. Knepley   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
106*de65f515SMatthew G. Knepley }
107518a8359SMatthew G. Knepley 
108518a8359SMatthew G. Knepley /* Return triangle subface for orientation o, if it is r for o == 0 */
109518a8359SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
1104bae88c7SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%3;
11142525629SMatthew G. Knepley }
112*de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
113*de65f515SMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 3+s-o)%3;
114*de65f515SMatthew G. Knepley }
11542525629SMatthew G. Knepley 
116e3f8b1d6SMatthew G. Knepley /* Return quad edge for orientation o, if it is r for o == 0 */
117e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
118e3f8b1d6SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%4;
119e3f8b1d6SMatthew G. Knepley }
120e3f8b1d6SMatthew G. Knepley 
121e3f8b1d6SMatthew G. Knepley /* Return quad subface for orientation o, if it is r for o == 0 */
122e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
1234bae88c7SMatthew G. Knepley   return (o < 0 ? 4-(o+r) : o+r)%4;
12442525629SMatthew G. Knepley }
12542525629SMatthew G. Knepley 
12675d3a19aSMatthew G. Knepley #undef __FUNCT__
12775d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetConeSizes"
12875d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
12975d3a19aSMatthew G. Knepley {
130b5da9499SMatthew 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;
13175d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
13275d3a19aSMatthew G. Knepley 
13375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
13475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
13575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
13675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
13775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
13875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
13975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
1403478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
14175d3a19aSMatthew G. Knepley   switch (refiner) {
1423478d7aaSMatthew G. Knepley   case 0: break;
14375d3a19aSMatthew G. Knepley   case 1:
14475d3a19aSMatthew G. Knepley     /* Simplicial 2D */
14575d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
14675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
14775d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
14875d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
14975d3a19aSMatthew G. Knepley 
15075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
15175d3a19aSMatthew G. Knepley       }
15275d3a19aSMatthew G. Knepley     }
15375d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
15475d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
15575d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
15675d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
15775d3a19aSMatthew G. Knepley         PetscInt       size;
15875d3a19aSMatthew G. Knepley 
15975d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
16075d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
16175d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
16275d3a19aSMatthew G. Knepley       }
16375d3a19aSMatthew G. Knepley     }
16475d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
16575d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
16675d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
16775d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
16875d3a19aSMatthew G. Knepley 
16975d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
17075d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
17175d3a19aSMatthew G. Knepley       }
17275d3a19aSMatthew G. Knepley     }
17375d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
17475d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
17575d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
17675d3a19aSMatthew G. Knepley       PetscInt       size;
17775d3a19aSMatthew G. Knepley 
17875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
17975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
18075d3a19aSMatthew G. Knepley     }
18175d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
18275d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
18375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
18475d3a19aSMatthew G. Knepley       PetscInt       size;
18575d3a19aSMatthew G. Knepley 
18675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
18775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
18875d3a19aSMatthew G. Knepley     }
18975d3a19aSMatthew G. Knepley     break;
19075d3a19aSMatthew G. Knepley   case 2:
19175d3a19aSMatthew G. Knepley     /* Hex 2D */
19275d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
19375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
19475d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
19575d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
19675d3a19aSMatthew G. Knepley 
19775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
19875d3a19aSMatthew G. Knepley       }
19975d3a19aSMatthew G. Knepley     }
20075d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
20175d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
20275d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
20375d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
20475d3a19aSMatthew G. Knepley         PetscInt       size;
20575d3a19aSMatthew G. Knepley 
20675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
20775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
20875d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
20975d3a19aSMatthew G. Knepley       }
21075d3a19aSMatthew G. Knepley     }
21175d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
21275d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
21375d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
21475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
21575d3a19aSMatthew G. Knepley 
21675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
21775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
21875d3a19aSMatthew G. Knepley       }
21975d3a19aSMatthew G. Knepley     }
22075d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
22175d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
22275d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
22375d3a19aSMatthew G. Knepley       PetscInt       size;
22475d3a19aSMatthew G. Knepley 
22575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
22675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
22775d3a19aSMatthew G. Knepley     }
22875d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
22975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
23075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
23175d3a19aSMatthew G. Knepley       PetscInt       size;
23275d3a19aSMatthew G. Knepley 
23375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
23475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
23575d3a19aSMatthew G. Knepley     }
23675d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
23775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
23875d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
23975d3a19aSMatthew G. Knepley 
24075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
24175d3a19aSMatthew G. Knepley     }
24275d3a19aSMatthew G. Knepley     break;
24375d3a19aSMatthew G. Knepley   case 3:
244d963de37SMatthew G. Knepley     /* Hybrid Simplicial 2D */
24575d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
24675d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
24775d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
24875d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
24975d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
25075d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
25175d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
25275d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
25375d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
25475d3a19aSMatthew G. Knepley 
25575d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
25675d3a19aSMatthew G. Knepley       }
25775d3a19aSMatthew G. Knepley     }
25875d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
25975d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
26075d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
26175d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
26275d3a19aSMatthew G. Knepley 
26375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
26475d3a19aSMatthew G. Knepley       }
26575d3a19aSMatthew G. Knepley     }
26675d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
26775d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
26875d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
26975d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
27075d3a19aSMatthew G. Knepley         PetscInt       size;
27175d3a19aSMatthew G. Knepley 
27275d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
27375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
27475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
27575d3a19aSMatthew G. Knepley       }
27675d3a19aSMatthew G. Knepley     }
27775d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
27875d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
27975d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
28075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
28175d3a19aSMatthew G. Knepley 
28275d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
28375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
28475d3a19aSMatthew G. Knepley       }
28575d3a19aSMatthew G. Knepley     }
28675d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
28775d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
28875d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
28975d3a19aSMatthew G. Knepley       PetscInt       size;
29075d3a19aSMatthew G. Knepley 
29175d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
29275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
29375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
29475d3a19aSMatthew G. Knepley     }
29575d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
29675d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
29775d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
29875d3a19aSMatthew G. Knepley 
29975d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
30075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
30175d3a19aSMatthew G. Knepley     }
30275d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
30375d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
30475d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
30575d3a19aSMatthew G. Knepley       PetscInt       size;
30675d3a19aSMatthew G. Knepley 
30775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
30875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
30975d3a19aSMatthew G. Knepley     }
31075d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
31175d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
31275d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
31375d3a19aSMatthew G. Knepley       const PetscInt *support;
31475d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
31575d3a19aSMatthew G. Knepley 
31675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
31775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
31875d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
31975d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
32075d3a19aSMatthew G. Knepley         else newSize += 2;
32175d3a19aSMatthew G. Knepley       }
32275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
32375d3a19aSMatthew G. Knepley     }
32475d3a19aSMatthew G. Knepley     break;
325b5da9499SMatthew G. Knepley   case 5:
326b5da9499SMatthew G. Knepley     /* Simplicial 3D */
327b5da9499SMatthew G. Knepley     /* All cells have 4 faces */
328b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
329b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
330dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
331b5da9499SMatthew G. Knepley 
332b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
333b5da9499SMatthew G. Knepley       }
334b5da9499SMatthew G. Knepley     }
335b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
336b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
337b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
338b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
339b5da9499SMatthew G. Knepley         PetscInt       size;
340b5da9499SMatthew G. Knepley 
341b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
342b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
343b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
344b5da9499SMatthew G. Knepley       }
345b5da9499SMatthew G. Knepley     }
346b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
347b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
348b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
349b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
350b5da9499SMatthew G. Knepley 
351b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
352b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
353b5da9499SMatthew G. Knepley       }
354b5da9499SMatthew G. Knepley     }
355b5da9499SMatthew G. Knepley     /* Split edges have 2 vertices and the same faces */
356b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
357b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
358b5da9499SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
359b5da9499SMatthew G. Knepley         PetscInt       size;
360b5da9499SMatthew G. Knepley 
361b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
362b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
363b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
364b5da9499SMatthew G. Knepley       }
365b5da9499SMatthew G. Knepley     }
366b5da9499SMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
367b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
368b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
369b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
370b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
371b5da9499SMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
372b5da9499SMatthew G. Knepley 
373b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
374b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
375b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
376b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
377b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
378b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
379b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
380b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
38186f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
38286f0afeeSMatthew G. Knepley           er = ornt[c] < 0 ? (-(ornt[c]+1) + 2-r)%3 : (ornt[c] + r)%3;
383b5da9499SMatthew G. Knepley           if (er == eint[c]) {
384b5da9499SMatthew G. Knepley             intFaces += 1;
385b5da9499SMatthew G. Knepley           } else {
386b5da9499SMatthew G. Knepley             intFaces += 2;
387b5da9499SMatthew G. Knepley           }
388b5da9499SMatthew G. Knepley         }
389b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
390b5da9499SMatthew G. Knepley       }
391b5da9499SMatthew G. Knepley     }
392b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
393b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
394b5da9499SMatthew G. Knepley       const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
395b5da9499SMatthew G. Knepley 
396b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
397b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
398b5da9499SMatthew G. Knepley     }
399b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
400b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
401b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
402b5da9499SMatthew G. Knepley       PetscInt       size;
403b5da9499SMatthew G. Knepley 
404b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
405b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
406b5da9499SMatthew G. Knepley     }
407b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
408b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
409b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
410b5da9499SMatthew G. Knepley       PetscInt       size, *star = NULL, starSize, s, cellSize = 0;
411b5da9499SMatthew G. Knepley 
412b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
413b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
414b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
415b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
416b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
417b5da9499SMatthew G. Knepley 
418b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
419b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
420b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
421b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
422b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
42342525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
424b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
425b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
426b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
42742525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
42842525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
429b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
430b5da9499SMatthew G. Knepley         }
431b5da9499SMatthew G. Knepley       }
432b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
433b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr);
434b5da9499SMatthew G. Knepley     }
435b5da9499SMatthew G. Knepley     break;
436dae4404aSMatthew G. Knepley   case 7:
4376ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
4386ce3c06aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
4396ce3c06aSMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
440dae4404aSMatthew G. Knepley     /* Interior cells have 4 faces */
441dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
442dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
443dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
444dae4404aSMatthew G. Knepley 
445dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
446dae4404aSMatthew G. Knepley       }
447dae4404aSMatthew G. Knepley     }
448dae4404aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
449dae4404aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
450dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
451dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
452dae4404aSMatthew G. Knepley 
453dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr);
454dae4404aSMatthew G. Knepley       }
455dae4404aSMatthew G. Knepley     }
4566ce3c06aSMatthew G. Knepley     /* Interior split faces have 3 edges and the same cells as the parent */
457dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
458dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
459dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
460dae4404aSMatthew G. Knepley         PetscInt       size;
461dae4404aSMatthew G. Knepley 
462dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
463dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
464dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
465dae4404aSMatthew G. Knepley       }
466dae4404aSMatthew G. Knepley     }
467dae4404aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
468dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
469dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
470dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
471dae4404aSMatthew G. Knepley 
472dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
473dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
474dae4404aSMatthew G. Knepley       }
475dae4404aSMatthew G. Knepley     }
4766ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
4776ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
4786ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
4796ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
4806ce3c06aSMatthew G. Knepley         PetscInt       size;
4816ce3c06aSMatthew G. Knepley 
4826ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
4836ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
4846ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
4856ce3c06aSMatthew G. Knepley       }
4866ce3c06aSMatthew G. Knepley     }
4876ce3c06aSMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
4886ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
4896ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
4906ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
4916ce3c06aSMatthew G. Knepley 
4926ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
4936ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
4946ce3c06aSMatthew G. Knepley       }
4956ce3c06aSMatthew G. Knepley     }
4966ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces */
497dae4404aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
498dae4404aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
499dae4404aSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
500dae4404aSMatthew G. Knepley         PetscInt       size;
501dae4404aSMatthew G. Knepley 
502dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
503dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
504dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
505dae4404aSMatthew G. Knepley       }
506dae4404aSMatthew G. Knepley     }
5076ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
508dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
509dae4404aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
510dae4404aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
511dae4404aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
512dae4404aSMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
513dae4404aSMatthew G. Knepley 
514dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
515dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
516dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
517dae4404aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
518dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
519dae4404aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
520dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
521dae4404aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
5226ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
523dae4404aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
524dae4404aSMatthew G. Knepley             er = ornt[c] < 0 ? (-(ornt[c]+1) + 2-r)%3 : (ornt[c] + r)%3;
525dae4404aSMatthew G. Knepley             if (er == eint[c]) {
526dae4404aSMatthew G. Knepley               intFaces += 1;
527dae4404aSMatthew G. Knepley             } else {
528dae4404aSMatthew G. Knepley               intFaces += 2;
529dae4404aSMatthew G. Knepley             }
5306ce3c06aSMatthew G. Knepley           } else {
5316ce3c06aSMatthew G. Knepley             intFaces += 1;
5326ce3c06aSMatthew G. Knepley           }
533dae4404aSMatthew G. Knepley         }
534dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
535dae4404aSMatthew G. Knepley       }
536dae4404aSMatthew G. Knepley     }
5376ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
538dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
539dae4404aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
540dae4404aSMatthew G. Knepley 
541dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
542dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
543dae4404aSMatthew G. Knepley     }
5446ce3c06aSMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
545dae4404aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
5466ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
5476ce3c06aSMatthew G. Knepley       PetscInt       size;
5486ce3c06aSMatthew G. Knepley 
5496ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
5506ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
5516ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
5526ce3c06aSMatthew G. Knepley     }
5536ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
5546ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
5556ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
556dae4404aSMatthew G. Knepley       PetscInt       size;
557dae4404aSMatthew G. Knepley 
558dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
559dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
5606ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr);
561dae4404aSMatthew G. Knepley     }
5626ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
563dae4404aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
564dae4404aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
565dae4404aSMatthew G. Knepley       PetscInt       size;
566dae4404aSMatthew G. Knepley 
567dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
568dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
569dae4404aSMatthew G. Knepley     }
5706ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
5716ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
5726ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
573dae4404aSMatthew G. Knepley       const PetscInt *support;
5746ce3c06aSMatthew G. Knepley       PetscInt        size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
575dae4404aSMatthew G. Knepley 
5766ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
5776ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
578dae4404aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
5796ce3c06aSMatthew G. Knepley         if (support[s] < fMax) faceSize += 2;
5806ce3c06aSMatthew G. Knepley         else                   faceSize += 1;
581dae4404aSMatthew G. Knepley       }
5826ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
5836ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
5846ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
5856ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
5866ce3c06aSMatthew G. Knepley 
5876ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
5886ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
5896ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
5906ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
5916ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
5926ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
5936ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
5946ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
5956ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
5966ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
5976ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
5986ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
5996ce3c06aSMatthew G. Knepley         }
6006ce3c06aSMatthew G. Knepley       }
6016ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
6026ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr);
603dae4404aSMatthew G. Knepley     }
604dae4404aSMatthew G. Knepley     break;
6052eabf88fSMatthew G. Knepley   case 6:
6062eabf88fSMatthew G. Knepley     /* Hex 3D */
6072eabf88fSMatthew G. Knepley     /* All cells have 6 faces */
6082eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6092eabf88fSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
6102eabf88fSMatthew G. Knepley         const PetscInt newp = (c - cStart)*8 + r;
6112eabf88fSMatthew G. Knepley 
6122eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
6132eabf88fSMatthew G. Knepley       }
6142eabf88fSMatthew G. Knepley     }
6152eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
6162eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
6172eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
6182eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
6192eabf88fSMatthew G. Knepley         PetscInt       size;
6202eabf88fSMatthew G. Knepley 
6212eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
6222eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
6232eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6242eabf88fSMatthew G. Knepley       }
6252eabf88fSMatthew G. Knepley     }
6262eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
6272eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6282eabf88fSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
6292eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
6302eabf88fSMatthew G. Knepley 
6312eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
6322eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
6332eabf88fSMatthew G. Knepley       }
6342eabf88fSMatthew G. Knepley     }
6352eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
6362eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
6372eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
6382eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
6392eabf88fSMatthew G. Knepley         PetscInt       size;
6402eabf88fSMatthew G. Knepley 
6412eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6422eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
6432eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6442eabf88fSMatthew G. Knepley       }
6452eabf88fSMatthew G. Knepley     }
6462eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
6472eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
6482eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
6492eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
6502eabf88fSMatthew G. Knepley         PetscInt       size;
6512eabf88fSMatthew G. Knepley 
6522eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6532eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
6542eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
6552eabf88fSMatthew G. Knepley       }
6562eabf88fSMatthew G. Knepley     }
6572eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
6582eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6592eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
6602eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
6612eabf88fSMatthew G. Knepley 
6622eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6632eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
6642eabf88fSMatthew G. Knepley       }
6652eabf88fSMatthew G. Knepley     }
6662eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
6672eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
6682eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
6692eabf88fSMatthew G. Knepley       PetscInt       size;
6702eabf88fSMatthew G. Knepley 
6712eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
6722eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6732eabf88fSMatthew G. Knepley     }
6742eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
6752eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
6762eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
6772eabf88fSMatthew G. Knepley       PetscInt       size;
6782eabf88fSMatthew G. Knepley 
6792eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
6802eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
6812eabf88fSMatthew G. Knepley     }
6822eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
6832eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
6842eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
6852eabf88fSMatthew G. Knepley       PetscInt       size;
6862eabf88fSMatthew G. Knepley 
6872eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
6882eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
6892eabf88fSMatthew G. Knepley     }
6902eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
6912eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6922eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
6932eabf88fSMatthew G. Knepley 
6942eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
6952eabf88fSMatthew G. Knepley     }
6962eabf88fSMatthew G. Knepley     break;
69775d3a19aSMatthew G. Knepley   default:
69875d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
69975d3a19aSMatthew G. Knepley   }
70075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
70175d3a19aSMatthew G. Knepley }
70275d3a19aSMatthew G. Knepley 
70375d3a19aSMatthew G. Knepley #undef __FUNCT__
70475d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCones"
70575d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
70675d3a19aSMatthew G. Knepley {
707b5da9499SMatthew G. Knepley   const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
7086ce3c06aSMatthew G. Knepley   PetscInt        cStart,    cEnd,    cMax,    vStart,    vEnd, vMax, fStart,    fEnd,    fMax,    eStart,    eEnd,    eMax;
7096ce3c06aSMatthew G. Knepley   PetscInt        cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew,    fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
7106ce3c06aSMatthew G. Knepley   PetscInt        depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
71175d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
71275d3a19aSMatthew G. Knepley 
71375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
71475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
71575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
71675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
71775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
71875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
71975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
7203478d7aaSMatthew G. Knepley   if (refiner) {
72175d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
72275d3a19aSMatthew G. Knepley     ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
7233478d7aaSMatthew G. Knepley   }
72475d3a19aSMatthew G. Knepley   switch (refiner) {
7253478d7aaSMatthew G. Knepley   case 0: break;
72675d3a19aSMatthew G. Knepley   case 1:
72775d3a19aSMatthew G. Knepley     /* Simplicial 2D */
72875d3a19aSMatthew G. Knepley     /*
72975d3a19aSMatthew G. Knepley      2
73075d3a19aSMatthew G. Knepley      |\
73175d3a19aSMatthew G. Knepley      | \
73275d3a19aSMatthew G. Knepley      |  \
73375d3a19aSMatthew G. Knepley      |   \
73475d3a19aSMatthew G. Knepley      | C  \
73575d3a19aSMatthew G. Knepley      |     \
73675d3a19aSMatthew G. Knepley      |      \
73775d3a19aSMatthew G. Knepley      2---1---1
73875d3a19aSMatthew G. Knepley      |\  D  / \
73975d3a19aSMatthew G. Knepley      | 2   0   \
74075d3a19aSMatthew G. Knepley      |A \ /  B  \
74175d3a19aSMatthew G. Knepley      0---0-------1
74275d3a19aSMatthew G. Knepley      */
74375d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
74475d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
74575d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
74675d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
74775d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
74875d3a19aSMatthew G. Knepley 
74975d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
75075d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
75175d3a19aSMatthew G. Knepley       /* A triangle */
75275d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
75375d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
75475d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
75575d3a19aSMatthew G. Knepley       orntNew[1] = -2;
75675d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
75775d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
75875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
75975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
76075d3a19aSMatthew G. Knepley #if 1
76175d3a19aSMatthew 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);
76275d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
76375d3a19aSMatthew 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);
76475d3a19aSMatthew G. Knepley       }
76575d3a19aSMatthew G. Knepley #endif
76675d3a19aSMatthew G. Knepley       /* B triangle */
76775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
76875d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
76975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
77075d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
77175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
77275d3a19aSMatthew G. Knepley       orntNew[2] = -2;
77375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
77475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
77575d3a19aSMatthew G. Knepley #if 1
77675d3a19aSMatthew 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);
77775d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
77875d3a19aSMatthew 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);
77975d3a19aSMatthew G. Knepley       }
78075d3a19aSMatthew G. Knepley #endif
78175d3a19aSMatthew G. Knepley       /* C triangle */
78275d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
78375d3a19aSMatthew G. Knepley       orntNew[0] = -2;
78475d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
78575d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
78675d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
78775d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
78875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
78975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
79075d3a19aSMatthew G. Knepley #if 1
79175d3a19aSMatthew 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);
79275d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
79375d3a19aSMatthew 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);
79475d3a19aSMatthew G. Knepley       }
79575d3a19aSMatthew G. Knepley #endif
79675d3a19aSMatthew G. Knepley       /* D triangle */
79775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
79875d3a19aSMatthew G. Knepley       orntNew[0] = 0;
79975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
80075d3a19aSMatthew G. Knepley       orntNew[1] = 0;
80175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
80275d3a19aSMatthew G. Knepley       orntNew[2] = 0;
80375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
80475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
80575d3a19aSMatthew G. Knepley #if 1
80675d3a19aSMatthew 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);
80775d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
80875d3a19aSMatthew 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);
80975d3a19aSMatthew G. Knepley       }
81075d3a19aSMatthew G. Knepley #endif
81175d3a19aSMatthew G. Knepley     }
81275d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
81375d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
81475d3a19aSMatthew G. Knepley     ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr);
81575d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
81675d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
81775d3a19aSMatthew G. Knepley 
81875d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
81975d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
820297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
82175d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
82275d3a19aSMatthew G. Knepley 
82375d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
82475d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
82575d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
82675d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
82775d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
82875d3a19aSMatthew G. Knepley #if 1
82975d3a19aSMatthew 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);
83075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
83175d3a19aSMatthew 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);
83275d3a19aSMatthew G. Knepley         }
83375d3a19aSMatthew G. Knepley #endif
83475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
83575d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
83675d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
83775d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
83875d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
839297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
84075d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
84175d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
84275d3a19aSMatthew G. Knepley           }
843297d2bf4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
84475d3a19aSMatthew G. Knepley         }
84575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
84675d3a19aSMatthew G. Knepley #if 1
84775d3a19aSMatthew 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);
84875d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
84975d3a19aSMatthew 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);
85075d3a19aSMatthew G. Knepley         }
85175d3a19aSMatthew G. Knepley #endif
85275d3a19aSMatthew G. Knepley       }
85375d3a19aSMatthew G. Knepley     }
85475d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
85575d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
85675d3a19aSMatthew G. Knepley       const PetscInt *cone;
85775d3a19aSMatthew G. Knepley 
85875d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
85975d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
86075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
86175d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
86275d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
86375d3a19aSMatthew G. Knepley 
86475d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
86575d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
86675d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
86775d3a19aSMatthew G. Knepley #if 1
86875d3a19aSMatthew 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);
86975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
87075d3a19aSMatthew 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);
87175d3a19aSMatthew G. Knepley         }
87275d3a19aSMatthew G. Knepley #endif
87375d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
87475d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
87575d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
87675d3a19aSMatthew G. Knepley #if 1
87775d3a19aSMatthew 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);
87875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
87975d3a19aSMatthew 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);
88075d3a19aSMatthew G. Knepley         }
88175d3a19aSMatthew G. Knepley #endif
88275d3a19aSMatthew G. Knepley       }
88375d3a19aSMatthew G. Knepley     }
88475d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
88575d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
88675d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
88775d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
88875d3a19aSMatthew G. Knepley       PetscInt        size, s;
88975d3a19aSMatthew G. Knepley 
89075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
89175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
89275d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
89375d3a19aSMatthew G. Knepley         PetscInt r = 0;
89475d3a19aSMatthew G. Knepley 
89575d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
89675d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
89775d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
89875d3a19aSMatthew G. Knepley       }
89975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
90075d3a19aSMatthew G. Knepley #if 1
90175d3a19aSMatthew 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);
90275d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
90375d3a19aSMatthew 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);
90475d3a19aSMatthew G. Knepley       }
90575d3a19aSMatthew G. Knepley #endif
90675d3a19aSMatthew G. Knepley     }
90775d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
90875d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
90975d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
91075d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
91175d3a19aSMatthew G. Knepley       PetscInt        size, s;
91275d3a19aSMatthew G. Knepley 
91375d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
91475d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
91575d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
91675d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
91775d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
91875d3a19aSMatthew G. Knepley         PetscInt r = 0;
91975d3a19aSMatthew G. Knepley 
92075d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
92175d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
92275d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
92375d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
92475d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
92575d3a19aSMatthew G. Knepley       }
92675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
92775d3a19aSMatthew G. Knepley #if 1
92875d3a19aSMatthew 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);
92975d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
93075d3a19aSMatthew 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);
93175d3a19aSMatthew G. Knepley       }
93275d3a19aSMatthew G. Knepley #endif
93375d3a19aSMatthew G. Knepley     }
93475d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
93575d3a19aSMatthew G. Knepley     break;
93675d3a19aSMatthew G. Knepley   case 2:
93775d3a19aSMatthew G. Knepley     /* Hex 2D */
93875d3a19aSMatthew G. Knepley     /*
93975d3a19aSMatthew G. Knepley      3---------2---------2
94075d3a19aSMatthew G. Knepley      |         |         |
94175d3a19aSMatthew G. Knepley      |    D    2    C    |
94275d3a19aSMatthew G. Knepley      |         |         |
94375d3a19aSMatthew G. Knepley      3----3----0----1----1
94475d3a19aSMatthew G. Knepley      |         |         |
94575d3a19aSMatthew G. Knepley      |    A    0    B    |
94675d3a19aSMatthew G. Knepley      |         |         |
94775d3a19aSMatthew G. Knepley      0---------0---------1
94875d3a19aSMatthew G. Knepley      */
94975d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
95075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
95175d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
95275d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
95375d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
95475d3a19aSMatthew G. Knepley 
95575d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
95675d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
95775d3a19aSMatthew G. Knepley       /* A quad */
95875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
95975d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
96075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
96175d3a19aSMatthew G. Knepley       orntNew[1] = 0;
96275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
96375d3a19aSMatthew G. Knepley       orntNew[2] = -2;
96475d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
96575d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
96675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
96775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
96875d3a19aSMatthew G. Knepley #if 1
96975d3a19aSMatthew 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);
97075d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
97175d3a19aSMatthew 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);
97275d3a19aSMatthew G. Knepley       }
97375d3a19aSMatthew G. Knepley #endif
97475d3a19aSMatthew G. Knepley       /* B quad */
97575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
97675d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
97775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
97875d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
97975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
98075d3a19aSMatthew G. Knepley       orntNew[2] = 0;
98175d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
98275d3a19aSMatthew G. Knepley       orntNew[3] = -2;
98375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
98475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
98575d3a19aSMatthew G. Knepley #if 1
98675d3a19aSMatthew 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);
98775d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
98875d3a19aSMatthew 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);
98975d3a19aSMatthew G. Knepley       }
99075d3a19aSMatthew G. Knepley #endif
99175d3a19aSMatthew G. Knepley       /* C quad */
99275d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
99375d3a19aSMatthew G. Knepley       orntNew[0] = -2;
99475d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
99575d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
99675d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
99775d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
99875d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
99975d3a19aSMatthew G. Knepley       orntNew[3] = 0;
100075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
100175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
100275d3a19aSMatthew G. Knepley #if 1
100375d3a19aSMatthew 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);
100475d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
100575d3a19aSMatthew 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);
100675d3a19aSMatthew G. Knepley       }
100775d3a19aSMatthew G. Knepley #endif
100875d3a19aSMatthew G. Knepley       /* D quad */
100975d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
101075d3a19aSMatthew G. Knepley       orntNew[0] = 0;
101175d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
101275d3a19aSMatthew G. Knepley       orntNew[1] = -2;
101375d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
101475d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
101575d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
101675d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
101775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
101875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
101975d3a19aSMatthew G. Knepley #if 1
102075d3a19aSMatthew 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);
102175d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
102275d3a19aSMatthew 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);
102375d3a19aSMatthew G. Knepley       }
102475d3a19aSMatthew G. Knepley #endif
102575d3a19aSMatthew G. Knepley     }
102675d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
102775d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
102875d3a19aSMatthew G. Knepley     ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr);
102975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
103075d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
103175d3a19aSMatthew G. Knepley 
103275d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
103375d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1034455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
103575d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
103675d3a19aSMatthew G. Knepley 
103775d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
103875d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
103975d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
104075d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
104175d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
104275d3a19aSMatthew G. Knepley #if 1
104375d3a19aSMatthew 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);
104475d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
104575d3a19aSMatthew 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);
104675d3a19aSMatthew G. Knepley         }
104775d3a19aSMatthew G. Knepley #endif
104875d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
104975d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
105075d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
105175d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
105275d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1053455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
105475d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
105575d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
105675d3a19aSMatthew G. Knepley           }
1057455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
105875d3a19aSMatthew G. Knepley         }
105975d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
106075d3a19aSMatthew G. Knepley #if 1
106175d3a19aSMatthew 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);
106275d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
106375d3a19aSMatthew 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);
106475d3a19aSMatthew G. Knepley         }
106575d3a19aSMatthew G. Knepley #endif
106675d3a19aSMatthew G. Knepley       }
106775d3a19aSMatthew G. Knepley     }
106875d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
106975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
107075d3a19aSMatthew G. Knepley       const PetscInt *cone;
107175d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
107275d3a19aSMatthew G. Knepley 
107375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
107475d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
107575d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
107675d3a19aSMatthew G. Knepley 
107775d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
107875d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
107975d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
108075d3a19aSMatthew G. Knepley #if 1
108175d3a19aSMatthew 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);
108275d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
108375d3a19aSMatthew 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);
108475d3a19aSMatthew G. Knepley         }
108575d3a19aSMatthew G. Knepley #endif
108675d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
108775d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
108875d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
108975d3a19aSMatthew G. Knepley #if 1
109075d3a19aSMatthew 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);
109175d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
109275d3a19aSMatthew 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);
109375d3a19aSMatthew G. Knepley         }
109475d3a19aSMatthew G. Knepley #endif
109575d3a19aSMatthew G. Knepley       }
109675d3a19aSMatthew G. Knepley     }
109775d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
109875d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
109975d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
110075d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
110175d3a19aSMatthew G. Knepley       PetscInt        size, s;
110275d3a19aSMatthew G. Knepley 
110375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
110475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
110575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
110675d3a19aSMatthew G. Knepley         PetscInt r = 0;
110775d3a19aSMatthew G. Knepley 
110875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
110975d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
111075d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
111175d3a19aSMatthew G. Knepley       }
111275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
111375d3a19aSMatthew G. Knepley #if 1
111475d3a19aSMatthew 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);
111575d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
111675d3a19aSMatthew 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);
111775d3a19aSMatthew G. Knepley       }
111875d3a19aSMatthew G. Knepley #endif
111975d3a19aSMatthew G. Knepley     }
112075d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
112175d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
112275d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
112375d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
112475d3a19aSMatthew G. Knepley       PetscInt        size, s;
112575d3a19aSMatthew G. Knepley 
112675d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
112775d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
112875d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
112975d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
113075d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
113175d3a19aSMatthew G. Knepley         PetscInt r = 0;
113275d3a19aSMatthew G. Knepley 
113375d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
113475d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
113575d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
113675d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
113775d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
113875d3a19aSMatthew G. Knepley       }
113975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
114075d3a19aSMatthew G. Knepley #if 1
114175d3a19aSMatthew 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);
114275d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
114375d3a19aSMatthew 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);
114475d3a19aSMatthew G. Knepley       }
114575d3a19aSMatthew G. Knepley #endif
114675d3a19aSMatthew G. Knepley     }
114775d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
114875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
114975d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
115075d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
115175d3a19aSMatthew G. Knepley 
115275d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
115375d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
115475d3a19aSMatthew G. Knepley       }
115575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
115675d3a19aSMatthew G. Knepley     }
1157da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
115875d3a19aSMatthew G. Knepley     break;
115975d3a19aSMatthew G. Knepley   case 3:
116075d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
116175d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
116275d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
116375d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
116475d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
116575d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
116675d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
116775d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
116875d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
116975d3a19aSMatthew G. Knepley 
117075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
117175d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
117275d3a19aSMatthew G. Knepley       /* A triangle */
117375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
117475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
117575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
117675d3a19aSMatthew G. Knepley       orntNew[1] = -2;
117775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
117875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
117975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
118075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
118175d3a19aSMatthew G. Knepley #if 1
118275d3a19aSMatthew 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);
118375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
118475d3a19aSMatthew 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);
118575d3a19aSMatthew G. Knepley       }
118675d3a19aSMatthew G. Knepley #endif
118775d3a19aSMatthew G. Knepley       /* B triangle */
118875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
118975d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
119075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
119175d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
119275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
119375d3a19aSMatthew G. Knepley       orntNew[2] = -2;
119475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
119575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
119675d3a19aSMatthew G. Knepley #if 1
119775d3a19aSMatthew 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);
119875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
119975d3a19aSMatthew 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);
120075d3a19aSMatthew G. Knepley       }
120175d3a19aSMatthew G. Knepley #endif
120275d3a19aSMatthew G. Knepley       /* C triangle */
120375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
120475d3a19aSMatthew G. Knepley       orntNew[0] = -2;
120575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
120675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
120775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
120875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
120975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
121075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
121175d3a19aSMatthew G. Knepley #if 1
121275d3a19aSMatthew 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);
121375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
121475d3a19aSMatthew 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);
121575d3a19aSMatthew G. Knepley       }
121675d3a19aSMatthew G. Knepley #endif
121775d3a19aSMatthew G. Knepley       /* D triangle */
121875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
121975d3a19aSMatthew G. Knepley       orntNew[0] = 0;
122075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
122175d3a19aSMatthew G. Knepley       orntNew[1] = 0;
122275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
122375d3a19aSMatthew G. Knepley       orntNew[2] = 0;
122475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
122575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
122675d3a19aSMatthew G. Knepley #if 1
122775d3a19aSMatthew 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);
122875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
122975d3a19aSMatthew 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);
123075d3a19aSMatthew G. Knepley       }
123175d3a19aSMatthew G. Knepley #endif
123275d3a19aSMatthew G. Knepley     }
123375d3a19aSMatthew G. Knepley     /*
123475d3a19aSMatthew G. Knepley      2----3----3
123575d3a19aSMatthew G. Knepley      |         |
123675d3a19aSMatthew G. Knepley      |    B    |
123775d3a19aSMatthew G. Knepley      |         |
123875d3a19aSMatthew G. Knepley      0----4--- 1
123975d3a19aSMatthew G. Knepley      |         |
124075d3a19aSMatthew G. Knepley      |    A    |
124175d3a19aSMatthew G. Knepley      |         |
124275d3a19aSMatthew G. Knepley      0----2----1
124375d3a19aSMatthew G. Knepley      */
124475d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
124575d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
124675d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
124775d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
124875d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
124975d3a19aSMatthew G. Knepley 
125075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
125175d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
125275d3a19aSMatthew G. Knepley       /* A quad */
125375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
125475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
125575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
125675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
125775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2] - fMax);
125875d3a19aSMatthew G. Knepley       orntNew[2] = 0;
125975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
126075d3a19aSMatthew G. Knepley       orntNew[3] = 0;
126175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
126275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
126375d3a19aSMatthew G. Knepley #if 1
126475d3a19aSMatthew 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);
126575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
126675d3a19aSMatthew 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);
126775d3a19aSMatthew G. Knepley       }
126875d3a19aSMatthew G. Knepley #endif
126975d3a19aSMatthew G. Knepley       /* B quad */
127075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
127175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
127275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
127375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
127475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
127575d3a19aSMatthew G. Knepley       orntNew[2] = 0;
127675d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3] - fMax);
127775d3a19aSMatthew G. Knepley       orntNew[3] = 0;
127875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
127975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
128075d3a19aSMatthew G. Knepley #if 1
128175d3a19aSMatthew 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);
128275d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
128375d3a19aSMatthew 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);
128475d3a19aSMatthew G. Knepley       }
128575d3a19aSMatthew G. Knepley #endif
128675d3a19aSMatthew G. Knepley     }
128775d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
128875d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
128975d3a19aSMatthew G. Knepley     ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr);
129075d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
129175d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
129275d3a19aSMatthew G. Knepley 
129375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
129475d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1295297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
129675d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
129775d3a19aSMatthew G. Knepley 
129875d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
129975d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
130075d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
130175d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
130275d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
130375d3a19aSMatthew G. Knepley #if 1
130475d3a19aSMatthew 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);
130575d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
130675d3a19aSMatthew 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);
130775d3a19aSMatthew G. Knepley         }
130875d3a19aSMatthew G. Knepley #endif
130975d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
131075d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
131175d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
131275d3a19aSMatthew G. Knepley           if (support[s] >= cMax) {
131375d3a19aSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
131475d3a19aSMatthew G. Knepley           } else {
131575d3a19aSMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
131675d3a19aSMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1317297d2bf4SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
131875d3a19aSMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
131975d3a19aSMatthew G. Knepley               if (cone[c] == f) break;
132075d3a19aSMatthew G. Knepley             }
1321297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
132275d3a19aSMatthew G. Knepley           }
132375d3a19aSMatthew G. Knepley         }
132475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
132575d3a19aSMatthew G. Knepley #if 1
132675d3a19aSMatthew 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);
132775d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
132875d3a19aSMatthew 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);
132975d3a19aSMatthew G. Knepley         }
133075d3a19aSMatthew G. Knepley #endif
133175d3a19aSMatthew G. Knepley       }
133275d3a19aSMatthew G. Knepley     }
133375d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
133475d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
133575d3a19aSMatthew G. Knepley       const PetscInt *cone;
133675d3a19aSMatthew G. Knepley 
133775d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
133875d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
133975d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
134075d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
134175d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
134275d3a19aSMatthew G. Knepley 
134375d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
134475d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
134575d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
134675d3a19aSMatthew G. Knepley #if 1
134775d3a19aSMatthew 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);
134875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
134975d3a19aSMatthew 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);
135075d3a19aSMatthew G. Knepley         }
135175d3a19aSMatthew G. Knepley #endif
135275d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
135375d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
135475d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
135575d3a19aSMatthew G. Knepley #if 1
135675d3a19aSMatthew 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);
135775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
135875d3a19aSMatthew 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);
135975d3a19aSMatthew G. Knepley         }
136075d3a19aSMatthew G. Knepley #endif
136175d3a19aSMatthew G. Knepley       }
136275d3a19aSMatthew G. Knepley     }
136375d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
136475d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
136575d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
136675d3a19aSMatthew G. Knepley       const PetscInt *cone;
136775d3a19aSMatthew G. Knepley       const PetscInt *support;
136875d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
136975d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
137075d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
137175d3a19aSMatthew G. Knepley 
137275d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
137375d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
137475d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
137575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
137675d3a19aSMatthew G. Knepley #if 1
137775d3a19aSMatthew 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);
137875d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
137975d3a19aSMatthew 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);
138075d3a19aSMatthew G. Knepley       }
138175d3a19aSMatthew G. Knepley #endif
138275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
138375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
138475d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
138575d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
138675d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
138775d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
138875d3a19aSMatthew G. Knepley         }
138975d3a19aSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
139075d3a19aSMatthew G. Knepley       }
139175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
139275d3a19aSMatthew G. Knepley #if 1
139375d3a19aSMatthew 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);
139475d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
139575d3a19aSMatthew 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);
139675d3a19aSMatthew G. Knepley       }
139775d3a19aSMatthew G. Knepley #endif
139875d3a19aSMatthew G. Knepley     }
139975d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
140075d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
140175d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
140275d3a19aSMatthew G. Knepley       const PetscInt *cone;
140375d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
140475d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
140575d3a19aSMatthew G. Knepley 
140675d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
140775d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
140875d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
140975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
141075d3a19aSMatthew G. Knepley #if 1
141175d3a19aSMatthew 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);
141275d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
141375d3a19aSMatthew 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);
141475d3a19aSMatthew G. Knepley       }
141575d3a19aSMatthew G. Knepley #endif
141675d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
141775d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
141875d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
141975d3a19aSMatthew G. Knepley #if 1
142075d3a19aSMatthew 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);
142175d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
142275d3a19aSMatthew 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);
142375d3a19aSMatthew G. Knepley       }
142475d3a19aSMatthew G. Knepley #endif
142575d3a19aSMatthew G. Knepley     }
142675d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
142775d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
142875d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
142975d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
143075d3a19aSMatthew G. Knepley       PetscInt        size, s;
143175d3a19aSMatthew G. Knepley 
143275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
143375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
143475d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
143575d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
143675d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
143775d3a19aSMatthew G. Knepley         } else {
143875d3a19aSMatthew G. Knepley           PetscInt r = 0;
143975d3a19aSMatthew G. Knepley 
144075d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
144175d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
144275d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
144375d3a19aSMatthew G. Knepley         }
144475d3a19aSMatthew G. Knepley       }
144575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
144675d3a19aSMatthew G. Knepley #if 1
144775d3a19aSMatthew 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);
144875d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
144975d3a19aSMatthew 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);
145075d3a19aSMatthew G. Knepley       }
145175d3a19aSMatthew G. Knepley #endif
145275d3a19aSMatthew G. Knepley     }
145375d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
145475d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
145575d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
145675d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
145775d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
145875d3a19aSMatthew G. Knepley 
145975d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
146075d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
146175d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
146275d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
146375d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
146475d3a19aSMatthew G. Knepley         PetscInt r = 0;
146575d3a19aSMatthew G. Knepley 
146675d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
146775d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
146875d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
146975d3a19aSMatthew G. Knepley 
147075d3a19aSMatthew G. Knepley           newSize += 1;
147175d3a19aSMatthew G. Knepley         } else {
147275d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
147375d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
147475d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
147575d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
147675d3a19aSMatthew G. Knepley 
147775d3a19aSMatthew G. Knepley           newSize += 2;
147875d3a19aSMatthew G. Knepley         }
147975d3a19aSMatthew G. Knepley       }
148075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
148175d3a19aSMatthew G. Knepley #if 1
148275d3a19aSMatthew 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);
148375d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
148475d3a19aSMatthew 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);
148575d3a19aSMatthew G. Knepley       }
148675d3a19aSMatthew G. Knepley #endif
148775d3a19aSMatthew G. Knepley     }
148875d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
148975d3a19aSMatthew G. Knepley     break;
1490b5da9499SMatthew G. Knepley   case 5:
1491b5da9499SMatthew G. Knepley     /* Simplicial 3D */
1492b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
1493b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
1494b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
1495b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
1496b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
1497b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1498b5da9499SMatthew G. Knepley 
1499b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1500b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1501b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
1502518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
1503b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1504518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
1505b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1506518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
1507b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1508b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
1509b5da9499SMatthew G. Knepley       orntNew[3] = 0;
1510b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1511b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1512b5da9499SMatthew G. Knepley #if 1
1513b5da9499SMatthew 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);
1514b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1515b5da9499SMatthew 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);
1516b5da9499SMatthew G. Knepley       }
1517b5da9499SMatthew G. Knepley #endif
1518b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
1519518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
1520b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1521518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
1522b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1523b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
1524b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1525518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
1526b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1527b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1528b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1529b5da9499SMatthew G. Knepley #if 1
1530b5da9499SMatthew 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);
1531b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1532b5da9499SMatthew 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);
1533b5da9499SMatthew G. Knepley       }
1534b5da9499SMatthew G. Knepley #endif
1535b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
1536518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
1537b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1538b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
1539b5da9499SMatthew G. Knepley       orntNew[1] = 0;
1540518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
1541b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1542518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
1543b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1544b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1545b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1546b5da9499SMatthew G. Knepley #if 1
1547b5da9499SMatthew 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);
1548b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1549b5da9499SMatthew 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);
1550b5da9499SMatthew G. Knepley       }
1551b5da9499SMatthew G. Knepley #endif
1552b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
1553b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
1554b5da9499SMatthew G. Knepley       orntNew[0] = 0;
1555518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
1556b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1557518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
1558b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1559518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
1560b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1561b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1562b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1563b5da9499SMatthew G. Knepley #if 1
1564b5da9499SMatthew 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);
1565b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1566b5da9499SMatthew 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);
1567b5da9499SMatthew G. Knepley       }
1568b5da9499SMatthew G. Knepley #endif
1569b5da9499SMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
1570b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
1571b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1572b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
1573b5da9499SMatthew G. Knepley       orntNew[1] = 0;
1574b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + 3;
1575b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -((-(ornt[2]+1)+2)%3+1) : (ornt[2]+2)%3;
1576b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
1577b5da9499SMatthew G. Knepley       orntNew[3] = 0;
1578b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
1579b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
1580b5da9499SMatthew G. Knepley #if 1
1581b5da9499SMatthew 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);
1582b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1583b5da9499SMatthew 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);
1584b5da9499SMatthew G. Knepley       }
1585b5da9499SMatthew G. Knepley #endif
1586b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
1587b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
1588b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1589b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3;
1590b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -((-(ornt[3]+1)+1)%3+1) : (ornt[3]+1)%3;
1591b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
1592b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1593b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
1594b5da9499SMatthew G. Knepley       orntNew[3] = 0;
1595b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
1596b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
1597b5da9499SMatthew G. Knepley #if 1
1598b5da9499SMatthew 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);
1599b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1600b5da9499SMatthew 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);
1601b5da9499SMatthew G. Knepley       }
1602b5da9499SMatthew G. Knepley #endif
1603b5da9499SMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
1604b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
1605b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1606b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
1607b5da9499SMatthew G. Knepley       orntNew[1] = -2;
1608b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[0] - fStart)*4 + 3;
1609b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : -((ornt[0]+1)%3+1);
1610b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
1611b5da9499SMatthew G. Knepley       orntNew[3] = -1;
1612b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
1613b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
1614b5da9499SMatthew G. Knepley #if 1
1615b5da9499SMatthew 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);
1616b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1617b5da9499SMatthew 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);
1618b5da9499SMatthew G. Knepley       }
1619b5da9499SMatthew G. Knepley #endif
1620b5da9499SMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
1621b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
1622b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1623b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
1624b5da9499SMatthew G. Knepley       orntNew[1] = -3;
1625b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
1626b5da9499SMatthew G. Knepley       orntNew[2] = -2;
1627b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3;
1628b5da9499SMatthew G. Knepley       orntNew[3] = ornt[2];
1629b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
1630b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
1631b5da9499SMatthew G. Knepley #if 1
1632b5da9499SMatthew 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);
1633b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1634b5da9499SMatthew 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);
1635b5da9499SMatthew G. Knepley       }
1636b5da9499SMatthew G. Knepley #endif
1637b5da9499SMatthew G. Knepley     }
1638b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
1639b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1640b5da9499SMatthew G. Knepley     ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr);
1641b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
1642b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
1643b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
1644b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
1645b5da9499SMatthew G. Knepley 
1646b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
1647b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
1648b5da9499SMatthew G. Knepley       /* A triangle */
1649b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
1650b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1651b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
1652b5da9499SMatthew G. Knepley       orntNew[1] = -2;
1653b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
1654b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1655b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1656b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1657b5da9499SMatthew G. Knepley #if 1
1658b5da9499SMatthew 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);
1659b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1660b5da9499SMatthew 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);
1661b5da9499SMatthew G. Knepley       }
1662b5da9499SMatthew G. Knepley #endif
1663b5da9499SMatthew G. Knepley       /* B triangle */
1664b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
1665b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1666b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
1667b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1668b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
1669b5da9499SMatthew G. Knepley       orntNew[2] = -2;
1670b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1671b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1672b5da9499SMatthew G. Knepley #if 1
1673b5da9499SMatthew 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);
1674b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1675b5da9499SMatthew 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);
1676b5da9499SMatthew G. Knepley       }
1677b5da9499SMatthew G. Knepley #endif
1678b5da9499SMatthew G. Knepley       /* C triangle */
1679b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
1680b5da9499SMatthew G. Knepley       orntNew[0] = -2;
1681b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
1682b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1683b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
1684b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1685b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1686b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1687b5da9499SMatthew G. Knepley #if 1
1688b5da9499SMatthew 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);
1689b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1690b5da9499SMatthew 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);
1691b5da9499SMatthew G. Knepley       }
1692b5da9499SMatthew G. Knepley #endif
1693b5da9499SMatthew G. Knepley       /* D triangle */
1694b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
1695b5da9499SMatthew G. Knepley       orntNew[0] = 0;
1696b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
1697b5da9499SMatthew G. Knepley       orntNew[1] = 0;
1698b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
1699b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1700b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1701b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1702b5da9499SMatthew G. Knepley #if 1
1703b5da9499SMatthew 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);
1704b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1705b5da9499SMatthew 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);
1706b5da9499SMatthew G. Knepley       }
1707b5da9499SMatthew G. Knepley #endif
1708b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
1709b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1710b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
1711b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
1712b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
1713b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1714b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1715b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
1716b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
1717b5da9499SMatthew G. Knepley           }
1718b5da9499SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : (ornt[c] < 0 ? faces[c*3+(-(ornt[c]+1)+1+3-r)%3] : faces[c*3+r]));
1719b5da9499SMatthew G. Knepley         }
1720b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
1721b5da9499SMatthew G. Knepley #if 1
1722b5da9499SMatthew 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);
1723b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
1724b5da9499SMatthew 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);
1725b5da9499SMatthew G. Knepley         }
1726b5da9499SMatthew G. Knepley #endif
1727b5da9499SMatthew G. Knepley       }
1728b5da9499SMatthew G. Knepley     }
1729b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
1730b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
1731b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
1732b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
1733b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
1734b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
1735b5da9499SMatthew G. Knepley 
1736b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1737b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1738b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
1739b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3);
1740b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
1741b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3);
1742b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
1743b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+0)%3 : (ornt[2]+2)%3);
1744b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
1745b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1746b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1747b5da9499SMatthew G. Knepley #if 1
1748b5da9499SMatthew 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);
1749b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1750b5da9499SMatthew 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);
1751b5da9499SMatthew G. Knepley       }
1752b5da9499SMatthew G. Knepley #endif
1753b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
1754b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
1755b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1756b5da9499SMatthew G. Knepley #if 1
1757b5da9499SMatthew 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);
1758b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1759b5da9499SMatthew 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);
1760b5da9499SMatthew G. Knepley       }
1761b5da9499SMatthew G. Knepley #endif
1762b5da9499SMatthew G. Knepley       ++newp;
1763b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
1764b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3);
1765b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
1766b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+2)%3 : (ornt[3]+0)%3);
1767b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
1768b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3);
1769b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
1770b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1771b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1772b5da9499SMatthew G. Knepley #if 1
1773b5da9499SMatthew 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);
1774b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1775b5da9499SMatthew 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);
1776b5da9499SMatthew G. Knepley       }
1777b5da9499SMatthew G. Knepley #endif
1778b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
1779b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
1780b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1781b5da9499SMatthew G. Knepley #if 1
1782b5da9499SMatthew 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);
1783b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1784b5da9499SMatthew 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);
1785b5da9499SMatthew G. Knepley       }
1786b5da9499SMatthew G. Knepley #endif
1787b5da9499SMatthew G. Knepley       ++newp;
1788b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
1789b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3);
1790b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
1791b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3);
1792b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
1793b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : (ornt[0]+1)%3);
1794b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
1795b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1796b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1797b5da9499SMatthew G. Knepley #if 1
1798b5da9499SMatthew 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);
1799b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1800b5da9499SMatthew 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);
1801b5da9499SMatthew G. Knepley       }
1802b5da9499SMatthew G. Knepley #endif
1803b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
1804b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
1805b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1806b5da9499SMatthew G. Knepley #if 1
1807b5da9499SMatthew 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);
1808b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1809b5da9499SMatthew 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);
1810b5da9499SMatthew G. Knepley       }
1811b5da9499SMatthew G. Knepley #endif
1812b5da9499SMatthew G. Knepley       ++newp;
1813b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
1814b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+2)%3 : (ornt[1]+0)%3);
1815b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
1816b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3);
1817b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
1818b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3);
1819b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
1820b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1821b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1822b5da9499SMatthew G. Knepley #if 1
1823b5da9499SMatthew 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);
1824b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1825b5da9499SMatthew 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);
1826b5da9499SMatthew G. Knepley       }
1827b5da9499SMatthew G. Knepley #endif
1828b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
1829b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
1830b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1831b5da9499SMatthew G. Knepley #if 1
1832b5da9499SMatthew 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);
1833b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1834b5da9499SMatthew 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);
1835b5da9499SMatthew G. Knepley       }
1836b5da9499SMatthew G. Knepley #endif
1837b5da9499SMatthew G. Knepley       ++newp;
1838b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
1839b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3);
1840b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
1841b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
1842b5da9499SMatthew G. Knepley       orntNew[1] = 0;
1843b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3);
1844b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
1845b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1846b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1847b5da9499SMatthew G. Knepley #if 1
1848b5da9499SMatthew 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);
1849b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1850b5da9499SMatthew 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);
1851b5da9499SMatthew G. Knepley       }
1852b5da9499SMatthew G. Knepley #endif
1853b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
1854b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
1855b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1856b5da9499SMatthew G. Knepley #if 1
1857b5da9499SMatthew 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);
1858b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1859b5da9499SMatthew 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);
1860b5da9499SMatthew G. Knepley       }
1861b5da9499SMatthew G. Knepley #endif
1862b5da9499SMatthew G. Knepley       ++newp;
1863b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
1864b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3);
1865b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
1866b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
1867b5da9499SMatthew G. Knepley       orntNew[1] = -2;
1868b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3);
1869b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? 0 : -2;
1870b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1871b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1872b5da9499SMatthew G. Knepley #if 1
1873b5da9499SMatthew 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);
1874b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1875b5da9499SMatthew 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);
1876b5da9499SMatthew G. Knepley       }
1877b5da9499SMatthew G. Knepley #endif
1878b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
1879b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
1880b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1881b5da9499SMatthew G. Knepley #if 1
1882b5da9499SMatthew 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);
1883b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1884b5da9499SMatthew 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);
1885b5da9499SMatthew G. Knepley       }
1886b5da9499SMatthew G. Knepley #endif
1887b5da9499SMatthew G. Knepley       ++newp;
1888b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
1889b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3);
1890b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
1891b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
1892b5da9499SMatthew G. Knepley       orntNew[1] = -2;
1893b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3);
1894b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
1895b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1896b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1897b5da9499SMatthew G. Knepley #if 1
1898b5da9499SMatthew 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);
1899b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1900b5da9499SMatthew 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);
1901b5da9499SMatthew G. Knepley       }
1902b5da9499SMatthew G. Knepley #endif
1903b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
1904b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
1905b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1906b5da9499SMatthew G. Knepley #if 1
1907b5da9499SMatthew 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);
1908b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1909b5da9499SMatthew 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);
1910b5da9499SMatthew G. Knepley       }
1911b5da9499SMatthew G. Knepley #endif
1912b5da9499SMatthew G. Knepley       ++newp;
1913b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
1914b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3);
1915b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
1916b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3);
1917b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
1918b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
1919b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1920b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1921b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1922b5da9499SMatthew G. Knepley #if 1
1923b5da9499SMatthew 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);
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       supportNew[0] = (c - cStart)*8 + 1+4;
1929b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
1930b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1931b5da9499SMatthew G. Knepley #if 1
1932b5da9499SMatthew 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);
1933b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1934b5da9499SMatthew 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);
1935b5da9499SMatthew G. Knepley       }
1936b5da9499SMatthew G. Knepley #endif
1937b5da9499SMatthew G. Knepley       ++newp;
1938b5da9499SMatthew G. Knepley     }
1939b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
1940b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
1941b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
1942b5da9499SMatthew G. Knepley 
1943b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
1944b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
1945b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
1946b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
1947b5da9499SMatthew G. Knepley 
1948b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
1949b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
1950b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
1951b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
1952b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1953b5da9499SMatthew G. Knepley #if 1
1954b5da9499SMatthew 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);
1955b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
1956b5da9499SMatthew 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);
1957b5da9499SMatthew G. Knepley         }
1958b5da9499SMatthew G. Knepley #endif
1959b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
1960b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
1961b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
1962b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
1963b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1964b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1965b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
1966b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
1967b5da9499SMatthew G. Knepley           }
1968b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
1969b5da9499SMatthew G. Knepley         }
1970b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1971b5da9499SMatthew G. Knepley #if 1
1972b5da9499SMatthew 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);
1973b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
1974b5da9499SMatthew 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);
1975b5da9499SMatthew G. Knepley         }
1976b5da9499SMatthew G. Knepley #endif
1977b5da9499SMatthew G. Knepley       }
1978b5da9499SMatthew G. Knepley     }
197986f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
1980b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
1981b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
1982b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
1983b5da9499SMatthew G. Knepley 
1984b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
1985b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1986b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
1987b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
1988b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
1989b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
1990b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
1991b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
1992b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
1993b5da9499SMatthew G. Knepley 
1994b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
1995b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
1996b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
1997b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1998b5da9499SMatthew G. Knepley #if 1
1999b5da9499SMatthew 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);
2000b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2001b5da9499SMatthew 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);
2002b5da9499SMatthew G. Knepley         }
2003b5da9499SMatthew G. Knepley #endif
2004b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
2005b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
2006b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2007b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2008b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2009b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2010b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
201186f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
201286f0afeeSMatthew G. Knepley           er   = ornt[c] < 0 ? (-(ornt[c]+1) + 2-r)%3 : (ornt[c] + r)%3;
2013b5da9499SMatthew G. Knepley           if (er == eint[c]) {
2014b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
2015b5da9499SMatthew G. Knepley           } else {
2016b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
2017b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
2018b5da9499SMatthew G. Knepley           }
2019b5da9499SMatthew G. Knepley         }
2020b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2021b5da9499SMatthew G. Knepley #if 1
2022b5da9499SMatthew 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);
2023b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
2024b5da9499SMatthew 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);
2025b5da9499SMatthew G. Knepley         }
2026b5da9499SMatthew G. Knepley #endif
2027b5da9499SMatthew G. Knepley       }
2028b5da9499SMatthew G. Knepley     }
2029b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
2030b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2031b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2032b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
20334a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
2034b5da9499SMatthew G. Knepley 
2035b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2036b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2037b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
203842525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
2039b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2040b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
204142525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
2042b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2043b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2044b5da9499SMatthew G. Knepley #if 1
2045b5da9499SMatthew 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);
2046b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2047b5da9499SMatthew 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);
2048b5da9499SMatthew G. Knepley       }
2049b5da9499SMatthew G. Knepley #endif
2050b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
2051b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
2052b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
2053b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
2054b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2055b5da9499SMatthew G. Knepley #if 1
2056b5da9499SMatthew 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);
2057b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2058b5da9499SMatthew 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);
2059b5da9499SMatthew G. Knepley       }
2060b5da9499SMatthew G. Knepley #endif
2061b5da9499SMatthew G. Knepley     }
2062b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
2063b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2064b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2065b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
2066b5da9499SMatthew G. Knepley       PetscInt        size, s;
2067b5da9499SMatthew G. Knepley 
2068b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2069b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2070b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2071b5da9499SMatthew G. Knepley         PetscInt r = 0;
2072b5da9499SMatthew G. Knepley 
2073b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2074b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
2075b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
2076b5da9499SMatthew G. Knepley       }
2077b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2078b5da9499SMatthew G. Knepley #if 1
2079b5da9499SMatthew 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);
2080b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2081b5da9499SMatthew 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);
2082b5da9499SMatthew G. Knepley       }
2083b5da9499SMatthew G. Knepley #endif
2084b5da9499SMatthew G. Knepley     }
2085b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
2086b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2087b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
2088b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
2089b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
2090b5da9499SMatthew G. Knepley 
2091b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
2092b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2093b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
2094b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
2095b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2096b5da9499SMatthew G. Knepley         PetscInt r = 0;
2097b5da9499SMatthew G. Knepley 
2098b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2099b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2100b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
2101b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
2102b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
2103b5da9499SMatthew G. Knepley       }
2104b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2105b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
2106b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
2107b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
2108b5da9499SMatthew G. Knepley 
2109b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
2110b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
2111b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2112b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
2113b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
211442525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
2115b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
2116b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2117b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
211842525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
211942525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
2120b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
2121b5da9499SMatthew G. Knepley         }
2122b5da9499SMatthew G. Knepley       }
2123b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2124b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2125b5da9499SMatthew G. Knepley #if 1
2126b5da9499SMatthew 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);
2127b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
2128b5da9499SMatthew 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);
2129b5da9499SMatthew G. Knepley       }
2130b5da9499SMatthew G. Knepley #endif
2131b5da9499SMatthew G. Knepley     }
2132b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2133b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
2134b5da9499SMatthew G. Knepley     break;
21356ce3c06aSMatthew G. Knepley   case 7:
21366ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
21376ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
21386ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
21396ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
21406ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
21416ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
21426ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
21436ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
21446ce3c06aSMatthew G. Knepley 
21456ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
21466ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
21476ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
21486ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
21496ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
21506ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
21516ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
21526ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
21536ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
21546ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
21556ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
21566ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
21576ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
21586ce3c06aSMatthew G. Knepley #if 1
21596ce3c06aSMatthew 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);
21606ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
21616ce3c06aSMatthew 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);
21626ce3c06aSMatthew G. Knepley       }
21636ce3c06aSMatthew G. Knepley #endif
21646ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
21656ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
21666ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
21676ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
21686ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
21696ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
21706ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
21716ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
21726ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
21736ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
21746ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
21756ce3c06aSMatthew G. Knepley #if 1
21766ce3c06aSMatthew 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);
21776ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
21786ce3c06aSMatthew 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);
21796ce3c06aSMatthew G. Knepley       }
21806ce3c06aSMatthew G. Knepley #endif
21816ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
21826ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
21836ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
21846ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
21856ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
21866ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
21876ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
21886ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
21896ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
21906ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
21916ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
21926ce3c06aSMatthew G. Knepley #if 1
21936ce3c06aSMatthew 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);
21946ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
21956ce3c06aSMatthew 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);
21966ce3c06aSMatthew G. Knepley       }
21976ce3c06aSMatthew G. Knepley #endif
21986ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
21996ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
22006ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
22016ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
22026ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
22036ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
22046ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
22056ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
22066ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
22076ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
22086ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
22096ce3c06aSMatthew G. Knepley #if 1
22106ce3c06aSMatthew 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);
22116ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
22126ce3c06aSMatthew 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);
22136ce3c06aSMatthew G. Knepley       }
22146ce3c06aSMatthew G. Knepley #endif
22156ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
22166ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
22176ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
22186ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
22196ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
22206ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + 3;
22216ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -((-(ornt[2]+1)+2)%3+1) : (ornt[2]+2)%3;
22226ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
22236ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
22246ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
22256ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
22266ce3c06aSMatthew G. Knepley #if 1
22276ce3c06aSMatthew 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);
22286ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
22296ce3c06aSMatthew 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);
22306ce3c06aSMatthew G. Knepley       }
22316ce3c06aSMatthew G. Knepley #endif
22326ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
22336ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
22346ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
22356ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3;
22366ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -((-(ornt[3]+1)+1)%3+1) : (ornt[3]+1)%3;
22376ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
22386ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
22396ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
22406ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
22416ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
22426ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
22436ce3c06aSMatthew G. Knepley #if 1
22446ce3c06aSMatthew 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);
22456ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
22466ce3c06aSMatthew 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);
22476ce3c06aSMatthew G. Knepley       }
22486ce3c06aSMatthew G. Knepley #endif
22496ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
22506ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
22516ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
22526ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
22536ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
22546ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[0] - fStart)*4 + 3;
22556ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : -((ornt[0]+1)%3+1);
22566ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
22576ce3c06aSMatthew G. Knepley       orntNew[3] = -1;
22586ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
22596ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
22606ce3c06aSMatthew G. Knepley #if 1
22616ce3c06aSMatthew 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);
22626ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
22636ce3c06aSMatthew 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);
22646ce3c06aSMatthew G. Knepley       }
22656ce3c06aSMatthew G. Knepley #endif
22666ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
22676ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
22686ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
22696ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
22706ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
22716ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
22726ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
22736ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3;
22746ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[2];
22756ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
22766ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
22776ce3c06aSMatthew G. Knepley #if 1
22786ce3c06aSMatthew 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);
22796ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
22806ce3c06aSMatthew 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);
22816ce3c06aSMatthew G. Knepley       }
22826ce3c06aSMatthew G. Knepley #endif
22836ce3c06aSMatthew G. Knepley     }
22846ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
22856ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
22866ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
22876ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
22886ce3c06aSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5];
22896ce3c06aSMatthew G. Knepley 
22906ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
22916ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
22926ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
22936ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
22946ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
22956ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
22966ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
22976ce3c06aSMatthew G. Knepley         coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriSubface_Static(ornt[0], (r+2)%3)] - fMax)*2 + (ornt[2+GetTriSubface_Static(ornt[0], (r+2)%3)] < 0 ? 0 : 1);
22986ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
22996ce3c06aSMatthew G. Knepley         coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriSubface_Static(ornt[0], r)]       - fMax)*2 + (ornt[2+GetTriSubface_Static(ornt[0], r)]       < 0 ? 1 : 0);
23006ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
23016ce3c06aSMatthew G. Knepley         coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
23026ce3c06aSMatthew G. Knepley         orntNew[4] = 0;
23036ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
23046ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
23056ce3c06aSMatthew G. Knepley #if 1
23066ce3c06aSMatthew 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);
23076ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
23086ce3c06aSMatthew 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);
23096ce3c06aSMatthew G. Knepley         }
23106ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
23116ce3c06aSMatthew 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);
23126ce3c06aSMatthew G. Knepley         }
23136ce3c06aSMatthew G. Knepley #endif
23146ce3c06aSMatthew G. Knepley       }
23156ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
23166ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
23176ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
23186ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
23196ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
23206ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
23216ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
23226ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
23236ce3c06aSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
23246ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
23256ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
23266ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
23276ce3c06aSMatthew G. Knepley #if 1
23286ce3c06aSMatthew 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);
23296ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
23306ce3c06aSMatthew 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);
23316ce3c06aSMatthew G. Knepley       }
23326ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
23336ce3c06aSMatthew 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);
23346ce3c06aSMatthew G. Knepley       }
23356ce3c06aSMatthew G. Knepley #endif
23366ce3c06aSMatthew G. Knepley     }
23376ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
23386ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
23396ce3c06aSMatthew G. Knepley     ierr = PetscMalloc((2 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr);
23406ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
23416ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
23426ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
23436ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
23446ce3c06aSMatthew G. Knepley 
23456ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
23466ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
23476ce3c06aSMatthew G. Knepley       /* A triangle */
23486ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
23496ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
23506ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
23516ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
23526ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
23536ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
23546ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
23556ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
23566ce3c06aSMatthew G. Knepley #if 1
23576ce3c06aSMatthew 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);
23586ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
23596ce3c06aSMatthew 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);
23606ce3c06aSMatthew G. Knepley       }
23616ce3c06aSMatthew G. Knepley #endif
23626ce3c06aSMatthew G. Knepley       /* B triangle */
23636ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
23646ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
23656ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
23666ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
23676ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
23686ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
23696ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
23706ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
23716ce3c06aSMatthew G. Knepley #if 1
23726ce3c06aSMatthew 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);
23736ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
23746ce3c06aSMatthew 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);
23756ce3c06aSMatthew G. Knepley       }
23766ce3c06aSMatthew G. Knepley #endif
23776ce3c06aSMatthew G. Knepley       /* C triangle */
23786ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
23796ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
23806ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
23816ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
23826ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
23836ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
23846ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
23856ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
23866ce3c06aSMatthew G. Knepley #if 1
23876ce3c06aSMatthew 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);
23886ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
23896ce3c06aSMatthew 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);
23906ce3c06aSMatthew G. Knepley       }
23916ce3c06aSMatthew G. Knepley #endif
23926ce3c06aSMatthew G. Knepley       /* D triangle */
23936ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
23946ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
23956ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
23966ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
23976ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
23986ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
23996ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
24006ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
24016ce3c06aSMatthew G. Knepley #if 1
24026ce3c06aSMatthew 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);
24036ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
24046ce3c06aSMatthew 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);
24056ce3c06aSMatthew G. Knepley       }
24066ce3c06aSMatthew G. Knepley #endif
24076ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
24086ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
24096ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
24106ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
24116ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
24126ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
24136ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
24146ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
24156ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
24166ce3c06aSMatthew G. Knepley           }
24176ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
24186ce3c06aSMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : (ornt[c] < 0 ? faces[c*3+(-(ornt[c]+1)+1+3-r)%3] : faces[c*3+r]));
24196ce3c06aSMatthew G. Knepley           } else {
24206ce3c06aSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + r;
24216ce3c06aSMatthew G. Knepley           }
24226ce3c06aSMatthew G. Knepley         }
24236ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
24246ce3c06aSMatthew G. Knepley #if 1
24256ce3c06aSMatthew 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);
24266ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
24276ce3c06aSMatthew 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);
24286ce3c06aSMatthew G. Knepley         }
24296ce3c06aSMatthew G. Knepley #endif
24306ce3c06aSMatthew G. Knepley       }
24316ce3c06aSMatthew G. Knepley     }
24326ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
24336ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
24346ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
24356ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
24366ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
24376ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
24386ce3c06aSMatthew G. Knepley 
24396ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
24406ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
24416ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
24426ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3);
24436ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
24446ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3);
24456ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
24466ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+0)%3 : (ornt[2]+2)%3);
24476ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
24486ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
24496ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
24506ce3c06aSMatthew G. Knepley #if 1
24516ce3c06aSMatthew 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);
24526ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
24536ce3c06aSMatthew 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);
24546ce3c06aSMatthew G. Knepley       }
24556ce3c06aSMatthew G. Knepley #endif
24566ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
24576ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
24586ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
24596ce3c06aSMatthew G. Knepley #if 1
24606ce3c06aSMatthew 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);
24616ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
24626ce3c06aSMatthew 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);
24636ce3c06aSMatthew G. Knepley       }
24646ce3c06aSMatthew G. Knepley #endif
24656ce3c06aSMatthew G. Knepley       ++newp;
24666ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
24676ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3);
24686ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
24696ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+2)%3 : (ornt[3]+0)%3);
24706ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
24716ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3);
24726ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
24736ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
24746ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
24756ce3c06aSMatthew G. Knepley #if 1
24766ce3c06aSMatthew 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);
24776ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
24786ce3c06aSMatthew 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);
24796ce3c06aSMatthew G. Knepley       }
24806ce3c06aSMatthew G. Knepley #endif
24816ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
24826ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
24836ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
24846ce3c06aSMatthew G. Knepley #if 1
24856ce3c06aSMatthew 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);
24866ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
24876ce3c06aSMatthew 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);
24886ce3c06aSMatthew G. Knepley       }
24896ce3c06aSMatthew G. Knepley #endif
24906ce3c06aSMatthew G. Knepley       ++newp;
24916ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
24926ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3);
24936ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
24946ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3);
24956ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
24966ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+1)%3 : (ornt[0]+1)%3);
24976ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
24986ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
24996ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
25006ce3c06aSMatthew G. Knepley #if 1
25016ce3c06aSMatthew 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);
25026ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25036ce3c06aSMatthew 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);
25046ce3c06aSMatthew G. Knepley       }
25056ce3c06aSMatthew G. Knepley #endif
25066ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
25076ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
25086ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
25096ce3c06aSMatthew G. Knepley #if 1
25106ce3c06aSMatthew 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);
25116ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
25126ce3c06aSMatthew 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);
25136ce3c06aSMatthew G. Knepley       }
25146ce3c06aSMatthew G. Knepley #endif
25156ce3c06aSMatthew G. Knepley       ++newp;
25166ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
25176ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+2)%3 : (ornt[1]+0)%3);
25186ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
25196ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3);
25206ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
25216ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3);
25226ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
25236ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
25246ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
25256ce3c06aSMatthew G. Knepley #if 1
25266ce3c06aSMatthew 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);
25276ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25286ce3c06aSMatthew 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);
25296ce3c06aSMatthew G. Knepley       }
25306ce3c06aSMatthew G. Knepley #endif
25316ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
25326ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
25336ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
25346ce3c06aSMatthew G. Knepley #if 1
25356ce3c06aSMatthew 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);
25366ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
25376ce3c06aSMatthew 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);
25386ce3c06aSMatthew G. Knepley       }
25396ce3c06aSMatthew G. Knepley #endif
25406ce3c06aSMatthew G. Knepley       ++newp;
25416ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
25426ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+1)%3 : (ornt[2]+1)%3);
25436ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
25446ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
25456ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
25466ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+0)%3 : (ornt[1]+2)%3);
25476ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
25486ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
25496ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
25506ce3c06aSMatthew G. Knepley #if 1
25516ce3c06aSMatthew 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);
25526ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25536ce3c06aSMatthew 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);
25546ce3c06aSMatthew G. Knepley       }
25556ce3c06aSMatthew G. Knepley #endif
25566ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
25576ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
25586ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
25596ce3c06aSMatthew G. Knepley #if 1
25606ce3c06aSMatthew 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);
25616ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
25626ce3c06aSMatthew 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);
25636ce3c06aSMatthew G. Knepley       }
25646ce3c06aSMatthew G. Knepley #endif
25656ce3c06aSMatthew G. Knepley       ++newp;
25666ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
25676ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+0)%3 : (ornt[0]+2)%3);
25686ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
25696ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
25706ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
25716ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + (ornt[2] < 0 ? (-(ornt[2]+1)+2)%3 : (ornt[2]+0)%3);
25726ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? 0 : -2;
25736ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
25746ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
25756ce3c06aSMatthew G. Knepley #if 1
25766ce3c06aSMatthew 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);
25776ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25786ce3c06aSMatthew 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);
25796ce3c06aSMatthew G. Knepley       }
25806ce3c06aSMatthew G. Knepley #endif
25816ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
25826ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
25836ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
25846ce3c06aSMatthew G. Knepley #if 1
25856ce3c06aSMatthew 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);
25866ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
25876ce3c06aSMatthew 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);
25886ce3c06aSMatthew G. Knepley       }
25896ce3c06aSMatthew G. Knepley #endif
25906ce3c06aSMatthew G. Knepley       ++newp;
25916ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
25926ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (ornt[1] < 0 ? (-(ornt[1]+1)+1)%3 : (ornt[1]+1)%3);
25936ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
25946ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
25956ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
25966ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+1)%3 : (ornt[3]+1)%3);
25976ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
25986ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
25996ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
26006ce3c06aSMatthew G. Knepley #if 1
26016ce3c06aSMatthew 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);
26026ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26036ce3c06aSMatthew 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);
26046ce3c06aSMatthew G. Knepley       }
26056ce3c06aSMatthew G. Knepley #endif
26066ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
26076ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
26086ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
26096ce3c06aSMatthew G. Knepley #if 1
26106ce3c06aSMatthew 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);
26116ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
26126ce3c06aSMatthew 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);
26136ce3c06aSMatthew G. Knepley       }
26146ce3c06aSMatthew G. Knepley #endif
26156ce3c06aSMatthew G. Knepley       ++newp;
26166ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
26176ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (ornt[0] < 0 ? (-(ornt[0]+1)+2)%3 : (ornt[0]+0)%3);
26186ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
26196ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + (ornt[3] < 0 ? (-(ornt[3]+1)+0)%3 : (ornt[3]+2)%3);
26206ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
26216ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
26226ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
26236ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
26246ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
26256ce3c06aSMatthew G. Knepley #if 1
26266ce3c06aSMatthew 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);
26276ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26286ce3c06aSMatthew 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);
26296ce3c06aSMatthew G. Knepley       }
26306ce3c06aSMatthew G. Knepley #endif
26316ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
26326ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
26336ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
26346ce3c06aSMatthew G. Knepley #if 1
26356ce3c06aSMatthew 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);
26366ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
26376ce3c06aSMatthew 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);
26386ce3c06aSMatthew G. Knepley       }
26396ce3c06aSMatthew G. Knepley #endif
26406ce3c06aSMatthew G. Knepley       ++newp;
26416ce3c06aSMatthew G. Knepley     }
26426ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
26436ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
26446ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
26456ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
26466ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
26476ce3c06aSMatthew G. Knepley 
26486ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
26496ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
26506ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
26516ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
26526ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
26536ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
26546ce3c06aSMatthew G. Knepley 
26556ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
26566ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
26576ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
26586ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
26596ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
26606ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
26616ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
26626ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
26636ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
26646ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
26656ce3c06aSMatthew G. Knepley #if 1
26666ce3c06aSMatthew 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);
26676ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
26686ce3c06aSMatthew 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);
26696ce3c06aSMatthew G. Knepley         }
26706ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
26716ce3c06aSMatthew 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);
26726ce3c06aSMatthew G. Knepley         }
26736ce3c06aSMatthew G. Knepley #endif
26746ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
26756ce3c06aSMatthew G. Knepley           const PetscInt *coneCell, *orntCell;
26766ce3c06aSMatthew G. Knepley 
26776ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
26786ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
26796ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
26806ce3c06aSMatthew 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]);
26816ce3c06aSMatthew G. Knepley           supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + GetTriSubface_Static(orntCell[c], (c-2+r)%3);
26826ce3c06aSMatthew G. Knepley         }
26836ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
26846ce3c06aSMatthew G. Knepley #if 1
26856ce3c06aSMatthew 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);
26866ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
26876ce3c06aSMatthew 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);
26886ce3c06aSMatthew G. Knepley         }
26896ce3c06aSMatthew G. Knepley #endif
26906ce3c06aSMatthew G. Knepley       }
26916ce3c06aSMatthew G. Knepley     }
26926ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
26936ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
26946ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
26956ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
26966ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
26976ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
26986ce3c06aSMatthew G. Knepley 
26996ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
27006ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
27016ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
27026ce3c06aSMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], (r+2)%3);
27036ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
27046ce3c06aSMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], (r+2)%3);
27056ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
27066ce3c06aSMatthew 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);
27076ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
27086ce3c06aSMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], r)]       - fMax);
27096ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
27106ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
27116ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
27126ce3c06aSMatthew G. Knepley #if 1
27136ce3c06aSMatthew 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);
27146ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
27156ce3c06aSMatthew 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);
27166ce3c06aSMatthew G. Knepley         }
27176ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
27186ce3c06aSMatthew 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);
27196ce3c06aSMatthew G. Knepley         }
27206ce3c06aSMatthew G. Knepley #endif
27216ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
27226ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
27236ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
27246ce3c06aSMatthew G. Knepley #if 1
27256ce3c06aSMatthew 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);
27266ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
27276ce3c06aSMatthew 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);
27286ce3c06aSMatthew G. Knepley         }
27296ce3c06aSMatthew G. Knepley #endif
27306ce3c06aSMatthew G. Knepley       }
27316ce3c06aSMatthew G. Knepley     }
27326ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
27336ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
27346ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
27356ce3c06aSMatthew G. Knepley 
27366ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
27376ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
27386ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
27396ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
27406ce3c06aSMatthew G. Knepley 
27416ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
27426ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
27436ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
27446ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
27456ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27466ce3c06aSMatthew G. Knepley #if 1
27476ce3c06aSMatthew 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);
27486ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
27496ce3c06aSMatthew 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);
27506ce3c06aSMatthew G. Knepley         }
27516ce3c06aSMatthew G. Knepley #endif
27526ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
27536ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
27546ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
27556ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
27566ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
27576ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
27586ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
27596ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
27606ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
27616ce3c06aSMatthew G. Knepley           } else {
27626ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
27636ce3c06aSMatthew G. Knepley           }
27646ce3c06aSMatthew G. Knepley         }
27656ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
27666ce3c06aSMatthew G. Knepley #if 1
27676ce3c06aSMatthew 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);
27686ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
27696ce3c06aSMatthew 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);
27706ce3c06aSMatthew G. Knepley         }
27716ce3c06aSMatthew G. Knepley #endif
27726ce3c06aSMatthew G. Knepley       }
27736ce3c06aSMatthew G. Knepley     }
27746ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
27756ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
27766ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
27776ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
27786ce3c06aSMatthew G. Knepley 
27796ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
27806ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
27816ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
27826ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
27836ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
27846ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
27856ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
27866ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
27876ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
27886ce3c06aSMatthew G. Knepley 
27896ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
27906ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
27916ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
27926ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27936ce3c06aSMatthew G. Knepley #if 1
27946ce3c06aSMatthew 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);
27956ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
27966ce3c06aSMatthew 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);
27976ce3c06aSMatthew G. Knepley         }
27986ce3c06aSMatthew G. Knepley #endif
27996ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
28006ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
28016ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
28026ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
28036ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
28046ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
28056ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
28066ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
28076ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
28086ce3c06aSMatthew G. Knepley             er   = ornt[c] < 0 ? (-(ornt[c]+1) + 2-r)%3 : (ornt[c] + r)%3;
28096ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
28106ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
28116ce3c06aSMatthew G. Knepley             } else {
28126ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
28136ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
28146ce3c06aSMatthew G. Knepley             }
28156ce3c06aSMatthew G. Knepley           } else {
28166ce3c06aSMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r+1)%3;
28176ce3c06aSMatthew G. Knepley           }
28186ce3c06aSMatthew G. Knepley         }
28196ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
28206ce3c06aSMatthew G. Knepley #if 1
28216ce3c06aSMatthew 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);
28226ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
28236ce3c06aSMatthew 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);
28246ce3c06aSMatthew G. Knepley         }
28256ce3c06aSMatthew G. Knepley #endif
28266ce3c06aSMatthew G. Knepley       }
28276ce3c06aSMatthew G. Knepley     }
28286ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
28296ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
28306ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
28316ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
28326ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
28336ce3c06aSMatthew G. Knepley 
28346ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
28356ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
28366ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
28376ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
28386ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
28396ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
28406ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
28416ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
28426ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
28436ce3c06aSMatthew G. Knepley #if 1
28446ce3c06aSMatthew 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);
28456ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
28466ce3c06aSMatthew 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);
28476ce3c06aSMatthew G. Knepley       }
28486ce3c06aSMatthew G. Knepley #endif
28496ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
28506ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
28516ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
28526ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
28536ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
28546ce3c06aSMatthew G. Knepley #if 1
28556ce3c06aSMatthew 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);
28566ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
28576ce3c06aSMatthew 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);
28586ce3c06aSMatthew G. Knepley       }
28596ce3c06aSMatthew G. Knepley #endif
28606ce3c06aSMatthew G. Knepley     }
28616ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
28626ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
28636ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
28646ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
28656ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
28666ce3c06aSMatthew G. Knepley 
28676ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
28686ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
28696ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
28706ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
28716ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
28726ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
28736ce3c06aSMatthew G. Knepley #if 1
28746ce3c06aSMatthew 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);
28756ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
28766ce3c06aSMatthew 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);
28776ce3c06aSMatthew G. Knepley       }
28786ce3c06aSMatthew G. Knepley #endif
28796ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
28806ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
28816ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
28826ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
28836ce3c06aSMatthew 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]);
28846ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
28856ce3c06aSMatthew G. Knepley       }
28866ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
28876ce3c06aSMatthew G. Knepley #if 1
28886ce3c06aSMatthew 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);
28896ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
28906ce3c06aSMatthew 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);
28916ce3c06aSMatthew G. Knepley       }
28926ce3c06aSMatthew G. Knepley #endif
28936ce3c06aSMatthew G. Knepley     }
28946ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
28956ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
28966ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
28976ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *ccone;
28986ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
28996ce3c06aSMatthew G. Knepley 
29006ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
29016ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
29026ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
29036ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
29046ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
29056ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
29066ce3c06aSMatthew G. Knepley #if 1
29076ce3c06aSMatthew 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);
29086ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
29096ce3c06aSMatthew 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);
29106ce3c06aSMatthew G. Knepley       }
29116ce3c06aSMatthew G. Knepley #endif
29126ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
29136ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
29146ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
29156ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
29166ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
29176ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
29186ce3c06aSMatthew 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]);
29196ce3c06aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-2)%3;
29206ce3c06aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
29216ce3c06aSMatthew G. Knepley       }
29226ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
29236ce3c06aSMatthew G. Knepley #if 1
29246ce3c06aSMatthew 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);
29256ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
29266ce3c06aSMatthew 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);
29276ce3c06aSMatthew G. Knepley       }
29286ce3c06aSMatthew G. Knepley #endif
29296ce3c06aSMatthew G. Knepley     }
29306ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
29316ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
29326ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
29336ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
29346ce3c06aSMatthew G. Knepley       PetscInt        size, s;
29356ce3c06aSMatthew G. Knepley 
29366ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
29376ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
29386ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
29396ce3c06aSMatthew G. Knepley         PetscInt r = 0;
29406ce3c06aSMatthew G. Knepley 
29416ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
29426ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
29436ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
29446ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
29456ce3c06aSMatthew G. Knepley       }
29466ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
29476ce3c06aSMatthew G. Knepley #if 1
29486ce3c06aSMatthew 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);
29496ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
29506ce3c06aSMatthew 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);
29516ce3c06aSMatthew G. Knepley       }
29526ce3c06aSMatthew G. Knepley #endif
29536ce3c06aSMatthew G. Knepley     }
29546ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
29556ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
29566ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
29576ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
29586ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
29596ce3c06aSMatthew G. Knepley 
29606ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
29616ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
29626ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
29636ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
29646ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
29656ce3c06aSMatthew G. Knepley         PetscInt r = 0;
29666ce3c06aSMatthew G. Knepley 
29676ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
29686ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
29696ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
29706ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
29716ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
29726ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
29736ce3c06aSMatthew G. Knepley           faceSize += 2;
29746ce3c06aSMatthew G. Knepley         } else {
29756ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
29766ce3c06aSMatthew G. Knepley           ++faceSize;
29776ce3c06aSMatthew G. Knepley         }
29786ce3c06aSMatthew G. Knepley       }
29796ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
29806ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
29816ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
29826ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
29836ce3c06aSMatthew G. Knepley 
29846ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
29856ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
29866ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
29876ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
29886ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
29896ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
29906ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
29916ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
29926ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
29936ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
29946ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
29956ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
29966ce3c06aSMatthew G. Knepley         }
29976ce3c06aSMatthew G. Knepley       }
29986ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
29996ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
30006ce3c06aSMatthew G. Knepley #if 1
30016ce3c06aSMatthew 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);
30026ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
30036ce3c06aSMatthew 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);
30046ce3c06aSMatthew G. Knepley       }
30056ce3c06aSMatthew G. Knepley #endif
30066ce3c06aSMatthew G. Knepley     }
30076ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
30086ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
30096ce3c06aSMatthew G. Knepley     break;
30102eabf88fSMatthew G. Knepley   case 6:
30112eabf88fSMatthew G. Knepley     /* Hex 3D */
30122eabf88fSMatthew G. Knepley     /*
30132eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
30142eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
30152eabf88fSMatthew G. Knepley      |         |         |       |         |         |
30162eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
30172eabf88fSMatthew G. Knepley      |         |         |       |         |         |
30182eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
30192eabf88fSMatthew G. Knepley      |         |         |       |         |         |
30202eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
30212eabf88fSMatthew G. Knepley      |         |         |       |         |         |
30222eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
30232eabf88fSMatthew G. Knepley      */
30242eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
30252eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
30262eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
30272eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
30282eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
30292eabf88fSMatthew G. Knepley 
30302eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
30312eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
30322eabf88fSMatthew G. Knepley       /* A hex */
3033e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
30342eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
30352eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
30362eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3037e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
30382eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
30392eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
30402eabf88fSMatthew G. Knepley       orntNew[3] = 0;
30412eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
30422eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3043e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
30442eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
30452eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
30462eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
30472eabf88fSMatthew G. Knepley #if 1
30482eabf88fSMatthew 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);
30492eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
30502eabf88fSMatthew 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);
30512eabf88fSMatthew G. Knepley       }
30522eabf88fSMatthew G. Knepley #endif
30532eabf88fSMatthew G. Knepley       /* B hex */
3054e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
30552eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
30562eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
30572eabf88fSMatthew G. Knepley       orntNew[1] = 0;
30582eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
30592eabf88fSMatthew G. Knepley       orntNew[2] = -3;
3060e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
30612eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
30622eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
30632eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3064e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
30652eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
30662eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
30672eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
30682eabf88fSMatthew G. Knepley #if 1
30692eabf88fSMatthew 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);
30702eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
30712eabf88fSMatthew 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);
30722eabf88fSMatthew G. Knepley       }
30732eabf88fSMatthew G. Knepley #endif
30742eabf88fSMatthew G. Knepley       /* C hex */
3075e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
30762eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
30772eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
30782eabf88fSMatthew G. Knepley       orntNew[1] = 0;
30792eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
30802eabf88fSMatthew G. Knepley       orntNew[2] = 0;
3081e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
30822eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3083e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
30842eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
30852eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
30862eabf88fSMatthew G. Knepley       orntNew[5] = -3;
30872eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
30882eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
30892eabf88fSMatthew G. Knepley #if 1
30902eabf88fSMatthew 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);
30912eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
30922eabf88fSMatthew 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);
30932eabf88fSMatthew G. Knepley       }
30942eabf88fSMatthew G. Knepley #endif
30952eabf88fSMatthew G. Knepley       /* D hex */
3096e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
30972eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
30982eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
30992eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3100e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
31012eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
31022eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
31032eabf88fSMatthew G. Knepley       orntNew[3] = -3;
3104e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
31052eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
31062eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
31072eabf88fSMatthew G. Knepley       orntNew[5] = -3;
31082eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
31092eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
31102eabf88fSMatthew G. Knepley #if 1
31112eabf88fSMatthew 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);
31122eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31132eabf88fSMatthew 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);
31142eabf88fSMatthew G. Knepley       }
31152eabf88fSMatthew G. Knepley #endif
31162eabf88fSMatthew G. Knepley       /* E hex */
31172eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
31182eabf88fSMatthew G. Knepley       orntNew[0] = -3;
3119e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
31202eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3121e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
31222eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
31232eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
31242eabf88fSMatthew G. Knepley       orntNew[3] = 0;
31252eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
31262eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3127e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
31282eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3129b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
3130b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
31312eabf88fSMatthew G. Knepley #if 1
3132b164cbf2SMatthew 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);
31332eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31342eabf88fSMatthew 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);
31352eabf88fSMatthew G. Knepley       }
31362eabf88fSMatthew G. Knepley #endif
31372eabf88fSMatthew G. Knepley       /* F hex */
31382eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
31392eabf88fSMatthew G. Knepley       orntNew[0] = -3;
3140e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
31412eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3142e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
31432eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
31442eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
31452eabf88fSMatthew G. Knepley       orntNew[3] = 0;
3146e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
31472eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
31482eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
31492eabf88fSMatthew G. Knepley       orntNew[5] = -3;
3150b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
3151b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
31522eabf88fSMatthew G. Knepley #if 1
3153b164cbf2SMatthew 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);
31542eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31552eabf88fSMatthew 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);
31562eabf88fSMatthew G. Knepley       }
31572eabf88fSMatthew G. Knepley #endif
31582eabf88fSMatthew G. Knepley       /* G hex */
31592eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
31602eabf88fSMatthew G. Knepley       orntNew[0] = -3;
3161e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
31622eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
31632eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
31642eabf88fSMatthew G. Knepley       orntNew[2] = -3;
3165e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
31662eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3167e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
31682eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
31692eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
31702eabf88fSMatthew G. Knepley       orntNew[5] = 0;
3171b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
3172b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
31732eabf88fSMatthew G. Knepley #if 1
3174b164cbf2SMatthew 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);
31752eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31762eabf88fSMatthew 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);
31772eabf88fSMatthew G. Knepley       }
31782eabf88fSMatthew G. Knepley #endif
31792eabf88fSMatthew G. Knepley       /* H hex */
31802eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
31812eabf88fSMatthew G. Knepley       orntNew[0] = -3;
3182e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
31832eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
31842eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
31852eabf88fSMatthew G. Knepley       orntNew[2] = -3;
3186e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
31872eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
31882eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
31892eabf88fSMatthew G. Knepley       orntNew[4] = -3;
3190e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
31912eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3192b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
3193b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
31942eabf88fSMatthew G. Knepley #if 1
3195b164cbf2SMatthew 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);
31962eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31972eabf88fSMatthew 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);
31982eabf88fSMatthew G. Knepley       }
31992eabf88fSMatthew G. Knepley #endif
32002eabf88fSMatthew G. Knepley     }
32012eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
32022eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
32032eabf88fSMatthew G. Knepley     ierr = PetscMalloc((4 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr);
32042eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
32052eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
3206aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
32072eabf88fSMatthew 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};
32082eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
32092eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3210aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
32112eabf88fSMatthew G. Knepley 
32122eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3213aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
3214aaebbb9dSMatthew G. Knepley         coneNew[0] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
3215aaebbb9dSMatthew G. Knepley         orntNew[0] = ornt[(r+3)%4];
3216aaebbb9dSMatthew G. Knepley         coneNew[1] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
3217aaebbb9dSMatthew G. Knepley         orntNew[1] = ornt[r];
32182eabf88fSMatthew G. Knepley         coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
3219aaebbb9dSMatthew G. Knepley         orntNew[2] = 0;
32202eabf88fSMatthew G. Knepley         coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
3221aaebbb9dSMatthew G. Knepley         orntNew[3] = -2;
32222eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3223aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32242eabf88fSMatthew G. Knepley #if 1
32252eabf88fSMatthew 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);
32262eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
32272eabf88fSMatthew 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);
32282eabf88fSMatthew G. Knepley         }
32292eabf88fSMatthew G. Knepley #endif
32302eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
32312eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
32322eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
32332eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
32342eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
32352eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
32362eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
32372eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
32382eabf88fSMatthew G. Knepley           }
3239a3f78057SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubface_Static(ornt[c], r)];
32402eabf88fSMatthew G. Knepley         }
32412eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
32422eabf88fSMatthew G. Knepley #if 1
32432eabf88fSMatthew 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);
32442eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
32452eabf88fSMatthew 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);
32462eabf88fSMatthew G. Knepley         }
32472eabf88fSMatthew G. Knepley #endif
32482eabf88fSMatthew G. Knepley       }
32492eabf88fSMatthew G. Knepley     }
32502eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
32512eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
32522eabf88fSMatthew 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};
3253afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
3254afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
32552eabf88fSMatthew G. Knepley 
32562eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3257afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3258afb2665bSMatthew G. Knepley       /* A-D face */
3259afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
3260afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
3261afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3262afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
3263afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3264afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3265afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3266afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3267afb2665bSMatthew G. Knepley       orntNew[3] = -2;
32682eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3269afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32702eabf88fSMatthew G. Knepley #if 1
32712eabf88fSMatthew 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);
32722eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
32732eabf88fSMatthew 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);
32742eabf88fSMatthew G. Knepley       }
32752eabf88fSMatthew G. Knepley #endif
3276afb2665bSMatthew G. Knepley       /* C-D face */
3277afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
3278afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
3279afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3280afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
3281afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3282afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3283afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3284afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3285afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3286afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3287afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3288afb2665bSMatthew G. Knepley #if 1
3289afb2665bSMatthew 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);
3290afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3291afb2665bSMatthew 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);
3292afb2665bSMatthew G. Knepley       }
3293afb2665bSMatthew G. Knepley #endif
3294afb2665bSMatthew G. Knepley       /* B-C face */
3295afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
3296afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
3297afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3298afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
3299afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3300afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3301afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3302afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3303afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3304afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3305afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3306afb2665bSMatthew G. Knepley #if 1
3307afb2665bSMatthew 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);
3308afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3309afb2665bSMatthew 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);
3310afb2665bSMatthew G. Knepley       }
3311afb2665bSMatthew G. Knepley #endif
3312afb2665bSMatthew G. Knepley       /* A-B face */
3313afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
3314afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
3315afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3316afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
3317afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3318afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3319afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3320afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3321afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3322afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3323afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3324afb2665bSMatthew G. Knepley #if 1
3325afb2665bSMatthew 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);
3326afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3327afb2665bSMatthew 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);
3328afb2665bSMatthew G. Knepley       }
3329afb2665bSMatthew G. Knepley #endif
3330afb2665bSMatthew G. Knepley       /* E-F face */
3331afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
3332afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
3333afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3334afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
3335afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3336afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3337afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3338afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3339afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3340afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3341afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3342afb2665bSMatthew G. Knepley #if 1
3343afb2665bSMatthew 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);
3344afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3345afb2665bSMatthew 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);
3346afb2665bSMatthew G. Knepley       }
3347afb2665bSMatthew G. Knepley #endif
3348afb2665bSMatthew G. Knepley       /* F-G face */
3349afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
3350afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
3351afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3352afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
3353afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3354afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3355afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3356afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3357afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3358afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3359afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3360afb2665bSMatthew G. Knepley #if 1
3361afb2665bSMatthew 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);
3362afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3363afb2665bSMatthew 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);
3364afb2665bSMatthew G. Knepley       }
3365afb2665bSMatthew G. Knepley #endif
3366afb2665bSMatthew G. Knepley       /* G-H face */
3367afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
3368afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
3369afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3370afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
3371afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3372afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3373afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3374afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3375afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3376afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3377afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3378afb2665bSMatthew G. Knepley #if 1
3379afb2665bSMatthew 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);
3380afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3381afb2665bSMatthew 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);
3382afb2665bSMatthew G. Knepley       }
3383afb2665bSMatthew G. Knepley #endif
3384afb2665bSMatthew G. Knepley       /* E-H face */
3385afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
3386afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
3387afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3388afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
3389afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3390afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3391afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3392afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3393afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3394afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3395afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3396afb2665bSMatthew G. Knepley #if 1
3397afb2665bSMatthew 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);
3398afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3399afb2665bSMatthew 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);
3400afb2665bSMatthew G. Knepley       }
3401afb2665bSMatthew G. Knepley #endif
3402afb2665bSMatthew G. Knepley       /* A-E face */
3403afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
3404afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
3405afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3406afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
3407afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3408afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3409afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3410afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3411afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3412afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3413afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3414afb2665bSMatthew G. Knepley #if 1
3415afb2665bSMatthew 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);
3416afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3417afb2665bSMatthew 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);
3418afb2665bSMatthew G. Knepley       }
3419afb2665bSMatthew G. Knepley #endif
3420afb2665bSMatthew G. Knepley       /* D-F face */
3421afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
3422afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
3423afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3424afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
3425afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3426afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3427afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3428afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3429afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3430afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3431afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3432afb2665bSMatthew G. Knepley #if 1
3433afb2665bSMatthew 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);
3434afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3435afb2665bSMatthew 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);
3436afb2665bSMatthew G. Knepley       }
3437afb2665bSMatthew G. Knepley #endif
3438afb2665bSMatthew G. Knepley       /* C-G face */
3439afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
3440afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
3441afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3442afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
3443afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3444afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3445afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3446afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3447afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3448afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3449afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3450afb2665bSMatthew G. Knepley #if 1
3451afb2665bSMatthew 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);
3452afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3453afb2665bSMatthew 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);
3454afb2665bSMatthew G. Knepley       }
3455afb2665bSMatthew G. Knepley #endif
3456afb2665bSMatthew G. Knepley       /* B-H face */
3457afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
3458afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
3459afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3460afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
3461afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3462afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3463afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3464afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3465afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3466afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3467afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3468afb2665bSMatthew G. Knepley #if 1
3469afb2665bSMatthew 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);
3470afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3471afb2665bSMatthew 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);
3472afb2665bSMatthew G. Knepley       }
3473afb2665bSMatthew G. Knepley #endif
3474afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
3475afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
34762eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
34772eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
34782eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
34792eabf88fSMatthew G. Knepley #if 1
34802eabf88fSMatthew 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);
34812eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34822eabf88fSMatthew 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);
34832eabf88fSMatthew G. Knepley         }
34842eabf88fSMatthew G. Knepley #endif
34852eabf88fSMatthew G. Knepley       }
34862eabf88fSMatthew G. Knepley     }
34872eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
34882eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
34892eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
34902eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
34912eabf88fSMatthew G. Knepley 
34922eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
34932eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
34942eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
34952eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
34962eabf88fSMatthew G. Knepley 
34972eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
34982eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
34992eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
35002eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
35012eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35022eabf88fSMatthew G. Knepley #if 1
35032eabf88fSMatthew 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);
35042eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35052eabf88fSMatthew 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);
35062eabf88fSMatthew G. Knepley         }
35072eabf88fSMatthew G. Knepley #endif
35082eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
35092eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
35102eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
35112eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
35122eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
35132eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
35142eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
35152eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
35162eabf88fSMatthew G. Knepley           }
35172eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
35182eabf88fSMatthew G. Knepley         }
35192eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35202eabf88fSMatthew G. Knepley #if 1
35212eabf88fSMatthew 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);
35222eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
35232eabf88fSMatthew 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);
35242eabf88fSMatthew G. Knepley         }
35252eabf88fSMatthew G. Knepley #endif
35262eabf88fSMatthew G. Knepley       }
35272eabf88fSMatthew G. Knepley     }
35282eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
35292eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
35306b852384SMatthew 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};
35312eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
35326b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
35332eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
35342eabf88fSMatthew G. Knepley 
35352eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
35362eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
35372eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
35382eabf88fSMatthew G. Knepley 
35392eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
35402eabf88fSMatthew G. Knepley         coneNew[1] = newv;
35412eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35422eabf88fSMatthew G. Knepley #if 1
35432eabf88fSMatthew 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);
35442eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35452eabf88fSMatthew 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);
35462eabf88fSMatthew G. Knepley         }
35472eabf88fSMatthew G. Knepley #endif
35482eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
35492eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
35502eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
35512eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
35522eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
35536b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
35546b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
35556b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
35562eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
35576b852384SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdge_Static(orntCell[c], r)];
35582eabf88fSMatthew G. Knepley         }
35592eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35602eabf88fSMatthew G. Knepley #if 1
35612eabf88fSMatthew 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);
35622eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
35632eabf88fSMatthew 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);
35642eabf88fSMatthew G. Knepley         }
35652eabf88fSMatthew G. Knepley #endif
35662eabf88fSMatthew G. Knepley       }
35672eabf88fSMatthew G. Knepley     }
35682eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
35692eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
35702eabf88fSMatthew 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};
35712eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
35722eabf88fSMatthew G. Knepley       const PetscInt *cone;
35732eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
35742eabf88fSMatthew G. Knepley 
35752eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
35762eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
35772eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
35782eabf88fSMatthew G. Knepley 
35792eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
35802eabf88fSMatthew G. Knepley         coneNew[1] = newv;
35812eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35822eabf88fSMatthew G. Knepley #if 1
35832eabf88fSMatthew 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);
35842eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35852eabf88fSMatthew 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);
35862eabf88fSMatthew G. Knepley         }
35872eabf88fSMatthew G. Knepley #endif
35882eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
35892eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
35902eabf88fSMatthew G. Knepley #if 1
35912eabf88fSMatthew 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);
35922eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
35932eabf88fSMatthew 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);
35942eabf88fSMatthew G. Knepley         }
35952eabf88fSMatthew G. Knepley #endif
35962eabf88fSMatthew G. Knepley       }
35972eabf88fSMatthew G. Knepley     }
35982eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
35992eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
36002eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
36012eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
36022eabf88fSMatthew G. Knepley       PetscInt        size, s;
36032eabf88fSMatthew G. Knepley 
36042eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
36052eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
36062eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36072eabf88fSMatthew G. Knepley         PetscInt r = 0;
36082eabf88fSMatthew G. Knepley 
36092eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36102eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
36112eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
36122eabf88fSMatthew G. Knepley       }
36132eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36142eabf88fSMatthew G. Knepley #if 1
36152eabf88fSMatthew 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);
36162eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
36172eabf88fSMatthew 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);
36182eabf88fSMatthew G. Knepley       }
36192eabf88fSMatthew G. Knepley #endif
36202eabf88fSMatthew G. Knepley     }
36212eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
36222eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
36232eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
36242eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
36252eabf88fSMatthew G. Knepley       PetscInt        size, s;
36262eabf88fSMatthew G. Knepley 
36272eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
36282eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
36292eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
36302eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
36312eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36322eabf88fSMatthew G. Knepley         PetscInt r;
36332eabf88fSMatthew G. Knepley 
36342eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3635a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
36362eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
36372eabf88fSMatthew G. Knepley       }
36382eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36392eabf88fSMatthew G. Knepley #if 1
36402eabf88fSMatthew 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);
36412eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
36422eabf88fSMatthew 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);
36432eabf88fSMatthew G. Knepley       }
36442eabf88fSMatthew G. Knepley #endif
36452eabf88fSMatthew G. Knepley     }
36462eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
36472eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
36482eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
36492eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
36502eabf88fSMatthew G. Knepley       PetscInt        size, s;
36512eabf88fSMatthew G. Knepley 
36522eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
36532eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
36542eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (e - eStart)*2 +  (f - fStart)*4 + r;
36552eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36562eabf88fSMatthew G. Knepley         PetscInt r;
36572eabf88fSMatthew G. Knepley 
36582eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36592eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
36602eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
36612eabf88fSMatthew G. Knepley       }
36622eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36632eabf88fSMatthew G. Knepley #if 1
36642eabf88fSMatthew 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);
36652eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
36662eabf88fSMatthew 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);
36672eabf88fSMatthew G. Knepley       }
36682eabf88fSMatthew G. Knepley #endif
36692eabf88fSMatthew G. Knepley     }
36702eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
36712eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
36722eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
36732eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
36742eabf88fSMatthew G. Knepley 
36752eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
36762eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
36772eabf88fSMatthew G. Knepley       }
36782eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36792eabf88fSMatthew G. Knepley     }
3680da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
36812eabf88fSMatthew G. Knepley     break;
368275d3a19aSMatthew G. Knepley   default:
368375d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
368475d3a19aSMatthew G. Knepley   }
368575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
368675d3a19aSMatthew G. Knepley }
368775d3a19aSMatthew G. Knepley 
368875d3a19aSMatthew G. Knepley #undef __FUNCT__
368975d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates"
369075d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
369175d3a19aSMatthew G. Knepley {
369275d3a19aSMatthew G. Knepley   PetscSection   coordSection, coordSectionNew;
369375d3a19aSMatthew G. Knepley   Vec            coordinates, coordinatesNew;
369475d3a19aSMatthew G. Knepley   PetscScalar   *coords, *coordsNew;
36953478d7aaSMatthew G. Knepley   const PetscInt numVertices = depthSize ? depthSize[0] : 0;
3696b5da9499SMatthew G. Knepley   PetscInt       dim, depth, coordSizeNew, cStart, cEnd, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
369775d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
369875d3a19aSMatthew G. Knepley 
369975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
370075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
370175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
370275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
3703b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
370475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
370575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
3706b5da9499SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, NULL, &fMax, &eMax, NULL);CHKERRQ(ierr);
37073478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);}
370875d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);
370975d3a19aSMatthew G. Knepley   ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
371075d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
371175d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
371275d3a19aSMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr);
37133478d7aaSMatthew G. Knepley   ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
371475d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
3715b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
371675d3a19aSMatthew G. Knepley   /* All vertices have the dim coordinates */
37173478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
371875d3a19aSMatthew G. Knepley     ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr);
371975d3a19aSMatthew G. Knepley     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr);
372075d3a19aSMatthew G. Knepley   }
372175d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
372275d3a19aSMatthew G. Knepley   ierr = DMPlexSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr);
372375d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
372475d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
372575d3a19aSMatthew G. Knepley   ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr);
372675d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
372775d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
372875d3a19aSMatthew G. Knepley   ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr);
372975d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
373075d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
3731b5da9499SMatthew G. Knepley   switch (refiner) {
37323478d7aaSMatthew G. Knepley   case 0: break;
3733b5da9499SMatthew G. Knepley   case 6: /* Hex 3D */
3734b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
3735b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
3736c91acedaSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
3737b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
3738b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
3739b5da9499SMatthew G. Knepley 
3740b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
3741b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
3742b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
3743b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
3744b5da9499SMatthew G. Knepley       }
3745b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
3746b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
3747b5da9499SMatthew G. Knepley       }
3748b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
3749b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
3750b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
3751b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
3752b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
3753b5da9499SMatthew G. Knepley       }
3754b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
3755b5da9499SMatthew G. Knepley     }
3756b5da9499SMatthew G. Knepley   case 2: /* Hex 2D */
3757b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
3758b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
3759c91acedaSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (c - cStart) + (dim > 2 ? (fEnd - fStart) : 0);
3760b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
3761b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
3762b5da9499SMatthew G. Knepley 
3763b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
3764b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
3765b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
3766b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
3767b5da9499SMatthew G. Knepley       }
3768b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
3769b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
3770b5da9499SMatthew G. Knepley       }
3771b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
3772b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
3773b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
3774b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
3775b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
3776b5da9499SMatthew G. Knepley       }
3777b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
3778b5da9499SMatthew G. Knepley     }
3779b5da9499SMatthew G. Knepley   case 1: /* Simplicial 2D */
3780b5da9499SMatthew G. Knepley   case 3: /* Hybrid Simplicial 2D */
3781b5da9499SMatthew G. Knepley   case 5: /* Simplicial 3D */
37826ce3c06aSMatthew G. Knepley   case 7: /* Hybrid Simplicial 3D */
3783b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
3784b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
3785b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
3786b5da9499SMatthew G. Knepley       const PetscInt *cone;
3787b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
3788b5da9499SMatthew G. Knepley 
3789b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
3790b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
3791b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
3792b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
3793b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
3794b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
3795b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
3796b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]);
3797b5da9499SMatthew G. Knepley       }
3798b5da9499SMatthew G. Knepley     }
379975d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
380075d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
380175d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
380275d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
380375d3a19aSMatthew G. Knepley 
380475d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
380575d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
380675d3a19aSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
380775d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
380875d3a19aSMatthew G. Knepley       }
380975d3a19aSMatthew G. Knepley     }
3810b5da9499SMatthew G. Knepley     break;
3811b5da9499SMatthew G. Knepley   default:
3812b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
381375d3a19aSMatthew G. Knepley   }
381475d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
381575d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
381675d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
381775d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
381875d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
381975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
382075d3a19aSMatthew G. Knepley }
382175d3a19aSMatthew G. Knepley 
382275d3a19aSMatthew G. Knepley #undef __FUNCT__
382375d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF"
382475d3a19aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
382575d3a19aSMatthew G. Knepley {
382675d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
382775d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
382875d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
382975d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
383075d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
383175d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
383275d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
383375d3a19aSMatthew G. Knepley 
383475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
383575d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
383675d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranks);CHKERRQ(ierr);
383775d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
383875d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
383975d3a19aSMatthew G. Knepley   }
384075d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
384175d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeaves * sizeof(PetscInt),    &ranksNew);CHKERRQ(ierr);
384275d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeaves * sizeof(PetscInt),    &localPointsNew);CHKERRQ(ierr);
384375d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeaves * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr);
384475d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
384575d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
384675d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
384775d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
384875d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
384975d3a19aSMatthew G. Knepley   }
385075d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
385175d3a19aSMatthew G. Knepley   ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);
385275d3a19aSMatthew G. Knepley   ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
385375d3a19aSMatthew G. Knepley   ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
385475d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
385575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
385675d3a19aSMatthew G. Knepley }
385775d3a19aSMatthew G. Knepley 
385875d3a19aSMatthew G. Knepley #undef __FUNCT__
385975d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF"
386075d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
386175d3a19aSMatthew G. Knepley {
386275d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
386375d3a19aSMatthew G. Knepley   IS                 processRanks;
386475d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
386575d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
386675d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
386775d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
386875d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
386975d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
387075d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
387175d3a19aSMatthew G. Knepley   PetscInt           depth, numNeighbors, pStartNew, pEndNew, cStart, cStartNew, cEnd, cMax, vStart, vStartNew, vEnd, vMax, fStart, fStartNew, fEnd, fMax, eStart, eStartNew, eEnd, eMax, r, n;
387275d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
387375d3a19aSMatthew G. Knepley 
387475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
387575d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
387675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
387775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
387875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
387975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
388075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
388175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
38823478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
388375d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
388475d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
388575d3a19aSMatthew G. Knepley   /* Caculate size of new SF */
388675d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
388775d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
388875d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
388975d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
389075d3a19aSMatthew G. Knepley 
389175d3a19aSMatthew G. Knepley     switch (refiner) {
389275d3a19aSMatthew G. Knepley     case 1:
389375d3a19aSMatthew G. Knepley       /* Simplicial 2D */
389475d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
389575d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
389675d3a19aSMatthew G. Knepley         ++numLeavesNew;
389775d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
389875d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
3899d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
390075d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
390175d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
390275d3a19aSMatthew G. Knepley         numLeavesNew += 4 + 3;
390375d3a19aSMatthew G. Knepley       }
390475d3a19aSMatthew G. Knepley       break;
390575d3a19aSMatthew G. Knepley     case 2:
390675d3a19aSMatthew G. Knepley       /* Hex 2D */
390775d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
390875d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
390975d3a19aSMatthew G. Knepley         ++numLeavesNew;
391075d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
391175d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
3912d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
391375d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
3914455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
3915455d6cd4SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
391675d3a19aSMatthew G. Knepley       }
391775d3a19aSMatthew G. Knepley       break;
3918b5da9499SMatthew G. Knepley     case 5:
3919b5da9499SMatthew G. Knepley       /* Simplicial 3D */
3920b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
3921b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
3922b5da9499SMatthew G. Knepley         ++numLeavesNew;
3923b5da9499SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
3924b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
3925b5da9499SMatthew G. Knepley         numLeavesNew += 2 + 1;
3926b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
3927b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
3928b5da9499SMatthew G. Knepley         numLeavesNew += 4 + 3;
3929b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
3930b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
3931b5da9499SMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
3932b5da9499SMatthew G. Knepley       }
3933b5da9499SMatthew G. Knepley       break;
39346ce3c06aSMatthew G. Knepley     case 7:
39356ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
39366ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
39376ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
39386ce3c06aSMatthew G. Knepley         ++numLeavesNew;
39396ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
39406ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
39416ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
39426ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
39436ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
39446ce3c06aSMatthew G. Knepley         ++numLeavesNew;
39456ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
39466ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
39476ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
39486ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
39496ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
39506ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
39516ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
39526ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
39536ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
39546ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
39556ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
39566ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
39576ce3c06aSMatthew G. Knepley       }
39586ce3c06aSMatthew G. Knepley       break;
39592eabf88fSMatthew G. Knepley     case 6:
39602eabf88fSMatthew G. Knepley       /* Hex 3D */
39612eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
39622eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
39632eabf88fSMatthew G. Knepley         ++numLeavesNew;
39642eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
39652eabf88fSMatthew G. Knepley         /* Old edges add new edges, and vertex */
39662eabf88fSMatthew G. Knepley         numLeavesNew += 2 + 1;
39672eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
39682eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
39692eabf88fSMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
39702eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
39712eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
39722eabf88fSMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
39732eabf88fSMatthew G. Knepley       }
39742eabf88fSMatthew G. Knepley       break;
397575d3a19aSMatthew G. Knepley     default:
397675d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
397775d3a19aSMatthew G. Knepley     }
397875d3a19aSMatthew G. Knepley   }
397975d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
398075d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
398175d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
398275d3a19aSMatthew G. Knepley   ierr = PetscMalloc5((depth+1)*numNeighbors,PetscInt,&rdepthSize,numNeighbors,PetscInt,&rvStartNew,numNeighbors,PetscInt,&reStartNew,numNeighbors,PetscInt,&rfStartNew,numNeighbors,PetscInt,&rcStartNew);CHKERRQ(ierr);
398375d3a19aSMatthew G. Knepley   ierr = PetscMalloc7(depth+1,PetscInt,&depthSizeOld,(depth+1)*numNeighbors,PetscInt,&rdepthSizeOld,(depth+1)*numNeighbors,PetscInt,&rdepthMaxOld,numNeighbors,PetscInt,&rvStart,numNeighbors,PetscInt,&reStart,numNeighbors,PetscInt,&rfStart,numNeighbors,PetscInt,&rcStart);CHKERRQ(ierr);
398475d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
398575d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
398675d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
398775d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
398875d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
398975d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
399075d3a19aSMatthew G. Knepley   }
399175d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
399275d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
399375d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
399475d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
399575d3a19aSMatthew G. Knepley 
399675d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
399775d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
399875d3a19aSMatthew G. Knepley 
399975d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
400075d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
400175d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
400275d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
400375d3a19aSMatthew G. Knepley 
400475d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
400575d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
400675d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
400775d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
400875d3a19aSMatthew G. Knepley   }
400975d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
401075d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
401175d3a19aSMatthew G. Knepley   /* Calculate new point SF */
401275d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeavesNew * sizeof(PetscInt),    &localPointsNew);CHKERRQ(ierr);
401375d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeavesNew * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr);
401475d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
401575d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
401675d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
401775d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
401875d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
401975d3a19aSMatthew G. Knepley 
402075d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
402175d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
402275d3a19aSMatthew G. Knepley     switch (refiner) {
402375d3a19aSMatthew G. Knepley     case 1:
402475d3a19aSMatthew G. Knepley       /* Simplicial 2D */
402575d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
402675d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
402775d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
402875d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
402975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
403075d3a19aSMatthew G. Knepley         ++m;
403175d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
403275d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
403375d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
403475d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
403575d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
403675d3a19aSMatthew G. Knepley         ++m;
403775d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
403875d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
403975d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
404075d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
404175d3a19aSMatthew G. Knepley         }
404275d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
404375d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
404475d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
404575d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
404675d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
404775d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
404875d3a19aSMatthew G. Knepley         }
404975d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
405075d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*3     + r;
405175d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
405275d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
405375d3a19aSMatthew G. Knepley         }
405475d3a19aSMatthew G. Knepley       }
405575d3a19aSMatthew G. Knepley       break;
405675d3a19aSMatthew G. Knepley     case 2:
405775d3a19aSMatthew G. Knepley       /* Hex 2D */
405875d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
405975d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
406075d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
406175d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
406275d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
406375d3a19aSMatthew G. Knepley         ++m;
406475d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
406575d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
406675d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
406775d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
406875d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
406975d3a19aSMatthew G. Knepley         ++m;
407075d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
407175d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
407275d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
407375d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
407475d3a19aSMatthew G. Knepley         }
407575d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
4076455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
407775d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
407875d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
407975d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
408075d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
408175d3a19aSMatthew G. Knepley         }
408275d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
408375d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*4     + r;
408475d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r;
408575d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
408675d3a19aSMatthew G. Knepley         }
4087455d6cd4SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
4088455d6cd4SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (fEnd - fStart)                    + (p  - cStart)     + r;
4089455d6cd4SMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
4090455d6cd4SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4091455d6cd4SMatthew G. Knepley         }
409275d3a19aSMatthew G. Knepley       }
409375d3a19aSMatthew G. Knepley       break;
409475d3a19aSMatthew G. Knepley     case 3:
409575d3a19aSMatthew G. Knepley       /* Hybrid simplicial 2D */
409675d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
409775d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
409875d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
409975d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
410075d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
410175d3a19aSMatthew G. Knepley         ++m;
410275d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
410375d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
410475d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
410575d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
410675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
410775d3a19aSMatthew G. Knepley         ++m;
410875d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
410975d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
411075d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
411175d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
411275d3a19aSMatthew G. Knepley         }
411375d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
411475d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
411575d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
411675d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
411775d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
411875d3a19aSMatthew G. Knepley         ++m;
411975d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
412075d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
412175d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
412275d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
412375d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
412475d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
412575d3a19aSMatthew G. Knepley         }
412675d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
412775d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
412875d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
412975d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
413075d3a19aSMatthew G. Knepley         }
413175d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
413275d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
413375d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
413475d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
413575d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
413675d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
413775d3a19aSMatthew G. Knepley         }
413875d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
413975d3a19aSMatthew 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]);
414075d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
414175d3a19aSMatthew G. Knepley         ++m;
414275d3a19aSMatthew G. Knepley       }
414375d3a19aSMatthew G. Knepley       break;
4144b5da9499SMatthew G. Knepley     case 5:
4145b5da9499SMatthew G. Knepley       /* Simplicial 3D */
4146b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
4147b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
4148b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
4149b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
4150b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
4151b5da9499SMatthew G. Knepley         ++m;
415287fe6628SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
4153b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
4154b5da9499SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
4155b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
4156b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
4157b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4158b5da9499SMatthew G. Knepley         }
4159b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
4160b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
4161b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
4162b5da9499SMatthew G. Knepley         ++m;
4163b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
4164b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
4165b5da9499SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
4166b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
4167b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
4168b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4169b5da9499SMatthew G. Knepley         }
4170b5da9499SMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
4171b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*3     + r;
4172b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r;
4173b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4174b5da9499SMatthew G. Knepley         }
4175b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
4176b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
4177b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
4178b5da9499SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
4179b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
4180b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4181b5da9499SMatthew G. Knepley         }
4182b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
4183b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*8     + r;
4184b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r;
4185b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4186b5da9499SMatthew G. Knepley         }
4187b5da9499SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
4188b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*3                    + (p  - cStart)*1     + r;
4189b5da9499SMatthew 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;
4190b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4191b5da9499SMatthew G. Knepley         }
4192b5da9499SMatthew G. Knepley       }
4193b5da9499SMatthew G. Knepley       break;
41946ce3c06aSMatthew G. Knepley     case 7:
41956ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
41966ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
41976ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
41986ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
41996ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
42006ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42016ce3c06aSMatthew G. Knepley         ++m;
42026ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
42036ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
42046ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
42056ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
42066ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
42076ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42086ce3c06aSMatthew G. Knepley         }
42096ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
42106ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
42116ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42126ce3c06aSMatthew G. Knepley         ++m;
42136ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
42146ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
42156ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
42166ce3c06aSMatthew 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]);
42176ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42186ce3c06aSMatthew G. Knepley         ++m;
42196ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
42206ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
42216ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
42226ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
42236ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
42246ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42256ce3c06aSMatthew G. Knepley         }
42266ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
42276ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
42286ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
42296ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42306ce3c06aSMatthew G. Knepley         }
42316ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
42326ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
42336ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
42346ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fStart)*2     + r;
42356ce3c06aSMatthew 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 - rfStart[n])*2 + r;
42366ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42376ce3c06aSMatthew G. Knepley         }
42386ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)     + (cMax                            - cStart)     + (fEnd                                          - fMax);
42396ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]);
42406ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42416ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
42426ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
42436ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
42446ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
42456ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
42466ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42476ce3c06aSMatthew G. Knepley         }
42486ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
42496ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
42506ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
42516ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42526ce3c06aSMatthew G. Knepley         }
42536ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + r;
42546ce3c06aSMatthew 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;
42556ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42566ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
42576ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
42586ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
42596ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
42606ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
42616ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42626ce3c06aSMatthew G. Knepley         }
42636ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
42646ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*4                              + (p  - cMax)*3                            + r;
42656ce3c06aSMatthew 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])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r;
42666ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42676ce3c06aSMatthew G. Knepley         }
42686ce3c06aSMatthew G. Knepley       }
42696ce3c06aSMatthew G. Knepley       break;
42702eabf88fSMatthew G. Knepley     case 6:
42712eabf88fSMatthew G. Knepley       /* Hex 3D */
42722eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
42732eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
42742eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
42752eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
42762eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42772eabf88fSMatthew G. Knepley         ++m;
42782eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
42792eabf88fSMatthew G. Knepley         /* Old edges add new edges and vertex */
42802eabf88fSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
42812eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
42822eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
42832eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42842eabf88fSMatthew G. Knepley         }
42852eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
42862eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
42872eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42882eabf88fSMatthew G. Knepley         ++m;
42892eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
42902eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
42912eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
42922eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
42932eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
42942eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42952eabf88fSMatthew G. Knepley         }
42962eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
42972eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*4     + r;
42982eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r;
42992eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43002eabf88fSMatthew G. Knepley         }
43012eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (p  - fStart);
43022eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]);
43032eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
43042eabf88fSMatthew G. Knepley         ++m;
43052eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
43062eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
43072eabf88fSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
43082eabf88fSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
43092eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
43102eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43112eabf88fSMatthew G. Knepley         }
43122eabf88fSMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
43132eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*12     + r;
43142eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r;
43152eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43162eabf88fSMatthew G. Knepley         }
43172eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
43182eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*4                    + (p  - cStart)*6     + r;
43192eabf88fSMatthew 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;
43202eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43212eabf88fSMatthew G. Knepley         }
43222eabf88fSMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
43232eabf88fSMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eEnd - eStart)              + (fEnd - fStart)                    + (p  - cStart)     + r;
43242eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
43252eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43262eabf88fSMatthew G. Knepley         }
43272eabf88fSMatthew G. Knepley       }
43282eabf88fSMatthew G. Knepley       break;
432975d3a19aSMatthew G. Knepley     default:
433075d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
433175d3a19aSMatthew G. Knepley     }
433275d3a19aSMatthew G. Knepley   }
433375d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
433475d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
433575d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
433675d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
433706a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
433875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
433975d3a19aSMatthew G. Knepley }
434075d3a19aSMatthew G. Knepley 
434175d3a19aSMatthew G. Knepley #undef __FUNCT__
434275d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels"
434375d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
434475d3a19aSMatthew G. Knepley {
434575d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
4346b5da9499SMatthew G. Knepley   PetscInt       depth, newp, cStart, cStartNew, cEnd, cMax, vStart, vStartNew, vEnd, vMax, fStart, fStartNew, fEnd, fMax, eStart, eStartNew, eEnd, eMax, r;
434775d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
434875d3a19aSMatthew G. Knepley 
434975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
435075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
435175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
435275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
435375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
4354d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
43553478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
435675d3a19aSMatthew G. Knepley   ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
435775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
435875d3a19aSMatthew G. Knepley   switch (refiner) {
43593478d7aaSMatthew G. Knepley   case 0: break;
436058b8852aSMatthew G. Knepley   case 7:
436158b8852aSMatthew G. Knepley   case 8:
436258b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
436375d3a19aSMatthew G. Knepley   case 3:
436458b8852aSMatthew G. Knepley   case 4:
436575d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
436675d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
436775d3a19aSMatthew G. Knepley   }
436875d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
436975d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
437075d3a19aSMatthew G. Knepley     const char     *lname;
437175d3a19aSMatthew G. Knepley     PetscBool       isDepth;
437275d3a19aSMatthew G. Knepley     IS              valueIS;
437375d3a19aSMatthew G. Knepley     const PetscInt *values;
437475d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
437575d3a19aSMatthew G. Knepley 
437675d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr);
437775d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
437875d3a19aSMatthew G. Knepley     if (isDepth) continue;
437975d3a19aSMatthew G. Knepley     ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr);
438075d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr);
438175d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
438275d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
438375d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
438475d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
438575d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
438675d3a19aSMatthew G. Knepley       IS              pointIS;
438775d3a19aSMatthew G. Knepley       const PetscInt *points;
438875d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
438975d3a19aSMatthew G. Knepley 
439075d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
439175d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
439275d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
439375d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
439475d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
439575d3a19aSMatthew G. Knepley         switch (refiner) {
439675d3a19aSMatthew G. Knepley         case 1:
439775d3a19aSMatthew G. Knepley           /* Simplicial 2D */
439875d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
439975d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
440075d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
440175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
440275d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
440375d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
440475d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
440575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
440675d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
440775d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
440875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
440975d3a19aSMatthew G. Knepley             }
441075d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
441175d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
441275d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
441375d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
441475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
441575d3a19aSMatthew G. Knepley             }
441675d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
441775d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
441875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
441975d3a19aSMatthew G. Knepley             }
442075d3a19aSMatthew G. Knepley           }
442175d3a19aSMatthew G. Knepley           break;
442275d3a19aSMatthew G. Knepley         case 2:
442375d3a19aSMatthew G. Knepley           /* Hex 2D */
442475d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
442575d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
442675d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
442775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
442875d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
442975d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
443075d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
443175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
443275d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
443375d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
443475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
443575d3a19aSMatthew G. Knepley             }
443675d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
443775d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
443875d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
443975d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
444075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
444175d3a19aSMatthew G. Knepley             }
444275d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
444375d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
444475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
444575d3a19aSMatthew G. Knepley             }
444675d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
444775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
444875d3a19aSMatthew G. Knepley           }
444975d3a19aSMatthew G. Knepley           break;
445075d3a19aSMatthew G. Knepley         case 3:
445175d3a19aSMatthew G. Knepley           /* Hybrid simplicial 2D */
445275d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
445375d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
445475d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
445575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
445675d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
445775d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
445875d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
445975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
446075d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
446175d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
446275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
446375d3a19aSMatthew G. Knepley             }
446475d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
446575d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
446675d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
446775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
446875d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
446975d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
447075d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
447175d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
447275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
447375d3a19aSMatthew G. Knepley             }
447475d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
447575d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
447675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
447775d3a19aSMatthew G. Knepley             }
447875d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
447975d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
448075d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
448175d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
448275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
448375d3a19aSMatthew G. Knepley             }
448475d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
448575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
448675d3a19aSMatthew G. Knepley           }
448775d3a19aSMatthew G. Knepley           break;
4488b5da9499SMatthew G. Knepley         case 5:
4489b5da9499SMatthew G. Knepley           /* Simplicial 3D */
4490b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
4491b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
4492b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
4493b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4494b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
4495b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
4496b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
4497b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
4498b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4499b5da9499SMatthew G. Knepley             }
4500b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
4501b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4502b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
4503b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
4504b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
4505b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
4506b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4507b5da9499SMatthew G. Knepley             }
4508b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
4509b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
4510b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4511b5da9499SMatthew G. Knepley             }
4512b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
4513b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
4514b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
4515b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
4516b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4517b5da9499SMatthew G. Knepley             }
4518b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
4519b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
4520b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4521b5da9499SMatthew G. Knepley             }
4522b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
4523b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
4524b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4525b5da9499SMatthew G. Knepley             }
4526b5da9499SMatthew G. Knepley           }
4527b5da9499SMatthew G. Knepley           break;
45286ce3c06aSMatthew G. Knepley         case 7:
45296ce3c06aSMatthew G. Knepley           /* Hybrid Simplicial 3D */
45306ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
45316ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
45326ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
45336ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45346ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
45356ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
45366ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
45376ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
45386ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45396ce3c06aSMatthew G. Knepley             }
45406ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
45416ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45426ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
45436ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
45446ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
45456ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45466ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
45476ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
45486ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
45496ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
45506ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45516ce3c06aSMatthew G. Knepley             }
45526ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
45536ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
45546ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45556ce3c06aSMatthew G. Knepley             }
45566ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
45576ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
45586ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
45596ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
45606ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45616ce3c06aSMatthew G. Knepley             }
45626ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
45636ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45646ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
45656ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
45666ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
45676ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
45686ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45696ce3c06aSMatthew G. Knepley             }
45706ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
45716ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
45726ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45736ce3c06aSMatthew G. Knepley             }
45746ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
45756ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
457658b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
45776ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
45786ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
45796ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
45806ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45816ce3c06aSMatthew G. Knepley             }
45826ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
45836ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
45846ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45856ce3c06aSMatthew G. Knepley             }
45866ce3c06aSMatthew G. Knepley           }
45876ce3c06aSMatthew G. Knepley           break;
45882eabf88fSMatthew G. Knepley         case 6:
45892eabf88fSMatthew G. Knepley           /* Hex 3D */
45902eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
45912eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
45922eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
45932eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
459419d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
45952eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
45962eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
45972eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
45982eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45992eabf88fSMatthew G. Knepley             }
46002eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
46012eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46022eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
46032eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
46042eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
46052eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
46062eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46072eabf88fSMatthew G. Knepley             }
46082eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
46092eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
46102eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46112eabf88fSMatthew G. Knepley             }
46122eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
46132eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46142eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
46152eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
46162eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
46172eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
46182eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46192eabf88fSMatthew G. Knepley             }
46202eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
46212eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
46222eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46232eabf88fSMatthew G. Knepley             }
46242eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
46252eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
46262eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46272eabf88fSMatthew G. Knepley             }
46282eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
46292eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46302eabf88fSMatthew G. Knepley           }
46312eabf88fSMatthew G. Knepley           break;
463275d3a19aSMatthew G. Knepley         default:
463375d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
463475d3a19aSMatthew G. Knepley         }
463575d3a19aSMatthew G. Knepley       }
463675d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
463775d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
463875d3a19aSMatthew G. Knepley     }
463975d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
464075d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
464175d3a19aSMatthew G. Knepley     if (0) {
464275d3a19aSMatthew G. Knepley       ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr);
464375d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
464475d3a19aSMatthew G. Knepley       ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
464575d3a19aSMatthew G. Knepley     }
464675d3a19aSMatthew G. Knepley   }
464775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
464875d3a19aSMatthew G. Knepley }
464975d3a19aSMatthew G. Knepley 
465075d3a19aSMatthew G. Knepley #undef __FUNCT__
4651509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexRefineUniform_Internal"
465275d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
4653509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
465475d3a19aSMatthew G. Knepley {
465575d3a19aSMatthew G. Knepley   DM             rdm;
465675d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
465775d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
465875d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
465975d3a19aSMatthew G. Knepley 
466075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
466175d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
466275d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
466375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
466475d3a19aSMatthew G. Knepley   ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr);
466575d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
466675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
466775d3a19aSMatthew G. Knepley   ierr = PetscMalloc((depth+1) * sizeof(PetscInt), &depthSize);CHKERRQ(ierr);
466875d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
466975d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
467075d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
467175d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
467275d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
467375d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
467475d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
467575d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
467675d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
467775d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
467875d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
467975d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
468075d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
468175d3a19aSMatthew G. Knepley   /* Step 6: Set coordinates for vertices */
468275d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
468375d3a19aSMatthew G. Knepley   /* Step 7: Create pointSF */
468475d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
468575d3a19aSMatthew G. Knepley   /* Step 8: Create labels */
468675d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
468775d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
468875d3a19aSMatthew G. Knepley 
468975d3a19aSMatthew G. Knepley   *dmRefined = rdm;
469075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
469175d3a19aSMatthew G. Knepley }
469275d3a19aSMatthew G. Knepley 
469375d3a19aSMatthew G. Knepley #undef __FUNCT__
469475d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform"
469575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
469675d3a19aSMatthew G. Knepley {
469775d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
469875d3a19aSMatthew G. Knepley 
469975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
470075d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
470175d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
470275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
470375d3a19aSMatthew G. Knepley }
470475d3a19aSMatthew G. Knepley 
470575d3a19aSMatthew G. Knepley #undef __FUNCT__
470675d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform"
470775d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
470875d3a19aSMatthew G. Knepley {
470975d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
471075d3a19aSMatthew G. Knepley 
471175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
471275d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
471375d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
471475d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
471575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
471675d3a19aSMatthew G. Knepley }
471775d3a19aSMatthew G. Knepley 
471875d3a19aSMatthew G. Knepley #undef __FUNCT__
471975d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit"
472075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
472175d3a19aSMatthew G. Knepley {
472275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
472375d3a19aSMatthew G. Knepley 
472475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
472575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
472675d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
472775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
472875d3a19aSMatthew G. Knepley }
472975d3a19aSMatthew G. Knepley 
473075d3a19aSMatthew G. Knepley #undef __FUNCT__
473175d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit"
473275d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
473375d3a19aSMatthew G. Knepley {
473475d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
473575d3a19aSMatthew G. Knepley 
473675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
473775d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
473875d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
473975d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
474075d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
474175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
474275d3a19aSMatthew G. Knepley }
474375d3a19aSMatthew G. Knepley 
474475d3a19aSMatthew G. Knepley #undef __FUNCT__
4745509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Internal"
4746509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
474775d3a19aSMatthew G. Knepley {
47483478d7aaSMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax;
474975d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
475075d3a19aSMatthew G. Knepley 
475175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
475275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
47533478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
47543478d7aaSMatthew G. Knepley   if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);}
475575d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
475675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr);
475775d3a19aSMatthew G. Knepley   switch (dim) {
475875d3a19aSMatthew G. Knepley   case 2:
475975d3a19aSMatthew G. Knepley     switch (coneSize) {
476075d3a19aSMatthew G. Knepley     case 3:
476175d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 3; /* Hybrid */
476275d3a19aSMatthew G. Knepley       else *cellRefiner = 1; /* Triangular */
476375d3a19aSMatthew G. Knepley       break;
476475d3a19aSMatthew G. Knepley     case 4:
476575d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 4; /* Hybrid */
476675d3a19aSMatthew G. Knepley       else *cellRefiner = 2; /* Quadrilateral */
476775d3a19aSMatthew G. Knepley       break;
476875d3a19aSMatthew G. Knepley     default:
476975d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
477075d3a19aSMatthew G. Knepley     }
477175d3a19aSMatthew G. Knepley     break;
4772b5da9499SMatthew G. Knepley   case 3:
4773b5da9499SMatthew G. Knepley     switch (coneSize) {
4774b5da9499SMatthew G. Knepley     case 4:
4775b5da9499SMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 7; /* Hybrid */
4776b5da9499SMatthew G. Knepley       else *cellRefiner = 5; /* Tetrahedral */
4777b5da9499SMatthew G. Knepley       break;
47782eabf88fSMatthew G. Knepley     case 6:
47792eabf88fSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 8; /* Hybrid */
47802eabf88fSMatthew G. Knepley       else *cellRefiner = 6; /* hexahedral */
47812eabf88fSMatthew G. Knepley       break;
4782b5da9499SMatthew G. Knepley     default:
4783b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
4784b5da9499SMatthew G. Knepley     }
4785b5da9499SMatthew G. Knepley     break;
478675d3a19aSMatthew G. Knepley   default:
478775d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
478875d3a19aSMatthew G. Knepley   }
478975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
479075d3a19aSMatthew G. Knepley }
4791