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