xref: /petsc/src/dm/impls/plex/plexrefine.c (revision d856d60f548e55eb3e8fbac696524978547eca9e)
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"
3086150812SJed Brown static 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 }
104de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
105de65f515SMatthew G. Knepley   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
106de65f515SMatthew G. Knepley }
107518a8359SMatthew G. Knepley 
108518a8359SMatthew G. Knepley /* Return triangle subface for orientation o, if it is r for o == 0 */
109518a8359SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
1104bae88c7SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%3;
11142525629SMatthew G. Knepley }
112de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
113de65f515SMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 3+s-o)%3;
114de65f515SMatthew G. Knepley }
11542525629SMatthew G. Knepley 
116431647a4SMatthew G. Knepley /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */
117431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) {
118431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+r) : o+r)%3;
119431647a4SMatthew G. Knepley }
120431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) {
121431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+s) : 3+s-o)%3;
122431647a4SMatthew G. Knepley }
123431647a4SMatthew G. Knepley 
12442525629SMatthew G. Knepley 
125e3f8b1d6SMatthew G. Knepley /* Return quad edge for orientation o, if it is r for o == 0 */
126e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
127e3f8b1d6SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%4;
128e3f8b1d6SMatthew G. Knepley }
129d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
130d6d937efSMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 4+s-o)%4;
131d6d937efSMatthew G. Knepley }
132e3f8b1d6SMatthew G. Knepley 
133e3f8b1d6SMatthew G. Knepley /* Return quad subface for orientation o, if it is r for o == 0 */
134e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
1354bae88c7SMatthew G. Knepley   return (o < 0 ? 4-(o+r) : o+r)%4;
13642525629SMatthew G. Knepley }
137d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
138d6d937efSMatthew G. Knepley   return (o < 0 ? 4-(o+s) : 4+s-o)%4;
139d6d937efSMatthew G. Knepley }
14042525629SMatthew G. Knepley 
14175d3a19aSMatthew G. Knepley #undef __FUNCT__
14275d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetConeSizes"
14386150812SJed Brown static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
14475d3a19aSMatthew G. Knepley {
145b5da9499SMatthew 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;
14675d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
14775d3a19aSMatthew G. Knepley 
14875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
14975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
15075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
15175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
15275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
15375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
15475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
1553478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
15675d3a19aSMatthew G. Knepley   switch (refiner) {
1573478d7aaSMatthew G. Knepley   case 0: break;
15875d3a19aSMatthew G. Knepley   case 1:
15975d3a19aSMatthew G. Knepley     /* Simplicial 2D */
16075d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
16175d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
16275d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
16375d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
16475d3a19aSMatthew G. Knepley 
16575d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
16675d3a19aSMatthew G. Knepley       }
16775d3a19aSMatthew G. Knepley     }
16875d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
16975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
17075d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
17175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
17275d3a19aSMatthew G. Knepley         PetscInt       size;
17375d3a19aSMatthew G. Knepley 
17475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
17575d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
17675d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
17775d3a19aSMatthew G. Knepley       }
17875d3a19aSMatthew G. Knepley     }
17975d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
18075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
18175d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
18275d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
18375d3a19aSMatthew G. Knepley 
18475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
18575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
18675d3a19aSMatthew G. Knepley       }
18775d3a19aSMatthew G. Knepley     }
18875d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
18975d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
19075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
19175d3a19aSMatthew G. Knepley       PetscInt       size;
19275d3a19aSMatthew G. Knepley 
19375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
19475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
19575d3a19aSMatthew G. Knepley     }
19675d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
19775d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
19875d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
19975d3a19aSMatthew G. Knepley       PetscInt       size;
20075d3a19aSMatthew G. Knepley 
20175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
20275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
20375d3a19aSMatthew G. Knepley     }
20475d3a19aSMatthew G. Knepley     break;
20575d3a19aSMatthew G. Knepley   case 2:
20675d3a19aSMatthew G. Knepley     /* Hex 2D */
20775d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
20875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
20975d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
21075d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
21175d3a19aSMatthew G. Knepley 
21275d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
21375d3a19aSMatthew G. Knepley       }
21475d3a19aSMatthew G. Knepley     }
21575d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
21675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
21775d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
21875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
21975d3a19aSMatthew G. Knepley         PetscInt       size;
22075d3a19aSMatthew G. Knepley 
22175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
22275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
22375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
22475d3a19aSMatthew G. Knepley       }
22575d3a19aSMatthew G. Knepley     }
22675d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
22775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
22875d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
22975d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
23075d3a19aSMatthew G. Knepley 
23175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
23275d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
23375d3a19aSMatthew G. Knepley       }
23475d3a19aSMatthew G. Knepley     }
23575d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
23675d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
23775d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
23875d3a19aSMatthew G. Knepley       PetscInt       size;
23975d3a19aSMatthew G. Knepley 
24075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
24175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
24275d3a19aSMatthew G. Knepley     }
24375d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
24475d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
24575d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
24675d3a19aSMatthew G. Knepley       PetscInt       size;
24775d3a19aSMatthew G. Knepley 
24875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
24975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
25075d3a19aSMatthew G. Knepley     }
25175d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
25275d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
25375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
25475d3a19aSMatthew G. Knepley 
25575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
25675d3a19aSMatthew G. Knepley     }
25775d3a19aSMatthew G. Knepley     break;
25875d3a19aSMatthew G. Knepley   case 3:
259d963de37SMatthew G. Knepley     /* Hybrid Simplicial 2D */
26075d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
26175d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
26275d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
26375d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
26475d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
26575d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
26675d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
26775d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
26875d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
26975d3a19aSMatthew G. Knepley 
27075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
27175d3a19aSMatthew G. Knepley       }
27275d3a19aSMatthew G. Knepley     }
27375d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
27475d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
27575d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
27675d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
27775d3a19aSMatthew G. Knepley 
27875d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
27975d3a19aSMatthew G. Knepley       }
28075d3a19aSMatthew G. Knepley     }
28175d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
28275d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
28375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
28475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
28575d3a19aSMatthew G. Knepley         PetscInt       size;
28675d3a19aSMatthew G. Knepley 
28775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
28875d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
28975d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
29075d3a19aSMatthew G. Knepley       }
29175d3a19aSMatthew G. Knepley     }
29275d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
29375d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
29475d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
29575d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
29675d3a19aSMatthew G. Knepley 
29775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
29875d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
29975d3a19aSMatthew G. Knepley       }
30075d3a19aSMatthew G. Knepley     }
30175d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
30275d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
30375d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
30475d3a19aSMatthew G. Knepley       PetscInt       size;
30575d3a19aSMatthew G. Knepley 
30675d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
30775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
30875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
30975d3a19aSMatthew G. Knepley     }
31075d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
31175d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
31275d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
31375d3a19aSMatthew G. Knepley 
31475d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
31575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
31675d3a19aSMatthew G. Knepley     }
31775d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
31875d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
31975d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
32075d3a19aSMatthew G. Knepley       PetscInt       size;
32175d3a19aSMatthew G. Knepley 
32275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
32375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
32475d3a19aSMatthew G. Knepley     }
32575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
32675d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
32775d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
32875d3a19aSMatthew G. Knepley       const PetscInt *support;
32975d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
33075d3a19aSMatthew G. Knepley 
33175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
33275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
33375d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
33475d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
33575d3a19aSMatthew G. Knepley         else newSize += 2;
33675d3a19aSMatthew G. Knepley       }
33775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
33875d3a19aSMatthew G. Knepley     }
33975d3a19aSMatthew G. Knepley     break;
340b5da9499SMatthew G. Knepley   case 5:
341b5da9499SMatthew G. Knepley     /* Simplicial 3D */
342b5da9499SMatthew G. Knepley     /* All cells have 4 faces */
343b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
344b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
345dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
346b5da9499SMatthew G. Knepley 
347b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
348b5da9499SMatthew G. Knepley       }
349b5da9499SMatthew G. Knepley     }
350b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
351b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
352b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
353b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
354b5da9499SMatthew G. Knepley         PetscInt       size;
355b5da9499SMatthew G. Knepley 
356b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
357b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
358b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
359b5da9499SMatthew G. Knepley       }
360b5da9499SMatthew G. Knepley     }
3619ddff745SMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
362b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
363b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
364b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
365b5da9499SMatthew G. Knepley 
366b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
367b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
368b5da9499SMatthew G. Knepley       }
369b5da9499SMatthew G. Knepley     }
370b5da9499SMatthew G. Knepley     /* Split edges have 2 vertices and the same faces */
371b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
372b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
373b5da9499SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
374b5da9499SMatthew G. Knepley         PetscInt       size;
375b5da9499SMatthew G. Knepley 
376b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
377b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
378b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
379b5da9499SMatthew G. Knepley       }
380b5da9499SMatthew G. Knepley     }
381b5da9499SMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
382b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
383b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
384b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
385b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
386b5da9499SMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
387b5da9499SMatthew G. Knepley 
388b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
389b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
390b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
391b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
392b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
393b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
394b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
395b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
39686f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
3979ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
398b5da9499SMatthew G. Knepley           if (er == eint[c]) {
399b5da9499SMatthew G. Knepley             intFaces += 1;
400b5da9499SMatthew G. Knepley           } else {
401b5da9499SMatthew G. Knepley             intFaces += 2;
402b5da9499SMatthew G. Knepley           }
403b5da9499SMatthew G. Knepley         }
404b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
405b5da9499SMatthew G. Knepley       }
406b5da9499SMatthew G. Knepley     }
4079ddff745SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
408b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
409b5da9499SMatthew G. Knepley       const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
410b5da9499SMatthew G. Knepley 
411b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
412b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
413b5da9499SMatthew G. Knepley     }
414b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
415b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
416b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
417b5da9499SMatthew G. Knepley       PetscInt       size;
418b5da9499SMatthew G. Knepley 
419b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
420b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
421b5da9499SMatthew G. Knepley     }
422b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
423b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
424b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
425b5da9499SMatthew G. Knepley       PetscInt       size, *star = NULL, starSize, s, cellSize = 0;
426b5da9499SMatthew G. Knepley 
427b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
428b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
429b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
430b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
431b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
432b5da9499SMatthew G. Knepley 
433b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
434b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
435b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
436b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
437b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
43842525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
439b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
440b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
441b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
44242525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
44342525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
444b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
445b5da9499SMatthew G. Knepley         }
446b5da9499SMatthew G. Knepley       }
447b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
448b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr);
449b5da9499SMatthew G. Knepley     }
450b5da9499SMatthew G. Knepley     break;
451dae4404aSMatthew G. Knepley   case 7:
4526ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
4536ce3c06aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
4546ce3c06aSMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
455dae4404aSMatthew G. Knepley     /* Interior cells have 4 faces */
456dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
457dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
458dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
459dae4404aSMatthew G. Knepley 
460dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
461dae4404aSMatthew G. Knepley       }
462dae4404aSMatthew G. Knepley     }
463dae4404aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
464dae4404aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
465dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
466dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
467dae4404aSMatthew G. Knepley 
468dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr);
469dae4404aSMatthew G. Knepley       }
470dae4404aSMatthew G. Knepley     }
4716ce3c06aSMatthew G. Knepley     /* Interior split faces have 3 edges and the same cells as the parent */
472dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
473dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
474dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
475dae4404aSMatthew G. Knepley         PetscInt       size;
476dae4404aSMatthew G. Knepley 
477dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
478dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
479dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
480dae4404aSMatthew G. Knepley       }
481dae4404aSMatthew G. Knepley     }
482dae4404aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
483dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
484dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
485dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
486dae4404aSMatthew G. Knepley 
487dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
488dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
489dae4404aSMatthew G. Knepley       }
490dae4404aSMatthew G. Knepley     }
4916ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
4926ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
4936ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
4946ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
4956ce3c06aSMatthew G. Knepley         PetscInt       size;
4966ce3c06aSMatthew G. Knepley 
4976ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
4986ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
4996ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
5006ce3c06aSMatthew G. Knepley       }
5016ce3c06aSMatthew G. Knepley     }
5026ce3c06aSMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
5036ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
5046ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
5056ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
5066ce3c06aSMatthew G. Knepley 
5076ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
5086ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
5096ce3c06aSMatthew G. Knepley       }
5106ce3c06aSMatthew G. Knepley     }
5116ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces */
512dae4404aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
513dae4404aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
514dae4404aSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
515dae4404aSMatthew G. Knepley         PetscInt       size;
516dae4404aSMatthew G. Knepley 
517dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
518dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
519dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
520dae4404aSMatthew G. Knepley       }
521dae4404aSMatthew G. Knepley     }
5226ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
523dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
524dae4404aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
525dae4404aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
526dae4404aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
527dae4404aSMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
528dae4404aSMatthew G. Knepley 
529dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
530dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
531dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
532dae4404aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
533dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
534dae4404aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
535dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
536dae4404aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
5376ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
538dae4404aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
5399ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
540dae4404aSMatthew G. Knepley             if (er == eint[c]) {
541dae4404aSMatthew G. Knepley               intFaces += 1;
542dae4404aSMatthew G. Knepley             } else {
543dae4404aSMatthew G. Knepley               intFaces += 2;
544dae4404aSMatthew G. Knepley             }
5456ce3c06aSMatthew G. Knepley           } else {
5466ce3c06aSMatthew G. Knepley             intFaces += 1;
5476ce3c06aSMatthew G. Knepley           }
548dae4404aSMatthew G. Knepley         }
549dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
550dae4404aSMatthew G. Knepley       }
551dae4404aSMatthew G. Knepley     }
5526ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
553dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
554dae4404aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
555dae4404aSMatthew G. Knepley 
556dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
557dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
558dae4404aSMatthew G. Knepley     }
5596ce3c06aSMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
560dae4404aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
5616ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
5626ce3c06aSMatthew G. Knepley       PetscInt       size;
5636ce3c06aSMatthew G. Knepley 
5646ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
5656ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
5666ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
5676ce3c06aSMatthew G. Knepley     }
5686ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
5696ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
5706ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
571dae4404aSMatthew G. Knepley       PetscInt       size;
572dae4404aSMatthew G. Knepley 
573dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
574dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
5756ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr);
576dae4404aSMatthew G. Knepley     }
5776ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
578dae4404aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
579dae4404aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
580dae4404aSMatthew G. Knepley       PetscInt       size;
581dae4404aSMatthew G. Knepley 
582dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
583dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
584dae4404aSMatthew G. Knepley     }
5856ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
5866ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
5876ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
588dae4404aSMatthew G. Knepley       const PetscInt *support;
5896ce3c06aSMatthew G. Knepley       PetscInt        size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
590dae4404aSMatthew G. Knepley 
5916ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
5926ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
593dae4404aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
5946ce3c06aSMatthew G. Knepley         if (support[s] < fMax) faceSize += 2;
5956ce3c06aSMatthew G. Knepley         else                   faceSize += 1;
596dae4404aSMatthew G. Knepley       }
5976ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
5986ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
5996ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
6006ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
6016ce3c06aSMatthew G. Knepley 
6026ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
6036ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
6046ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
6056ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
6066ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
6076ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
6086ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
6096ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
6106ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
6116ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
6126ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
6136ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
6146ce3c06aSMatthew G. Knepley         }
6156ce3c06aSMatthew G. Knepley       }
6166ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
6176ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr);
618dae4404aSMatthew G. Knepley     }
619dae4404aSMatthew G. Knepley     break;
6202eabf88fSMatthew G. Knepley   case 6:
6212eabf88fSMatthew G. Knepley     /* Hex 3D */
6222eabf88fSMatthew G. Knepley     /* All cells have 6 faces */
6232eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6242eabf88fSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
6252eabf88fSMatthew G. Knepley         const PetscInt newp = (c - cStart)*8 + r;
6262eabf88fSMatthew G. Knepley 
6272eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
6282eabf88fSMatthew G. Knepley       }
6292eabf88fSMatthew G. Knepley     }
6302eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
6312eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
6322eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
6332eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
6342eabf88fSMatthew G. Knepley         PetscInt       size;
6352eabf88fSMatthew G. Knepley 
6362eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
6372eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
6382eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6392eabf88fSMatthew G. Knepley       }
6402eabf88fSMatthew G. Knepley     }
6412eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
6422eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6432eabf88fSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
6442eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
6452eabf88fSMatthew G. Knepley 
6462eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
6472eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
6482eabf88fSMatthew G. Knepley       }
6492eabf88fSMatthew G. Knepley     }
6502eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
6512eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
6522eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
6532eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
6542eabf88fSMatthew G. Knepley         PetscInt       size;
6552eabf88fSMatthew G. Knepley 
6562eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6572eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
6582eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6592eabf88fSMatthew G. Knepley       }
6602eabf88fSMatthew G. Knepley     }
6612eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
6622eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
6632eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
6642eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
6652eabf88fSMatthew G. Knepley         PetscInt       size;
6662eabf88fSMatthew G. Knepley 
6672eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6682eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
6692eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
6702eabf88fSMatthew G. Knepley       }
6712eabf88fSMatthew G. Knepley     }
6722eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
6732eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6742eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
6752eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
6762eabf88fSMatthew G. Knepley 
6772eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6782eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
6792eabf88fSMatthew G. Knepley       }
6802eabf88fSMatthew G. Knepley     }
6812eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
6822eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
6832eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
6842eabf88fSMatthew G. Knepley       PetscInt       size;
6852eabf88fSMatthew G. Knepley 
6862eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
6872eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6882eabf88fSMatthew G. Knepley     }
6892eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
6902eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
6912eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
6922eabf88fSMatthew G. Knepley       PetscInt       size;
6932eabf88fSMatthew G. Knepley 
6942eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
6952eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
6962eabf88fSMatthew G. Knepley     }
6972eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
6982eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
6992eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
7002eabf88fSMatthew G. Knepley       PetscInt       size;
7012eabf88fSMatthew G. Knepley 
7022eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
7032eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
7042eabf88fSMatthew G. Knepley     }
7052eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
7062eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
7072eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
7082eabf88fSMatthew G. Knepley 
7092eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
7102eabf88fSMatthew G. Knepley     }
7112eabf88fSMatthew G. Knepley     break;
71275d3a19aSMatthew G. Knepley   default:
71375d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
71475d3a19aSMatthew G. Knepley   }
71575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
71675d3a19aSMatthew G. Knepley }
71775d3a19aSMatthew G. Knepley 
71875d3a19aSMatthew G. Knepley #undef __FUNCT__
71975d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCones"
72086150812SJed Brown static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
72175d3a19aSMatthew G. Knepley {
722b5da9499SMatthew G. Knepley   const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
7236ce3c06aSMatthew G. Knepley   PetscInt        cStart,    cEnd,    cMax,    vStart,    vEnd, vMax, fStart,    fEnd,    fMax,    eStart,    eEnd,    eMax;
7246ce3c06aSMatthew G. Knepley   PetscInt        cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew,    fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
7256ce3c06aSMatthew G. Knepley   PetscInt        depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
72675d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
72775d3a19aSMatthew G. Knepley 
72875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
72975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
73075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
73175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
73275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
73375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
73475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
7353478d7aaSMatthew G. Knepley   if (refiner) {
73675d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
73775d3a19aSMatthew G. Knepley     ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
7383478d7aaSMatthew G. Knepley   }
73975d3a19aSMatthew G. Knepley   switch (refiner) {
7403478d7aaSMatthew G. Knepley   case 0: break;
74175d3a19aSMatthew G. Knepley   case 1:
74275d3a19aSMatthew G. Knepley     /* Simplicial 2D */
74375d3a19aSMatthew G. Knepley     /*
74475d3a19aSMatthew G. Knepley      2
74575d3a19aSMatthew G. Knepley      |\
74675d3a19aSMatthew G. Knepley      | \
74775d3a19aSMatthew G. Knepley      |  \
74875d3a19aSMatthew G. Knepley      |   \
74975d3a19aSMatthew G. Knepley      | C  \
75075d3a19aSMatthew G. Knepley      |     \
75175d3a19aSMatthew G. Knepley      |      \
75275d3a19aSMatthew G. Knepley      2---1---1
75375d3a19aSMatthew G. Knepley      |\  D  / \
75475d3a19aSMatthew G. Knepley      | 2   0   \
75575d3a19aSMatthew G. Knepley      |A \ /  B  \
75675d3a19aSMatthew G. Knepley      0---0-------1
75775d3a19aSMatthew G. Knepley      */
75875d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
75975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
76075d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
76175d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
76275d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
76375d3a19aSMatthew G. Knepley 
76475d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
76575d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
76675d3a19aSMatthew G. Knepley       /* A triangle */
76775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
76875d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
76975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
77075d3a19aSMatthew G. Knepley       orntNew[1] = -2;
77175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
77275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
77375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
77475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
77575d3a19aSMatthew G. Knepley #if 1
77675d3a19aSMatthew 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);
77775d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
77875d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
77975d3a19aSMatthew G. Knepley       }
78075d3a19aSMatthew G. Knepley #endif
78175d3a19aSMatthew G. Knepley       /* B triangle */
78275d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
78375d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
78475d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
78575d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
78675d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
78775d3a19aSMatthew G. Knepley       orntNew[2] = -2;
78875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
78975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
79075d3a19aSMatthew G. Knepley #if 1
79175d3a19aSMatthew 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);
79275d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
79375d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
79475d3a19aSMatthew G. Knepley       }
79575d3a19aSMatthew G. Knepley #endif
79675d3a19aSMatthew G. Knepley       /* C triangle */
79775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
79875d3a19aSMatthew G. Knepley       orntNew[0] = -2;
79975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
80075d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
80175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
80275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
80375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
80475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
80575d3a19aSMatthew G. Knepley #if 1
80675d3a19aSMatthew 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);
80775d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
80875d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
80975d3a19aSMatthew G. Knepley       }
81075d3a19aSMatthew G. Knepley #endif
81175d3a19aSMatthew G. Knepley       /* D triangle */
81275d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
81375d3a19aSMatthew G. Knepley       orntNew[0] = 0;
81475d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
81575d3a19aSMatthew G. Knepley       orntNew[1] = 0;
81675d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
81775d3a19aSMatthew G. Knepley       orntNew[2] = 0;
81875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
81975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
82075d3a19aSMatthew G. Knepley #if 1
82175d3a19aSMatthew 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);
82275d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
82375d3a19aSMatthew 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);
82475d3a19aSMatthew G. Knepley       }
82575d3a19aSMatthew G. Knepley #endif
82675d3a19aSMatthew G. Knepley     }
82775d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
82875d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
829785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
83075d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
83175d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
83275d3a19aSMatthew G. Knepley 
83375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
83475d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
835297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
83675d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
83775d3a19aSMatthew G. Knepley 
83875d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
83975d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
84075d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
84175d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
84275d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
84375d3a19aSMatthew G. Knepley #if 1
84475d3a19aSMatthew 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);
84575d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
84675d3a19aSMatthew 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);
84775d3a19aSMatthew G. Knepley         }
84875d3a19aSMatthew G. Knepley #endif
84975d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
85075d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
85175d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
85275d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
85375d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
854297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
85575d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
85675d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
85775d3a19aSMatthew G. Knepley           }
858297d2bf4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
85975d3a19aSMatthew G. Knepley         }
86075d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);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 < supportSize; ++p) {
86475d3a19aSMatthew 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);
86575d3a19aSMatthew G. Knepley         }
86675d3a19aSMatthew G. Knepley #endif
86775d3a19aSMatthew G. Knepley       }
86875d3a19aSMatthew G. Knepley     }
86975d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
87075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
87175d3a19aSMatthew G. Knepley       const PetscInt *cone;
87275d3a19aSMatthew G. Knepley 
87375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
87475d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
87575d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
87675d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
87775d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
87875d3a19aSMatthew G. Knepley 
87975d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
88075d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
88175d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
88275d3a19aSMatthew G. Knepley #if 1
88375d3a19aSMatthew 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);
88475d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
88575d3a19aSMatthew 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);
88675d3a19aSMatthew G. Knepley         }
88775d3a19aSMatthew G. Knepley #endif
88875d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
88975d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
89075d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
89175d3a19aSMatthew G. Knepley #if 1
89275d3a19aSMatthew 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);
89375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
89475d3a19aSMatthew 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);
89575d3a19aSMatthew G. Knepley         }
89675d3a19aSMatthew G. Knepley #endif
89775d3a19aSMatthew G. Knepley       }
89875d3a19aSMatthew G. Knepley     }
89975d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
90075d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
90175d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
90275d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
90375d3a19aSMatthew G. Knepley       PetscInt        size, s;
90475d3a19aSMatthew G. Knepley 
90575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
90675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
90775d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
90875d3a19aSMatthew G. Knepley         PetscInt r = 0;
90975d3a19aSMatthew G. Knepley 
91075d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
91175d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
91275d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
91375d3a19aSMatthew G. Knepley       }
91475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
91575d3a19aSMatthew G. Knepley #if 1
91675d3a19aSMatthew 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);
91775d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
91875d3a19aSMatthew 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);
91975d3a19aSMatthew G. Knepley       }
92075d3a19aSMatthew G. Knepley #endif
92175d3a19aSMatthew G. Knepley     }
92275d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
92375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
92475d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
92575d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
92675d3a19aSMatthew G. Knepley       PetscInt        size, s;
92775d3a19aSMatthew G. Knepley 
92875d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
92975d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
93075d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
93175d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
93275d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
93375d3a19aSMatthew G. Knepley         PetscInt r = 0;
93475d3a19aSMatthew G. Knepley 
93575d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
93675d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
93775d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
93875d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
93975d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
94075d3a19aSMatthew G. Knepley       }
94175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
94275d3a19aSMatthew G. Knepley #if 1
94375d3a19aSMatthew 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);
94475d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
94575d3a19aSMatthew 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);
94675d3a19aSMatthew G. Knepley       }
94775d3a19aSMatthew G. Knepley #endif
94875d3a19aSMatthew G. Knepley     }
94975d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
95075d3a19aSMatthew G. Knepley     break;
95175d3a19aSMatthew G. Knepley   case 2:
95275d3a19aSMatthew G. Knepley     /* Hex 2D */
95375d3a19aSMatthew G. Knepley     /*
95475d3a19aSMatthew G. Knepley      3---------2---------2
95575d3a19aSMatthew G. Knepley      |         |         |
95675d3a19aSMatthew G. Knepley      |    D    2    C    |
95775d3a19aSMatthew G. Knepley      |         |         |
95875d3a19aSMatthew G. Knepley      3----3----0----1----1
95975d3a19aSMatthew G. Knepley      |         |         |
96075d3a19aSMatthew G. Knepley      |    A    0    B    |
96175d3a19aSMatthew G. Knepley      |         |         |
96275d3a19aSMatthew G. Knepley      0---------0---------1
96375d3a19aSMatthew G. Knepley      */
96475d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
96575d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
96675d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
96775d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
96875d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
96975d3a19aSMatthew G. Knepley 
97075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
97175d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
97275d3a19aSMatthew G. Knepley       /* A quad */
97375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
97475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
97575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
97675d3a19aSMatthew G. Knepley       orntNew[1] = 0;
97775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
97875d3a19aSMatthew G. Knepley       orntNew[2] = -2;
97975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
98075d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
98175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
98275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
98375d3a19aSMatthew G. Knepley #if 1
98475d3a19aSMatthew 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);
98575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
98675d3a19aSMatthew 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);
98775d3a19aSMatthew G. Knepley       }
98875d3a19aSMatthew G. Knepley #endif
98975d3a19aSMatthew G. Knepley       /* B quad */
99075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
99175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
99275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
99375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
99475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
99575d3a19aSMatthew G. Knepley       orntNew[2] = 0;
99675d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
99775d3a19aSMatthew G. Knepley       orntNew[3] = -2;
99875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
99975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
100075d3a19aSMatthew G. Knepley #if 1
100175d3a19aSMatthew 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);
100275d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
100375d3a19aSMatthew 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);
100475d3a19aSMatthew G. Knepley       }
100575d3a19aSMatthew G. Knepley #endif
100675d3a19aSMatthew G. Knepley       /* C quad */
100775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
100875d3a19aSMatthew G. Knepley       orntNew[0] = -2;
100975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
101075d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
101175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
101275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
101375d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
101475d3a19aSMatthew G. Knepley       orntNew[3] = 0;
101575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
101675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
101775d3a19aSMatthew G. Knepley #if 1
101875d3a19aSMatthew 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);
101975d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
102075d3a19aSMatthew 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);
102175d3a19aSMatthew G. Knepley       }
102275d3a19aSMatthew G. Knepley #endif
102375d3a19aSMatthew G. Knepley       /* D quad */
102475d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
102575d3a19aSMatthew G. Knepley       orntNew[0] = 0;
102675d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
102775d3a19aSMatthew G. Knepley       orntNew[1] = -2;
102875d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
102975d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
103075d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
103175d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
103275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
103375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
103475d3a19aSMatthew G. Knepley #if 1
103575d3a19aSMatthew 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);
103675d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
103775d3a19aSMatthew 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);
103875d3a19aSMatthew G. Knepley       }
103975d3a19aSMatthew G. Knepley #endif
104075d3a19aSMatthew G. Knepley     }
104175d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
104275d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1043785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
104475d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
104575d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
104675d3a19aSMatthew G. Knepley 
104775d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
104875d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1049455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
105075d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
105175d3a19aSMatthew G. Knepley 
105275d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
105375d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
105475d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
105575d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
105675d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
105775d3a19aSMatthew G. Knepley #if 1
105875d3a19aSMatthew 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);
105975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
106075d3a19aSMatthew 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);
106175d3a19aSMatthew G. Knepley         }
106275d3a19aSMatthew G. Knepley #endif
106375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
106475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
106575d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
106675d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
106775d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1068455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
106975d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
107075d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
107175d3a19aSMatthew G. Knepley           }
1072455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
107375d3a19aSMatthew G. Knepley         }
107475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
107575d3a19aSMatthew G. Knepley #if 1
107675d3a19aSMatthew 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);
107775d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
107875d3a19aSMatthew 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);
107975d3a19aSMatthew G. Knepley         }
108075d3a19aSMatthew G. Knepley #endif
108175d3a19aSMatthew G. Knepley       }
108275d3a19aSMatthew G. Knepley     }
108375d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
108475d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
108575d3a19aSMatthew G. Knepley       const PetscInt *cone;
108675d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
108775d3a19aSMatthew G. Knepley 
108875d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
108975d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
109075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
109175d3a19aSMatthew G. Knepley 
109275d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
109375d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
109475d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
109575d3a19aSMatthew G. Knepley #if 1
109675d3a19aSMatthew 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);
109775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
109875d3a19aSMatthew 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);
109975d3a19aSMatthew G. Knepley         }
110075d3a19aSMatthew G. Knepley #endif
110175d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
110275d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
110375d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
110475d3a19aSMatthew G. Knepley #if 1
110575d3a19aSMatthew 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);
110675d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
110775d3a19aSMatthew 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);
110875d3a19aSMatthew G. Knepley         }
110975d3a19aSMatthew G. Knepley #endif
111075d3a19aSMatthew G. Knepley       }
111175d3a19aSMatthew G. Knepley     }
111275d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
111375d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
111475d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
111575d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
111675d3a19aSMatthew G. Knepley       PetscInt        size, s;
111775d3a19aSMatthew G. Knepley 
111875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
111975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
112075d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
112175d3a19aSMatthew G. Knepley         PetscInt r = 0;
112275d3a19aSMatthew G. Knepley 
112375d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
112475d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
112575d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
112675d3a19aSMatthew G. Knepley       }
112775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
112875d3a19aSMatthew G. Knepley #if 1
112975d3a19aSMatthew 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);
113075d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
113175d3a19aSMatthew 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);
113275d3a19aSMatthew G. Knepley       }
113375d3a19aSMatthew G. Knepley #endif
113475d3a19aSMatthew G. Knepley     }
113575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
113675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
113775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
113875d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
113975d3a19aSMatthew G. Knepley       PetscInt        size, s;
114075d3a19aSMatthew G. Knepley 
114175d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
114275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
114375d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
114475d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
114575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
114675d3a19aSMatthew G. Knepley         PetscInt r = 0;
114775d3a19aSMatthew G. Knepley 
114875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
114975d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
115075d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
115175d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
115275d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
115375d3a19aSMatthew G. Knepley       }
115475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
115575d3a19aSMatthew G. Knepley #if 1
115675d3a19aSMatthew 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);
115775d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
115875d3a19aSMatthew 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);
115975d3a19aSMatthew G. Knepley       }
116075d3a19aSMatthew G. Knepley #endif
116175d3a19aSMatthew G. Knepley     }
116275d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
116375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
116475d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
116575d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
116675d3a19aSMatthew G. Knepley 
116775d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
116875d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
116975d3a19aSMatthew G. Knepley       }
117075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
117175d3a19aSMatthew G. Knepley     }
1172da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
117375d3a19aSMatthew G. Knepley     break;
117475d3a19aSMatthew G. Knepley   case 3:
117575d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
117675d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
117775d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
117875d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
117975d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
118075d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
118175d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
118275d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
118375d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
118475d3a19aSMatthew G. Knepley 
118575d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
118675d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
118775d3a19aSMatthew G. Knepley       /* A triangle */
118875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
118975d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
119075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
119175d3a19aSMatthew G. Knepley       orntNew[1] = -2;
119275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
119375d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
119475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
119575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
119675d3a19aSMatthew G. Knepley #if 1
119775d3a19aSMatthew 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);
119875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
119975d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
120075d3a19aSMatthew G. Knepley       }
120175d3a19aSMatthew G. Knepley #endif
120275d3a19aSMatthew G. Knepley       /* B triangle */
120375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
120475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
120575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
120675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
120775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
120875d3a19aSMatthew G. Knepley       orntNew[2] = -2;
120975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
121075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
121175d3a19aSMatthew G. Knepley #if 1
121275d3a19aSMatthew 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);
121375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
121475d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
121575d3a19aSMatthew G. Knepley       }
121675d3a19aSMatthew G. Knepley #endif
121775d3a19aSMatthew G. Knepley       /* C triangle */
121875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
121975d3a19aSMatthew G. Knepley       orntNew[0] = -2;
122075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
122175d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
122275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
122375d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
122475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
122575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
122675d3a19aSMatthew G. Knepley #if 1
122775d3a19aSMatthew 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);
122875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
122975d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
123075d3a19aSMatthew G. Knepley       }
123175d3a19aSMatthew G. Knepley #endif
123275d3a19aSMatthew G. Knepley       /* D triangle */
123375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
123475d3a19aSMatthew G. Knepley       orntNew[0] = 0;
123575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
123675d3a19aSMatthew G. Knepley       orntNew[1] = 0;
123775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
123875d3a19aSMatthew G. Knepley       orntNew[2] = 0;
123975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
124075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
124175d3a19aSMatthew G. Knepley #if 1
124275d3a19aSMatthew 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);
124375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
124475d3a19aSMatthew 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);
124575d3a19aSMatthew G. Knepley       }
124675d3a19aSMatthew G. Knepley #endif
124775d3a19aSMatthew G. Knepley     }
124875d3a19aSMatthew G. Knepley     /*
124975d3a19aSMatthew G. Knepley      2----3----3
125075d3a19aSMatthew G. Knepley      |         |
125175d3a19aSMatthew G. Knepley      |    B    |
125275d3a19aSMatthew G. Knepley      |         |
125375d3a19aSMatthew G. Knepley      0----4--- 1
125475d3a19aSMatthew G. Knepley      |         |
125575d3a19aSMatthew G. Knepley      |    A    |
125675d3a19aSMatthew G. Knepley      |         |
125775d3a19aSMatthew G. Knepley      0----2----1
125875d3a19aSMatthew G. Knepley      */
125975d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
126075d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
126175d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
126275d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
126375d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
126475d3a19aSMatthew G. Knepley 
126575d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
126675d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
126775d3a19aSMatthew G. Knepley       /* A quad */
126875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
126975d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
127075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
127175d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
127275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2] - fMax);
127375d3a19aSMatthew G. Knepley       orntNew[2] = 0;
127475d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
127575d3a19aSMatthew G. Knepley       orntNew[3] = 0;
127675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
127775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
127875d3a19aSMatthew G. Knepley #if 1
127975d3a19aSMatthew 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);
128075d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
128175d3a19aSMatthew 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);
128275d3a19aSMatthew G. Knepley       }
128375d3a19aSMatthew G. Knepley #endif
128475d3a19aSMatthew G. Knepley       /* B quad */
128575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
128675d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
128775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
128875d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
128975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
129075d3a19aSMatthew G. Knepley       orntNew[2] = 0;
129175d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3] - fMax);
129275d3a19aSMatthew G. Knepley       orntNew[3] = 0;
129375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
129475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
129575d3a19aSMatthew G. Knepley #if 1
129675d3a19aSMatthew 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);
129775d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
129875d3a19aSMatthew 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);
129975d3a19aSMatthew G. Knepley       }
130075d3a19aSMatthew G. Knepley #endif
130175d3a19aSMatthew G. Knepley     }
130275d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
130375d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1304785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
130575d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
130675d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
130775d3a19aSMatthew G. Knepley 
130875d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
130975d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1310297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
131175d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
131275d3a19aSMatthew G. Knepley 
131375d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
131475d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
131575d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
131675d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
131775d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
131875d3a19aSMatthew G. Knepley #if 1
131975d3a19aSMatthew 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);
132075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
132175d3a19aSMatthew 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);
132275d3a19aSMatthew G. Knepley         }
132375d3a19aSMatthew G. Knepley #endif
132475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
132575d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
132675d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
132775d3a19aSMatthew G. Knepley           if (support[s] >= cMax) {
132875d3a19aSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
132975d3a19aSMatthew G. Knepley           } else {
133075d3a19aSMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
133175d3a19aSMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1332297d2bf4SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
133375d3a19aSMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
133475d3a19aSMatthew G. Knepley               if (cone[c] == f) break;
133575d3a19aSMatthew G. Knepley             }
1336297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
133775d3a19aSMatthew G. Knepley           }
133875d3a19aSMatthew G. Knepley         }
133975d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);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 < supportSize; ++p) {
134375d3a19aSMatthew 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);
134475d3a19aSMatthew G. Knepley         }
134575d3a19aSMatthew G. Knepley #endif
134675d3a19aSMatthew G. Knepley       }
134775d3a19aSMatthew G. Knepley     }
134875d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
134975d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
135075d3a19aSMatthew G. Knepley       const PetscInt *cone;
135175d3a19aSMatthew G. Knepley 
135275d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
135375d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
135475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
135575d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
135675d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
135775d3a19aSMatthew G. Knepley 
135875d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
135975d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
136075d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
136175d3a19aSMatthew G. Knepley #if 1
136275d3a19aSMatthew 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);
136375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
136475d3a19aSMatthew 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);
136575d3a19aSMatthew G. Knepley         }
136675d3a19aSMatthew G. Knepley #endif
136775d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
136875d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
136975d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 ((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);
137475d3a19aSMatthew G. Knepley         }
137575d3a19aSMatthew G. Knepley #endif
137675d3a19aSMatthew G. Knepley       }
137775d3a19aSMatthew G. Knepley     }
137875d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
137975d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
138075d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
138175d3a19aSMatthew G. Knepley       const PetscInt *cone;
138275d3a19aSMatthew G. Knepley       const PetscInt *support;
138375d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
138475d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
138575d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
138675d3a19aSMatthew G. Knepley 
138775d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
138875d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
138975d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
139075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
139175d3a19aSMatthew G. Knepley #if 1
139275d3a19aSMatthew 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);
139375d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
139475d3a19aSMatthew 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);
139575d3a19aSMatthew G. Knepley       }
139675d3a19aSMatthew G. Knepley #endif
139775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
139875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
139975d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
140075d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
140175d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
140275d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
140375d3a19aSMatthew G. Knepley         }
140475d3a19aSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
140575d3a19aSMatthew G. Knepley       }
140675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
140775d3a19aSMatthew G. Knepley #if 1
140875d3a19aSMatthew 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);
140975d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
141075d3a19aSMatthew 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);
141175d3a19aSMatthew G. Knepley       }
141275d3a19aSMatthew G. Knepley #endif
141375d3a19aSMatthew G. Knepley     }
141475d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
141575d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
141675d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
141775d3a19aSMatthew G. Knepley       const PetscInt *cone;
141875d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
141975d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
142075d3a19aSMatthew G. Knepley 
142175d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
142275d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
142375d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
142475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
142575d3a19aSMatthew G. Knepley #if 1
142675d3a19aSMatthew 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);
142775d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
142875d3a19aSMatthew 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);
142975d3a19aSMatthew G. Knepley       }
143075d3a19aSMatthew G. Knepley #endif
143175d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
143275d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
143375d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
143475d3a19aSMatthew G. Knepley #if 1
143575d3a19aSMatthew 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);
143675d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
143775d3a19aSMatthew 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);
143875d3a19aSMatthew G. Knepley       }
143975d3a19aSMatthew G. Knepley #endif
144075d3a19aSMatthew G. Knepley     }
144175d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
144275d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
144375d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
144475d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
144575d3a19aSMatthew G. Knepley       PetscInt        size, s;
144675d3a19aSMatthew G. Knepley 
144775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
144875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
144975d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
145075d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
145175d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
145275d3a19aSMatthew G. Knepley         } else {
145375d3a19aSMatthew G. Knepley           PetscInt r = 0;
145475d3a19aSMatthew G. Knepley 
145575d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
145675d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
145775d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
145875d3a19aSMatthew G. Knepley         }
145975d3a19aSMatthew G. Knepley       }
146075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
146175d3a19aSMatthew G. Knepley #if 1
146275d3a19aSMatthew 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);
146375d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
146475d3a19aSMatthew 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);
146575d3a19aSMatthew G. Knepley       }
146675d3a19aSMatthew G. Knepley #endif
146775d3a19aSMatthew G. Knepley     }
146875d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
146975d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
147075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
147175d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
147275d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
147375d3a19aSMatthew G. Knepley 
147475d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
147575d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
147675d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
147775d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
147875d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
147975d3a19aSMatthew G. Knepley         PetscInt r = 0;
148075d3a19aSMatthew G. Knepley 
148175d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
148275d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
148375d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
148475d3a19aSMatthew G. Knepley 
148575d3a19aSMatthew G. Knepley           newSize += 1;
148675d3a19aSMatthew G. Knepley         } else {
148775d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
148875d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
148975d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
149075d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
149175d3a19aSMatthew G. Knepley 
149275d3a19aSMatthew G. Knepley           newSize += 2;
149375d3a19aSMatthew G. Knepley         }
149475d3a19aSMatthew G. Knepley       }
149575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
149675d3a19aSMatthew G. Knepley #if 1
149775d3a19aSMatthew 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);
149875d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
149975d3a19aSMatthew 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);
150075d3a19aSMatthew G. Knepley       }
150175d3a19aSMatthew G. Knepley #endif
150275d3a19aSMatthew G. Knepley     }
150375d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
150475d3a19aSMatthew G. Knepley     break;
1505b5da9499SMatthew G. Knepley   case 5:
1506b5da9499SMatthew G. Knepley     /* Simplicial 3D */
1507b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
1508b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
1509b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
1510b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
1511b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
1512b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1513b5da9499SMatthew G. Knepley 
1514b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1515b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1516b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
1517518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
1518b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1519518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
1520b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1521518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
1522b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1523b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
1524b5da9499SMatthew G. Knepley       orntNew[3] = 0;
1525b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1526b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1527b5da9499SMatthew G. Knepley #if 1
1528b5da9499SMatthew 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);
1529b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1530b5da9499SMatthew 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);
1531b5da9499SMatthew G. Knepley       }
1532b5da9499SMatthew G. Knepley #endif
1533b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
1534518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
1535b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1536518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
1537b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1538b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
1539b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1540518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
1541b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1542b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1543b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1544b5da9499SMatthew G. Knepley #if 1
1545b5da9499SMatthew 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);
1546b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1547b5da9499SMatthew 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);
1548b5da9499SMatthew G. Knepley       }
1549b5da9499SMatthew G. Knepley #endif
1550b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
1551518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
1552b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1553b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
1554b5da9499SMatthew G. Knepley       orntNew[1] = 0;
1555518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
1556b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1557518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
1558b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1559b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1560b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1561b5da9499SMatthew G. Knepley #if 1
1562b5da9499SMatthew 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);
1563b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1564b5da9499SMatthew 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);
1565b5da9499SMatthew G. Knepley       }
1566b5da9499SMatthew G. Knepley #endif
1567b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
1568b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
1569b5da9499SMatthew G. Knepley       orntNew[0] = 0;
1570518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
1571b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1572518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
1573b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1574518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
1575b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1576b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1577b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1578b5da9499SMatthew G. Knepley #if 1
1579b5da9499SMatthew 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);
1580b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1581b5da9499SMatthew 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);
1582b5da9499SMatthew G. Knepley       }
1583b5da9499SMatthew G. Knepley #endif
1584b5da9499SMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
1585b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
1586b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1587fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
1588db2c6090SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
1589fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
1590fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
1591fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
1592fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
1593b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
1594b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
1595b5da9499SMatthew G. Knepley #if 1
1596b5da9499SMatthew 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);
1597b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1598b5da9499SMatthew 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);
1599b5da9499SMatthew G. Knepley       }
1600b5da9499SMatthew G. Knepley #endif
1601b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
1602b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
1603b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1604fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
1605fac4ab25SMatthew G. Knepley       orntNew[1] = 1;
1606fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
1607b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1608fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
1609db2c6090SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
1610b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
1611b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
1612b5da9499SMatthew G. Knepley #if 1
1613b5da9499SMatthew 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);
1614b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1615b5da9499SMatthew 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);
1616b5da9499SMatthew G. Knepley       }
1617b5da9499SMatthew G. Knepley #endif
1618b5da9499SMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
1619b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
1620b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1621fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
1622db2c6090SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
1623fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
1624fac4ab25SMatthew G. Knepley       orntNew[2] = -3;
1625fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
1626fac4ab25SMatthew G. Knepley       orntNew[3] = -2;
1627b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
1628b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
1629b5da9499SMatthew G. Knepley #if 1
1630b5da9499SMatthew 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);
1631b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1632b5da9499SMatthew 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);
1633b5da9499SMatthew G. Knepley       }
1634b5da9499SMatthew G. Knepley #endif
1635b5da9499SMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
1636b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
1637b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1638fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
1639b5da9499SMatthew G. Knepley       orntNew[1] = -3;
1640fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
1641db2c6090SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
1642fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
1643fac4ab25SMatthew G. Knepley       orntNew[3] = -3;
1644b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
1645b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
1646b5da9499SMatthew G. Knepley #if 1
1647b5da9499SMatthew 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);
1648b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1649b5da9499SMatthew 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);
1650b5da9499SMatthew G. Knepley       }
1651b5da9499SMatthew G. Knepley #endif
1652b5da9499SMatthew G. Knepley     }
1653b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
1654b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1655785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
1656b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
1657b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
1658b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
1659b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
1660b5da9499SMatthew G. Knepley 
1661b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
1662b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
1663b5da9499SMatthew G. Knepley       /* A triangle */
1664b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
1665b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1666b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
1667b5da9499SMatthew G. Knepley       orntNew[1] = -2;
1668b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
1669b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1670b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1671b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1672b5da9499SMatthew G. Knepley #if 1
1673b5da9499SMatthew 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);
1674b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1675b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
1676b5da9499SMatthew G. Knepley       }
1677b5da9499SMatthew G. Knepley #endif
1678b5da9499SMatthew G. Knepley       /* B triangle */
1679b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
1680b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1681b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
1682b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1683b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
1684b5da9499SMatthew G. Knepley       orntNew[2] = -2;
1685b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1686b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1687b5da9499SMatthew G. Knepley #if 1
1688b5da9499SMatthew 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);
1689b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1690b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
1691b5da9499SMatthew G. Knepley       }
1692b5da9499SMatthew G. Knepley #endif
1693b5da9499SMatthew G. Knepley       /* C triangle */
1694b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
1695b5da9499SMatthew G. Knepley       orntNew[0] = -2;
1696b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
1697b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1698b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
1699b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1700b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1701b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1702b5da9499SMatthew G. Knepley #if 1
1703b5da9499SMatthew 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);
1704b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1705b5da9499SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
1706b5da9499SMatthew G. Knepley       }
1707b5da9499SMatthew G. Knepley #endif
1708b5da9499SMatthew G. Knepley       /* D triangle */
1709b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
1710b5da9499SMatthew G. Knepley       orntNew[0] = 0;
1711b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
1712b5da9499SMatthew G. Knepley       orntNew[1] = 0;
1713b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
1714b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1715b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1716b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1717b5da9499SMatthew G. Knepley #if 1
1718b5da9499SMatthew 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);
1719b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1720b5da9499SMatthew 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);
1721b5da9499SMatthew G. Knepley       }
1722b5da9499SMatthew G. Knepley #endif
1723b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
1724b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1725b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
1726b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
1727219f7b90SMatthew G. Knepley           PetscInt subf;
1728b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
1729b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1730b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1731b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
1732b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
1733b5da9499SMatthew G. Knepley           }
1734219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
1735219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
1736b5da9499SMatthew G. Knepley         }
1737b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
1738b5da9499SMatthew G. Knepley #if 1
17399ddff745SMatthew G. Knepley         if ((newp+r < fStartNew) || (newp+r >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fEndNew);
1740b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
1741b5da9499SMatthew 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);
1742b5da9499SMatthew G. Knepley         }
1743b5da9499SMatthew G. Knepley #endif
1744b5da9499SMatthew G. Knepley       }
1745b5da9499SMatthew G. Knepley     }
1746b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
1747b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
1748b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
1749b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
1750b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
1751b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
1752b5da9499SMatthew G. Knepley 
1753b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1754b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1755b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
17564bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
1757b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
17584bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
1759b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
17604bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
1761b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
1762b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1763b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1764b5da9499SMatthew G. Knepley #if 1
1765b5da9499SMatthew 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);
1766b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1767b5da9499SMatthew 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);
1768b5da9499SMatthew G. Knepley       }
1769b5da9499SMatthew G. Knepley #endif
1770b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
1771b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
1772b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1773b5da9499SMatthew G. Knepley #if 1
1774b5da9499SMatthew 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);
1775b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1776b5da9499SMatthew 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);
1777b5da9499SMatthew G. Knepley       }
1778b5da9499SMatthew G. Knepley #endif
1779b5da9499SMatthew G. Knepley       ++newp;
1780b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
17814bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
1782b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
17834bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
1784b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
17854bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
1786b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
1787b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1788b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1789b5da9499SMatthew G. Knepley #if 1
17904bb260e2SMatthew 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);
1791b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1792b5da9499SMatthew 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);
1793b5da9499SMatthew G. Knepley       }
1794b5da9499SMatthew G. Knepley #endif
1795b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
1796b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
1797b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1798b5da9499SMatthew G. Knepley #if 1
1799b5da9499SMatthew 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);
1800b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1801b5da9499SMatthew 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);
1802b5da9499SMatthew G. Knepley       }
1803b5da9499SMatthew G. Knepley #endif
1804b5da9499SMatthew G. Knepley       ++newp;
1805b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
18064bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
1807b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
18084bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
1809b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
18104bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
1811b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
1812b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1813b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1814b5da9499SMatthew G. Knepley #if 1
1815b5da9499SMatthew 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);
1816b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1817b5da9499SMatthew 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);
1818b5da9499SMatthew G. Knepley       }
1819b5da9499SMatthew G. Knepley #endif
1820b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
1821b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
1822b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1823b5da9499SMatthew G. Knepley #if 1
1824b5da9499SMatthew 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);
1825b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1826b5da9499SMatthew 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);
1827b5da9499SMatthew G. Knepley       }
1828b5da9499SMatthew G. Knepley #endif
1829b5da9499SMatthew G. Knepley       ++newp;
1830b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
18314bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
1832b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
18334bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
1834b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
18354bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
1836b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
1837b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1838b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1839b5da9499SMatthew G. Knepley #if 1
1840b5da9499SMatthew 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);
1841b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1842b5da9499SMatthew 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);
1843b5da9499SMatthew G. Knepley       }
1844b5da9499SMatthew G. Knepley #endif
1845b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
1846b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
1847b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1848b5da9499SMatthew G. Knepley #if 1
1849b5da9499SMatthew 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);
1850b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1851b5da9499SMatthew 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);
1852b5da9499SMatthew G. Knepley       }
1853b5da9499SMatthew G. Knepley #endif
1854b5da9499SMatthew G. Knepley       ++newp;
1855b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
18564bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
1857b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
1858b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
18594bb260e2SMatthew G. Knepley       orntNew[1] = -2;
18604bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
1861b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
1862b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1863b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1864b5da9499SMatthew G. Knepley #if 1
1865b5da9499SMatthew 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);
1866b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1867b5da9499SMatthew 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);
1868b5da9499SMatthew G. Knepley       }
1869b5da9499SMatthew G. Knepley #endif
1870b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
1871b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
1872b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1873b5da9499SMatthew G. Knepley #if 1
1874b5da9499SMatthew 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);
1875b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1876b5da9499SMatthew 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);
1877b5da9499SMatthew G. Knepley       }
1878b5da9499SMatthew G. Knepley #endif
1879b5da9499SMatthew G. Knepley       ++newp;
1880b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
18814bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
1882b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
1883b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
18844bb260e2SMatthew G. Knepley       orntNew[1] = 0;
18854bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
18862baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
1887b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1888b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1889b5da9499SMatthew G. Knepley #if 1
1890b5da9499SMatthew 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);
1891b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1892b5da9499SMatthew 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);
1893b5da9499SMatthew G. Knepley       }
1894b5da9499SMatthew G. Knepley #endif
1895b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
1896b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
1897b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1898b5da9499SMatthew G. Knepley #if 1
1899b5da9499SMatthew 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);
1900b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1901b5da9499SMatthew 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);
1902b5da9499SMatthew G. Knepley       }
1903b5da9499SMatthew G. Knepley #endif
1904b5da9499SMatthew G. Knepley       ++newp;
1905b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
19064bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
1907b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
1908b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
1909fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
19104bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
1911b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
1912b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1913b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1914b5da9499SMatthew G. Knepley #if 1
1915b5da9499SMatthew 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);
1916b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1917b5da9499SMatthew 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);
1918b5da9499SMatthew G. Knepley       }
1919b5da9499SMatthew G. Knepley #endif
1920b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
1921b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
1922b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1923b5da9499SMatthew G. Knepley #if 1
1924b5da9499SMatthew 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);
1925b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1926b5da9499SMatthew 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);
1927b5da9499SMatthew G. Knepley       }
1928b5da9499SMatthew G. Knepley #endif
1929b5da9499SMatthew G. Knepley       ++newp;
1930b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
19314bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
1932b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
19334bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
1934b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
1935b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
19364bb260e2SMatthew G. Knepley       orntNew[2] = -2;
1937b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1938b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1939b5da9499SMatthew G. Knepley #if 1
1940b5da9499SMatthew 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);
1941b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1942b5da9499SMatthew 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);
1943b5da9499SMatthew G. Knepley       }
1944b5da9499SMatthew G. Knepley #endif
1945b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
1946b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
1947b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1948b5da9499SMatthew G. Knepley #if 1
1949b5da9499SMatthew 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);
1950b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1951b5da9499SMatthew 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);
1952b5da9499SMatthew G. Knepley       }
1953b5da9499SMatthew G. Knepley #endif
1954b5da9499SMatthew G. Knepley       ++newp;
1955b5da9499SMatthew G. Knepley     }
1956b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
1957b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
1958b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
1959b5da9499SMatthew G. Knepley 
1960b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
1961b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
1962b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
1963b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
1964b5da9499SMatthew G. Knepley 
1965b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
1966b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
1967b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
1968b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
1969b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1970b5da9499SMatthew G. Knepley #if 1
1971b5da9499SMatthew 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);
1972b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
1973b5da9499SMatthew 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);
1974b5da9499SMatthew G. Knepley         }
1975b5da9499SMatthew G. Knepley #endif
1976b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
1977b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
1978b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
1979b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
1980b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1981b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1982b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
1983b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
1984b5da9499SMatthew G. Knepley           }
1985b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
1986b5da9499SMatthew G. Knepley         }
1987b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1988b5da9499SMatthew G. Knepley #if 1
1989b5da9499SMatthew 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);
1990b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
1991b5da9499SMatthew 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);
1992b5da9499SMatthew G. Knepley         }
1993b5da9499SMatthew G. Knepley #endif
1994b5da9499SMatthew G. Knepley       }
1995b5da9499SMatthew G. Knepley     }
199686f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
1997b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
1998b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
1999b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
2000b5da9499SMatthew G. Knepley 
2001b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2002b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2003b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
2004b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
2005b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
2006b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
2007b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
2008b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
2009b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
2010b5da9499SMatthew G. Knepley 
2011b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2012b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
2013b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
2014b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);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 < 2; ++p) {
2018b5da9499SMatthew 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);
2019b5da9499SMatthew G. Knepley         }
2020b5da9499SMatthew G. Knepley #endif
2021b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
2022b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
2023b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2024b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2025b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2026b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2027b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
202886f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
20299ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
2030b5da9499SMatthew G. Knepley           if (er == eint[c]) {
2031b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
2032b5da9499SMatthew G. Knepley           } else {
2033b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
2034b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
2035b5da9499SMatthew G. Knepley           }
2036b5da9499SMatthew G. Knepley         }
2037b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);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 < intFaces; ++p) {
2041b5da9499SMatthew 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);
2042b5da9499SMatthew G. Knepley         }
2043b5da9499SMatthew G. Knepley #endif
2044b5da9499SMatthew G. Knepley       }
2045b5da9499SMatthew G. Knepley     }
2046b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
2047b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2048b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2049b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
20504a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
2051b5da9499SMatthew G. Knepley 
2052b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2053b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2054b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
205542525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
2056b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2057b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
205842525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
2059b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2060b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2061b5da9499SMatthew G. Knepley #if 1
2062b5da9499SMatthew 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);
2063b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2064b5da9499SMatthew 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);
2065b5da9499SMatthew G. Knepley       }
2066b5da9499SMatthew G. Knepley #endif
2067b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
2068b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
2069b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
2070b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
2071b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2072b5da9499SMatthew G. Knepley #if 1
2073b5da9499SMatthew 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);
2074b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2075b5da9499SMatthew 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);
2076b5da9499SMatthew G. Knepley       }
2077b5da9499SMatthew G. Knepley #endif
2078b5da9499SMatthew G. Knepley     }
2079b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
2080b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2081b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2082b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
2083b5da9499SMatthew G. Knepley       PetscInt        size, s;
2084b5da9499SMatthew G. Knepley 
2085b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2086b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2087b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2088b5da9499SMatthew G. Knepley         PetscInt r = 0;
2089b5da9499SMatthew G. Knepley 
2090b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2091b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
2092b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
2093b5da9499SMatthew G. Knepley       }
2094b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2095b5da9499SMatthew G. Knepley #if 1
2096b5da9499SMatthew 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);
2097b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2098b5da9499SMatthew 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);
2099b5da9499SMatthew G. Knepley       }
2100b5da9499SMatthew G. Knepley #endif
2101b5da9499SMatthew G. Knepley     }
2102b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
2103b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2104b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
2105b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
2106b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
2107b5da9499SMatthew G. Knepley 
2108b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
2109b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2110b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
2111b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
2112b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2113b5da9499SMatthew G. Knepley         PetscInt r = 0;
2114b5da9499SMatthew G. Knepley 
2115b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2116b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2117b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
2118b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
2119b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
2120b5da9499SMatthew G. Knepley       }
2121b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2122b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
2123b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
2124b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
2125b5da9499SMatthew G. Knepley 
2126b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
2127b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
2128b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2129b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
2130b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
213142525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
2132b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
2133b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2134b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
213542525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
213642525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
2137b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
2138b5da9499SMatthew G. Knepley         }
2139b5da9499SMatthew G. Knepley       }
2140b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2141b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2142b5da9499SMatthew G. Knepley #if 1
2143b5da9499SMatthew 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);
2144b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
2145b5da9499SMatthew 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);
2146b5da9499SMatthew G. Knepley       }
2147b5da9499SMatthew G. Knepley #endif
2148b5da9499SMatthew G. Knepley     }
2149b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2150b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
2151b5da9499SMatthew G. Knepley     break;
21526ce3c06aSMatthew G. Knepley   case 7:
21536ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
21546ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
21556ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
21566ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
21576ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
21586ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
21596ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
21606ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
21616ce3c06aSMatthew G. Knepley 
21626ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
21636ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
21646ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
21656ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
21666ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
21676ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
21686ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
21696ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
21706ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
21716ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
21726ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
21736ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
21746ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
21756ce3c06aSMatthew G. Knepley #if 1
21766ce3c06aSMatthew 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);
21776ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
21786ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
21796ce3c06aSMatthew G. Knepley       }
21806ce3c06aSMatthew G. Knepley #endif
21816ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
21826ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
21836ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
21846ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
21856ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
21866ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
21876ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
21886ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
21896ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
21906ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
21916ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
21926ce3c06aSMatthew G. Knepley #if 1
21936ce3c06aSMatthew 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);
21946ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
21956ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
21966ce3c06aSMatthew G. Knepley       }
21976ce3c06aSMatthew G. Knepley #endif
21986ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
21996ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
22006ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
22016ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
22026ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
22036ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
22046ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
22056ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
22066ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
22076ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
22086ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
22096ce3c06aSMatthew G. Knepley #if 1
22106ce3c06aSMatthew 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);
22116ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
22126ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
22136ce3c06aSMatthew G. Knepley       }
22146ce3c06aSMatthew G. Knepley #endif
22156ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
22166ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
22176ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
22186ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
22196ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
22206ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
22216ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
22226ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
22236ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
22246ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
22256ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
22266ce3c06aSMatthew G. Knepley #if 1
22276ce3c06aSMatthew 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);
22286ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
22296ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
22306ce3c06aSMatthew G. Knepley       }
22316ce3c06aSMatthew G. Knepley #endif
22326ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
22336ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
22346ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
22359ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
22369ddff745SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
22379ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
22389ddff745SMatthew G. Knepley       orntNew[2] = 0;
22399ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
22409ddff745SMatthew G. Knepley       orntNew[3] = 2;
22416ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
22426ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
22436ce3c06aSMatthew G. Knepley #if 1
22446ce3c06aSMatthew 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);
22456ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
22466ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
22476ce3c06aSMatthew G. Knepley       }
22486ce3c06aSMatthew G. Knepley #endif
22496ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
22506ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
22516ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
22529ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
22539ddff745SMatthew G. Knepley       orntNew[1] = 1;
22549ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
22556ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
22569ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
22579ddff745SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
22586ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
22596ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
22606ce3c06aSMatthew G. Knepley #if 1
22616ce3c06aSMatthew 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);
22626ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
22636ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
22646ce3c06aSMatthew G. Knepley       }
22656ce3c06aSMatthew G. Knepley #endif
22666ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
22676ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
22686ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
22699ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
22709ddff745SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
22719ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
22729ddff745SMatthew G. Knepley       orntNew[2] = -3;
22739ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
22749ddff745SMatthew G. Knepley       orntNew[3] = -2;
22756ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
22766ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
22776ce3c06aSMatthew G. Knepley #if 1
22786ce3c06aSMatthew 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);
22796ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
22806ce3c06aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
22816ce3c06aSMatthew G. Knepley       }
22826ce3c06aSMatthew G. Knepley #endif
22836ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
22846ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
22856ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
22869ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
22876ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
22889ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
22899ddff745SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
22909ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
22919ddff745SMatthew G. Knepley       orntNew[3] = -3;
22926ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
22936ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
22946ce3c06aSMatthew G. Knepley #if 1
22956ce3c06aSMatthew 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);
22966ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
22976ce3c06aSMatthew 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);
22986ce3c06aSMatthew G. Knepley       }
22996ce3c06aSMatthew G. Knepley #endif
23006ce3c06aSMatthew G. Knepley     }
23016ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
23026ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
23036ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
2304d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
23056ce3c06aSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5];
23066ce3c06aSMatthew G. Knepley 
23076ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
23086ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2309d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
23106ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
23116ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
23126ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
23136ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
23146ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
2315d3a1cc75SMatthew G. Knepley         coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? 0 : 1);
23166ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
2317d3a1cc75SMatthew G. Knepley         coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)]       - fMax)*2 + (fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? 1 : 0);
23186ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
23196ce3c06aSMatthew G. Knepley         coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
23206ce3c06aSMatthew G. Knepley         orntNew[4] = 0;
23216ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
23226ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
23236ce3c06aSMatthew G. Knepley #if 1
23246ce3c06aSMatthew 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);
23256ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
23266ce3c06aSMatthew 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);
23276ce3c06aSMatthew G. Knepley         }
23286ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
23296ce3c06aSMatthew 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);
23306ce3c06aSMatthew G. Knepley         }
23316ce3c06aSMatthew G. Knepley #endif
23326ce3c06aSMatthew G. Knepley       }
23336ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
23346ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
23356ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
23366ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
23376ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
23386ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
23396ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
23406ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
23416ce3c06aSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
23426ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
23436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
23446ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
23456ce3c06aSMatthew G. Knepley #if 1
23466ce3c06aSMatthew 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);
23476ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
23486ce3c06aSMatthew 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);
23496ce3c06aSMatthew G. Knepley       }
23506ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
23516ce3c06aSMatthew 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);
23526ce3c06aSMatthew G. Knepley       }
23536ce3c06aSMatthew G. Knepley #endif
23546ce3c06aSMatthew G. Knepley     }
23556ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
23566ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2357785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
23586ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
23596ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
23606ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
23616ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
23626ce3c06aSMatthew G. Knepley 
23636ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
23646ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
23656ce3c06aSMatthew G. Knepley       /* A triangle */
23666ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
23676ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
23686ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
23696ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
23706ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
23716ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
23726ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
23736ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
23746ce3c06aSMatthew G. Knepley #if 1
23756ce3c06aSMatthew 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);
23766ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
23776ce3c06aSMatthew 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);
23786ce3c06aSMatthew G. Knepley       }
23796ce3c06aSMatthew G. Knepley #endif
23806ce3c06aSMatthew G. Knepley       /* B triangle */
23816ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
23826ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
23836ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
23846ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
23856ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
23866ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
23876ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
23886ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
23896ce3c06aSMatthew G. Knepley #if 1
23906ce3c06aSMatthew 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);
23916ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
23926ce3c06aSMatthew 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);
23936ce3c06aSMatthew G. Knepley       }
23946ce3c06aSMatthew G. Knepley #endif
23956ce3c06aSMatthew G. Knepley       /* C triangle */
23966ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
23976ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
23986ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
23996ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
24006ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
24016ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
24026ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
24036ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
24046ce3c06aSMatthew G. Knepley #if 1
24056ce3c06aSMatthew 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);
24066ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
24076ce3c06aSMatthew 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);
24086ce3c06aSMatthew G. Knepley       }
24096ce3c06aSMatthew G. Knepley #endif
24106ce3c06aSMatthew G. Knepley       /* D triangle */
24116ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
24126ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
24136ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
24146ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
24156ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
24166ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
24176ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
24186ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
24196ce3c06aSMatthew G. Knepley #if 1
24206ce3c06aSMatthew 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);
24216ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
24226ce3c06aSMatthew 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);
24236ce3c06aSMatthew G. Knepley       }
24246ce3c06aSMatthew G. Knepley #endif
24256ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
24266ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
24276ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
24286ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
24299ddff745SMatthew G. Knepley           PetscInt subf;
24306ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
24316ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
24326ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
24336ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
24346ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
24356ce3c06aSMatthew G. Knepley           }
24369ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
24376ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
24389ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
24396ce3c06aSMatthew G. Knepley           } else {
24409ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
24416ce3c06aSMatthew G. Knepley           }
24426ce3c06aSMatthew G. Knepley         }
24436ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
24446ce3c06aSMatthew G. Knepley #if 1
24459ddff745SMatthew G. Knepley         if ((newp+r < fStartNew) || (newp+r >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fMaxNew);
24466ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
24476ce3c06aSMatthew 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);
24486ce3c06aSMatthew G. Knepley         }
24496ce3c06aSMatthew G. Knepley #endif
24506ce3c06aSMatthew G. Knepley       }
24516ce3c06aSMatthew G. Knepley     }
24526ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
24536ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
24546ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
24556ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
24566ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
24576ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
24586ce3c06aSMatthew G. Knepley 
24596ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
24606ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
24616ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
24629ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
24636ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
24649ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
24656ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
24669ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
24676ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
24686ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
24696ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
24706ce3c06aSMatthew G. Knepley #if 1
24716ce3c06aSMatthew 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);
24726ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
24736ce3c06aSMatthew 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);
24746ce3c06aSMatthew G. Knepley       }
24756ce3c06aSMatthew G. Knepley #endif
24766ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
24776ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
24786ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
24796ce3c06aSMatthew G. Knepley #if 1
24806ce3c06aSMatthew 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);
24816ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
24826ce3c06aSMatthew 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);
24836ce3c06aSMatthew G. Knepley       }
24846ce3c06aSMatthew G. Knepley #endif
24856ce3c06aSMatthew G. Knepley       ++newp;
24866ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
24879ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
24886ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
24899ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
24906ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
24919ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
24926ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
24936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
24946ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
24956ce3c06aSMatthew G. Knepley #if 1
24966ce3c06aSMatthew 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);
24976ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
24986ce3c06aSMatthew 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);
24996ce3c06aSMatthew G. Knepley       }
25006ce3c06aSMatthew G. Knepley #endif
25016ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
25026ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
25036ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
25046ce3c06aSMatthew G. Knepley #if 1
25056ce3c06aSMatthew 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);
25066ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
25076ce3c06aSMatthew 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);
25086ce3c06aSMatthew G. Knepley       }
25096ce3c06aSMatthew G. Knepley #endif
25106ce3c06aSMatthew G. Knepley       ++newp;
25116ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
25129ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
25136ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
25149ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
25156ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
25169ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
25176ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
25186ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
25196ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
25206ce3c06aSMatthew G. Knepley #if 1
25216ce3c06aSMatthew 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);
25226ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25236ce3c06aSMatthew 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);
25246ce3c06aSMatthew G. Knepley       }
25256ce3c06aSMatthew G. Knepley #endif
25266ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
25276ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
25286ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
25296ce3c06aSMatthew G. Knepley #if 1
25306ce3c06aSMatthew 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);
25316ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
25326ce3c06aSMatthew 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);
25336ce3c06aSMatthew G. Knepley       }
25346ce3c06aSMatthew G. Knepley #endif
25356ce3c06aSMatthew G. Knepley       ++newp;
25366ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
25379ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
25386ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
25399ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
25406ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
25419ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
25426ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
25436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
25446ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
25456ce3c06aSMatthew G. Knepley #if 1
25466ce3c06aSMatthew 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);
25476ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25486ce3c06aSMatthew 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);
25496ce3c06aSMatthew G. Knepley       }
25506ce3c06aSMatthew G. Knepley #endif
25516ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
25526ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
25536ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
25546ce3c06aSMatthew G. Knepley #if 1
25556ce3c06aSMatthew 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);
25566ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
25576ce3c06aSMatthew 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);
25586ce3c06aSMatthew G. Knepley       }
25596ce3c06aSMatthew G. Knepley #endif
25606ce3c06aSMatthew G. Knepley       ++newp;
25616ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
25629ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
25636ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
25646ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
25659ddff745SMatthew G. Knepley       orntNew[1] = -2;
25669ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
25676ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
25686ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
25696ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
25706ce3c06aSMatthew G. Knepley #if 1
25716ce3c06aSMatthew 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);
25726ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25736ce3c06aSMatthew 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);
25746ce3c06aSMatthew G. Knepley       }
25756ce3c06aSMatthew G. Knepley #endif
25766ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
25776ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
25786ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
25796ce3c06aSMatthew G. Knepley #if 1
25806ce3c06aSMatthew 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);
25816ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
25826ce3c06aSMatthew 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);
25836ce3c06aSMatthew G. Knepley       }
25846ce3c06aSMatthew G. Knepley #endif
25856ce3c06aSMatthew G. Knepley       ++newp;
25866ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
25879ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
25886ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
25896ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
25909ddff745SMatthew G. Knepley       orntNew[1] = 0;
25919ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
25929ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
25936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
25946ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
25956ce3c06aSMatthew G. Knepley #if 1
25966ce3c06aSMatthew 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);
25976ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25986ce3c06aSMatthew 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);
25996ce3c06aSMatthew G. Knepley       }
26006ce3c06aSMatthew G. Knepley #endif
26016ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
26026ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
26036ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
26046ce3c06aSMatthew G. Knepley #if 1
26056ce3c06aSMatthew 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);
26066ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
26076ce3c06aSMatthew 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);
26086ce3c06aSMatthew G. Knepley       }
26096ce3c06aSMatthew G. Knepley #endif
26106ce3c06aSMatthew G. Knepley       ++newp;
26116ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
26129ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
26136ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
26146ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
26159ddff745SMatthew G. Knepley       orntNew[1] = 0;
26169ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
26176ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
26186ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
26196ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
26206ce3c06aSMatthew G. Knepley #if 1
26216ce3c06aSMatthew 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);
26226ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26236ce3c06aSMatthew 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);
26246ce3c06aSMatthew G. Knepley       }
26256ce3c06aSMatthew G. Knepley #endif
26266ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
26276ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
26286ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
26296ce3c06aSMatthew G. Knepley #if 1
26306ce3c06aSMatthew 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);
26316ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
26326ce3c06aSMatthew 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);
26336ce3c06aSMatthew G. Knepley       }
26346ce3c06aSMatthew G. Knepley #endif
26356ce3c06aSMatthew G. Knepley       ++newp;
26366ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
26379ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
26386ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
26399ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
26406ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
26416ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
26429ddff745SMatthew G. Knepley       orntNew[2] = -2;
26436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
26446ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
26456ce3c06aSMatthew G. Knepley #if 1
26466ce3c06aSMatthew 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);
26476ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26486ce3c06aSMatthew 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);
26496ce3c06aSMatthew G. Knepley       }
26506ce3c06aSMatthew G. Knepley #endif
26516ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
26526ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
26536ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
26546ce3c06aSMatthew G. Knepley #if 1
26556ce3c06aSMatthew 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);
26566ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
26576ce3c06aSMatthew 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);
26586ce3c06aSMatthew G. Knepley       }
26596ce3c06aSMatthew G. Knepley #endif
26606ce3c06aSMatthew G. Knepley       ++newp;
26616ce3c06aSMatthew G. Knepley     }
26626ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
26636ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
26646ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
26656ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
26666ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
26676ce3c06aSMatthew G. Knepley 
26686ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
26696ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
26706ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
26716ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
26726ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
26736ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
26746ce3c06aSMatthew G. Knepley 
26756ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
26766ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
26776ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
26786ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
26796ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
26806ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
26816ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
26826ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
26836ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
26846ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
26856ce3c06aSMatthew G. Knepley #if 1
26866ce3c06aSMatthew 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);
26876ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
26886ce3c06aSMatthew 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);
26896ce3c06aSMatthew G. Knepley         }
26906ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
26916ce3c06aSMatthew 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);
26926ce3c06aSMatthew G. Knepley         }
26936ce3c06aSMatthew G. Knepley #endif
26946ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
2695d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
26966ce3c06aSMatthew G. Knepley 
26976ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
26986ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
26996ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
27006ce3c06aSMatthew 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]);
2701d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
2702d3a1cc75SMatthew G. Knepley           supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%3;
27036ce3c06aSMatthew G. Knepley         }
27046ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
27056ce3c06aSMatthew G. Knepley #if 1
27066ce3c06aSMatthew 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);
27076ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
27086ce3c06aSMatthew 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);
27096ce3c06aSMatthew G. Knepley         }
27106ce3c06aSMatthew G. Knepley #endif
27116ce3c06aSMatthew G. Knepley       }
27126ce3c06aSMatthew G. Knepley     }
27136ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
27146ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
27156ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
27166ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
27176ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
27186ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
27196ce3c06aSMatthew G. Knepley 
27206ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
27216ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
27226ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
27236ce3c06aSMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], (r+2)%3);
27246ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
27256ce3c06aSMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], (r+2)%3);
27266ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
27276ce3c06aSMatthew 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);
27286ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
27296ce3c06aSMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], r)]       - fMax);
27306ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
27316ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
27326ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
27336ce3c06aSMatthew G. Knepley #if 1
27346ce3c06aSMatthew 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);
27356ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
27366ce3c06aSMatthew 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);
27376ce3c06aSMatthew G. Knepley         }
27386ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
27396ce3c06aSMatthew 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);
27406ce3c06aSMatthew G. Knepley         }
27416ce3c06aSMatthew G. Knepley #endif
27426ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
27436ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
27446ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
27456ce3c06aSMatthew G. Knepley #if 1
27466ce3c06aSMatthew 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);
27476ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
27486ce3c06aSMatthew 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);
27496ce3c06aSMatthew G. Knepley         }
27506ce3c06aSMatthew G. Knepley #endif
27516ce3c06aSMatthew G. Knepley       }
27526ce3c06aSMatthew G. Knepley     }
27536ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
27546ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
27556ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
27566ce3c06aSMatthew G. Knepley 
27576ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
27586ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
27596ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
27606ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
27616ce3c06aSMatthew G. Knepley 
27626ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
27636ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
27646ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
27656ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
27666ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27676ce3c06aSMatthew G. Knepley #if 1
27686ce3c06aSMatthew 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);
27696ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
27706ce3c06aSMatthew 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);
27716ce3c06aSMatthew G. Knepley         }
27726ce3c06aSMatthew G. Knepley #endif
27736ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
27746ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
27756ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
27766ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
27776ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
27786ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
27796ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
27806ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
27816ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
27826ce3c06aSMatthew G. Knepley           } else {
27836ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
27846ce3c06aSMatthew G. Knepley           }
27856ce3c06aSMatthew G. Knepley         }
27866ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);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 < supportSize; ++p) {
27906ce3c06aSMatthew 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);
27916ce3c06aSMatthew G. Knepley         }
27926ce3c06aSMatthew G. Knepley #endif
27936ce3c06aSMatthew G. Knepley       }
27946ce3c06aSMatthew G. Knepley     }
27956ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
27966ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
27976ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
27986ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
27996ce3c06aSMatthew G. Knepley 
28006ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
28016ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
28026ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
28036ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
28046ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
28056ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
28066ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
28076ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
28086ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
28096ce3c06aSMatthew G. Knepley 
28106ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
28116ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
28126ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
28136ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);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 < 2; ++p) {
28176ce3c06aSMatthew 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);
28186ce3c06aSMatthew G. Knepley         }
28196ce3c06aSMatthew G. Knepley #endif
28206ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
28216ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
28226ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
28236ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
28246ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
28256ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
28266ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
28276ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
28286ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
28299ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
28306ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
28316ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
28326ce3c06aSMatthew G. Knepley             } else {
28336ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
28346ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
28356ce3c06aSMatthew G. Knepley             }
28366ce3c06aSMatthew G. Knepley           } else {
2837e515e2ddSMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(ornt[c], r) + 1)%3;
28386ce3c06aSMatthew G. Knepley           }
28396ce3c06aSMatthew G. Knepley         }
28406ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
28416ce3c06aSMatthew G. Knepley #if 1
28426ce3c06aSMatthew 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);
28436ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
28446ce3c06aSMatthew 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);
28456ce3c06aSMatthew G. Knepley         }
28466ce3c06aSMatthew G. Knepley #endif
28476ce3c06aSMatthew G. Knepley       }
28486ce3c06aSMatthew G. Knepley     }
28496ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
28506ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
28516ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
28526ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
28536ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
28546ce3c06aSMatthew G. Knepley 
28556ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
28566ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
28576ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
28586ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
28596ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
28606ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
28616ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
28626ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
28636ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
28646ce3c06aSMatthew G. Knepley #if 1
28656ce3c06aSMatthew 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);
28666ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
28676ce3c06aSMatthew 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);
28686ce3c06aSMatthew G. Knepley       }
28696ce3c06aSMatthew G. Knepley #endif
28706ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
28716ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
28726ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
28736ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
28746ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
28756ce3c06aSMatthew G. Knepley #if 1
28766ce3c06aSMatthew 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);
28776ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
28786ce3c06aSMatthew 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);
28796ce3c06aSMatthew G. Knepley       }
28806ce3c06aSMatthew G. Knepley #endif
28816ce3c06aSMatthew G. Knepley     }
28826ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
28836ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
28846ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
28856ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
28866ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
28876ce3c06aSMatthew G. Knepley 
28886ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
28896ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
28906ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
28916ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
28926ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
28936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
28946ce3c06aSMatthew G. Knepley #if 1
28956ce3c06aSMatthew 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);
28966ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
28976ce3c06aSMatthew 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);
28986ce3c06aSMatthew G. Knepley       }
28996ce3c06aSMatthew G. Knepley #endif
29006ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
29016ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
29026ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
29036ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
29046ce3c06aSMatthew 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]);
29056ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
29066ce3c06aSMatthew G. Knepley       }
29076ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
29086ce3c06aSMatthew G. Knepley #if 1
29096ce3c06aSMatthew 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);
29106ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
29116ce3c06aSMatthew 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);
29126ce3c06aSMatthew G. Knepley       }
29136ce3c06aSMatthew G. Knepley #endif
29146ce3c06aSMatthew G. Knepley     }
29156ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
29166ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
29176ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
2918623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
29196ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
29206ce3c06aSMatthew G. Knepley 
29216ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
29226ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
29236ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
29246ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
29256ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
29266ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
29276ce3c06aSMatthew G. Knepley #if 1
29286ce3c06aSMatthew 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);
29296ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
29306ce3c06aSMatthew 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);
29316ce3c06aSMatthew G. Knepley       }
29326ce3c06aSMatthew G. Knepley #endif
29336ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
29346ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
29356ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
29366ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
29376ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
2938623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
29396ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
29406ce3c06aSMatthew 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]);
2941623f4348SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + GetTriSubfaceInverse_Static(cornt[0], c-2);
2942623f4348SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(cornt[0], c-2) + 1)%3;
29436ce3c06aSMatthew G. Knepley       }
29446ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
29456ce3c06aSMatthew G. Knepley #if 1
29466ce3c06aSMatthew 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);
29476ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
29486ce3c06aSMatthew 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);
29496ce3c06aSMatthew G. Knepley       }
29506ce3c06aSMatthew G. Knepley #endif
29516ce3c06aSMatthew G. Knepley     }
29526ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
29536ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
29546ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
29556ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
29566ce3c06aSMatthew G. Knepley       PetscInt        size, s;
29576ce3c06aSMatthew G. Knepley 
29586ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
29596ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
29606ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
29616ce3c06aSMatthew G. Knepley         PetscInt r = 0;
29626ce3c06aSMatthew G. Knepley 
29636ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
29646ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
29656ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
29666ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
29676ce3c06aSMatthew G. Knepley       }
29686ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
29696ce3c06aSMatthew G. Knepley #if 1
29706ce3c06aSMatthew 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);
29716ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
29726ce3c06aSMatthew 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);
29736ce3c06aSMatthew G. Knepley       }
29746ce3c06aSMatthew G. Knepley #endif
29756ce3c06aSMatthew G. Knepley     }
29766ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
29776ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
29786ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
29796ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
29806ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
29816ce3c06aSMatthew G. Knepley 
29826ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
29836ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
29846ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
29856ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
29866ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
29876ce3c06aSMatthew G. Knepley         PetscInt r = 0;
29886ce3c06aSMatthew G. Knepley 
29896ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
29906ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
29916ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
29926ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
29936ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
29946ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
29956ce3c06aSMatthew G. Knepley           faceSize += 2;
29966ce3c06aSMatthew G. Knepley         } else {
29976ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
29986ce3c06aSMatthew G. Knepley           ++faceSize;
29996ce3c06aSMatthew G. Knepley         }
30006ce3c06aSMatthew G. Knepley       }
30016ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
30026ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
30036ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
30046ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
30056ce3c06aSMatthew G. Knepley 
30066ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
30076ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
30086ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
30096ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
30106ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
30116ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
30126ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
30136ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
30146ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
30156ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
30166ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
30176ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
30186ce3c06aSMatthew G. Knepley         }
30196ce3c06aSMatthew G. Knepley       }
30206ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
30216ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
30226ce3c06aSMatthew G. Knepley #if 1
30236ce3c06aSMatthew 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);
30246ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
30256ce3c06aSMatthew 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);
30266ce3c06aSMatthew G. Knepley       }
30276ce3c06aSMatthew G. Knepley #endif
30286ce3c06aSMatthew G. Knepley     }
30296ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
30306ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
30316ce3c06aSMatthew G. Knepley     break;
30322eabf88fSMatthew G. Knepley   case 6:
30332eabf88fSMatthew G. Knepley     /* Hex 3D */
30342eabf88fSMatthew G. Knepley     /*
30352eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
30362eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
30372eabf88fSMatthew G. Knepley      |         |         |       |         |         |
30382eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
30392eabf88fSMatthew G. Knepley      |         |         |       |         |         |
30402eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
30412eabf88fSMatthew G. Knepley      |         |         |       |         |         |
30422eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
30432eabf88fSMatthew G. Knepley      |         |         |       |         |         |
30442eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
30452eabf88fSMatthew G. Knepley      */
30462eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
30472eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
30482eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
30492eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
30502eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
30512eabf88fSMatthew G. Knepley 
30522eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
30532eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
30542eabf88fSMatthew G. Knepley       /* A hex */
3055e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
30562eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
30572eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
30582eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3059e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
30602eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
30612eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
30622eabf88fSMatthew G. Knepley       orntNew[3] = 0;
30632eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
30642eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3065e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
30662eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
30672eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
30682eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
30692eabf88fSMatthew G. Knepley #if 1
30702eabf88fSMatthew 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);
30712eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
30722eabf88fSMatthew 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);
30732eabf88fSMatthew G. Knepley       }
30742eabf88fSMatthew G. Knepley #endif
30752eabf88fSMatthew G. Knepley       /* B hex */
3076e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
30772eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
30782eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
30792eabf88fSMatthew G. Knepley       orntNew[1] = 0;
30802eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
3081a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3082e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
30832eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
30842eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
30852eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3086e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
30872eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
30882eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
30892eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
30902eabf88fSMatthew G. Knepley #if 1
30912eabf88fSMatthew 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);
30922eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
30932eabf88fSMatthew 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);
30942eabf88fSMatthew G. Knepley       }
30952eabf88fSMatthew G. Knepley #endif
30962eabf88fSMatthew G. Knepley       /* C hex */
3097e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
30982eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
30992eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
31002eabf88fSMatthew G. Knepley       orntNew[1] = 0;
31012eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3102a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3103e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
31042eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3105e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
31062eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
31072eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
3108a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
31092eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
31102eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
31112eabf88fSMatthew G. Knepley #if 1
31122eabf88fSMatthew 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);
31132eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31142eabf88fSMatthew 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);
31152eabf88fSMatthew G. Knepley       }
31162eabf88fSMatthew G. Knepley #endif
31172eabf88fSMatthew G. Knepley       /* D hex */
3118e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
31192eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
31202eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
31212eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3122e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
31232eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
31242eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3125a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3126e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
31272eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
31282eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
3129a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
31302eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
31312eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
31322eabf88fSMatthew G. Knepley #if 1
31332eabf88fSMatthew 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);
31342eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31352eabf88fSMatthew 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);
31362eabf88fSMatthew G. Knepley       }
31372eabf88fSMatthew G. Knepley #endif
31382eabf88fSMatthew G. Knepley       /* E hex */
31392eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
3140a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3141e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
31422eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3143e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
31442eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
31452eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
31462eabf88fSMatthew G. Knepley       orntNew[3] = 0;
31472eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3148a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
3149e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
31502eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3151b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
3152b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
31532eabf88fSMatthew G. Knepley #if 1
3154b164cbf2SMatthew 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);
31552eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31562eabf88fSMatthew 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);
31572eabf88fSMatthew G. Knepley       }
31582eabf88fSMatthew G. Knepley #endif
31592eabf88fSMatthew G. Knepley       /* F hex */
31602eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
3161a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3162e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
31632eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3164e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
31652eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
31662eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3167a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
3168e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
31692eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
31702eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3171a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
3172b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
3173b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
31742eabf88fSMatthew G. Knepley #if 1
3175b164cbf2SMatthew 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);
31762eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31772eabf88fSMatthew 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);
31782eabf88fSMatthew G. Knepley       }
31792eabf88fSMatthew G. Knepley #endif
31802eabf88fSMatthew G. Knepley       /* G hex */
31812eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
3182a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3183e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
31842eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
31852eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3186a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
3187e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
31882eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3189e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
31902eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
31912eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3192a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
3193b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
3194b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
31952eabf88fSMatthew G. Knepley #if 1
3196b164cbf2SMatthew 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);
31972eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
31982eabf88fSMatthew 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);
31992eabf88fSMatthew G. Knepley       }
32002eabf88fSMatthew G. Knepley #endif
32012eabf88fSMatthew G. Knepley       /* H hex */
32022eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
3203a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3204e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
32052eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
32062eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
3207a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3208e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
32092eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
32102eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3211a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
3212e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
32132eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3214b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
3215b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
32162eabf88fSMatthew G. Knepley #if 1
3217b164cbf2SMatthew 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);
32182eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
32192eabf88fSMatthew 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);
32202eabf88fSMatthew G. Knepley       }
32212eabf88fSMatthew G. Knepley #endif
32222eabf88fSMatthew G. Knepley     }
32232eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
32242eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3225785e854fSJed Brown     ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
32262eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
32272eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
3228aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
32292eabf88fSMatthew 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};
32302eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
32312eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3232aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
32332eabf88fSMatthew G. Knepley 
32342eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3235aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
3236a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
3237a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
3238a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
3239a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
3240a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
3241a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
3242a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
3243a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
32442eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3245aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32462eabf88fSMatthew G. Knepley #if 1
32472eabf88fSMatthew 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);
32482eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
32492eabf88fSMatthew 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);
32502eabf88fSMatthew G. Knepley         }
32512eabf88fSMatthew G. Knepley #endif
32522eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
32532eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
32542eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
32552eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
32562eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
32572eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
32582eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
32592eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
32602eabf88fSMatthew G. Knepley           }
3261a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
32622eabf88fSMatthew G. Knepley         }
32632eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);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 < supportSize; ++p) {
32672eabf88fSMatthew 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);
32682eabf88fSMatthew G. Knepley         }
32692eabf88fSMatthew G. Knepley #endif
32702eabf88fSMatthew G. Knepley       }
32712eabf88fSMatthew G. Knepley     }
32722eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
32732eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
32742eabf88fSMatthew 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};
3275afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
3276afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
32772eabf88fSMatthew G. Knepley 
32782eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3279afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3280afb2665bSMatthew G. Knepley       /* A-D face */
3281afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
3282a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
3283a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3284a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3285afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3286a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3287a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3288a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
3289afb2665bSMatthew G. Knepley       orntNew[3] = -2;
32902eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3291afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32922eabf88fSMatthew G. Knepley #if 1
32932eabf88fSMatthew 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);
32942eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
32952eabf88fSMatthew 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);
32962eabf88fSMatthew G. Knepley       }
32972eabf88fSMatthew G. Knepley #endif
3298afb2665bSMatthew G. Knepley       /* C-D face */
3299afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
3300a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
3301a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3302a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3303afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3304a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3305a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3306a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
3307afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3308afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3309afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3310afb2665bSMatthew G. Knepley #if 1
3311afb2665bSMatthew 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);
3312afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3313afb2665bSMatthew 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);
3314afb2665bSMatthew G. Knepley       }
3315afb2665bSMatthew G. Knepley #endif
3316afb2665bSMatthew G. Knepley       /* B-C face */
3317afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
3318afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
3319afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3320afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
3321afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3322afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3323afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3324afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3325afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3326afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3327afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3328afb2665bSMatthew G. Knepley #if 1
3329afb2665bSMatthew 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);
3330afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3331afb2665bSMatthew 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);
3332afb2665bSMatthew G. Knepley       }
3333afb2665bSMatthew G. Knepley #endif
3334afb2665bSMatthew G. Knepley       /* A-B face */
3335afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
3336afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
3337afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3338afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
3339afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3340afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3341afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3342afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3343afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3344afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3345afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3346afb2665bSMatthew G. Knepley #if 1
3347afb2665bSMatthew 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);
3348afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3349afb2665bSMatthew 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);
3350afb2665bSMatthew G. Knepley       }
3351afb2665bSMatthew G. Knepley #endif
3352afb2665bSMatthew G. Knepley       /* E-F face */
3353afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
3354a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3355afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3356a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
3357a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3358a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
3359afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3360a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3361a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3362afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3363afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3364afb2665bSMatthew G. Knepley #if 1
3365afb2665bSMatthew 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);
3366afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3367afb2665bSMatthew 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);
3368afb2665bSMatthew G. Knepley       }
3369afb2665bSMatthew G. Knepley #endif
3370afb2665bSMatthew G. Knepley       /* F-G face */
3371afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
3372a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3373afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3374a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
3375a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3376a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
3377afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3378a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3379a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3380afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3381afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3382afb2665bSMatthew G. Knepley #if 1
3383afb2665bSMatthew 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);
3384afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3385afb2665bSMatthew 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);
3386afb2665bSMatthew G. Knepley       }
3387afb2665bSMatthew G. Knepley #endif
3388afb2665bSMatthew G. Knepley       /* G-H face */
3389afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
3390afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
3391afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3392afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
3393afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3394afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3395afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3396afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3397afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3398afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3399afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3400afb2665bSMatthew G. Knepley #if 1
3401afb2665bSMatthew 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);
3402afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3403afb2665bSMatthew 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);
3404afb2665bSMatthew G. Knepley       }
3405afb2665bSMatthew G. Knepley #endif
3406afb2665bSMatthew G. Knepley       /* E-H face */
3407afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
3408a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3409afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3410a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
3411a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3412a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
3413afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3414a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3415a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3416afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3417afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3418afb2665bSMatthew G. Knepley #if 1
3419afb2665bSMatthew 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);
3420afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3421afb2665bSMatthew 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);
3422afb2665bSMatthew G. Knepley       }
3423afb2665bSMatthew G. Knepley #endif
3424afb2665bSMatthew G. Knepley       /* A-E face */
3425afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
3426a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
3427a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3428a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3429afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3430a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3431a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3432a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
3433afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3434afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3435afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3436afb2665bSMatthew G. Knepley #if 1
3437afb2665bSMatthew 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);
3438afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3439afb2665bSMatthew 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);
3440afb2665bSMatthew G. Knepley       }
3441afb2665bSMatthew G. Knepley #endif
3442afb2665bSMatthew G. Knepley       /* D-F face */
3443afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
3444afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
3445afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3446afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
3447afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3448afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3449afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3450afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3451afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3452afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3453afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3454afb2665bSMatthew G. Knepley #if 1
3455afb2665bSMatthew 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);
3456afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3457afb2665bSMatthew 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);
3458afb2665bSMatthew G. Knepley       }
3459afb2665bSMatthew G. Knepley #endif
3460afb2665bSMatthew G. Knepley       /* C-G face */
3461afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
3462a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3463afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3464a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
3465a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3466a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
3467afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3468a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3469a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3470afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3471afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3472afb2665bSMatthew G. Knepley #if 1
3473afb2665bSMatthew 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);
3474afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3475afb2665bSMatthew 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);
3476afb2665bSMatthew G. Knepley       }
3477afb2665bSMatthew G. Knepley #endif
3478afb2665bSMatthew G. Knepley       /* B-H face */
3479afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
3480a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3481a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3482a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3483a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3484a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
3485a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3486a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
3487a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3488afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3489afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3490afb2665bSMatthew G. Knepley #if 1
3491afb2665bSMatthew 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);
3492afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3493afb2665bSMatthew 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);
3494afb2665bSMatthew G. Knepley       }
3495afb2665bSMatthew G. Knepley #endif
3496afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
3497afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
34982eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
34992eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
35002eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
35012eabf88fSMatthew G. Knepley #if 1
35022eabf88fSMatthew 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);
35032eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35042eabf88fSMatthew 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);
35052eabf88fSMatthew G. Knepley         }
35062eabf88fSMatthew G. Knepley #endif
35072eabf88fSMatthew G. Knepley       }
35082eabf88fSMatthew G. Knepley     }
35092eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
35102eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
35112eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
35122eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
35132eabf88fSMatthew G. Knepley 
35142eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
35152eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
35162eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
35172eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
35182eabf88fSMatthew G. Knepley 
35192eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
35202eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
35212eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
35222eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
35232eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35242eabf88fSMatthew G. Knepley #if 1
35252eabf88fSMatthew 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);
35262eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35272eabf88fSMatthew 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);
35282eabf88fSMatthew G. Knepley         }
35292eabf88fSMatthew G. Knepley #endif
35302eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
35312eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
35322eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
35332eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
35342eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
35352eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
35362eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
35372eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
35382eabf88fSMatthew G. Knepley           }
35392eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
35402eabf88fSMatthew G. Knepley         }
35412eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35422eabf88fSMatthew G. Knepley #if 1
35432eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
35442eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
35452eabf88fSMatthew 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);
35462eabf88fSMatthew G. Knepley         }
35472eabf88fSMatthew G. Knepley #endif
35482eabf88fSMatthew G. Knepley       }
35492eabf88fSMatthew G. Knepley     }
35502eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
35512eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
35526b852384SMatthew 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};
35532eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
35546b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
35552eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
35562eabf88fSMatthew G. Knepley 
35572eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
35582eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
35592eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
35602eabf88fSMatthew G. Knepley 
35612eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
35622eabf88fSMatthew G. Knepley         coneNew[1] = newv;
35632eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35642eabf88fSMatthew G. Knepley #if 1
35652eabf88fSMatthew 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);
35662eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35672eabf88fSMatthew 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);
35682eabf88fSMatthew G. Knepley         }
35692eabf88fSMatthew G. Knepley #endif
35702eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
35712eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
35722eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
35732eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
35742eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
35756b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
35766b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
35776b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
35782eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
3579a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
35802eabf88fSMatthew G. Knepley         }
35812eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35822eabf88fSMatthew G. Knepley #if 1
35832eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
35842eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
35852eabf88fSMatthew 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);
35862eabf88fSMatthew G. Knepley         }
35872eabf88fSMatthew G. Knepley #endif
35882eabf88fSMatthew G. Knepley       }
35892eabf88fSMatthew G. Knepley     }
35902eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
35912eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
35922eabf88fSMatthew 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};
35932eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
35942eabf88fSMatthew G. Knepley       const PetscInt *cone;
35952eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
35962eabf88fSMatthew G. Knepley 
35972eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
35982eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
35992eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
36002eabf88fSMatthew G. Knepley 
36012eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
36022eabf88fSMatthew G. Knepley         coneNew[1] = newv;
36032eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36042eabf88fSMatthew G. Knepley #if 1
36052eabf88fSMatthew 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);
36062eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
36072eabf88fSMatthew 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);
36082eabf88fSMatthew G. Knepley         }
36092eabf88fSMatthew G. Knepley #endif
36102eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
36112eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36122eabf88fSMatthew G. Knepley #if 1
36132eabf88fSMatthew 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);
36142eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
36152eabf88fSMatthew 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);
36162eabf88fSMatthew G. Knepley         }
36172eabf88fSMatthew G. Knepley #endif
36182eabf88fSMatthew G. Knepley       }
36192eabf88fSMatthew G. Knepley     }
36202eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
36212eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
36222eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
36232eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
36242eabf88fSMatthew G. Knepley       PetscInt        size, s;
36252eabf88fSMatthew G. Knepley 
36262eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
36272eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
36282eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36292eabf88fSMatthew G. Knepley         PetscInt r = 0;
36302eabf88fSMatthew G. Knepley 
36312eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36322eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
36332eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
36342eabf88fSMatthew G. Knepley       }
36352eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36362eabf88fSMatthew G. Knepley #if 1
36372eabf88fSMatthew 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);
36382eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
36392eabf88fSMatthew 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);
36402eabf88fSMatthew G. Knepley       }
36412eabf88fSMatthew G. Knepley #endif
36422eabf88fSMatthew G. Knepley     }
36432eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
36442eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
36452eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
36462eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
36472eabf88fSMatthew G. Knepley       PetscInt        size, s;
36482eabf88fSMatthew G. Knepley 
36492eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
36502eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
36512eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
36522eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
36532eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36542eabf88fSMatthew G. Knepley         PetscInt r;
36552eabf88fSMatthew G. Knepley 
36562eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3657a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
36582eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
36592eabf88fSMatthew G. Knepley       }
36602eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36612eabf88fSMatthew G. Knepley #if 1
36622eabf88fSMatthew 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);
36632eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
36642eabf88fSMatthew 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);
36652eabf88fSMatthew G. Knepley       }
36662eabf88fSMatthew G. Knepley #endif
36672eabf88fSMatthew G. Knepley     }
36682eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
36692eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
36702eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
36712eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
36722eabf88fSMatthew G. Knepley       PetscInt        size, s;
36732eabf88fSMatthew G. Knepley 
36742eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
36752eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
36762eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (e - eStart)*2 +  (f - fStart)*4 + r;
36772eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36782eabf88fSMatthew G. Knepley         PetscInt r;
36792eabf88fSMatthew G. Knepley 
36802eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36812eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
36822eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
36832eabf88fSMatthew G. Knepley       }
36842eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36852eabf88fSMatthew G. Knepley #if 1
36862eabf88fSMatthew 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);
36872eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
36882eabf88fSMatthew 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);
36892eabf88fSMatthew G. Knepley       }
36902eabf88fSMatthew G. Knepley #endif
36912eabf88fSMatthew G. Knepley     }
36922eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
36932eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
36942eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
36952eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
36962eabf88fSMatthew G. Knepley 
36972eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
36982eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
36992eabf88fSMatthew G. Knepley       }
37002eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37012eabf88fSMatthew G. Knepley     }
3702da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
37032eabf88fSMatthew G. Knepley     break;
370475d3a19aSMatthew G. Knepley   default:
370575d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
370675d3a19aSMatthew G. Knepley   }
370775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
370875d3a19aSMatthew G. Knepley }
370975d3a19aSMatthew G. Knepley 
371075d3a19aSMatthew G. Knepley #undef __FUNCT__
371175d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates"
371286150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
371375d3a19aSMatthew G. Knepley {
371475d3a19aSMatthew G. Knepley   PetscSection   coordSection, coordSectionNew;
371575d3a19aSMatthew G. Knepley   Vec            coordinates, coordinatesNew;
371675d3a19aSMatthew G. Knepley   PetscScalar   *coords, *coordsNew;
37173478d7aaSMatthew G. Knepley   const PetscInt numVertices = depthSize ? depthSize[0] : 0;
3718b5da9499SMatthew G. Knepley   PetscInt       dim, depth, coordSizeNew, cStart, cEnd, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
371975d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
372075d3a19aSMatthew G. Knepley 
372175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
372275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
372375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
372475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
3725b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
372675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
372775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
3728b5da9499SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, NULL, &fMax, &eMax, NULL);CHKERRQ(ierr);
37293478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);}
373075d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);
373175d3a19aSMatthew G. Knepley   ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
373275d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
373375d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
373475d3a19aSMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr);
37353478d7aaSMatthew G. Knepley   ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
373675d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
3737b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
373875d3a19aSMatthew G. Knepley   /* All vertices have the dim coordinates */
37393478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
374075d3a19aSMatthew G. Knepley     ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr);
374175d3a19aSMatthew G. Knepley     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr);
374275d3a19aSMatthew G. Knepley   }
374375d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
374475d3a19aSMatthew G. Knepley   ierr = DMPlexSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr);
374575d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
374675d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
374775d3a19aSMatthew G. Knepley   ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr);
374875d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
374975d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
375075d3a19aSMatthew G. Knepley   ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr);
375175d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
375275d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
3753b5da9499SMatthew G. Knepley   switch (refiner) {
37543478d7aaSMatthew G. Knepley   case 0: break;
3755b5da9499SMatthew G. Knepley   case 6: /* Hex 3D */
3756*d856d60fSMatthew G. Knepley   case 8: /* Hybrid Hex 3D */
3757b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
3758*d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
3759c91acedaSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
3760b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
3761b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
3762b5da9499SMatthew G. Knepley 
3763b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
3764b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
3765b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
3766b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
3767b5da9499SMatthew G. Knepley       }
3768b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
3769b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
3770b5da9499SMatthew G. Knepley       }
3771b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
3772b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
3773b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
3774b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
3775b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
3776b5da9499SMatthew G. Knepley       }
3777b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
3778b5da9499SMatthew G. Knepley     }
3779b5da9499SMatthew G. Knepley   case 2: /* Hex 2D */
3780b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
3781b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
3782c91acedaSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (c - cStart) + (dim > 2 ? (fEnd - fStart) : 0);
3783b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
3784b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
3785b5da9499SMatthew G. Knepley 
3786b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
3787b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
3788b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
3789b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
3790b5da9499SMatthew G. Knepley       }
3791b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
3792b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
3793b5da9499SMatthew G. Knepley       }
3794b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
3795b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
3796b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
3797b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
3798b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
3799b5da9499SMatthew G. Knepley       }
3800b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
3801b5da9499SMatthew G. Knepley     }
3802b5da9499SMatthew G. Knepley   case 1: /* Simplicial 2D */
3803b5da9499SMatthew G. Knepley   case 3: /* Hybrid Simplicial 2D */
3804b5da9499SMatthew G. Knepley   case 5: /* Simplicial 3D */
38056ce3c06aSMatthew G. Knepley   case 7: /* Hybrid Simplicial 3D */
3806b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
3807b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
3808b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
3809b5da9499SMatthew G. Knepley       const PetscInt *cone;
3810b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
3811b5da9499SMatthew G. Knepley 
3812b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
3813b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
3814b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
3815b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
3816b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
3817b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
3818b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
3819b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]);
3820b5da9499SMatthew G. Knepley       }
3821b5da9499SMatthew G. Knepley     }
382275d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
382375d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
382475d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
382575d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
382675d3a19aSMatthew G. Knepley 
382775d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
382875d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
382975d3a19aSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
383075d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
383175d3a19aSMatthew G. Knepley       }
383275d3a19aSMatthew G. Knepley     }
3833b5da9499SMatthew G. Knepley     break;
3834b5da9499SMatthew G. Knepley   default:
3835b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
383675d3a19aSMatthew G. Knepley   }
383775d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
383875d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
383975d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
384075d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
384175d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
384275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
384375d3a19aSMatthew G. Knepley }
384475d3a19aSMatthew G. Knepley 
384575d3a19aSMatthew G. Knepley #undef __FUNCT__
384675d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF"
384786150812SJed Brown static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
384875d3a19aSMatthew G. Knepley {
384975d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
385075d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
385175d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
385275d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
385375d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
385475d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
385575d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
385675d3a19aSMatthew G. Knepley 
385775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
385875d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
3859785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
386075d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
386175d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
386275d3a19aSMatthew G. Knepley   }
386375d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
3864785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &ranksNew);CHKERRQ(ierr);
3865785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &localPointsNew);CHKERRQ(ierr);
3866785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
386775d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
386875d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
386975d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
387075d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
387175d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
387275d3a19aSMatthew G. Knepley   }
387375d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
387475d3a19aSMatthew G. Knepley   ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);
387575d3a19aSMatthew G. Knepley   ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
387675d3a19aSMatthew G. Knepley   ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
387775d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
387875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
387975d3a19aSMatthew G. Knepley }
388075d3a19aSMatthew G. Knepley 
388175d3a19aSMatthew G. Knepley #undef __FUNCT__
388275d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF"
388386150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
388475d3a19aSMatthew G. Knepley {
388575d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
388675d3a19aSMatthew G. Knepley   IS                 processRanks;
388775d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
388875d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
388975d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
389075d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
389175d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
389275d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
389375d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
38947ba685a0SMatthew G. Knepley   PetscInt           depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
38957ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
389675d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
389775d3a19aSMatthew G. Knepley 
389875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
389975d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
390075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
390175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
390275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
390375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
390475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
390575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
39063478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
390775d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
390875d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
390975d3a19aSMatthew G. Knepley   /* Caculate size of new SF */
391075d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
391175d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
391275d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
391375d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
391475d3a19aSMatthew G. Knepley 
391575d3a19aSMatthew G. Knepley     switch (refiner) {
391675d3a19aSMatthew G. Knepley     case 1:
391775d3a19aSMatthew G. Knepley       /* Simplicial 2D */
391875d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
391975d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
392075d3a19aSMatthew G. Knepley         ++numLeavesNew;
392175d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
392275d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
3923d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
392475d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
392575d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
392675d3a19aSMatthew G. Knepley         numLeavesNew += 4 + 3;
392775d3a19aSMatthew G. Knepley       }
392875d3a19aSMatthew G. Knepley       break;
392975d3a19aSMatthew G. Knepley     case 2:
393075d3a19aSMatthew G. Knepley       /* Hex 2D */
393175d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
393275d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
393375d3a19aSMatthew G. Knepley         ++numLeavesNew;
393475d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
393575d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
3936d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
393775d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
3938455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
3939455d6cd4SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
394075d3a19aSMatthew G. Knepley       }
394175d3a19aSMatthew G. Knepley       break;
3942b5da9499SMatthew G. Knepley     case 5:
3943b5da9499SMatthew G. Knepley       /* Simplicial 3D */
3944b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
3945b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
3946b5da9499SMatthew G. Knepley         ++numLeavesNew;
3947b5da9499SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
3948b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
3949b5da9499SMatthew G. Knepley         numLeavesNew += 2 + 1;
3950b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
3951b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
3952b5da9499SMatthew G. Knepley         numLeavesNew += 4 + 3;
3953b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
3954b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
3955b5da9499SMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
3956b5da9499SMatthew G. Knepley       }
3957b5da9499SMatthew G. Knepley       break;
39586ce3c06aSMatthew G. Knepley     case 7:
39596ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
39606ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
39616ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
39626ce3c06aSMatthew G. Knepley         ++numLeavesNew;
39636ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
39646ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
39656ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
39666ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
39676ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
39686ce3c06aSMatthew G. Knepley         ++numLeavesNew;
39696ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
39706ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
39716ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
39726ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
39736ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
39746ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
39756ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
39766ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
39776ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
39786ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
39796ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
39806ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
39816ce3c06aSMatthew G. Knepley       }
39826ce3c06aSMatthew G. Knepley       break;
39832eabf88fSMatthew G. Knepley     case 6:
39842eabf88fSMatthew G. Knepley       /* Hex 3D */
39852eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
39862eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
39872eabf88fSMatthew G. Knepley         ++numLeavesNew;
39882eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
39892eabf88fSMatthew G. Knepley         /* Old edges add new edges, and vertex */
39902eabf88fSMatthew G. Knepley         numLeavesNew += 2 + 1;
39912eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
39922eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
39932eabf88fSMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
39942eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
39952eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
39962eabf88fSMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
39972eabf88fSMatthew G. Knepley       }
39982eabf88fSMatthew G. Knepley       break;
399975d3a19aSMatthew G. Knepley     default:
400075d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
400175d3a19aSMatthew G. Knepley     }
400275d3a19aSMatthew G. Knepley   }
400375d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
400475d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
400575d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
4006dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
4007dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
400875d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
400975d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
401075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
401175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
401275d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
401375d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
401475d3a19aSMatthew G. Knepley   }
401575d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
401675d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
401775d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
401875d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
401975d3a19aSMatthew G. Knepley 
402075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
402175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
402275d3a19aSMatthew G. Knepley 
402375d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
402475d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
402575d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
402675d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
402775d3a19aSMatthew G. Knepley 
402875d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
402975d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
403075d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
403175d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
403275d3a19aSMatthew G. Knepley   }
403375d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
403475d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
403575d3a19aSMatthew G. Knepley   /* Calculate new point SF */
4036785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew,    &localPointsNew);CHKERRQ(ierr);
4037785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
403875d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
403975d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
404075d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
404175d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
404275d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
404375d3a19aSMatthew G. Knepley 
404475d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
404575d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
404675d3a19aSMatthew G. Knepley     switch (refiner) {
404775d3a19aSMatthew G. Knepley     case 1:
404875d3a19aSMatthew G. Knepley       /* Simplicial 2D */
404975d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
405075d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
405175d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
405275d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
405375d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
405475d3a19aSMatthew G. Knepley         ++m;
405575d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
405675d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
405775d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
405875d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
405975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
406075d3a19aSMatthew G. Knepley         ++m;
406175d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
406275d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
406375d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
406475d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
406575d3a19aSMatthew G. Knepley         }
406675d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
406775d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
406875d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
406975d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
407075d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
407175d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
407275d3a19aSMatthew G. Knepley         }
407375d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
407475d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*3     + r;
407575d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
407675d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
407775d3a19aSMatthew G. Knepley         }
407875d3a19aSMatthew G. Knepley       }
407975d3a19aSMatthew G. Knepley       break;
408075d3a19aSMatthew G. Knepley     case 2:
408175d3a19aSMatthew G. Knepley       /* Hex 2D */
408275d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
408375d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
408475d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
408575d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
408675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
408775d3a19aSMatthew G. Knepley         ++m;
408875d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
408975d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
409075d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
409175d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
409275d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
409375d3a19aSMatthew G. Knepley         ++m;
409475d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
409575d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
409675d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
409775d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
409875d3a19aSMatthew G. Knepley         }
409975d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
4100455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
410175d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
410275d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
410375d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
410475d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
410575d3a19aSMatthew G. Knepley         }
410675d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
410775d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*4     + r;
410875d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r;
410975d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
411075d3a19aSMatthew G. Knepley         }
4111455d6cd4SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
4112455d6cd4SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (fEnd - fStart)                    + (p  - cStart)     + r;
4113455d6cd4SMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
4114455d6cd4SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4115455d6cd4SMatthew G. Knepley         }
411675d3a19aSMatthew G. Knepley       }
411775d3a19aSMatthew G. Knepley       break;
411875d3a19aSMatthew G. Knepley     case 3:
411975d3a19aSMatthew G. Knepley       /* Hybrid simplicial 2D */
412075d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
412175d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
412275d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
412375d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
412475d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
412575d3a19aSMatthew G. Knepley         ++m;
412675d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
412775d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
412875d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
412975d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
413075d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
413175d3a19aSMatthew G. Knepley         ++m;
413275d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
413375d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
413475d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
413575d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
413675d3a19aSMatthew G. Knepley         }
413775d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
413875d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
413975d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
414075d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
414175d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
414275d3a19aSMatthew G. Knepley         ++m;
414375d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
414475d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
414575d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
414675d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
414775d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
414875d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
414975d3a19aSMatthew G. Knepley         }
415075d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
415175d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
415275d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
415375d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
415475d3a19aSMatthew G. Knepley         }
415575d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
415675d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
415775d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
415875d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
415975d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
416075d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
416175d3a19aSMatthew G. Knepley         }
416275d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
416375d3a19aSMatthew 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]);
416475d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
416575d3a19aSMatthew G. Knepley         ++m;
416675d3a19aSMatthew G. Knepley       }
416775d3a19aSMatthew G. Knepley       break;
4168b5da9499SMatthew G. Knepley     case 5:
4169b5da9499SMatthew G. Knepley       /* Simplicial 3D */
4170b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
4171b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
4172b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
4173b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
4174b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
4175b5da9499SMatthew G. Knepley         ++m;
417687fe6628SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
4177b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
4178b5da9499SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
4179b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
4180b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
4181b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4182b5da9499SMatthew G. Knepley         }
4183b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
4184b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
4185b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
4186b5da9499SMatthew G. Knepley         ++m;
4187b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
4188b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
4189b5da9499SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
4190b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
4191b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
4192b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4193b5da9499SMatthew G. Knepley         }
4194b5da9499SMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
4195b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*3     + r;
4196b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r;
4197b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4198b5da9499SMatthew G. Knepley         }
4199b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
4200b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
4201b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
4202b5da9499SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
4203b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
4204b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4205b5da9499SMatthew G. Knepley         }
4206b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
4207b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*8     + r;
4208b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r;
4209b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4210b5da9499SMatthew G. Knepley         }
4211b5da9499SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
4212b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*3                    + (p  - cStart)*1     + r;
4213b5da9499SMatthew 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;
4214b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
4215b5da9499SMatthew G. Knepley         }
4216b5da9499SMatthew G. Knepley       }
4217b5da9499SMatthew G. Knepley       break;
42186ce3c06aSMatthew G. Knepley     case 7:
42196ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
42206ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
42216ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
42226ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
42236ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
42246ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42256ce3c06aSMatthew G. Knepley         ++m;
42266ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
42276ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
42286ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
42296ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
42306ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
42316ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42326ce3c06aSMatthew G. Knepley         }
42336ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
42346ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
42356ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42366ce3c06aSMatthew G. Knepley         ++m;
42376ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
42386ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
42396ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
42406ce3c06aSMatthew 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]);
42416ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
42426ce3c06aSMatthew G. Knepley         ++m;
42436ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
42446ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
42456ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
42466ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
42476ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
42486ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42496ce3c06aSMatthew G. Knepley         }
42506ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
42516ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
42526ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
42536ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42546ce3c06aSMatthew G. Knepley         }
42556ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
42566ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
42576ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
42586ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fStart)*2     + 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 + (rp - rfStart[n])*2 + r;
42606ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42616ce3c06aSMatthew G. Knepley         }
42626ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)     + (cMax                            - cStart)     + (fEnd                                          - fMax);
42636ce3c06aSMatthew 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]);
42646ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
426509b1338fSMatthew G. Knepley         ++m;
42666ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
42676ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
42686ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
42696ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
42706ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
42716ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42726ce3c06aSMatthew G. Knepley         }
42736ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
42746ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
42756ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
42766ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42776ce3c06aSMatthew G. Knepley         }
42786ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + r;
42796ce3c06aSMatthew 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;
42806ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
428109b1338fSMatthew G. Knepley         ++m;
42826ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
42836ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
42846ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
42856ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
42866ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
42876ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42886ce3c06aSMatthew G. Knepley         }
42896ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
42906ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*4                              + (p  - cMax)*3                            + r;
42916ce3c06aSMatthew 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;
42926ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
42936ce3c06aSMatthew G. Knepley         }
42946ce3c06aSMatthew G. Knepley       }
42956ce3c06aSMatthew G. Knepley       break;
42962eabf88fSMatthew G. Knepley     case 6:
42972eabf88fSMatthew G. Knepley       /* Hex 3D */
42982eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
42992eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
43002eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
43012eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
43022eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
43032eabf88fSMatthew G. Knepley         ++m;
43042eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
43052eabf88fSMatthew G. Knepley         /* Old edges add new edges and vertex */
43062eabf88fSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
43072eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
43082eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
43092eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43102eabf88fSMatthew G. Knepley         }
43112eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
43122eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
43132eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
43142eabf88fSMatthew G. Knepley         ++m;
43152eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
43162eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
43172eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
43182eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
43192eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
43202eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43212eabf88fSMatthew G. Knepley         }
43222eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
43232eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*4     + r;
43242eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r;
43252eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43262eabf88fSMatthew G. Knepley         }
43272eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (p  - fStart);
43282eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]);
43292eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
43302eabf88fSMatthew G. Knepley         ++m;
43312eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
43322eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
43332eabf88fSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
43342eabf88fSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
43352eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
43362eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43372eabf88fSMatthew G. Knepley         }
43382eabf88fSMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
43392eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*12     + r;
43402eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r;
43412eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43422eabf88fSMatthew G. Knepley         }
43432eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
43442eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*4                    + (p  - cStart)*6     + r;
43452eabf88fSMatthew 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;
43462eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43472eabf88fSMatthew G. Knepley         }
43482eabf88fSMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
43492eabf88fSMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eEnd - eStart)              + (fEnd - fStart)                    + (p  - cStart)     + r;
43502eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
43512eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
43522eabf88fSMatthew G. Knepley         }
43532eabf88fSMatthew G. Knepley       }
43542eabf88fSMatthew G. Knepley       break;
435575d3a19aSMatthew G. Knepley     default:
435675d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
435775d3a19aSMatthew G. Knepley     }
435875d3a19aSMatthew G. Knepley   }
435909b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
436075d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
436175d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
436275d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
436375d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
436406a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
436575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
436675d3a19aSMatthew G. Knepley }
436775d3a19aSMatthew G. Knepley 
436875d3a19aSMatthew G. Knepley #undef __FUNCT__
436975d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels"
437086150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
437175d3a19aSMatthew G. Knepley {
437275d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
43737ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
43747ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
437575d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
437675d3a19aSMatthew G. Knepley 
437775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
437875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
437975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
438075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
438175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
4382d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
43833478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
438475d3a19aSMatthew G. Knepley   ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
438575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
438675d3a19aSMatthew G. Knepley   switch (refiner) {
43873478d7aaSMatthew G. Knepley   case 0: break;
438858b8852aSMatthew G. Knepley   case 7:
438958b8852aSMatthew G. Knepley   case 8:
439058b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
439175d3a19aSMatthew G. Knepley   case 3:
439258b8852aSMatthew G. Knepley   case 4:
439375d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
439475d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
439575d3a19aSMatthew G. Knepley   }
439675d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
439775d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
439875d3a19aSMatthew G. Knepley     const char     *lname;
439975d3a19aSMatthew G. Knepley     PetscBool       isDepth;
440075d3a19aSMatthew G. Knepley     IS              valueIS;
440175d3a19aSMatthew G. Knepley     const PetscInt *values;
440275d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
440375d3a19aSMatthew G. Knepley 
440475d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr);
440575d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
440675d3a19aSMatthew G. Knepley     if (isDepth) continue;
440775d3a19aSMatthew G. Knepley     ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr);
440875d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr);
440975d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
441075d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
441175d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
441275d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
441375d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
441475d3a19aSMatthew G. Knepley       IS              pointIS;
441575d3a19aSMatthew G. Knepley       const PetscInt *points;
441675d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
441775d3a19aSMatthew G. Knepley 
441875d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
441975d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
442075d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
442175d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
442275d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
442375d3a19aSMatthew G. Knepley         switch (refiner) {
442475d3a19aSMatthew G. Knepley         case 1:
442575d3a19aSMatthew G. Knepley           /* Simplicial 2D */
442675d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
442775d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
442875d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
442975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
443075d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
443175d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
443275d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
443375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
443475d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
443575d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
443675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
443775d3a19aSMatthew G. Knepley             }
443875d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
443975d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
444075d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
444175d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
444275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
444375d3a19aSMatthew G. Knepley             }
444475d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
444575d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
444675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
444775d3a19aSMatthew G. Knepley             }
444875d3a19aSMatthew G. Knepley           }
444975d3a19aSMatthew G. Knepley           break;
445075d3a19aSMatthew G. Knepley         case 2:
445175d3a19aSMatthew G. Knepley           /* Hex 2D */
445275d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
445375d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
445475d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
445575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
445675d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
445775d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
445875d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
445975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
446075d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
446175d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
446275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
446375d3a19aSMatthew G. Knepley             }
446475d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
446575d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
446675d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
446775d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
446875d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
446975d3a19aSMatthew G. Knepley             }
447075d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
447175d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
447275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
447375d3a19aSMatthew G. Knepley             }
447475d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
447575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
447675d3a19aSMatthew G. Knepley           }
447775d3a19aSMatthew G. Knepley           break;
447875d3a19aSMatthew G. Knepley         case 3:
447975d3a19aSMatthew G. Knepley           /* Hybrid simplicial 2D */
448075d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
448175d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
448275d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
448375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
448475d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
448575d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
448675d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
448775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
448875d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
448975d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
449075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
449175d3a19aSMatthew G. Knepley             }
449275d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
449375d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
449475d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
449575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
449675d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
449775d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
449875d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
449975d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
450075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
450175d3a19aSMatthew G. Knepley             }
450275d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
450375d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
450475d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
450575d3a19aSMatthew G. Knepley             }
450675d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
450775d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
450875d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
450975d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
451075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
451175d3a19aSMatthew G. Knepley             }
451275d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
451375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
451475d3a19aSMatthew G. Knepley           }
451575d3a19aSMatthew G. Knepley           break;
4516b5da9499SMatthew G. Knepley         case 5:
4517b5da9499SMatthew G. Knepley           /* Simplicial 3D */
4518b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
4519b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
4520b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
4521b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4522b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
4523b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
4524b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
4525b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
4526b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4527b5da9499SMatthew G. Knepley             }
4528b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
4529b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4530b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
4531b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
4532b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
4533b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
4534b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4535b5da9499SMatthew G. Knepley             }
4536b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
4537b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
4538b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4539b5da9499SMatthew G. Knepley             }
4540b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
4541b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
4542b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
4543b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
4544b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4545b5da9499SMatthew G. Knepley             }
4546b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
4547b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
4548b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4549b5da9499SMatthew G. Knepley             }
4550b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
4551b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
4552b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
4553b5da9499SMatthew G. Knepley             }
4554b5da9499SMatthew G. Knepley           }
4555b5da9499SMatthew G. Knepley           break;
45566ce3c06aSMatthew G. Knepley         case 7:
45576ce3c06aSMatthew G. Knepley           /* Hybrid Simplicial 3D */
45586ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
45596ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
45606ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
45616ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45626ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
45636ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
45646ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
45656ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
45666ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45676ce3c06aSMatthew G. Knepley             }
45686ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
45696ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45706ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
45716ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
45726ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
45736ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45746ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
45756ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
45766ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
45776ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
45786ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45796ce3c06aSMatthew G. Knepley             }
45806ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
45816ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
45826ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45836ce3c06aSMatthew G. Knepley             }
45846ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
45856ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
45866ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
45876ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
45886ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45896ce3c06aSMatthew G. Knepley             }
45906ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
45916ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45926ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
45936ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
45946ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
45956ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
45966ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
45976ce3c06aSMatthew G. Knepley             }
45986ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
45996ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
46006ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46016ce3c06aSMatthew G. Knepley             }
46026ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
46036ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
460458b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
46056ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
46066ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
46076ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
46086ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46096ce3c06aSMatthew G. Knepley             }
46106ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
46116ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
46126ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46136ce3c06aSMatthew G. Knepley             }
46146ce3c06aSMatthew G. Knepley           }
46156ce3c06aSMatthew G. Knepley           break;
46162eabf88fSMatthew G. Knepley         case 6:
46172eabf88fSMatthew G. Knepley           /* Hex 3D */
46182eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
46192eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
46202eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
46212eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
462219d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
46232eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
46242eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
46252eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
46262eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46272eabf88fSMatthew G. Knepley             }
46282eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
46292eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46302eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
46312eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
46322eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
46332eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
46342eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46352eabf88fSMatthew G. Knepley             }
46362eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
46372eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
46382eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46392eabf88fSMatthew G. Knepley             }
46402eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
46412eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46422eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
46432eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
46442eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
46452eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
46462eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46472eabf88fSMatthew G. Knepley             }
46482eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
46492eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
46502eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46512eabf88fSMatthew G. Knepley             }
46522eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
46532eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
46542eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46552eabf88fSMatthew G. Knepley             }
46562eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
46572eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
46582eabf88fSMatthew G. Knepley           }
46592eabf88fSMatthew G. Knepley           break;
466075d3a19aSMatthew G. Knepley         default:
466175d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
466275d3a19aSMatthew G. Knepley         }
466375d3a19aSMatthew G. Knepley       }
466475d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
466575d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
466675d3a19aSMatthew G. Knepley     }
466775d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
466875d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
466975d3a19aSMatthew G. Knepley     if (0) {
467075d3a19aSMatthew G. Knepley       ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr);
467175d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
467275d3a19aSMatthew G. Knepley       ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
467375d3a19aSMatthew G. Knepley     }
467475d3a19aSMatthew G. Knepley   }
467575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
467675d3a19aSMatthew G. Knepley }
467775d3a19aSMatthew G. Knepley 
467875d3a19aSMatthew G. Knepley #undef __FUNCT__
4679509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexRefineUniform_Internal"
468075d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
4681509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
468275d3a19aSMatthew G. Knepley {
468375d3a19aSMatthew G. Knepley   DM             rdm;
468475d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
468575d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
468675d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
468775d3a19aSMatthew G. Knepley 
468875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
468975d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
469075d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
469175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
469275d3a19aSMatthew G. Knepley   ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr);
469375d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
469475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
4695785e854fSJed Brown   ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr);
469675d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
469775d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
469875d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
469975d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
470075d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
470175d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
470275d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
470375d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
470475d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
470575d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
470675d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
470775d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
470875d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
470975d3a19aSMatthew G. Knepley   /* Step 6: Set coordinates for vertices */
471075d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
471175d3a19aSMatthew G. Knepley   /* Step 7: Create pointSF */
471275d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
471375d3a19aSMatthew G. Knepley   /* Step 8: Create labels */
471475d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
471575d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
471675d3a19aSMatthew G. Knepley 
471775d3a19aSMatthew G. Knepley   *dmRefined = rdm;
471875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
471975d3a19aSMatthew G. Knepley }
472075d3a19aSMatthew G. Knepley 
472175d3a19aSMatthew G. Knepley #undef __FUNCT__
472275d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform"
472375d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
472475d3a19aSMatthew G. Knepley {
472575d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
472675d3a19aSMatthew G. Knepley 
472775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
472875d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
472975d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
473075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
473175d3a19aSMatthew G. Knepley }
473275d3a19aSMatthew G. Knepley 
473375d3a19aSMatthew G. Knepley #undef __FUNCT__
473475d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform"
473575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
473675d3a19aSMatthew G. Knepley {
473775d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
473875d3a19aSMatthew G. Knepley 
473975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
474075d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
474175d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
474275d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
474375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
474475d3a19aSMatthew G. Knepley }
474575d3a19aSMatthew G. Knepley 
474675d3a19aSMatthew G. Knepley #undef __FUNCT__
474775d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit"
474875d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
474975d3a19aSMatthew G. Knepley {
475075d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
475175d3a19aSMatthew G. Knepley 
475275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
475375d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
475475d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
475575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
475675d3a19aSMatthew G. Knepley }
475775d3a19aSMatthew G. Knepley 
475875d3a19aSMatthew G. Knepley #undef __FUNCT__
475975d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit"
476075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
476175d3a19aSMatthew G. Knepley {
476275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
476375d3a19aSMatthew G. Knepley 
476475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
476575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
476675d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
476775d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
476875d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
476975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
477075d3a19aSMatthew G. Knepley }
477175d3a19aSMatthew G. Knepley 
477275d3a19aSMatthew G. Knepley #undef __FUNCT__
4773509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Internal"
4774509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
477575d3a19aSMatthew G. Knepley {
47763478d7aaSMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax;
477775d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
477875d3a19aSMatthew G. Knepley 
477975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
478075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
47813478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
47823478d7aaSMatthew G. Knepley   if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);}
478375d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
478475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr);
478575d3a19aSMatthew G. Knepley   switch (dim) {
478675d3a19aSMatthew G. Knepley   case 2:
478775d3a19aSMatthew G. Knepley     switch (coneSize) {
478875d3a19aSMatthew G. Knepley     case 3:
478975d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 3; /* Hybrid */
479075d3a19aSMatthew G. Knepley       else *cellRefiner = 1; /* Triangular */
479175d3a19aSMatthew G. Knepley       break;
479275d3a19aSMatthew G. Knepley     case 4:
479375d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 4; /* Hybrid */
479475d3a19aSMatthew G. Knepley       else *cellRefiner = 2; /* Quadrilateral */
479575d3a19aSMatthew G. Knepley       break;
479675d3a19aSMatthew G. Knepley     default:
479775d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
479875d3a19aSMatthew G. Knepley     }
479975d3a19aSMatthew G. Knepley     break;
4800b5da9499SMatthew G. Knepley   case 3:
4801b5da9499SMatthew G. Knepley     switch (coneSize) {
4802b5da9499SMatthew G. Knepley     case 4:
4803b5da9499SMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 7; /* Hybrid */
4804b5da9499SMatthew G. Knepley       else *cellRefiner = 5; /* Tetrahedral */
4805b5da9499SMatthew G. Knepley       break;
48062eabf88fSMatthew G. Knepley     case 6:
48072eabf88fSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 8; /* Hybrid */
48082eabf88fSMatthew G. Knepley       else *cellRefiner = 6; /* hexahedral */
48092eabf88fSMatthew G. Knepley       break;
4810b5da9499SMatthew G. Knepley     default:
4811b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
4812b5da9499SMatthew G. Knepley     }
4813b5da9499SMatthew G. Knepley     break;
481475d3a19aSMatthew G. Knepley   default:
481575d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
481675d3a19aSMatthew G. Knepley   }
481775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
481875d3a19aSMatthew G. Knepley }
4819