xref: /petsc/src/dm/impls/plex/plexrefine.c (revision dcca6d9d80ebd869fe6029bd05a3aa9faafef49e)
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 {
28106ce3c06aSMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (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);
28916ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *ccone;
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);
29116ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
29126ce3c06aSMatthew 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]);
29136ce3c06aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-2)%3;
29146ce3c06aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
29156ce3c06aSMatthew G. Knepley       }
29166ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
29176ce3c06aSMatthew G. Knepley #if 1
29186ce3c06aSMatthew 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);
29196ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
29206ce3c06aSMatthew 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);
29216ce3c06aSMatthew G. Knepley       }
29226ce3c06aSMatthew G. Knepley #endif
29236ce3c06aSMatthew G. Knepley     }
29246ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
29256ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
29266ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
29276ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
29286ce3c06aSMatthew G. Knepley       PetscInt        size, s;
29296ce3c06aSMatthew G. Knepley 
29306ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
29316ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
29326ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
29336ce3c06aSMatthew G. Knepley         PetscInt r = 0;
29346ce3c06aSMatthew G. Knepley 
29356ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
29366ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
29376ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
29386ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
29396ce3c06aSMatthew G. Knepley       }
29406ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
29416ce3c06aSMatthew G. Knepley #if 1
29426ce3c06aSMatthew 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);
29436ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
29446ce3c06aSMatthew 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);
29456ce3c06aSMatthew G. Knepley       }
29466ce3c06aSMatthew G. Knepley #endif
29476ce3c06aSMatthew G. Knepley     }
29486ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
29496ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
29506ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
29516ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
29526ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
29536ce3c06aSMatthew G. Knepley 
29546ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
29556ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
29566ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
29576ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
29586ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
29596ce3c06aSMatthew G. Knepley         PetscInt r = 0;
29606ce3c06aSMatthew G. Knepley 
29616ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
29626ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
29636ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
29646ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
29656ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
29666ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
29676ce3c06aSMatthew G. Knepley           faceSize += 2;
29686ce3c06aSMatthew G. Knepley         } else {
29696ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
29706ce3c06aSMatthew G. Knepley           ++faceSize;
29716ce3c06aSMatthew G. Knepley         }
29726ce3c06aSMatthew G. Knepley       }
29736ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
29746ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
29756ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
29766ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
29776ce3c06aSMatthew G. Knepley 
29786ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
29796ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
29806ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
29816ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
29826ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
29836ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
29846ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
29856ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
29866ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
29876ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
29886ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
29896ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
29906ce3c06aSMatthew G. Knepley         }
29916ce3c06aSMatthew G. Knepley       }
29926ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
29936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
29946ce3c06aSMatthew G. Knepley #if 1
29956ce3c06aSMatthew 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);
29966ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
29976ce3c06aSMatthew 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);
29986ce3c06aSMatthew G. Knepley       }
29996ce3c06aSMatthew G. Knepley #endif
30006ce3c06aSMatthew G. Knepley     }
30016ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
30026ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
30036ce3c06aSMatthew G. Knepley     break;
30042eabf88fSMatthew G. Knepley   case 6:
30052eabf88fSMatthew G. Knepley     /* Hex 3D */
30062eabf88fSMatthew G. Knepley     /*
30072eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
30082eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
30092eabf88fSMatthew G. Knepley      |         |         |       |         |         |
30102eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
30112eabf88fSMatthew G. Knepley      |         |         |       |         |         |
30122eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
30132eabf88fSMatthew G. Knepley      |         |         |       |         |         |
30142eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
30152eabf88fSMatthew G. Knepley      |         |         |       |         |         |
30162eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
30172eabf88fSMatthew G. Knepley      */
30182eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
30192eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
30202eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
30212eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
30222eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
30232eabf88fSMatthew G. Knepley 
30242eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
30252eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
30262eabf88fSMatthew G. Knepley       /* A hex */
3027e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
30282eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
30292eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
30302eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3031e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
30322eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
30332eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
30342eabf88fSMatthew G. Knepley       orntNew[3] = 0;
30352eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
30362eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3037e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
30382eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
30392eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
30402eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
30412eabf88fSMatthew G. Knepley #if 1
30422eabf88fSMatthew 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);
30432eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
30442eabf88fSMatthew 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);
30452eabf88fSMatthew G. Knepley       }
30462eabf88fSMatthew G. Knepley #endif
30472eabf88fSMatthew G. Knepley       /* B hex */
3048e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
30492eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
30502eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
30512eabf88fSMatthew G. Knepley       orntNew[1] = 0;
30522eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
30532eabf88fSMatthew G. Knepley       orntNew[2] = -3;
3054e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
30552eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
30562eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
30572eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3058e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
30592eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
30602eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
30612eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
30622eabf88fSMatthew G. Knepley #if 1
30632eabf88fSMatthew 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);
30642eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
30652eabf88fSMatthew 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);
30662eabf88fSMatthew G. Knepley       }
30672eabf88fSMatthew G. Knepley #endif
30682eabf88fSMatthew G. Knepley       /* C hex */
3069e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
30702eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
30712eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
30722eabf88fSMatthew G. Knepley       orntNew[1] = 0;
30732eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
30742eabf88fSMatthew G. Knepley       orntNew[2] = 0;
3075e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
30762eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3077e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
30782eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
30792eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
30802eabf88fSMatthew G. Knepley       orntNew[5] = -3;
30812eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
30822eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
30832eabf88fSMatthew G. Knepley #if 1
30842eabf88fSMatthew 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);
30852eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
30862eabf88fSMatthew 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);
30872eabf88fSMatthew G. Knepley       }
30882eabf88fSMatthew G. Knepley #endif
30892eabf88fSMatthew G. Knepley       /* D hex */
3090e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
30912eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
30922eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
30932eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3094e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
30952eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
30962eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
30972eabf88fSMatthew G. Knepley       orntNew[3] = -3;
3098e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
30992eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
31002eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
31012eabf88fSMatthew G. Knepley       orntNew[5] = -3;
31022eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
31032eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
31042eabf88fSMatthew G. Knepley #if 1
31052eabf88fSMatthew 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);
31062eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31072eabf88fSMatthew 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);
31082eabf88fSMatthew G. Knepley       }
31092eabf88fSMatthew G. Knepley #endif
31102eabf88fSMatthew G. Knepley       /* E hex */
31112eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
31122eabf88fSMatthew G. Knepley       orntNew[0] = -3;
3113e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
31142eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3115e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
31162eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
31172eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
31182eabf88fSMatthew G. Knepley       orntNew[3] = 0;
31192eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
31202eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3121e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
31222eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3123b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
3124b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
31252eabf88fSMatthew G. Knepley #if 1
3126b164cbf2SMatthew 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);
31272eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31282eabf88fSMatthew 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);
31292eabf88fSMatthew G. Knepley       }
31302eabf88fSMatthew G. Knepley #endif
31312eabf88fSMatthew G. Knepley       /* F hex */
31322eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
31332eabf88fSMatthew G. Knepley       orntNew[0] = -3;
3134e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
31352eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3136e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
31372eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
31382eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
31392eabf88fSMatthew G. Knepley       orntNew[3] = 0;
3140e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
31412eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
31422eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
31432eabf88fSMatthew G. Knepley       orntNew[5] = -3;
3144b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
3145b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
31462eabf88fSMatthew G. Knepley #if 1
3147b164cbf2SMatthew 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);
31482eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31492eabf88fSMatthew 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);
31502eabf88fSMatthew G. Knepley       }
31512eabf88fSMatthew G. Knepley #endif
31522eabf88fSMatthew G. Knepley       /* G hex */
31532eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
31542eabf88fSMatthew G. Knepley       orntNew[0] = -3;
3155e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
31562eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
31572eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
31582eabf88fSMatthew G. Knepley       orntNew[2] = -3;
3159e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
31602eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3161e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
31622eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
31632eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
31642eabf88fSMatthew G. Knepley       orntNew[5] = 0;
3165b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
3166b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
31672eabf88fSMatthew G. Knepley #if 1
3168b164cbf2SMatthew 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);
31692eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31702eabf88fSMatthew 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);
31712eabf88fSMatthew G. Knepley       }
31722eabf88fSMatthew G. Knepley #endif
31732eabf88fSMatthew G. Knepley       /* H hex */
31742eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
31752eabf88fSMatthew G. Knepley       orntNew[0] = -3;
3176e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
31772eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
31782eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
31792eabf88fSMatthew G. Knepley       orntNew[2] = -3;
3180e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
31812eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
31822eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
31832eabf88fSMatthew G. Knepley       orntNew[4] = -3;
3184e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
31852eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3186b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
3187b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
31882eabf88fSMatthew G. Knepley #if 1
3189b164cbf2SMatthew 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);
31902eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31912eabf88fSMatthew 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);
31922eabf88fSMatthew G. Knepley       }
31932eabf88fSMatthew G. Knepley #endif
31942eabf88fSMatthew G. Knepley     }
31952eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
31962eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
31972eabf88fSMatthew G. Knepley     ierr = PetscMalloc((4 + maxSupportSize*2) * sizeof(PetscInt), &supportRef);CHKERRQ(ierr);
31982eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
31992eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
3200aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
32012eabf88fSMatthew 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};
32022eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
32032eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3204aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
32052eabf88fSMatthew G. Knepley 
32062eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3207aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
3208aaebbb9dSMatthew G. Knepley         coneNew[0] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
3209aaebbb9dSMatthew G. Knepley         orntNew[0] = ornt[(r+3)%4];
3210aaebbb9dSMatthew G. Knepley         coneNew[1] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
3211aaebbb9dSMatthew G. Knepley         orntNew[1] = ornt[r];
32122eabf88fSMatthew G. Knepley         coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
3213aaebbb9dSMatthew G. Knepley         orntNew[2] = 0;
32142eabf88fSMatthew G. Knepley         coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
3215aaebbb9dSMatthew G. Knepley         orntNew[3] = -2;
32162eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3217aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32182eabf88fSMatthew G. Knepley #if 1
32192eabf88fSMatthew 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);
32202eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
32212eabf88fSMatthew 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);
32222eabf88fSMatthew G. Knepley         }
32232eabf88fSMatthew G. Knepley #endif
32242eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
32252eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
32262eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
32272eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
32282eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
32292eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
32302eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
32312eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
32322eabf88fSMatthew G. Knepley           }
3233a3f78057SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubface_Static(ornt[c], r)];
32342eabf88fSMatthew G. Knepley         }
32352eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
32362eabf88fSMatthew G. Knepley #if 1
32372eabf88fSMatthew 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);
32382eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
32392eabf88fSMatthew 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);
32402eabf88fSMatthew G. Knepley         }
32412eabf88fSMatthew G. Knepley #endif
32422eabf88fSMatthew G. Knepley       }
32432eabf88fSMatthew G. Knepley     }
32442eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
32452eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
32462eabf88fSMatthew 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};
3247afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
3248afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
32492eabf88fSMatthew G. Knepley 
32502eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3251afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3252afb2665bSMatthew G. Knepley       /* A-D face */
3253afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
3254afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
3255afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3256afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
3257afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3258afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3259afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3260afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3261afb2665bSMatthew G. Knepley       orntNew[3] = -2;
32622eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3263afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32642eabf88fSMatthew G. Knepley #if 1
32652eabf88fSMatthew 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);
32662eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
32672eabf88fSMatthew 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);
32682eabf88fSMatthew G. Knepley       }
32692eabf88fSMatthew G. Knepley #endif
3270afb2665bSMatthew G. Knepley       /* C-D face */
3271afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
3272afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
3273afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3274afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
3275afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3276afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3277afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3278afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3279afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3280afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3281afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3282afb2665bSMatthew G. Knepley #if 1
3283afb2665bSMatthew 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);
3284afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3285afb2665bSMatthew 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);
3286afb2665bSMatthew G. Knepley       }
3287afb2665bSMatthew G. Knepley #endif
3288afb2665bSMatthew G. Knepley       /* B-C face */
3289afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
3290afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
3291afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3292afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
3293afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3294afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3295afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3296afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3297afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3298afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3299afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3300afb2665bSMatthew G. Knepley #if 1
3301afb2665bSMatthew 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);
3302afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3303afb2665bSMatthew 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);
3304afb2665bSMatthew G. Knepley       }
3305afb2665bSMatthew G. Knepley #endif
3306afb2665bSMatthew G. Knepley       /* A-B face */
3307afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
3308afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
3309afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3310afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
3311afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3312afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3313afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3314afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3315afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3316afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3317afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3318afb2665bSMatthew G. Knepley #if 1
3319afb2665bSMatthew 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);
3320afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3321afb2665bSMatthew 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);
3322afb2665bSMatthew G. Knepley       }
3323afb2665bSMatthew G. Knepley #endif
3324afb2665bSMatthew G. Knepley       /* E-F face */
3325afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
3326afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
3327afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3328afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
3329afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3330afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3331afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3332afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3333afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3334afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3335afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3336afb2665bSMatthew G. Knepley #if 1
3337afb2665bSMatthew 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);
3338afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3339afb2665bSMatthew 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);
3340afb2665bSMatthew G. Knepley       }
3341afb2665bSMatthew G. Knepley #endif
3342afb2665bSMatthew G. Knepley       /* F-G face */
3343afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
3344afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
3345afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3346afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
3347afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3348afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3349afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3350afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3351afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3352afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3353afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3354afb2665bSMatthew G. Knepley #if 1
3355afb2665bSMatthew 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);
3356afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3357afb2665bSMatthew 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);
3358afb2665bSMatthew G. Knepley       }
3359afb2665bSMatthew G. Knepley #endif
3360afb2665bSMatthew G. Knepley       /* G-H face */
3361afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
3362afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
3363afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3364afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
3365afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3366afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3367afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3368afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3369afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3370afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3371afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3372afb2665bSMatthew G. Knepley #if 1
3373afb2665bSMatthew 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);
3374afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3375afb2665bSMatthew 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);
3376afb2665bSMatthew G. Knepley       }
3377afb2665bSMatthew G. Knepley #endif
3378afb2665bSMatthew G. Knepley       /* E-H face */
3379afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
3380afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
3381afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3382afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
3383afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3384afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3385afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3386afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3387afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3388afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3389afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3390afb2665bSMatthew G. Knepley #if 1
3391afb2665bSMatthew 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);
3392afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3393afb2665bSMatthew 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);
3394afb2665bSMatthew G. Knepley       }
3395afb2665bSMatthew G. Knepley #endif
3396afb2665bSMatthew G. Knepley       /* A-E face */
3397afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
3398afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
3399afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3400afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
3401afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3402afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3403afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3404afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3405afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3406afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3407afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3408afb2665bSMatthew G. Knepley #if 1
3409afb2665bSMatthew 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);
3410afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3411afb2665bSMatthew 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);
3412afb2665bSMatthew G. Knepley       }
3413afb2665bSMatthew G. Knepley #endif
3414afb2665bSMatthew G. Knepley       /* D-F face */
3415afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
3416afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
3417afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3418afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
3419afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3420afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3421afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3422afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3423afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3424afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3425afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3426afb2665bSMatthew G. Knepley #if 1
3427afb2665bSMatthew 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);
3428afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3429afb2665bSMatthew 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);
3430afb2665bSMatthew G. Knepley       }
3431afb2665bSMatthew G. Knepley #endif
3432afb2665bSMatthew G. Knepley       /* C-G face */
3433afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
3434afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
3435afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3436afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
3437afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3438afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3439afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3440afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3441afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3442afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3443afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3444afb2665bSMatthew G. Knepley #if 1
3445afb2665bSMatthew 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);
3446afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3447afb2665bSMatthew 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);
3448afb2665bSMatthew G. Knepley       }
3449afb2665bSMatthew G. Knepley #endif
3450afb2665bSMatthew G. Knepley       /* B-H face */
3451afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
3452afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
3453afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3454afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
3455afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3456afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3457afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3458afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3459afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3460afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3461afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3462afb2665bSMatthew G. Knepley #if 1
3463afb2665bSMatthew 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);
3464afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3465afb2665bSMatthew 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);
3466afb2665bSMatthew G. Knepley       }
3467afb2665bSMatthew G. Knepley #endif
3468afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
3469afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
34702eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
34712eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
34722eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
34732eabf88fSMatthew G. Knepley #if 1
34742eabf88fSMatthew 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);
34752eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34762eabf88fSMatthew 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);
34772eabf88fSMatthew G. Knepley         }
34782eabf88fSMatthew G. Knepley #endif
34792eabf88fSMatthew G. Knepley       }
34802eabf88fSMatthew G. Knepley     }
34812eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
34822eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
34832eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
34842eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
34852eabf88fSMatthew G. Knepley 
34862eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
34872eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
34882eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
34892eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
34902eabf88fSMatthew G. Knepley 
34912eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
34922eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
34932eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
34942eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
34952eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34962eabf88fSMatthew G. Knepley #if 1
34972eabf88fSMatthew 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);
34982eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34992eabf88fSMatthew 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);
35002eabf88fSMatthew G. Knepley         }
35012eabf88fSMatthew G. Knepley #endif
35022eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
35032eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
35042eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
35052eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
35062eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
35072eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
35082eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
35092eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
35102eabf88fSMatthew G. Knepley           }
35112eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
35122eabf88fSMatthew G. Knepley         }
35132eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35142eabf88fSMatthew G. Knepley #if 1
35152eabf88fSMatthew 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);
35162eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
35172eabf88fSMatthew 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);
35182eabf88fSMatthew G. Knepley         }
35192eabf88fSMatthew G. Knepley #endif
35202eabf88fSMatthew G. Knepley       }
35212eabf88fSMatthew G. Knepley     }
35222eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
35232eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
35246b852384SMatthew 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};
35252eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
35266b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
35272eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
35282eabf88fSMatthew G. Knepley 
35292eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
35302eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
35312eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
35322eabf88fSMatthew G. Knepley 
35332eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
35342eabf88fSMatthew G. Knepley         coneNew[1] = newv;
35352eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35362eabf88fSMatthew G. Knepley #if 1
35372eabf88fSMatthew 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);
35382eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35392eabf88fSMatthew 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);
35402eabf88fSMatthew G. Knepley         }
35412eabf88fSMatthew G. Knepley #endif
35422eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
35432eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
35442eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
35452eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
35462eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
35476b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
35486b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
35496b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
35502eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
35516b852384SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdge_Static(orntCell[c], r)];
35522eabf88fSMatthew G. Knepley         }
35532eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35542eabf88fSMatthew G. Knepley #if 1
35552eabf88fSMatthew 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);
35562eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
35572eabf88fSMatthew 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);
35582eabf88fSMatthew G. Knepley         }
35592eabf88fSMatthew G. Knepley #endif
35602eabf88fSMatthew G. Knepley       }
35612eabf88fSMatthew G. Knepley     }
35622eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
35632eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
35642eabf88fSMatthew 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};
35652eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
35662eabf88fSMatthew G. Knepley       const PetscInt *cone;
35672eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
35682eabf88fSMatthew G. Knepley 
35692eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
35702eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
35712eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
35722eabf88fSMatthew G. Knepley 
35732eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
35742eabf88fSMatthew G. Knepley         coneNew[1] = newv;
35752eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35762eabf88fSMatthew G. Knepley #if 1
35772eabf88fSMatthew 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);
35782eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35792eabf88fSMatthew 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);
35802eabf88fSMatthew G. Knepley         }
35812eabf88fSMatthew G. Knepley #endif
35822eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
35832eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
35842eabf88fSMatthew G. Knepley #if 1
35852eabf88fSMatthew 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);
35862eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
35872eabf88fSMatthew 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);
35882eabf88fSMatthew G. Knepley         }
35892eabf88fSMatthew G. Knepley #endif
35902eabf88fSMatthew G. Knepley       }
35912eabf88fSMatthew G. Knepley     }
35922eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
35932eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
35942eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
35952eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
35962eabf88fSMatthew G. Knepley       PetscInt        size, s;
35972eabf88fSMatthew G. Knepley 
35982eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
35992eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
36002eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36012eabf88fSMatthew G. Knepley         PetscInt r = 0;
36022eabf88fSMatthew G. Knepley 
36032eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36042eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
36052eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
36062eabf88fSMatthew G. Knepley       }
36072eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36082eabf88fSMatthew G. Knepley #if 1
36092eabf88fSMatthew 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);
36102eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
36112eabf88fSMatthew 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);
36122eabf88fSMatthew G. Knepley       }
36132eabf88fSMatthew G. Knepley #endif
36142eabf88fSMatthew G. Knepley     }
36152eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
36162eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
36172eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
36182eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
36192eabf88fSMatthew G. Knepley       PetscInt        size, s;
36202eabf88fSMatthew G. Knepley 
36212eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
36222eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
36232eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
36242eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
36252eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36262eabf88fSMatthew G. Knepley         PetscInt r;
36272eabf88fSMatthew G. Knepley 
36282eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3629a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
36302eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
36312eabf88fSMatthew G. Knepley       }
36322eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36332eabf88fSMatthew G. Knepley #if 1
36342eabf88fSMatthew 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);
36352eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
36362eabf88fSMatthew 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);
36372eabf88fSMatthew G. Knepley       }
36382eabf88fSMatthew G. Knepley #endif
36392eabf88fSMatthew G. Knepley     }
36402eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
36412eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
36422eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
36432eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
36442eabf88fSMatthew G. Knepley       PetscInt        size, s;
36452eabf88fSMatthew G. Knepley 
36462eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
36472eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
36482eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (e - eStart)*2 +  (f - fStart)*4 + r;
36492eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36502eabf88fSMatthew G. Knepley         PetscInt r;
36512eabf88fSMatthew G. Knepley 
36522eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36532eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
36542eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
36552eabf88fSMatthew G. Knepley       }
36562eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36572eabf88fSMatthew G. Knepley #if 1
36582eabf88fSMatthew 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);
36592eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
36602eabf88fSMatthew 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);
36612eabf88fSMatthew G. Knepley       }
36622eabf88fSMatthew G. Knepley #endif
36632eabf88fSMatthew G. Knepley     }
36642eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
36652eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
36662eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
36672eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
36682eabf88fSMatthew G. Knepley 
36692eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
36702eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
36712eabf88fSMatthew G. Knepley       }
36722eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36732eabf88fSMatthew G. Knepley     }
3674da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
36752eabf88fSMatthew G. Knepley     break;
367675d3a19aSMatthew G. Knepley   default:
367775d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
367875d3a19aSMatthew G. Knepley   }
367975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
368075d3a19aSMatthew G. Knepley }
368175d3a19aSMatthew G. Knepley 
368275d3a19aSMatthew G. Knepley #undef __FUNCT__
368375d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates"
368475d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
368575d3a19aSMatthew G. Knepley {
368675d3a19aSMatthew G. Knepley   PetscSection   coordSection, coordSectionNew;
368775d3a19aSMatthew G. Knepley   Vec            coordinates, coordinatesNew;
368875d3a19aSMatthew G. Knepley   PetscScalar   *coords, *coordsNew;
36893478d7aaSMatthew G. Knepley   const PetscInt numVertices = depthSize ? depthSize[0] : 0;
3690b5da9499SMatthew G. Knepley   PetscInt       dim, depth, coordSizeNew, cStart, cEnd, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
369175d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
369275d3a19aSMatthew G. Knepley 
369375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
369475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
369575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
369675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
3697b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
369875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
369975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
3700b5da9499SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, NULL, &fMax, &eMax, NULL);CHKERRQ(ierr);
37013478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);}
370275d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);
370375d3a19aSMatthew G. Knepley   ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
370475d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
370575d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
370675d3a19aSMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr);
37073478d7aaSMatthew G. Knepley   ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
370875d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
3709b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
371075d3a19aSMatthew G. Knepley   /* All vertices have the dim coordinates */
37113478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
371275d3a19aSMatthew G. Knepley     ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr);
371375d3a19aSMatthew G. Knepley     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr);
371475d3a19aSMatthew G. Knepley   }
371575d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
371675d3a19aSMatthew G. Knepley   ierr = DMPlexSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr);
371775d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
371875d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
371975d3a19aSMatthew G. Knepley   ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr);
372075d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
372175d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
372275d3a19aSMatthew G. Knepley   ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr);
372375d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
372475d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
3725b5da9499SMatthew G. Knepley   switch (refiner) {
37263478d7aaSMatthew G. Knepley   case 0: break;
3727b5da9499SMatthew G. Knepley   case 6: /* Hex 3D */
3728b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
3729b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
3730c91acedaSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
3731b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
3732b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
3733b5da9499SMatthew G. Knepley 
3734b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
3735b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
3736b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
3737b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
3738b5da9499SMatthew G. Knepley       }
3739b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
3740b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
3741b5da9499SMatthew G. Knepley       }
3742b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
3743b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
3744b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
3745b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
3746b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
3747b5da9499SMatthew G. Knepley       }
3748b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
3749b5da9499SMatthew G. Knepley     }
3750b5da9499SMatthew G. Knepley   case 2: /* Hex 2D */
3751b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
3752b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
3753c91acedaSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (c - cStart) + (dim > 2 ? (fEnd - fStart) : 0);
3754b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
3755b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
3756b5da9499SMatthew G. Knepley 
3757b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
3758b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
3759b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
3760b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
3761b5da9499SMatthew G. Knepley       }
3762b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
3763b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
3764b5da9499SMatthew G. Knepley       }
3765b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
3766b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
3767b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
3768b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
3769b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
3770b5da9499SMatthew G. Knepley       }
3771b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
3772b5da9499SMatthew G. Knepley     }
3773b5da9499SMatthew G. Knepley   case 1: /* Simplicial 2D */
3774b5da9499SMatthew G. Knepley   case 3: /* Hybrid Simplicial 2D */
3775b5da9499SMatthew G. Knepley   case 5: /* Simplicial 3D */
37766ce3c06aSMatthew G. Knepley   case 7: /* Hybrid Simplicial 3D */
3777b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
3778b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
3779b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
3780b5da9499SMatthew G. Knepley       const PetscInt *cone;
3781b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
3782b5da9499SMatthew G. Knepley 
3783b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
3784b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
3785b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
3786b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
3787b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
3788b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
3789b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
3790b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]);
3791b5da9499SMatthew G. Knepley       }
3792b5da9499SMatthew G. Knepley     }
379375d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
379475d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
379575d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
379675d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
379775d3a19aSMatthew G. Knepley 
379875d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
379975d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
380075d3a19aSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
380175d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
380275d3a19aSMatthew G. Knepley       }
380375d3a19aSMatthew G. Knepley     }
3804b5da9499SMatthew G. Knepley     break;
3805b5da9499SMatthew G. Knepley   default:
3806b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
380775d3a19aSMatthew G. Knepley   }
380875d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
380975d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
381075d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
381175d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
381275d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
381375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
381475d3a19aSMatthew G. Knepley }
381575d3a19aSMatthew G. Knepley 
381675d3a19aSMatthew G. Knepley #undef __FUNCT__
381775d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF"
381875d3a19aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
381975d3a19aSMatthew G. Knepley {
382075d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
382175d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
382275d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
382375d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
382475d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
382575d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
382675d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
382775d3a19aSMatthew G. Knepley 
382875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
382975d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
383075d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeaves * sizeof(PetscInt), &ranks);CHKERRQ(ierr);
383175d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
383275d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
383375d3a19aSMatthew G. Knepley   }
383475d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
383575d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeaves * sizeof(PetscInt),    &ranksNew);CHKERRQ(ierr);
383675d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeaves * sizeof(PetscInt),    &localPointsNew);CHKERRQ(ierr);
383775d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeaves * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr);
383875d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
383975d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
384075d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
384175d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
384275d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
384375d3a19aSMatthew G. Knepley   }
384475d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
384575d3a19aSMatthew G. Knepley   ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);
384675d3a19aSMatthew G. Knepley   ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
384775d3a19aSMatthew G. Knepley   ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
384875d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
384975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
385075d3a19aSMatthew G. Knepley }
385175d3a19aSMatthew G. Knepley 
385275d3a19aSMatthew G. Knepley #undef __FUNCT__
385375d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF"
385475d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
385575d3a19aSMatthew G. Knepley {
385675d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
385775d3a19aSMatthew G. Knepley   IS                 processRanks;
385875d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
385975d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
386075d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
386175d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
386275d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
386375d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
386475d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
386575d3a19aSMatthew 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;
386675d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
386775d3a19aSMatthew G. Knepley 
386875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
386975d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
387075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
387175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
387275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
387375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
387475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
387575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
38763478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
387775d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
387875d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
387975d3a19aSMatthew G. Knepley   /* Caculate size of new SF */
388075d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
388175d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
388275d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
388375d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
388475d3a19aSMatthew G. Knepley 
388575d3a19aSMatthew G. Knepley     switch (refiner) {
388675d3a19aSMatthew G. Knepley     case 1:
388775d3a19aSMatthew G. Knepley       /* Simplicial 2D */
388875d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
388975d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
389075d3a19aSMatthew G. Knepley         ++numLeavesNew;
389175d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
389275d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
3893d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
389475d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
389575d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
389675d3a19aSMatthew G. Knepley         numLeavesNew += 4 + 3;
389775d3a19aSMatthew G. Knepley       }
389875d3a19aSMatthew G. Knepley       break;
389975d3a19aSMatthew G. Knepley     case 2:
390075d3a19aSMatthew G. Knepley       /* Hex 2D */
390175d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
390275d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
390375d3a19aSMatthew G. Knepley         ++numLeavesNew;
390475d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
390575d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
3906d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
390775d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
3908455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
3909455d6cd4SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
391075d3a19aSMatthew G. Knepley       }
391175d3a19aSMatthew G. Knepley       break;
3912b5da9499SMatthew G. Knepley     case 5:
3913b5da9499SMatthew G. Knepley       /* Simplicial 3D */
3914b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
3915b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
3916b5da9499SMatthew G. Knepley         ++numLeavesNew;
3917b5da9499SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
3918b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
3919b5da9499SMatthew G. Knepley         numLeavesNew += 2 + 1;
3920b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
3921b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
3922b5da9499SMatthew G. Knepley         numLeavesNew += 4 + 3;
3923b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
3924b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
3925b5da9499SMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
3926b5da9499SMatthew G. Knepley       }
3927b5da9499SMatthew G. Knepley       break;
39286ce3c06aSMatthew G. Knepley     case 7:
39296ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
39306ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
39316ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
39326ce3c06aSMatthew G. Knepley         ++numLeavesNew;
39336ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
39346ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
39356ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
39366ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
39376ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
39386ce3c06aSMatthew G. Knepley         ++numLeavesNew;
39396ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
39406ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
39416ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
39426ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
39436ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
39446ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
39456ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
39466ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
39476ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
39486ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
39496ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
39506ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
39516ce3c06aSMatthew G. Knepley       }
39526ce3c06aSMatthew G. Knepley       break;
39532eabf88fSMatthew G. Knepley     case 6:
39542eabf88fSMatthew G. Knepley       /* Hex 3D */
39552eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
39562eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
39572eabf88fSMatthew G. Knepley         ++numLeavesNew;
39582eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
39592eabf88fSMatthew G. Knepley         /* Old edges add new edges, and vertex */
39602eabf88fSMatthew G. Knepley         numLeavesNew += 2 + 1;
39612eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
39622eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
39632eabf88fSMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
39642eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
39652eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
39662eabf88fSMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
39672eabf88fSMatthew G. Knepley       }
39682eabf88fSMatthew G. Knepley       break;
396975d3a19aSMatthew G. Knepley     default:
397075d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
397175d3a19aSMatthew G. Knepley     }
397275d3a19aSMatthew G. Knepley   }
397375d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
397475d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
397575d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
3976*dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
3977*dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
397875d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
397975d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
398075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
398175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
398275d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
398375d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
398475d3a19aSMatthew G. Knepley   }
398575d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
398675d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
398775d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
398875d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
398975d3a19aSMatthew G. Knepley 
399075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
399175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
399275d3a19aSMatthew G. Knepley 
399375d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
399475d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
399575d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
399675d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
399775d3a19aSMatthew G. Knepley 
399875d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
399975d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
400075d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
400175d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
400275d3a19aSMatthew G. Knepley   }
400375d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
400475d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
400575d3a19aSMatthew G. Knepley   /* Calculate new point SF */
400675d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeavesNew * sizeof(PetscInt),    &localPointsNew);CHKERRQ(ierr);
400775d3a19aSMatthew G. Knepley   ierr = PetscMalloc(numLeavesNew * sizeof(PetscSFNode), &remotePointsNew);CHKERRQ(ierr);
400875d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
400975d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
401075d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
401175d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
401275d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
401375d3a19aSMatthew G. Knepley 
401475d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
401575d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
401675d3a19aSMatthew G. Knepley     switch (refiner) {
401775d3a19aSMatthew G. Knepley     case 1:
401875d3a19aSMatthew G. Knepley       /* Simplicial 2D */
401975d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
402075d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
402175d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
402275d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
402375d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
402475d3a19aSMatthew G. Knepley         ++m;
402575d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
402675d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
402775d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
402875d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
402975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
403075d3a19aSMatthew G. Knepley         ++m;
403175d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
403275d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
403375d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
403475d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
403575d3a19aSMatthew G. Knepley         }
403675d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
403775d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
403875d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
403975d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
404075d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
404175d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
404275d3a19aSMatthew G. Knepley         }
404375d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
404475d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*3     + r;
404575d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
404675d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
404775d3a19aSMatthew G. Knepley         }
404875d3a19aSMatthew G. Knepley       }
404975d3a19aSMatthew G. Knepley       break;
405075d3a19aSMatthew G. Knepley     case 2:
405175d3a19aSMatthew G. Knepley       /* Hex 2D */
405275d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
405375d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
405475d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
405575d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
405675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
405775d3a19aSMatthew G. Knepley         ++m;
405875d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
405975d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
406075d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
406175d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
406275d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
406375d3a19aSMatthew G. Knepley         ++m;
406475d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
406575d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
406675d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
406775d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
406875d3a19aSMatthew G. Knepley         }
406975d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
4070455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
407175d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
407275d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
407375d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
407475d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
407575d3a19aSMatthew G. Knepley         }
407675d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
407775d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*4     + r;
407875d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r;
407975d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
408075d3a19aSMatthew G. Knepley         }
4081455d6cd4SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
4082455d6cd4SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (fEnd - fStart)                    + (p  - cStart)     + r;
4083455d6cd4SMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
4084455d6cd4SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4085455d6cd4SMatthew G. Knepley         }
408675d3a19aSMatthew G. Knepley       }
408775d3a19aSMatthew G. Knepley       break;
408875d3a19aSMatthew G. Knepley     case 3:
408975d3a19aSMatthew G. Knepley       /* Hybrid simplicial 2D */
409075d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
409175d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
409275d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
409375d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
409475d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
409575d3a19aSMatthew G. Knepley         ++m;
409675d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
409775d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
409875d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
409975d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
410075d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
410175d3a19aSMatthew G. Knepley         ++m;
410275d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
410375d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
410475d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
410575d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
410675d3a19aSMatthew G. Knepley         }
410775d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
410875d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
410975d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
411075d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
411175d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
411275d3a19aSMatthew G. Knepley         ++m;
411375d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
411475d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
411575d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
411675d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
411775d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
411875d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
411975d3a19aSMatthew G. Knepley         }
412075d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
412175d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
412275d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
412375d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
412475d3a19aSMatthew G. Knepley         }
412575d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
412675d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
412775d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
412875d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
412975d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
413075d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
413175d3a19aSMatthew G. Knepley         }
413275d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
413375d3a19aSMatthew 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]);
413475d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
413575d3a19aSMatthew G. Knepley         ++m;
413675d3a19aSMatthew G. Knepley       }
413775d3a19aSMatthew G. Knepley       break;
4138b5da9499SMatthew G. Knepley     case 5:
4139b5da9499SMatthew G. Knepley       /* Simplicial 3D */
4140b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
4141b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
4142b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
4143b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
4144b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
4145b5da9499SMatthew G. Knepley         ++m;
414687fe6628SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
4147b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
4148b5da9499SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
4149b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
4150b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
4151b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4152b5da9499SMatthew G. Knepley         }
4153b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
4154b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
4155b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
4156b5da9499SMatthew G. Knepley         ++m;
4157b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
4158b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
4159b5da9499SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
4160b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
4161b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
4162b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4163b5da9499SMatthew G. Knepley         }
4164b5da9499SMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
4165b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*3     + r;
4166b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r;
4167b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4168b5da9499SMatthew G. Knepley         }
4169b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
4170b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
4171b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
4172b5da9499SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
4173b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
4174b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4175b5da9499SMatthew G. Knepley         }
4176b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
4177b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*8     + r;
4178b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r;
4179b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4180b5da9499SMatthew G. Knepley         }
4181b5da9499SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
4182b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*3                    + (p  - cStart)*1     + r;
4183b5da9499SMatthew 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;
4184b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4185b5da9499SMatthew G. Knepley         }
4186b5da9499SMatthew G. Knepley       }
4187b5da9499SMatthew G. Knepley       break;
41886ce3c06aSMatthew G. Knepley     case 7:
41896ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
41906ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
41916ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
41926ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
41936ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
41946ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
41956ce3c06aSMatthew G. Knepley         ++m;
41966ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
41976ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
41986ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
41996ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
42006ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
42016ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42026ce3c06aSMatthew G. Knepley         }
42036ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
42046ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
42056ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42066ce3c06aSMatthew G. Knepley         ++m;
42076ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
42086ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
42096ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
42106ce3c06aSMatthew 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]);
42116ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42126ce3c06aSMatthew G. Knepley         ++m;
42136ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
42146ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
42156ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
42166ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
42176ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
42186ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42196ce3c06aSMatthew G. Knepley         }
42206ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
42216ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
42226ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
42236ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42246ce3c06aSMatthew G. Knepley         }
42256ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
42266ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
42276ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
42286ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fStart)*2     + r;
42296ce3c06aSMatthew 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;
42306ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42316ce3c06aSMatthew G. Knepley         }
42326ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)     + (cMax                            - cStart)     + (fEnd                                          - fMax);
42336ce3c06aSMatthew 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]);
42346ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42356ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
42366ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
42376ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
42386ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
42396ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
42406ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42416ce3c06aSMatthew G. Knepley         }
42426ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
42436ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
42446ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
42456ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42466ce3c06aSMatthew G. Knepley         }
42476ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + r;
42486ce3c06aSMatthew 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;
42496ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42506ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
42516ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
42526ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
42536ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
42546ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
42556ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42566ce3c06aSMatthew G. Knepley         }
42576ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
42586ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*4                              + (p  - cMax)*3                            + r;
42596ce3c06aSMatthew 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;
42606ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42616ce3c06aSMatthew G. Knepley         }
42626ce3c06aSMatthew G. Knepley       }
42636ce3c06aSMatthew G. Knepley       break;
42642eabf88fSMatthew G. Knepley     case 6:
42652eabf88fSMatthew G. Knepley       /* Hex 3D */
42662eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
42672eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
42682eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
42692eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
42702eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42712eabf88fSMatthew G. Knepley         ++m;
42722eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
42732eabf88fSMatthew G. Knepley         /* Old edges add new edges and vertex */
42742eabf88fSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
42752eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
42762eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
42772eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42782eabf88fSMatthew G. Knepley         }
42792eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
42802eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
42812eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42822eabf88fSMatthew G. Knepley         ++m;
42832eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
42842eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
42852eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
42862eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
42872eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
42882eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42892eabf88fSMatthew G. Knepley         }
42902eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
42912eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*4     + r;
42922eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r;
42932eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42942eabf88fSMatthew G. Knepley         }
42952eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (p  - fStart);
42962eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]);
42972eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42982eabf88fSMatthew G. Knepley         ++m;
42992eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
43002eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
43012eabf88fSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
43022eabf88fSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
43032eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
43042eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43052eabf88fSMatthew G. Knepley         }
43062eabf88fSMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
43072eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*12     + r;
43082eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r;
43092eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43102eabf88fSMatthew G. Knepley         }
43112eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
43122eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*4                    + (p  - cStart)*6     + r;
43132eabf88fSMatthew 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;
43142eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43152eabf88fSMatthew G. Knepley         }
43162eabf88fSMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
43172eabf88fSMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eEnd - eStart)              + (fEnd - fStart)                    + (p  - cStart)     + r;
43182eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
43192eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43202eabf88fSMatthew G. Knepley         }
43212eabf88fSMatthew G. Knepley       }
43222eabf88fSMatthew G. Knepley       break;
432375d3a19aSMatthew G. Knepley     default:
432475d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
432575d3a19aSMatthew G. Knepley     }
432675d3a19aSMatthew G. Knepley   }
432775d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
432875d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
432975d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
433075d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
433106a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
433275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
433375d3a19aSMatthew G. Knepley }
433475d3a19aSMatthew G. Knepley 
433575d3a19aSMatthew G. Knepley #undef __FUNCT__
433675d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels"
433775d3a19aSMatthew G. Knepley PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
433875d3a19aSMatthew G. Knepley {
433975d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
4340b5da9499SMatthew G. Knepley   PetscInt       depth, newp, cStart, cStartNew, cEnd, cMax, vStart, vStartNew, vEnd, vMax, fStart, fStartNew, fEnd, fMax, eStart, eStartNew, eEnd, eMax, r;
434175d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
434275d3a19aSMatthew G. Knepley 
434375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
434475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
434575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
434675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
434775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
4348d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
43493478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
435075d3a19aSMatthew G. Knepley   ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
435175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
435275d3a19aSMatthew G. Knepley   switch (refiner) {
43533478d7aaSMatthew G. Knepley   case 0: break;
435458b8852aSMatthew G. Knepley   case 7:
435558b8852aSMatthew G. Knepley   case 8:
435658b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
435775d3a19aSMatthew G. Knepley   case 3:
435858b8852aSMatthew G. Knepley   case 4:
435975d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
436075d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
436175d3a19aSMatthew G. Knepley   }
436275d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
436375d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
436475d3a19aSMatthew G. Knepley     const char     *lname;
436575d3a19aSMatthew G. Knepley     PetscBool       isDepth;
436675d3a19aSMatthew G. Knepley     IS              valueIS;
436775d3a19aSMatthew G. Knepley     const PetscInt *values;
436875d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
436975d3a19aSMatthew G. Knepley 
437075d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr);
437175d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
437275d3a19aSMatthew G. Knepley     if (isDepth) continue;
437375d3a19aSMatthew G. Knepley     ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr);
437475d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr);
437575d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
437675d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
437775d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
437875d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
437975d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
438075d3a19aSMatthew G. Knepley       IS              pointIS;
438175d3a19aSMatthew G. Knepley       const PetscInt *points;
438275d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
438375d3a19aSMatthew G. Knepley 
438475d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
438575d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
438675d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
438775d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
438875d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
438975d3a19aSMatthew G. Knepley         switch (refiner) {
439075d3a19aSMatthew G. Knepley         case 1:
439175d3a19aSMatthew G. Knepley           /* Simplicial 2D */
439275d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
439375d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
439475d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
439575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
439675d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
439775d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
439875d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
439975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
440075d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
440175d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
440275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
440375d3a19aSMatthew G. Knepley             }
440475d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
440575d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
440675d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
440775d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
440875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
440975d3a19aSMatthew G. Knepley             }
441075d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
441175d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
441275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
441375d3a19aSMatthew G. Knepley             }
441475d3a19aSMatthew G. Knepley           }
441575d3a19aSMatthew G. Knepley           break;
441675d3a19aSMatthew G. Knepley         case 2:
441775d3a19aSMatthew G. Knepley           /* Hex 2D */
441875d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
441975d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
442075d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
442175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
442275d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
442375d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
442475d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
442575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
442675d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
442775d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
442875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
442975d3a19aSMatthew G. Knepley             }
443075d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
443175d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
443275d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
443375d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
443475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
443575d3a19aSMatthew G. Knepley             }
443675d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
443775d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
443875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
443975d3a19aSMatthew G. Knepley             }
444075d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
444175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
444275d3a19aSMatthew G. Knepley           }
444375d3a19aSMatthew G. Knepley           break;
444475d3a19aSMatthew G. Knepley         case 3:
444575d3a19aSMatthew G. Knepley           /* Hybrid simplicial 2D */
444675d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
444775d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
444875d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
444975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
445075d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
445175d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
445275d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
445375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
445475d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
445575d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
445675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
445775d3a19aSMatthew G. Knepley             }
445875d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
445975d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
446075d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
446175d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
446275d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
446375d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
446475d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
446575d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
446675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
446775d3a19aSMatthew G. Knepley             }
446875d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
446975d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
447075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
447175d3a19aSMatthew G. Knepley             }
447275d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
447375d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
447475d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
447575d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
447675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
447775d3a19aSMatthew G. Knepley             }
447875d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
447975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
448075d3a19aSMatthew G. Knepley           }
448175d3a19aSMatthew G. Knepley           break;
4482b5da9499SMatthew G. Knepley         case 5:
4483b5da9499SMatthew G. Knepley           /* Simplicial 3D */
4484b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
4485b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
4486b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
4487b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4488b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
4489b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
4490b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
4491b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
4492b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4493b5da9499SMatthew G. Knepley             }
4494b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
4495b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4496b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
4497b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
4498b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
4499b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
4500b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4501b5da9499SMatthew G. Knepley             }
4502b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
4503b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
4504b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4505b5da9499SMatthew G. Knepley             }
4506b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
4507b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
4508b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
4509b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
4510b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4511b5da9499SMatthew G. Knepley             }
4512b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
4513b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
4514b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4515b5da9499SMatthew G. Knepley             }
4516b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
4517b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
4518b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4519b5da9499SMatthew G. Knepley             }
4520b5da9499SMatthew G. Knepley           }
4521b5da9499SMatthew G. Knepley           break;
45226ce3c06aSMatthew G. Knepley         case 7:
45236ce3c06aSMatthew G. Knepley           /* Hybrid Simplicial 3D */
45246ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
45256ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
45266ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
45276ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45286ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
45296ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
45306ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
45316ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
45326ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45336ce3c06aSMatthew G. Knepley             }
45346ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
45356ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45366ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
45376ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
45386ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
45396ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45406ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
45416ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
45426ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
45436ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
45446ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45456ce3c06aSMatthew G. Knepley             }
45466ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
45476ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
45486ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45496ce3c06aSMatthew G. Knepley             }
45506ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
45516ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
45526ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
45536ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
45546ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45556ce3c06aSMatthew G. Knepley             }
45566ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
45576ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45586ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
45596ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
45606ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
45616ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
45626ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45636ce3c06aSMatthew G. Knepley             }
45646ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
45656ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
45666ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45676ce3c06aSMatthew G. Knepley             }
45686ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
45696ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
457058b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
45716ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
45726ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
45736ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
45746ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45756ce3c06aSMatthew G. Knepley             }
45766ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
45776ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
45786ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45796ce3c06aSMatthew G. Knepley             }
45806ce3c06aSMatthew G. Knepley           }
45816ce3c06aSMatthew G. Knepley           break;
45822eabf88fSMatthew G. Knepley         case 6:
45832eabf88fSMatthew G. Knepley           /* Hex 3D */
45842eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
45852eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
45862eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
45872eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
458819d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
45892eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
45902eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
45912eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
45922eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45932eabf88fSMatthew G. Knepley             }
45942eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
45952eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45962eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
45972eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
45982eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
45992eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
46002eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46012eabf88fSMatthew G. Knepley             }
46022eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
46032eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
46042eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46052eabf88fSMatthew G. Knepley             }
46062eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
46072eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46082eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
46092eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
46102eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
46112eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
46122eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46132eabf88fSMatthew G. Knepley             }
46142eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
46152eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
46162eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46172eabf88fSMatthew G. Knepley             }
46182eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
46192eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
46202eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46212eabf88fSMatthew G. Knepley             }
46222eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
46232eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46242eabf88fSMatthew G. Knepley           }
46252eabf88fSMatthew G. Knepley           break;
462675d3a19aSMatthew G. Knepley         default:
462775d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
462875d3a19aSMatthew G. Knepley         }
462975d3a19aSMatthew G. Knepley       }
463075d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
463175d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
463275d3a19aSMatthew G. Knepley     }
463375d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
463475d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
463575d3a19aSMatthew G. Knepley     if (0) {
463675d3a19aSMatthew G. Knepley       ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr);
463775d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
463875d3a19aSMatthew G. Knepley       ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
463975d3a19aSMatthew G. Knepley     }
464075d3a19aSMatthew G. Knepley   }
464175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
464275d3a19aSMatthew G. Knepley }
464375d3a19aSMatthew G. Knepley 
464475d3a19aSMatthew G. Knepley #undef __FUNCT__
4645509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexRefineUniform_Internal"
464675d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
4647509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
464875d3a19aSMatthew G. Knepley {
464975d3a19aSMatthew G. Knepley   DM             rdm;
465075d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
465175d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
465275d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
465375d3a19aSMatthew G. Knepley 
465475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
465575d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
465675d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
465775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
465875d3a19aSMatthew G. Knepley   ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr);
465975d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
466075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
466175d3a19aSMatthew G. Knepley   ierr = PetscMalloc((depth+1) * sizeof(PetscInt), &depthSize);CHKERRQ(ierr);
466275d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
466375d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
466475d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
466575d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
466675d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
466775d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
466875d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
466975d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
467075d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
467175d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
467275d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
467375d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
467475d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
467575d3a19aSMatthew G. Knepley   /* Step 6: Set coordinates for vertices */
467675d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
467775d3a19aSMatthew G. Knepley   /* Step 7: Create pointSF */
467875d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
467975d3a19aSMatthew G. Knepley   /* Step 8: Create labels */
468075d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
468175d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
468275d3a19aSMatthew G. Knepley 
468375d3a19aSMatthew G. Knepley   *dmRefined = rdm;
468475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
468575d3a19aSMatthew G. Knepley }
468675d3a19aSMatthew G. Knepley 
468775d3a19aSMatthew G. Knepley #undef __FUNCT__
468875d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform"
468975d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
469075d3a19aSMatthew G. Knepley {
469175d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
469275d3a19aSMatthew G. Knepley 
469375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
469475d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
469575d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
469675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
469775d3a19aSMatthew G. Knepley }
469875d3a19aSMatthew G. Knepley 
469975d3a19aSMatthew G. Knepley #undef __FUNCT__
470075d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform"
470175d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
470275d3a19aSMatthew G. Knepley {
470375d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
470475d3a19aSMatthew G. Knepley 
470575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
470675d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
470775d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
470875d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
470975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
471075d3a19aSMatthew G. Knepley }
471175d3a19aSMatthew G. Knepley 
471275d3a19aSMatthew G. Knepley #undef __FUNCT__
471375d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit"
471475d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
471575d3a19aSMatthew G. Knepley {
471675d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
471775d3a19aSMatthew G. Knepley 
471875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
471975d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
472075d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
472175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
472275d3a19aSMatthew G. Knepley }
472375d3a19aSMatthew G. Knepley 
472475d3a19aSMatthew G. Knepley #undef __FUNCT__
472575d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit"
472675d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
472775d3a19aSMatthew G. Knepley {
472875d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
472975d3a19aSMatthew G. Knepley 
473075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
473175d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
473275d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
473375d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
473475d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
473575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
473675d3a19aSMatthew G. Knepley }
473775d3a19aSMatthew G. Knepley 
473875d3a19aSMatthew G. Knepley #undef __FUNCT__
4739509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Internal"
4740509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
474175d3a19aSMatthew G. Knepley {
47423478d7aaSMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax;
474375d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
474475d3a19aSMatthew G. Knepley 
474575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
474675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
47473478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
47483478d7aaSMatthew G. Knepley   if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);}
474975d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
475075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr);
475175d3a19aSMatthew G. Knepley   switch (dim) {
475275d3a19aSMatthew G. Knepley   case 2:
475375d3a19aSMatthew G. Knepley     switch (coneSize) {
475475d3a19aSMatthew G. Knepley     case 3:
475575d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 3; /* Hybrid */
475675d3a19aSMatthew G. Knepley       else *cellRefiner = 1; /* Triangular */
475775d3a19aSMatthew G. Knepley       break;
475875d3a19aSMatthew G. Knepley     case 4:
475975d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 4; /* Hybrid */
476075d3a19aSMatthew G. Knepley       else *cellRefiner = 2; /* Quadrilateral */
476175d3a19aSMatthew G. Knepley       break;
476275d3a19aSMatthew G. Knepley     default:
476375d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
476475d3a19aSMatthew G. Knepley     }
476575d3a19aSMatthew G. Knepley     break;
4766b5da9499SMatthew G. Knepley   case 3:
4767b5da9499SMatthew G. Knepley     switch (coneSize) {
4768b5da9499SMatthew G. Knepley     case 4:
4769b5da9499SMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 7; /* Hybrid */
4770b5da9499SMatthew G. Knepley       else *cellRefiner = 5; /* Tetrahedral */
4771b5da9499SMatthew G. Knepley       break;
47722eabf88fSMatthew G. Knepley     case 6:
47732eabf88fSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 8; /* Hybrid */
47742eabf88fSMatthew G. Knepley       else *cellRefiner = 6; /* hexahedral */
47752eabf88fSMatthew G. Knepley       break;
4776b5da9499SMatthew G. Knepley     default:
4777b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
4778b5da9499SMatthew G. Knepley     }
4779b5da9499SMatthew G. Knepley     break;
478075d3a19aSMatthew G. Knepley   default:
478175d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
478275d3a19aSMatthew G. Knepley   }
478375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
478475d3a19aSMatthew G. Knepley }
4785