xref: /petsc/src/dm/impls/plex/plexrefine.c (revision 149f48fdb98b7b5c0dbe27ead462caa306989693)
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 */
60*149f48fdSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* 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;
9427fcede3SMatthew G. Knepley   case 8:
9527fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
9627fcede3SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
9727fcede3SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
9827fcede3SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
9927fcede3SMatthew G. Knepley     /* Hexahedra */
10027fcede3SMatthew G. Knepley     depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
10127fcede3SMatthew G. Knepley     depthSize[1] = 2*(eMax - eStart) +  4*(fMax - fStart) + 6*(cMax - cStart);    /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */
10227fcede3SMatthew G. Knepley     depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart);                        /* Every face is split into 4 faces, and 12 faces are added for each cell */
10327fcede3SMatthew G. Knepley     depthSize[3] = 8*(cMax - cStart);                                             /* Every cell split into 8 cells */
10427fcede3SMatthew G. Knepley     /* Quadrilateral Prisms */
10527fcede3SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
10627fcede3SMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax)   +   (cEnd - cMax);      /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
10727fcede3SMatthew G. Knepley     depthSize[2] += 2*(fEnd - fMax)   + 4*(cEnd - cMax);                          /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */
10827fcede3SMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                              /* Every hybrid cell split into 4 cells */
10927fcede3SMatthew G. Knepley     break;
11075d3a19aSMatthew G. Knepley   default:
11175d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
11275d3a19aSMatthew G. Knepley   }
11375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
11475d3a19aSMatthew G. Knepley }
11575d3a19aSMatthew G. Knepley 
11642525629SMatthew G. Knepley /* Return triangle edge for orientation o, if it is r for o == 0 */
11742525629SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
118518a8359SMatthew G. Knepley   return (o < 0 ? 2-(o+r) : o+r)%3;
119518a8359SMatthew G. Knepley }
120de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
121de65f515SMatthew G. Knepley   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
122de65f515SMatthew G. Knepley }
123518a8359SMatthew G. Knepley 
124518a8359SMatthew G. Knepley /* Return triangle subface for orientation o, if it is r for o == 0 */
125518a8359SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
1264bae88c7SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%3;
12742525629SMatthew G. Knepley }
128de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
129de65f515SMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 3+s-o)%3;
130de65f515SMatthew G. Knepley }
13142525629SMatthew G. Knepley 
132431647a4SMatthew G. Knepley /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */
133431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) {
134431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+r) : o+r)%3;
135431647a4SMatthew G. Knepley }
136431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) {
137431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+s) : 3+s-o)%3;
138431647a4SMatthew G. Knepley }
139431647a4SMatthew G. Knepley 
14042525629SMatthew G. Knepley 
141e3f8b1d6SMatthew G. Knepley /* Return quad edge for orientation o, if it is r for o == 0 */
142e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
143e3f8b1d6SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%4;
144e3f8b1d6SMatthew G. Knepley }
145d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
146d6d937efSMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 4+s-o)%4;
147d6d937efSMatthew G. Knepley }
148e3f8b1d6SMatthew G. Knepley 
149e3f8b1d6SMatthew G. Knepley /* Return quad subface for orientation o, if it is r for o == 0 */
150e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
1514bae88c7SMatthew G. Knepley   return (o < 0 ? 4-(o+r) : o+r)%4;
15242525629SMatthew G. Knepley }
153d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
154d6d937efSMatthew G. Knepley   return (o < 0 ? 4-(o+s) : 4+s-o)%4;
155d6d937efSMatthew G. Knepley }
15642525629SMatthew G. Knepley 
15775d3a19aSMatthew G. Knepley #undef __FUNCT__
15875d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetConeSizes"
15986150812SJed Brown static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
16075d3a19aSMatthew G. Knepley {
161b5da9499SMatthew 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;
16275d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
16375d3a19aSMatthew G. Knepley 
16475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
16575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
16675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
16775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
16875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
16975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
17075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
1713478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
17275d3a19aSMatthew G. Knepley   switch (refiner) {
1733478d7aaSMatthew G. Knepley   case 0: break;
17475d3a19aSMatthew G. Knepley   case 1:
17575d3a19aSMatthew G. Knepley     /* Simplicial 2D */
17675d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
17775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
17875d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
17975d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
18075d3a19aSMatthew G. Knepley 
18175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
18275d3a19aSMatthew G. Knepley       }
18375d3a19aSMatthew G. Knepley     }
18475d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
18575d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
18675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
18775d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
18875d3a19aSMatthew G. Knepley         PetscInt       size;
18975d3a19aSMatthew G. Knepley 
19075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
19175d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
19275d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
19375d3a19aSMatthew G. Knepley       }
19475d3a19aSMatthew G. Knepley     }
19575d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
19675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
19775d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
19875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
19975d3a19aSMatthew G. Knepley 
20075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
20175d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
20275d3a19aSMatthew G. Knepley       }
20375d3a19aSMatthew G. Knepley     }
20475d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
20575d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
20675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
20775d3a19aSMatthew G. Knepley       PetscInt       size;
20875d3a19aSMatthew G. Knepley 
20975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
21075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
21175d3a19aSMatthew G. Knepley     }
21275d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
21375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
21475d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
21575d3a19aSMatthew G. Knepley       PetscInt       size;
21675d3a19aSMatthew G. Knepley 
21775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
21875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
21975d3a19aSMatthew G. Knepley     }
22075d3a19aSMatthew G. Knepley     break;
22175d3a19aSMatthew G. Knepley   case 2:
22275d3a19aSMatthew G. Knepley     /* Hex 2D */
22375d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
22475d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
22575d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
226*149f48fdSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
22775d3a19aSMatthew G. Knepley 
22875d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
22975d3a19aSMatthew G. Knepley       }
23075d3a19aSMatthew G. Knepley     }
23175d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
23275d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
23375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
23475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
23575d3a19aSMatthew G. Knepley         PetscInt       size;
23675d3a19aSMatthew G. Knepley 
23775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
23875d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
23975d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
24075d3a19aSMatthew G. Knepley       }
24175d3a19aSMatthew G. Knepley     }
24275d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
24375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
24475d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
24575d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
24675d3a19aSMatthew G. Knepley 
24775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
24875d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
24975d3a19aSMatthew G. Knepley       }
25075d3a19aSMatthew G. Knepley     }
25175d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
25275d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
25375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
25475d3a19aSMatthew G. Knepley       PetscInt       size;
25575d3a19aSMatthew G. Knepley 
25675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
25775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
25875d3a19aSMatthew G. Knepley     }
25975d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
26075d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
26175d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
26275d3a19aSMatthew G. Knepley       PetscInt       size;
26375d3a19aSMatthew G. Knepley 
26475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
26575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
26675d3a19aSMatthew G. Knepley     }
26775d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
26875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
26975d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
27075d3a19aSMatthew G. Knepley 
27175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
27275d3a19aSMatthew G. Knepley     }
27375d3a19aSMatthew G. Knepley     break;
27475d3a19aSMatthew G. Knepley   case 3:
275d963de37SMatthew G. Knepley     /* Hybrid Simplicial 2D */
27675d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
27775d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
27875d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
27975d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
28075d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
28175d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
28275d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
28375d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
28475d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
28575d3a19aSMatthew G. Knepley 
28675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
28775d3a19aSMatthew G. Knepley       }
28875d3a19aSMatthew G. Knepley     }
28975d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
29075d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
29175d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
29275d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
29375d3a19aSMatthew G. Knepley 
29475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
29575d3a19aSMatthew G. Knepley       }
29675d3a19aSMatthew G. Knepley     }
29775d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
29875d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
29975d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
30075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
30175d3a19aSMatthew G. Knepley         PetscInt       size;
30275d3a19aSMatthew G. Knepley 
30375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
30475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
30575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
30675d3a19aSMatthew G. Knepley       }
30775d3a19aSMatthew G. Knepley     }
30875d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
30975d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
31075d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
31175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
31275d3a19aSMatthew G. Knepley 
31375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
31475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
31575d3a19aSMatthew G. Knepley       }
31675d3a19aSMatthew G. Knepley     }
31775d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
31875d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
31975d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
32075d3a19aSMatthew G. Knepley       PetscInt       size;
32175d3a19aSMatthew G. Knepley 
32275d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
32375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
32475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
32575d3a19aSMatthew G. Knepley     }
32675d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
32775d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
32875d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
32975d3a19aSMatthew G. Knepley 
33075d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
33175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
33275d3a19aSMatthew G. Knepley     }
33375d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
33475d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
33575d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
33675d3a19aSMatthew G. Knepley       PetscInt       size;
33775d3a19aSMatthew G. Knepley 
33875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
33975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
34075d3a19aSMatthew G. Knepley     }
34175d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
34275d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
34375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
34475d3a19aSMatthew G. Knepley       const PetscInt *support;
34575d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
34675d3a19aSMatthew G. Knepley 
34775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
34875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
34975d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
35075d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
35175d3a19aSMatthew G. Knepley         else newSize += 2;
35275d3a19aSMatthew G. Knepley       }
35375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
35475d3a19aSMatthew G. Knepley     }
35575d3a19aSMatthew G. Knepley     break;
356b5da9499SMatthew G. Knepley   case 5:
357b5da9499SMatthew G. Knepley     /* Simplicial 3D */
358b5da9499SMatthew G. Knepley     /* All cells have 4 faces */
359b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
360b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
361dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
362b5da9499SMatthew G. Knepley 
363b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
364b5da9499SMatthew G. Knepley       }
365b5da9499SMatthew G. Knepley     }
366b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
367b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
368b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
369b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
370b5da9499SMatthew G. Knepley         PetscInt       size;
371b5da9499SMatthew G. Knepley 
372b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
373b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
374b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
375b5da9499SMatthew G. Knepley       }
376b5da9499SMatthew G. Knepley     }
3779ddff745SMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
378b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
379b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
380b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
381b5da9499SMatthew G. Knepley 
382b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
383b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
384b5da9499SMatthew G. Knepley       }
385b5da9499SMatthew G. Knepley     }
386b5da9499SMatthew G. Knepley     /* Split edges have 2 vertices and the same faces */
387b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
388b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
389b5da9499SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
390b5da9499SMatthew G. Knepley         PetscInt       size;
391b5da9499SMatthew G. Knepley 
392b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
393b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
394b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
395b5da9499SMatthew G. Knepley       }
396b5da9499SMatthew G. Knepley     }
397b5da9499SMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
398b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
399b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
400b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
401b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
402b5da9499SMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
403b5da9499SMatthew G. Knepley 
404b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
405b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
406b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
407b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
408b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
409b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
410b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
411b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
41286f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
4139ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
414b5da9499SMatthew G. Knepley           if (er == eint[c]) {
415b5da9499SMatthew G. Knepley             intFaces += 1;
416b5da9499SMatthew G. Knepley           } else {
417b5da9499SMatthew G. Knepley             intFaces += 2;
418b5da9499SMatthew G. Knepley           }
419b5da9499SMatthew G. Knepley         }
420b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
421b5da9499SMatthew G. Knepley       }
422b5da9499SMatthew G. Knepley     }
4239ddff745SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
424b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
425b5da9499SMatthew G. Knepley       const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
426b5da9499SMatthew G. Knepley 
427b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
428b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
429b5da9499SMatthew G. Knepley     }
430b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
431b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
432b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
433b5da9499SMatthew G. Knepley       PetscInt       size;
434b5da9499SMatthew G. Knepley 
435b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
436b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
437b5da9499SMatthew G. Knepley     }
438b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
439b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
440b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
441b5da9499SMatthew G. Knepley       PetscInt       size, *star = NULL, starSize, s, cellSize = 0;
442b5da9499SMatthew G. Knepley 
443b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
444b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
445b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
446b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
447b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
448b5da9499SMatthew G. Knepley 
449b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
450b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
451b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
452b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
453b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
45442525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
455b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
456b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
457b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
45842525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
45942525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
460b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
461b5da9499SMatthew G. Knepley         }
462b5da9499SMatthew G. Knepley       }
463b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
464b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr);
465b5da9499SMatthew G. Knepley     }
466b5da9499SMatthew G. Knepley     break;
467dae4404aSMatthew G. Knepley   case 7:
4686ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
4696ce3c06aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
4706ce3c06aSMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
471dae4404aSMatthew G. Knepley     /* Interior cells have 4 faces */
472dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
473dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
474dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
475dae4404aSMatthew G. Knepley 
476dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
477dae4404aSMatthew G. Knepley       }
478dae4404aSMatthew G. Knepley     }
479dae4404aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
480dae4404aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
481dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
482dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
483dae4404aSMatthew G. Knepley 
484dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr);
485dae4404aSMatthew G. Knepley       }
486dae4404aSMatthew G. Knepley     }
4876ce3c06aSMatthew G. Knepley     /* Interior split faces have 3 edges and the same cells as the parent */
488dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
489dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
490dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
491dae4404aSMatthew G. Knepley         PetscInt       size;
492dae4404aSMatthew G. Knepley 
493dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
494dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
495dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
496dae4404aSMatthew G. Knepley       }
497dae4404aSMatthew G. Knepley     }
498dae4404aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
499dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
500dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
501dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
502dae4404aSMatthew G. Knepley 
503dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
504dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
505dae4404aSMatthew G. Knepley       }
506dae4404aSMatthew G. Knepley     }
5076ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
5086ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
5096ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
5106ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
5116ce3c06aSMatthew G. Knepley         PetscInt       size;
5126ce3c06aSMatthew G. Knepley 
5136ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
5146ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
5156ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
5166ce3c06aSMatthew G. Knepley       }
5176ce3c06aSMatthew G. Knepley     }
5186ce3c06aSMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
5196ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
5206ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
5216ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
5226ce3c06aSMatthew G. Knepley 
5236ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
5246ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
5256ce3c06aSMatthew G. Knepley       }
5266ce3c06aSMatthew G. Knepley     }
5276ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces */
528dae4404aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
529dae4404aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
530dae4404aSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
531dae4404aSMatthew G. Knepley         PetscInt       size;
532dae4404aSMatthew G. Knepley 
533dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
534dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
535dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
536dae4404aSMatthew G. Knepley       }
537dae4404aSMatthew G. Knepley     }
5386ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
539dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
540dae4404aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
541dae4404aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
542dae4404aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
543dae4404aSMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
544dae4404aSMatthew G. Knepley 
545dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
546dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
547dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
548dae4404aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
549dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
550dae4404aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
551dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
552dae4404aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
5536ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
554dae4404aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
5559ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
556dae4404aSMatthew G. Knepley             if (er == eint[c]) {
557dae4404aSMatthew G. Knepley               intFaces += 1;
558dae4404aSMatthew G. Knepley             } else {
559dae4404aSMatthew G. Knepley               intFaces += 2;
560dae4404aSMatthew G. Knepley             }
5616ce3c06aSMatthew G. Knepley           } else {
5626ce3c06aSMatthew G. Knepley             intFaces += 1;
5636ce3c06aSMatthew G. Knepley           }
564dae4404aSMatthew G. Knepley         }
565dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
566dae4404aSMatthew G. Knepley       }
567dae4404aSMatthew G. Knepley     }
5686ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
569dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
570dae4404aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
571dae4404aSMatthew G. Knepley 
572dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
573dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
574dae4404aSMatthew G. Knepley     }
5756ce3c06aSMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
576dae4404aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
5776ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
5786ce3c06aSMatthew G. Knepley       PetscInt       size;
5796ce3c06aSMatthew G. Knepley 
5806ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
5816ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
5826ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
5836ce3c06aSMatthew G. Knepley     }
5846ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
5856ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
5866ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
587dae4404aSMatthew G. Knepley       PetscInt       size;
588dae4404aSMatthew G. Knepley 
589dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
590dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
5916ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr);
592dae4404aSMatthew G. Knepley     }
5936ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
594dae4404aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
595dae4404aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
596dae4404aSMatthew G. Knepley       PetscInt       size;
597dae4404aSMatthew G. Knepley 
598dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
599dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
600dae4404aSMatthew G. Knepley     }
6016ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
6026ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
6036ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
604dae4404aSMatthew G. Knepley       const PetscInt *support;
6056ce3c06aSMatthew G. Knepley       PetscInt        size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
606dae4404aSMatthew G. Knepley 
6076ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
6086ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
609dae4404aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
6106ce3c06aSMatthew G. Knepley         if (support[s] < fMax) faceSize += 2;
6116ce3c06aSMatthew G. Knepley         else                   faceSize += 1;
612dae4404aSMatthew G. Knepley       }
6136ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
6146ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
6156ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
6166ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
6176ce3c06aSMatthew G. Knepley 
6186ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
6196ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
6206ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
6216ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
6226ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
6236ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
6246ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
6256ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
6266ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
6276ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
6286ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
6296ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
6306ce3c06aSMatthew G. Knepley         }
6316ce3c06aSMatthew G. Knepley       }
6326ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
6336ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr);
634dae4404aSMatthew G. Knepley     }
635dae4404aSMatthew G. Knepley     break;
6362eabf88fSMatthew G. Knepley   case 6:
6372eabf88fSMatthew G. Knepley     /* Hex 3D */
6382eabf88fSMatthew G. Knepley     /* All cells have 6 faces */
6392eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6402eabf88fSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
6412eabf88fSMatthew G. Knepley         const PetscInt newp = (c - cStart)*8 + r;
6422eabf88fSMatthew G. Knepley 
6432eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
6442eabf88fSMatthew G. Knepley       }
6452eabf88fSMatthew G. Knepley     }
6462eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
6472eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
6482eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
6492eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
6502eabf88fSMatthew G. Knepley         PetscInt       size;
6512eabf88fSMatthew G. Knepley 
6522eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
6532eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
6542eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6552eabf88fSMatthew G. Knepley       }
6562eabf88fSMatthew G. Knepley     }
6572eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
6582eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6592eabf88fSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
6602eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
6612eabf88fSMatthew G. Knepley 
6622eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
6632eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
6642eabf88fSMatthew G. Knepley       }
6652eabf88fSMatthew G. Knepley     }
6662eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
6672eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
6682eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
6692eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
6702eabf88fSMatthew G. Knepley         PetscInt       size;
6712eabf88fSMatthew G. Knepley 
6722eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6732eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
6742eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6752eabf88fSMatthew G. Knepley       }
6762eabf88fSMatthew G. Knepley     }
6772eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
6782eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
6792eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
6802eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
6812eabf88fSMatthew G. Knepley         PetscInt       size;
6822eabf88fSMatthew G. Knepley 
6832eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6842eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
6852eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
6862eabf88fSMatthew G. Knepley       }
6872eabf88fSMatthew G. Knepley     }
6882eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
6892eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6902eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
6912eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
6922eabf88fSMatthew G. Knepley 
6932eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6942eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
6952eabf88fSMatthew G. Knepley       }
6962eabf88fSMatthew G. Knepley     }
6972eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
6982eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
6992eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
7002eabf88fSMatthew G. Knepley       PetscInt       size;
7012eabf88fSMatthew G. Knepley 
7022eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
7032eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
7042eabf88fSMatthew G. Knepley     }
7052eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
7062eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
7072eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
7082eabf88fSMatthew G. Knepley       PetscInt       size;
7092eabf88fSMatthew G. Knepley 
7102eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
7112eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
7122eabf88fSMatthew G. Knepley     }
7132eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
7142eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
7152eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
7162eabf88fSMatthew G. Knepley       PetscInt       size;
7172eabf88fSMatthew G. Knepley 
7182eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
7192eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
7202eabf88fSMatthew G. Knepley     }
7212eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
7222eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
7232eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
7242eabf88fSMatthew G. Knepley 
7252eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
7262eabf88fSMatthew G. Knepley     }
7272eabf88fSMatthew G. Knepley     break;
72827fcede3SMatthew G. Knepley   case 8:
72927fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
73027fcede3SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
73127fcede3SMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
73227fcede3SMatthew G. Knepley     /* Interior cells have 6 faces */
73327fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
73427fcede3SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
73527fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
73627fcede3SMatthew G. Knepley 
73727fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
73827fcede3SMatthew G. Knepley       }
73927fcede3SMatthew G. Knepley     }
74027fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces */
74127fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
74227fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
74327fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
74427fcede3SMatthew G. Knepley 
74527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
74627fcede3SMatthew G. Knepley       }
74727fcede3SMatthew G. Knepley     }
74827fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
74927fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
75027fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
75127fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
75227fcede3SMatthew G. Knepley         PetscInt       size;
75327fcede3SMatthew G. Knepley 
75427fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
75527fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
75627fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
75727fcede3SMatthew G. Knepley       }
75827fcede3SMatthew G. Knepley     }
75927fcede3SMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
76027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
76127fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
76227fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
76327fcede3SMatthew G. Knepley 
76427fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
76527fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
76627fcede3SMatthew G. Knepley       }
76727fcede3SMatthew G. Knepley     }
76827fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
76927fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
77027fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
77127fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
77227fcede3SMatthew G. Knepley         PetscInt       size;
77327fcede3SMatthew G. Knepley 
77427fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
77527fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
77627fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
77727fcede3SMatthew G. Knepley       }
77827fcede3SMatthew G. Knepley     }
77927fcede3SMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
78027fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
78127fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
78227fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
78327fcede3SMatthew G. Knepley 
78427fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
78527fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
78627fcede3SMatthew G. Knepley       }
78727fcede3SMatthew G. Knepley     }
78827fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
78927fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
79027fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
79127fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
79227fcede3SMatthew G. Knepley         PetscInt       size;
79327fcede3SMatthew G. Knepley 
79427fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
79527fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
79627fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
79727fcede3SMatthew G. Knepley       }
79827fcede3SMatthew G. Knepley     }
79927fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
80027fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
80127fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
80227fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
80327fcede3SMatthew G. Knepley         PetscInt       size;
80427fcede3SMatthew G. Knepley 
80527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
80627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
80727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
80827fcede3SMatthew G. Knepley       }
80927fcede3SMatthew G. Knepley     }
81027fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
81127fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
81227fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
81327fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
81427fcede3SMatthew G. Knepley 
81527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
81627fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
81727fcede3SMatthew G. Knepley       }
81827fcede3SMatthew G. Knepley     }
81927fcede3SMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
82027fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
82127fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
82227fcede3SMatthew G. Knepley       PetscInt       size;
82327fcede3SMatthew G. Knepley 
82427fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
82527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
82627fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
82727fcede3SMatthew G. Knepley     }
82827fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
82927fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
83027fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
83127fcede3SMatthew G. Knepley       PetscInt       size;
83227fcede3SMatthew G. Knepley 
83327fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
83427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
83527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
83627fcede3SMatthew G. Knepley     }
83727fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
83827fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
83927fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
84027fcede3SMatthew G. Knepley 
84127fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
84227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
84327fcede3SMatthew G. Knepley     }
84427fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
84527fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
84627fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
84727fcede3SMatthew G. Knepley       PetscInt       size;
84827fcede3SMatthew G. Knepley 
84927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
85027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
85127fcede3SMatthew G. Knepley     }
85227fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
85327fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
85427fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
85527fcede3SMatthew G. Knepley       PetscInt       size;
85627fcede3SMatthew G. Knepley 
85727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
85827fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
85927fcede3SMatthew G. Knepley     }
86027fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
86127fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
86227fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
86327fcede3SMatthew G. Knepley       PetscInt       size;
86427fcede3SMatthew G. Knepley 
86527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
86627fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
86727fcede3SMatthew G. Knepley     }
86827fcede3SMatthew G. Knepley     /* Interior cell vertices have 6 supports */
86927fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
87027fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
87127fcede3SMatthew G. Knepley 
87227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
87327fcede3SMatthew G. Knepley     }
87427fcede3SMatthew G. Knepley     break;
87575d3a19aSMatthew G. Knepley   default:
87675d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
87775d3a19aSMatthew G. Knepley   }
87875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
87975d3a19aSMatthew G. Knepley }
88075d3a19aSMatthew G. Knepley 
88175d3a19aSMatthew G. Knepley #undef __FUNCT__
88275d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCones"
88386150812SJed Brown static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
88475d3a19aSMatthew G. Knepley {
885b5da9499SMatthew G. Knepley   const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
8866ce3c06aSMatthew G. Knepley   PetscInt        cStart,    cEnd,    cMax,    vStart,    vEnd, vMax, fStart,    fEnd,    fMax,    eStart,    eEnd,    eMax;
8876ce3c06aSMatthew G. Knepley   PetscInt        cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew,    fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
8886ce3c06aSMatthew G. Knepley   PetscInt        depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
88975d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
89075d3a19aSMatthew G. Knepley 
89175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
89275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
89375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
89475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
89575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
89675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
89775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
8983478d7aaSMatthew G. Knepley   if (refiner) {
89975d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
90075d3a19aSMatthew G. Knepley     ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
9013478d7aaSMatthew G. Knepley   }
90275d3a19aSMatthew G. Knepley   switch (refiner) {
9033478d7aaSMatthew G. Knepley   case 0: break;
90475d3a19aSMatthew G. Knepley   case 1:
90575d3a19aSMatthew G. Knepley     /* Simplicial 2D */
90675d3a19aSMatthew G. Knepley     /*
90775d3a19aSMatthew G. Knepley      2
90875d3a19aSMatthew G. Knepley      |\
90975d3a19aSMatthew G. Knepley      | \
91075d3a19aSMatthew G. Knepley      |  \
91175d3a19aSMatthew G. Knepley      |   \
91275d3a19aSMatthew G. Knepley      | C  \
91375d3a19aSMatthew G. Knepley      |     \
91475d3a19aSMatthew G. Knepley      |      \
91575d3a19aSMatthew G. Knepley      2---1---1
91675d3a19aSMatthew G. Knepley      |\  D  / \
91775d3a19aSMatthew G. Knepley      | 2   0   \
91875d3a19aSMatthew G. Knepley      |A \ /  B  \
91975d3a19aSMatthew G. Knepley      0---0-------1
92075d3a19aSMatthew G. Knepley      */
92175d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
92275d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
92375d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
92475d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
92575d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
92675d3a19aSMatthew G. Knepley 
92775d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
92875d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
92975d3a19aSMatthew G. Knepley       /* A triangle */
93075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
93175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
93275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
93375d3a19aSMatthew G. Knepley       orntNew[1] = -2;
93475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
93575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
93675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
93775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
93875d3a19aSMatthew G. Knepley #if 1
93975d3a19aSMatthew 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);
94075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
94175d3a19aSMatthew 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);
94275d3a19aSMatthew G. Knepley       }
94375d3a19aSMatthew G. Knepley #endif
94475d3a19aSMatthew G. Knepley       /* B triangle */
94575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
94675d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
94775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
94875d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
94975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
95075d3a19aSMatthew G. Knepley       orntNew[2] = -2;
95175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
95275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
95375d3a19aSMatthew G. Knepley #if 1
95475d3a19aSMatthew 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);
95575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
95675d3a19aSMatthew 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);
95775d3a19aSMatthew G. Knepley       }
95875d3a19aSMatthew G. Knepley #endif
95975d3a19aSMatthew G. Knepley       /* C triangle */
96075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
96175d3a19aSMatthew G. Knepley       orntNew[0] = -2;
96275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
96375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
96475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
96575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
96675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
96775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
96875d3a19aSMatthew G. Knepley #if 1
96975d3a19aSMatthew 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);
97075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
97175d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
97275d3a19aSMatthew G. Knepley       }
97375d3a19aSMatthew G. Knepley #endif
97475d3a19aSMatthew G. Knepley       /* D triangle */
97575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
97675d3a19aSMatthew G. Knepley       orntNew[0] = 0;
97775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
97875d3a19aSMatthew G. Knepley       orntNew[1] = 0;
97975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
98075d3a19aSMatthew G. Knepley       orntNew[2] = 0;
98175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
98275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
98375d3a19aSMatthew G. Knepley #if 1
98475d3a19aSMatthew 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);
98575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++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     }
99075d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
99175d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
992785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
99375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
99475d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
99575d3a19aSMatthew G. Knepley 
99675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
99775d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
998297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
99975d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
100075d3a19aSMatthew G. Knepley 
100175d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
100275d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
100375d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
100475d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
100575d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
100675d3a19aSMatthew G. Knepley #if 1
100775d3a19aSMatthew 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);
100875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
100975d3a19aSMatthew 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);
101075d3a19aSMatthew G. Knepley         }
101175d3a19aSMatthew G. Knepley #endif
101275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
101375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
101475d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
101575d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
101675d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1017297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
101875d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
101975d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
102075d3a19aSMatthew G. Knepley           }
1021297d2bf4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
102275d3a19aSMatthew G. Knepley         }
102375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
102475d3a19aSMatthew G. Knepley #if 1
102575d3a19aSMatthew 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);
102675d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
102775d3a19aSMatthew 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);
102875d3a19aSMatthew G. Knepley         }
102975d3a19aSMatthew G. Knepley #endif
103075d3a19aSMatthew G. Knepley       }
103175d3a19aSMatthew G. Knepley     }
103275d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
103375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
103475d3a19aSMatthew G. Knepley       const PetscInt *cone;
103575d3a19aSMatthew G. Knepley 
103675d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
103775d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
103875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
103975d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
104075d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
104175d3a19aSMatthew G. Knepley 
104275d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
104375d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
104475d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
104575d3a19aSMatthew G. Knepley #if 1
104675d3a19aSMatthew 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);
104775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
104875d3a19aSMatthew 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);
104975d3a19aSMatthew G. Knepley         }
105075d3a19aSMatthew G. Knepley #endif
105175d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
105275d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
105375d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
105475d3a19aSMatthew G. Knepley #if 1
105575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
105675d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
105775d3a19aSMatthew 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);
105875d3a19aSMatthew G. Knepley         }
105975d3a19aSMatthew G. Knepley #endif
106075d3a19aSMatthew G. Knepley       }
106175d3a19aSMatthew G. Knepley     }
106275d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
106375d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
106475d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
106575d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
106675d3a19aSMatthew G. Knepley       PetscInt        size, s;
106775d3a19aSMatthew G. Knepley 
106875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
106975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
107075d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
107175d3a19aSMatthew G. Knepley         PetscInt r = 0;
107275d3a19aSMatthew G. Knepley 
107375d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
107475d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
107575d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
107675d3a19aSMatthew G. Knepley       }
107775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
107875d3a19aSMatthew G. Knepley #if 1
107975d3a19aSMatthew 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);
108075d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
108175d3a19aSMatthew 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);
108275d3a19aSMatthew G. Knepley       }
108375d3a19aSMatthew G. Knepley #endif
108475d3a19aSMatthew G. Knepley     }
108575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
108675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
108775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
108875d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
108975d3a19aSMatthew G. Knepley       PetscInt        size, s;
109075d3a19aSMatthew G. Knepley 
109175d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
109275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
109375d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
109475d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
109575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
109675d3a19aSMatthew G. Knepley         PetscInt r = 0;
109775d3a19aSMatthew G. Knepley 
109875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
109975d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
110075d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
110175d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
110275d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
110375d3a19aSMatthew G. Knepley       }
110475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
110575d3a19aSMatthew G. Knepley #if 1
110675d3a19aSMatthew 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);
110775d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
110875d3a19aSMatthew 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);
110975d3a19aSMatthew G. Knepley       }
111075d3a19aSMatthew G. Knepley #endif
111175d3a19aSMatthew G. Knepley     }
111275d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
111375d3a19aSMatthew G. Knepley     break;
111475d3a19aSMatthew G. Knepley   case 2:
111575d3a19aSMatthew G. Knepley     /* Hex 2D */
111675d3a19aSMatthew G. Knepley     /*
111775d3a19aSMatthew G. Knepley      3---------2---------2
111875d3a19aSMatthew G. Knepley      |         |         |
111975d3a19aSMatthew G. Knepley      |    D    2    C    |
112075d3a19aSMatthew G. Knepley      |         |         |
112175d3a19aSMatthew G. Knepley      3----3----0----1----1
112275d3a19aSMatthew G. Knepley      |         |         |
112375d3a19aSMatthew G. Knepley      |    A    0    B    |
112475d3a19aSMatthew G. Knepley      |         |         |
112575d3a19aSMatthew G. Knepley      0---------0---------1
112675d3a19aSMatthew G. Knepley      */
112775d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
112875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
112975d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
113075d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
113175d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
113275d3a19aSMatthew G. Knepley 
113375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
113475d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
113575d3a19aSMatthew G. Knepley       /* A quad */
113675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
113775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
113875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
113975d3a19aSMatthew G. Knepley       orntNew[1] = 0;
114075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
114175d3a19aSMatthew G. Knepley       orntNew[2] = -2;
114275d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
114375d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
114475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
114575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
114675d3a19aSMatthew G. Knepley #if 1
114775d3a19aSMatthew 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);
114875d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
114975d3a19aSMatthew 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);
115075d3a19aSMatthew G. Knepley       }
115175d3a19aSMatthew G. Knepley #endif
115275d3a19aSMatthew G. Knepley       /* B quad */
115375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
115475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
115575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
115675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
115775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
115875d3a19aSMatthew G. Knepley       orntNew[2] = 0;
115975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
116075d3a19aSMatthew G. Knepley       orntNew[3] = -2;
116175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
116275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
116375d3a19aSMatthew G. Knepley #if 1
116475d3a19aSMatthew 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);
116575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
116675d3a19aSMatthew 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);
116775d3a19aSMatthew G. Knepley       }
116875d3a19aSMatthew G. Knepley #endif
116975d3a19aSMatthew G. Knepley       /* C quad */
117075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
117175d3a19aSMatthew G. Knepley       orntNew[0] = -2;
117275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
117375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
117475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
117575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
117675d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
117775d3a19aSMatthew G. Knepley       orntNew[3] = 0;
117875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
117975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
118075d3a19aSMatthew G. Knepley #if 1
118175d3a19aSMatthew 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);
118275d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
118375d3a19aSMatthew 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);
118475d3a19aSMatthew G. Knepley       }
118575d3a19aSMatthew G. Knepley #endif
118675d3a19aSMatthew G. Knepley       /* D quad */
118775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
118875d3a19aSMatthew G. Knepley       orntNew[0] = 0;
118975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
119075d3a19aSMatthew G. Knepley       orntNew[1] = -2;
119175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
119275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
119375d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
119475d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
119575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
119675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
119775d3a19aSMatthew G. Knepley #if 1
119875d3a19aSMatthew 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);
119975d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
120075d3a19aSMatthew 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);
120175d3a19aSMatthew G. Knepley       }
120275d3a19aSMatthew G. Knepley #endif
120375d3a19aSMatthew G. Knepley     }
120475d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
120575d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1206785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
120775d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
120875d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
120975d3a19aSMatthew G. Knepley 
121075d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
121175d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1212455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
121375d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
121475d3a19aSMatthew G. Knepley 
121575d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
121675d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
121775d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
121875d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
121975d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
122075d3a19aSMatthew G. Knepley #if 1
122175d3a19aSMatthew 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);
122275d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
122375d3a19aSMatthew 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);
122475d3a19aSMatthew G. Knepley         }
122575d3a19aSMatthew G. Knepley #endif
122675d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
122775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
122875d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
122975d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
123075d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1231455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
123275d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
123375d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
123475d3a19aSMatthew G. Knepley           }
1235455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
123675d3a19aSMatthew G. Knepley         }
123775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
123875d3a19aSMatthew G. Knepley #if 1
123975d3a19aSMatthew 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);
124075d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
124175d3a19aSMatthew 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);
124275d3a19aSMatthew G. Knepley         }
124375d3a19aSMatthew G. Knepley #endif
124475d3a19aSMatthew G. Knepley       }
124575d3a19aSMatthew G. Knepley     }
124675d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
124775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
124875d3a19aSMatthew G. Knepley       const PetscInt *cone;
124975d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
125075d3a19aSMatthew G. Knepley 
125175d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
125275d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
125375d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
125475d3a19aSMatthew G. Knepley 
125575d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
125675d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
125775d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
125875d3a19aSMatthew G. Knepley #if 1
125975d3a19aSMatthew 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);
126075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
126175d3a19aSMatthew 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);
126275d3a19aSMatthew G. Knepley         }
126375d3a19aSMatthew G. Knepley #endif
126475d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
126575d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
126675d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
126775d3a19aSMatthew G. Knepley #if 1
126875d3a19aSMatthew 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);
126975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
127075d3a19aSMatthew 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);
127175d3a19aSMatthew G. Knepley         }
127275d3a19aSMatthew G. Knepley #endif
127375d3a19aSMatthew G. Knepley       }
127475d3a19aSMatthew G. Knepley     }
127575d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
127675d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
127775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
127875d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
127975d3a19aSMatthew G. Knepley       PetscInt        size, s;
128075d3a19aSMatthew G. Knepley 
128175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
128275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
128375d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
128475d3a19aSMatthew G. Knepley         PetscInt r = 0;
128575d3a19aSMatthew G. Knepley 
128675d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
128775d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
128875d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
128975d3a19aSMatthew G. Knepley       }
129075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
129175d3a19aSMatthew G. Knepley #if 1
129275d3a19aSMatthew 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);
129375d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
129475d3a19aSMatthew 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);
129575d3a19aSMatthew G. Knepley       }
129675d3a19aSMatthew G. Knepley #endif
129775d3a19aSMatthew G. Knepley     }
129875d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
129975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
130075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
130175d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
130275d3a19aSMatthew G. Knepley       PetscInt        size, s;
130375d3a19aSMatthew G. Knepley 
130475d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
130575d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
130675d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
130775d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
130875d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
130975d3a19aSMatthew G. Knepley         PetscInt r = 0;
131075d3a19aSMatthew G. Knepley 
131175d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
131275d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
131375d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
131475d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
131575d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
131675d3a19aSMatthew G. Knepley       }
131775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
131875d3a19aSMatthew G. Knepley #if 1
131975d3a19aSMatthew 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);
132075d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
132175d3a19aSMatthew 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);
132275d3a19aSMatthew G. Knepley       }
132375d3a19aSMatthew G. Knepley #endif
132475d3a19aSMatthew G. Knepley     }
132575d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
132675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
132775d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
132875d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
132975d3a19aSMatthew G. Knepley 
133075d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
133175d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
133275d3a19aSMatthew G. Knepley       }
133375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
133475d3a19aSMatthew G. Knepley     }
1335da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
133675d3a19aSMatthew G. Knepley     break;
133775d3a19aSMatthew G. Knepley   case 3:
1338*149f48fdSMatthew G. Knepley     /* Hybrid Simplicial 2D */
133975d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
134075d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
134175d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
134275d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
1343*149f48fdSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
134475d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
134575d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
134675d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
134775d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
134875d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
134975d3a19aSMatthew G. Knepley 
135075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
135175d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
135275d3a19aSMatthew G. Knepley       /* A triangle */
135375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
135475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
135575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
135675d3a19aSMatthew G. Knepley       orntNew[1] = -2;
135775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
135875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
135975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
136075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
136175d3a19aSMatthew G. Knepley #if 1
1362*149f48fdSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+0, cStartNew, cMaxNew);
136375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1364*149f48fdSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
136575d3a19aSMatthew G. Knepley       }
136675d3a19aSMatthew G. Knepley #endif
136775d3a19aSMatthew G. Knepley       /* B triangle */
136875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
136975d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
137075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
137175d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
137275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
137375d3a19aSMatthew G. Knepley       orntNew[2] = -2;
137475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
137575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
137675d3a19aSMatthew G. Knepley #if 1
137775d3a19aSMatthew 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);
137875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
137975d3a19aSMatthew 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);
138075d3a19aSMatthew G. Knepley       }
138175d3a19aSMatthew G. Knepley #endif
138275d3a19aSMatthew G. Knepley       /* C triangle */
138375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
138475d3a19aSMatthew G. Knepley       orntNew[0] = -2;
138575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
138675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
138775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
138875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
138975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
139075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
139175d3a19aSMatthew G. Knepley #if 1
139275d3a19aSMatthew 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);
139375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
139475d3a19aSMatthew 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);
139575d3a19aSMatthew G. Knepley       }
139675d3a19aSMatthew G. Knepley #endif
139775d3a19aSMatthew G. Knepley       /* D triangle */
139875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
139975d3a19aSMatthew G. Knepley       orntNew[0] = 0;
140075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
140175d3a19aSMatthew G. Knepley       orntNew[1] = 0;
140275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
140375d3a19aSMatthew G. Knepley       orntNew[2] = 0;
140475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
140575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
140675d3a19aSMatthew G. Knepley #if 1
140775d3a19aSMatthew 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);
140875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
140975d3a19aSMatthew 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);
141075d3a19aSMatthew G. Knepley       }
141175d3a19aSMatthew G. Knepley #endif
141275d3a19aSMatthew G. Knepley     }
141375d3a19aSMatthew G. Knepley     /*
141475d3a19aSMatthew G. Knepley      2----3----3
141575d3a19aSMatthew G. Knepley      |         |
141675d3a19aSMatthew G. Knepley      |    B    |
141775d3a19aSMatthew G. Knepley      |         |
141875d3a19aSMatthew G. Knepley      0----4--- 1
141975d3a19aSMatthew G. Knepley      |         |
142075d3a19aSMatthew G. Knepley      |    A    |
142175d3a19aSMatthew G. Knepley      |         |
142275d3a19aSMatthew G. Knepley      0----2----1
142375d3a19aSMatthew G. Knepley      */
142475d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
142575d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
142675d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
142775d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
142875d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
142975d3a19aSMatthew G. Knepley 
143075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
143175d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
143275d3a19aSMatthew G. Knepley       /* A quad */
143375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
143475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
143575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
143675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
143775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2] - fMax);
143875d3a19aSMatthew G. Knepley       orntNew[2] = 0;
143975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
144075d3a19aSMatthew G. Knepley       orntNew[3] = 0;
144175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
144275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
144375d3a19aSMatthew G. Knepley #if 1
144475d3a19aSMatthew 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);
144575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
144675d3a19aSMatthew 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);
144775d3a19aSMatthew G. Knepley       }
144875d3a19aSMatthew G. Knepley #endif
144975d3a19aSMatthew G. Knepley       /* B quad */
145075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
145175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
145275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
145375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
145475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
145575d3a19aSMatthew G. Knepley       orntNew[2] = 0;
145675d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3] - fMax);
145775d3a19aSMatthew G. Knepley       orntNew[3] = 0;
145875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
145975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
146075d3a19aSMatthew G. Knepley #if 1
146175d3a19aSMatthew 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);
146275d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
146375d3a19aSMatthew 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);
146475d3a19aSMatthew G. Knepley       }
146575d3a19aSMatthew G. Knepley #endif
146675d3a19aSMatthew G. Knepley     }
146775d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
146875d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1469785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
147075d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
147175d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
147275d3a19aSMatthew G. Knepley 
147375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
147475d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1475297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
147675d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
147775d3a19aSMatthew G. Knepley 
147875d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
147975d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
148075d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
148175d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
148275d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
148375d3a19aSMatthew G. Knepley #if 1
148475d3a19aSMatthew 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);
148575d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
148675d3a19aSMatthew 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);
148775d3a19aSMatthew G. Knepley         }
148875d3a19aSMatthew G. Knepley #endif
148975d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
149075d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
149175d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
149275d3a19aSMatthew G. Knepley           if (support[s] >= cMax) {
149375d3a19aSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
149475d3a19aSMatthew G. Knepley           } else {
149575d3a19aSMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
149675d3a19aSMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1497297d2bf4SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
149875d3a19aSMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
149975d3a19aSMatthew G. Knepley               if (cone[c] == f) break;
150075d3a19aSMatthew G. Knepley             }
1501297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
150275d3a19aSMatthew G. Knepley           }
150375d3a19aSMatthew G. Knepley         }
150475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
150575d3a19aSMatthew G. Knepley #if 1
150675d3a19aSMatthew 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);
150775d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
150875d3a19aSMatthew 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);
150975d3a19aSMatthew G. Knepley         }
151075d3a19aSMatthew G. Knepley #endif
151175d3a19aSMatthew G. Knepley       }
151275d3a19aSMatthew G. Knepley     }
151375d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
151475d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
151575d3a19aSMatthew G. Knepley       const PetscInt *cone;
151675d3a19aSMatthew G. Knepley 
151775d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
151875d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
151975d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
152075d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
152175d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
152275d3a19aSMatthew G. Knepley 
152375d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
152475d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
152575d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
152675d3a19aSMatthew G. Knepley #if 1
152775d3a19aSMatthew 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);
152875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
152975d3a19aSMatthew 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);
153075d3a19aSMatthew G. Knepley         }
153175d3a19aSMatthew G. Knepley #endif
153275d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
153375d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
153475d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
153575d3a19aSMatthew G. Knepley #if 1
153675d3a19aSMatthew 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);
153775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
153875d3a19aSMatthew 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);
153975d3a19aSMatthew G. Knepley         }
154075d3a19aSMatthew G. Knepley #endif
154175d3a19aSMatthew G. Knepley       }
154275d3a19aSMatthew G. Knepley     }
154375d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
154475d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
154575d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
154675d3a19aSMatthew G. Knepley       const PetscInt *cone;
154775d3a19aSMatthew G. Knepley       const PetscInt *support;
154875d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
154975d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
155075d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
155175d3a19aSMatthew G. Knepley 
155275d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
155375d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
155475d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
155575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
155675d3a19aSMatthew G. Knepley #if 1
155775d3a19aSMatthew 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);
155875d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
155975d3a19aSMatthew 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);
156075d3a19aSMatthew G. Knepley       }
156175d3a19aSMatthew G. Knepley #endif
156275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
156375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
156475d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
156575d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
156675d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
156775d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
156875d3a19aSMatthew G. Knepley         }
156975d3a19aSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
157075d3a19aSMatthew G. Knepley       }
157175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
157275d3a19aSMatthew G. Knepley #if 1
157375d3a19aSMatthew 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);
157475d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
157575d3a19aSMatthew 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);
157675d3a19aSMatthew G. Knepley       }
157775d3a19aSMatthew G. Knepley #endif
157875d3a19aSMatthew G. Knepley     }
157975d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
158075d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
158175d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
158275d3a19aSMatthew G. Knepley       const PetscInt *cone;
158375d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
158475d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
158575d3a19aSMatthew G. Knepley 
158675d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
158775d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
158875d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
158975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
159075d3a19aSMatthew G. Knepley #if 1
159175d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
159275d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
159375d3a19aSMatthew G. Knepley         if ((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);
159475d3a19aSMatthew G. Knepley       }
159575d3a19aSMatthew G. Knepley #endif
159675d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
159775d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
159875d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
159975d3a19aSMatthew G. Knepley #if 1
160075d3a19aSMatthew 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);
160175d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
160275d3a19aSMatthew 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);
160375d3a19aSMatthew G. Knepley       }
160475d3a19aSMatthew G. Knepley #endif
160575d3a19aSMatthew G. Knepley     }
160675d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
160775d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
160875d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
160975d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
161075d3a19aSMatthew G. Knepley       PetscInt        size, s;
161175d3a19aSMatthew G. Knepley 
161275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
161375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
161475d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
161575d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
161675d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
161775d3a19aSMatthew G. Knepley         } else {
161875d3a19aSMatthew G. Knepley           PetscInt r = 0;
161975d3a19aSMatthew G. Knepley 
162075d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
162175d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
162275d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
162375d3a19aSMatthew G. Knepley         }
162475d3a19aSMatthew G. Knepley       }
162575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
162675d3a19aSMatthew G. Knepley #if 1
162775d3a19aSMatthew 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);
162875d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
162975d3a19aSMatthew 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);
163075d3a19aSMatthew G. Knepley       }
163175d3a19aSMatthew G. Knepley #endif
163275d3a19aSMatthew G. Knepley     }
163375d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
163475d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
163575d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
163675d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
163775d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
163875d3a19aSMatthew G. Knepley 
163975d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
164075d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
164175d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
164275d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
164375d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
164475d3a19aSMatthew G. Knepley         PetscInt r = 0;
164575d3a19aSMatthew G. Knepley 
164675d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
164775d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
164875d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
164975d3a19aSMatthew G. Knepley 
165075d3a19aSMatthew G. Knepley           newSize += 1;
165175d3a19aSMatthew G. Knepley         } else {
165275d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
165375d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
165475d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
165575d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
165675d3a19aSMatthew G. Knepley 
165775d3a19aSMatthew G. Knepley           newSize += 2;
165875d3a19aSMatthew G. Knepley         }
165975d3a19aSMatthew G. Knepley       }
166075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
166175d3a19aSMatthew G. Knepley #if 1
166275d3a19aSMatthew 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);
166375d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
166475d3a19aSMatthew 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);
166575d3a19aSMatthew G. Knepley       }
166675d3a19aSMatthew G. Knepley #endif
166775d3a19aSMatthew G. Knepley     }
166875d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
166975d3a19aSMatthew G. Knepley     break;
1670b5da9499SMatthew G. Knepley   case 5:
1671b5da9499SMatthew G. Knepley     /* Simplicial 3D */
1672b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
1673b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
1674b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
1675b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
1676b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
1677b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1678b5da9499SMatthew G. Knepley 
1679b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1680b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1681b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
1682518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
1683b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1684518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
1685b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1686518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
1687b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1688b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
1689b5da9499SMatthew G. Knepley       orntNew[3] = 0;
1690b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1691b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1692b5da9499SMatthew G. Knepley #if 1
1693b5da9499SMatthew 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);
1694b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1695b5da9499SMatthew 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);
1696b5da9499SMatthew G. Knepley       }
1697b5da9499SMatthew G. Knepley #endif
1698b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
1699518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
1700b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1701518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
1702b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1703b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
1704b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1705518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
1706b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1707b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1708b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1709b5da9499SMatthew G. Knepley #if 1
1710b5da9499SMatthew 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);
1711b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1712b5da9499SMatthew 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);
1713b5da9499SMatthew G. Knepley       }
1714b5da9499SMatthew G. Knepley #endif
1715b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
1716518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
1717b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1718b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
1719b5da9499SMatthew G. Knepley       orntNew[1] = 0;
1720518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
1721b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1722518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
1723b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1724b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1725b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1726b5da9499SMatthew G. Knepley #if 1
1727b5da9499SMatthew 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);
1728b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1729b5da9499SMatthew 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);
1730b5da9499SMatthew G. Knepley       }
1731b5da9499SMatthew G. Knepley #endif
1732b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
1733b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
1734b5da9499SMatthew G. Knepley       orntNew[0] = 0;
1735518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
1736b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1737518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
1738b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1739518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
1740b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1741b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1742b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1743b5da9499SMatthew G. Knepley #if 1
1744b5da9499SMatthew 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);
1745b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1746b5da9499SMatthew 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);
1747b5da9499SMatthew G. Knepley       }
1748b5da9499SMatthew G. Knepley #endif
1749b5da9499SMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
1750b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
1751b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1752fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
1753db2c6090SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
1754fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
1755fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
1756fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
1757fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
1758b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
1759b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
1760b5da9499SMatthew G. Knepley #if 1
1761b5da9499SMatthew 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);
1762b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1763b5da9499SMatthew 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);
1764b5da9499SMatthew G. Knepley       }
1765b5da9499SMatthew G. Knepley #endif
1766b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
1767b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
1768b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1769fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
1770fac4ab25SMatthew G. Knepley       orntNew[1] = 1;
1771fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
1772b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1773fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
1774db2c6090SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
1775b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
1776b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
1777b5da9499SMatthew G. Knepley #if 1
1778b5da9499SMatthew 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);
1779b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1780b5da9499SMatthew 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);
1781b5da9499SMatthew G. Knepley       }
1782b5da9499SMatthew G. Knepley #endif
1783b5da9499SMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
1784b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
1785b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1786fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
1787db2c6090SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
1788fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
1789fac4ab25SMatthew G. Knepley       orntNew[2] = -3;
1790fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
1791fac4ab25SMatthew G. Knepley       orntNew[3] = -2;
1792b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
1793b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
1794b5da9499SMatthew G. Knepley #if 1
1795b5da9499SMatthew 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);
1796b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1797b5da9499SMatthew 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);
1798b5da9499SMatthew G. Knepley       }
1799b5da9499SMatthew G. Knepley #endif
1800b5da9499SMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
1801b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
1802b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1803fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
1804b5da9499SMatthew G. Knepley       orntNew[1] = -3;
1805fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
1806db2c6090SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
1807fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
1808fac4ab25SMatthew G. Knepley       orntNew[3] = -3;
1809b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
1810b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
1811b5da9499SMatthew G. Knepley #if 1
1812b5da9499SMatthew 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);
1813b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1814b5da9499SMatthew 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);
1815b5da9499SMatthew G. Knepley       }
1816b5da9499SMatthew G. Knepley #endif
1817b5da9499SMatthew G. Knepley     }
1818b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
1819b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1820785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
1821b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
1822b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
1823b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
1824b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
1825b5da9499SMatthew G. Knepley 
1826b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
1827b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
1828b5da9499SMatthew G. Knepley       /* A triangle */
1829b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
1830b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1831b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
1832b5da9499SMatthew G. Knepley       orntNew[1] = -2;
1833b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
1834b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1835b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1836b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1837b5da9499SMatthew G. Knepley #if 1
1838b5da9499SMatthew 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);
1839b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1840b5da9499SMatthew 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);
1841b5da9499SMatthew G. Knepley       }
1842b5da9499SMatthew G. Knepley #endif
1843b5da9499SMatthew G. Knepley       /* B triangle */
1844b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
1845b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1846b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
1847b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1848b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
1849b5da9499SMatthew G. Knepley       orntNew[2] = -2;
1850b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1851b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1852b5da9499SMatthew G. Knepley #if 1
1853b5da9499SMatthew 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);
1854b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1855b5da9499SMatthew 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);
1856b5da9499SMatthew G. Knepley       }
1857b5da9499SMatthew G. Knepley #endif
1858b5da9499SMatthew G. Knepley       /* C triangle */
1859b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
1860b5da9499SMatthew G. Knepley       orntNew[0] = -2;
1861b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
1862b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1863b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
1864b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1865b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1866b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1867b5da9499SMatthew G. Knepley #if 1
1868b5da9499SMatthew 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);
1869b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1870b5da9499SMatthew 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);
1871b5da9499SMatthew G. Knepley       }
1872b5da9499SMatthew G. Knepley #endif
1873b5da9499SMatthew G. Knepley       /* D triangle */
1874b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
1875b5da9499SMatthew G. Knepley       orntNew[0] = 0;
1876b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
1877b5da9499SMatthew G. Knepley       orntNew[1] = 0;
1878b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
1879b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1880b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1881b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1882b5da9499SMatthew G. Knepley #if 1
1883b5da9499SMatthew 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);
1884b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1885b5da9499SMatthew 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);
1886b5da9499SMatthew G. Knepley       }
1887b5da9499SMatthew G. Knepley #endif
1888b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
1889b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1890b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
1891b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
1892219f7b90SMatthew G. Knepley           PetscInt subf;
1893b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
1894b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1895b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1896b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
1897b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
1898b5da9499SMatthew G. Knepley           }
1899219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
1900219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
1901b5da9499SMatthew G. Knepley         }
1902b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
1903b5da9499SMatthew G. Knepley #if 1
19049ddff745SMatthew 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);
1905b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
1906b5da9499SMatthew 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);
1907b5da9499SMatthew G. Knepley         }
1908b5da9499SMatthew G. Knepley #endif
1909b5da9499SMatthew G. Knepley       }
1910b5da9499SMatthew G. Knepley     }
1911b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
1912b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
1913b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
1914b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
1915b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
1916b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
1917b5da9499SMatthew G. Knepley 
1918b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1919b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1920b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
19214bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
1922b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
19234bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
1924b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
19254bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
1926b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
1927b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1928b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1929b5da9499SMatthew G. Knepley #if 1
1930b5da9499SMatthew 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);
1931b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1932b5da9499SMatthew 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);
1933b5da9499SMatthew G. Knepley       }
1934b5da9499SMatthew G. Knepley #endif
1935b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
1936b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
1937b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1938b5da9499SMatthew G. Knepley #if 1
1939b5da9499SMatthew 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);
1940b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1941b5da9499SMatthew 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);
1942b5da9499SMatthew G. Knepley       }
1943b5da9499SMatthew G. Knepley #endif
1944b5da9499SMatthew G. Knepley       ++newp;
1945b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
19464bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
1947b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
19484bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
1949b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
19504bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
1951b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
1952b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1953b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1954b5da9499SMatthew G. Knepley #if 1
19554bb260e2SMatthew 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);
1956b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1957b5da9499SMatthew 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);
1958b5da9499SMatthew G. Knepley       }
1959b5da9499SMatthew G. Knepley #endif
1960b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
1961b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
1962b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1963b5da9499SMatthew G. Knepley #if 1
1964b5da9499SMatthew 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);
1965b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1966b5da9499SMatthew 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);
1967b5da9499SMatthew G. Knepley       }
1968b5da9499SMatthew G. Knepley #endif
1969b5da9499SMatthew G. Knepley       ++newp;
1970b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
19714bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
1972b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
19734bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
1974b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
19754bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
1976b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
1977b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1978b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1979b5da9499SMatthew G. Knepley #if 1
1980b5da9499SMatthew 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);
1981b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1982b5da9499SMatthew 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);
1983b5da9499SMatthew G. Knepley       }
1984b5da9499SMatthew G. Knepley #endif
1985b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
1986b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
1987b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1988b5da9499SMatthew G. Knepley #if 1
1989b5da9499SMatthew 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);
1990b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1991b5da9499SMatthew 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);
1992b5da9499SMatthew G. Knepley       }
1993b5da9499SMatthew G. Knepley #endif
1994b5da9499SMatthew G. Knepley       ++newp;
1995b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
19964bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
1997b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
19984bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
1999b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
20004bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2001b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2002b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2003b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2004b5da9499SMatthew G. Knepley #if 1
2005b5da9499SMatthew 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);
2006b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2007b5da9499SMatthew 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);
2008b5da9499SMatthew G. Knepley       }
2009b5da9499SMatthew G. Knepley #endif
2010b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
2011b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2012b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2013b5da9499SMatthew G. Knepley #if 1
2014b5da9499SMatthew 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);
2015b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2016b5da9499SMatthew 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);
2017b5da9499SMatthew G. Knepley       }
2018b5da9499SMatthew G. Knepley #endif
2019b5da9499SMatthew G. Knepley       ++newp;
2020b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
20214bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2022b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
2023b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
20244bb260e2SMatthew G. Knepley       orntNew[1] = -2;
20254bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2026b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2027b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2028b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2029b5da9499SMatthew G. Knepley #if 1
2030b5da9499SMatthew 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);
2031b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2032b5da9499SMatthew 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);
2033b5da9499SMatthew G. Knepley       }
2034b5da9499SMatthew G. Knepley #endif
2035b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2036b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2037b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2038b5da9499SMatthew G. Knepley #if 1
2039b5da9499SMatthew 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);
2040b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2041b5da9499SMatthew 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);
2042b5da9499SMatthew G. Knepley       }
2043b5da9499SMatthew G. Knepley #endif
2044b5da9499SMatthew G. Knepley       ++newp;
2045b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
20464bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2047b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2048b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
20494bb260e2SMatthew G. Knepley       orntNew[1] = 0;
20504bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
20512baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
2052b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2053b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2054b5da9499SMatthew G. Knepley #if 1
2055b5da9499SMatthew 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);
2056b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2057b5da9499SMatthew 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);
2058b5da9499SMatthew G. Knepley       }
2059b5da9499SMatthew G. Knepley #endif
2060b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2061b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2062b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2063b5da9499SMatthew G. Knepley #if 1
2064b5da9499SMatthew 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);
2065b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2066b5da9499SMatthew 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);
2067b5da9499SMatthew G. Knepley       }
2068b5da9499SMatthew G. Knepley #endif
2069b5da9499SMatthew G. Knepley       ++newp;
2070b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
20714bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2072b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
2073b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2074fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
20754bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2076b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
2077b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2078b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2079b5da9499SMatthew G. Knepley #if 1
2080b5da9499SMatthew 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);
2081b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2082b5da9499SMatthew 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);
2083b5da9499SMatthew G. Knepley       }
2084b5da9499SMatthew G. Knepley #endif
2085b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2086b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2087b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2088b5da9499SMatthew G. Knepley #if 1
2089b5da9499SMatthew 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);
2090b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2091b5da9499SMatthew 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);
2092b5da9499SMatthew G. Knepley       }
2093b5da9499SMatthew G. Knepley #endif
2094b5da9499SMatthew G. Knepley       ++newp;
2095b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
20964bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2097b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
20984bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2099b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
2100b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
21014bb260e2SMatthew G. Knepley       orntNew[2] = -2;
2102b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2103b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2104b5da9499SMatthew G. Knepley #if 1
2105b5da9499SMatthew 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);
2106b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2107b5da9499SMatthew 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);
2108b5da9499SMatthew G. Knepley       }
2109b5da9499SMatthew G. Knepley #endif
2110b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2111b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2112b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2113b5da9499SMatthew G. Knepley #if 1
2114b5da9499SMatthew 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);
2115b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2116b5da9499SMatthew 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);
2117b5da9499SMatthew G. Knepley       }
2118b5da9499SMatthew G. Knepley #endif
2119b5da9499SMatthew G. Knepley       ++newp;
2120b5da9499SMatthew G. Knepley     }
2121b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
2122b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2123b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
2124b5da9499SMatthew G. Knepley 
2125b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2126b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
2127b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2128b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2129b5da9499SMatthew G. Knepley 
2130b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
2131b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2132b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2133b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2134b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2135b5da9499SMatthew G. Knepley #if 1
2136b5da9499SMatthew 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);
2137b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2138b5da9499SMatthew 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);
2139b5da9499SMatthew G. Knepley         }
2140b5da9499SMatthew G. Knepley #endif
2141b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
2142b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2143b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2144b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2145b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2146b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2147b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2148b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
2149b5da9499SMatthew G. Knepley           }
2150b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
2151b5da9499SMatthew G. Knepley         }
2152b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2153b5da9499SMatthew G. Knepley #if 1
2154b5da9499SMatthew 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);
2155b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2156b5da9499SMatthew 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);
2157b5da9499SMatthew G. Knepley         }
2158b5da9499SMatthew G. Knepley #endif
2159b5da9499SMatthew G. Knepley       }
2160b5da9499SMatthew G. Knepley     }
216186f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
2162b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2163b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2164b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
2165b5da9499SMatthew G. Knepley 
2166b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2167b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2168b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
2169b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
2170b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
2171b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
2172b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
2173b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
2174b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
2175b5da9499SMatthew G. Knepley 
2176b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2177b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
2178b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
2179b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2180b5da9499SMatthew G. Knepley #if 1
2181b5da9499SMatthew 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);
2182b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2183b5da9499SMatthew 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);
2184b5da9499SMatthew G. Knepley         }
2185b5da9499SMatthew G. Knepley #endif
2186b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
2187b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
2188b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2189b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2190b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2191b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2192b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
219386f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
21949ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
2195b5da9499SMatthew G. Knepley           if (er == eint[c]) {
2196b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
2197b5da9499SMatthew G. Knepley           } else {
2198b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
2199b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
2200b5da9499SMatthew G. Knepley           }
2201b5da9499SMatthew G. Knepley         }
2202b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2203b5da9499SMatthew G. Knepley #if 1
2204b5da9499SMatthew 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);
2205b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
2206b5da9499SMatthew 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);
2207b5da9499SMatthew G. Knepley         }
2208b5da9499SMatthew G. Knepley #endif
2209b5da9499SMatthew G. Knepley       }
2210b5da9499SMatthew G. Knepley     }
2211b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
2212b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2213b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2214b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
22154a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
2216b5da9499SMatthew G. Knepley 
2217b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2218b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2219b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
222042525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
2221b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2222b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
222342525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
2224b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2225b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2226b5da9499SMatthew G. Knepley #if 1
2227b5da9499SMatthew 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);
2228b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2229b5da9499SMatthew 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);
2230b5da9499SMatthew G. Knepley       }
2231b5da9499SMatthew G. Knepley #endif
2232b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
2233b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
2234b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
2235b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
2236b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2237b5da9499SMatthew G. Knepley #if 1
2238b5da9499SMatthew 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);
2239b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2240b5da9499SMatthew 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);
2241b5da9499SMatthew G. Knepley       }
2242b5da9499SMatthew G. Knepley #endif
2243b5da9499SMatthew G. Knepley     }
2244b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
2245b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2246b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2247b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
2248b5da9499SMatthew G. Knepley       PetscInt        size, s;
2249b5da9499SMatthew G. Knepley 
2250b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2251b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2252b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2253b5da9499SMatthew G. Knepley         PetscInt r = 0;
2254b5da9499SMatthew G. Knepley 
2255b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2256b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
2257b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
2258b5da9499SMatthew G. Knepley       }
2259b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2260b5da9499SMatthew G. Knepley #if 1
2261b5da9499SMatthew 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);
2262b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2263b5da9499SMatthew 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);
2264b5da9499SMatthew G. Knepley       }
2265b5da9499SMatthew G. Knepley #endif
2266b5da9499SMatthew G. Knepley     }
2267b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
2268b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2269b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
2270b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
2271b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
2272b5da9499SMatthew G. Knepley 
2273b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
2274b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2275b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
2276b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
2277b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2278b5da9499SMatthew G. Knepley         PetscInt r = 0;
2279b5da9499SMatthew G. Knepley 
2280b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2281b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2282b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
2283b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
2284b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
2285b5da9499SMatthew G. Knepley       }
2286b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2287b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
2288b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
2289b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
2290b5da9499SMatthew G. Knepley 
2291b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
2292b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
2293b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2294b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
2295b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
229642525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
2297b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
2298b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2299b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
230042525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
230142525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
2302b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
2303b5da9499SMatthew G. Knepley         }
2304b5da9499SMatthew G. Knepley       }
2305b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2306b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2307b5da9499SMatthew G. Knepley #if 1
2308b5da9499SMatthew 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);
2309b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
2310b5da9499SMatthew 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);
2311b5da9499SMatthew G. Knepley       }
2312b5da9499SMatthew G. Knepley #endif
2313b5da9499SMatthew G. Knepley     }
2314b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2315b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
2316b5da9499SMatthew G. Knepley     break;
23176ce3c06aSMatthew G. Knepley   case 7:
23186ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
23196ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
23206ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
23216ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
23226ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
23236ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
23246ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
23256ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
23266ce3c06aSMatthew G. Knepley 
23276ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
23286ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
23296ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
23306ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
23316ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
23326ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
23336ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
23346ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
23356ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
23366ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
23376ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
23386ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
23396ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
23406ce3c06aSMatthew G. Knepley #if 1
23416ce3c06aSMatthew 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);
23426ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
23436ce3c06aSMatthew 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);
23446ce3c06aSMatthew G. Knepley       }
23456ce3c06aSMatthew G. Knepley #endif
23466ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
23476ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
23486ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
23496ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
23506ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
23516ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
23526ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
23536ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
23546ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
23556ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
23566ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
23576ce3c06aSMatthew G. Knepley #if 1
23586ce3c06aSMatthew 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);
23596ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
23606ce3c06aSMatthew 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);
23616ce3c06aSMatthew G. Knepley       }
23626ce3c06aSMatthew G. Knepley #endif
23636ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
23646ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
23656ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
23666ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
23676ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
23686ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
23696ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
23706ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
23716ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
23726ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
23736ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
23746ce3c06aSMatthew G. Knepley #if 1
23756ce3c06aSMatthew 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);
23766ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
23776ce3c06aSMatthew 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);
23786ce3c06aSMatthew G. Knepley       }
23796ce3c06aSMatthew G. Knepley #endif
23806ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
23816ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
23826ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
23836ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
23846ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
23856ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
23866ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
23876ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
23886ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
23896ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
23906ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
23916ce3c06aSMatthew G. Knepley #if 1
23926ce3c06aSMatthew 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);
23936ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
23946ce3c06aSMatthew 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);
23956ce3c06aSMatthew G. Knepley       }
23966ce3c06aSMatthew G. Knepley #endif
23976ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
23986ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
23996ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
24009ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
24019ddff745SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
24029ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
24039ddff745SMatthew G. Knepley       orntNew[2] = 0;
24049ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
24059ddff745SMatthew G. Knepley       orntNew[3] = 2;
24066ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
24076ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
24086ce3c06aSMatthew G. Knepley #if 1
24096ce3c06aSMatthew 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);
24106ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
24116ce3c06aSMatthew 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);
24126ce3c06aSMatthew G. Knepley       }
24136ce3c06aSMatthew G. Knepley #endif
24146ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
24156ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
24166ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
24179ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
24189ddff745SMatthew G. Knepley       orntNew[1] = 1;
24199ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
24206ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
24219ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
24229ddff745SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
24236ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
24246ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
24256ce3c06aSMatthew G. Knepley #if 1
24266ce3c06aSMatthew 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);
24276ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
24286ce3c06aSMatthew 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);
24296ce3c06aSMatthew G. Knepley       }
24306ce3c06aSMatthew G. Knepley #endif
24316ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
24326ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
24336ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
24349ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
24359ddff745SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
24369ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
24379ddff745SMatthew G. Knepley       orntNew[2] = -3;
24389ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
24399ddff745SMatthew G. Knepley       orntNew[3] = -2;
24406ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
24416ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
24426ce3c06aSMatthew G. Knepley #if 1
24436ce3c06aSMatthew 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);
24446ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
24456ce3c06aSMatthew 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);
24466ce3c06aSMatthew G. Knepley       }
24476ce3c06aSMatthew G. Knepley #endif
24486ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
24496ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
24506ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
24519ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
24526ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
24539ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
24549ddff745SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
24559ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
24569ddff745SMatthew G. Knepley       orntNew[3] = -3;
24576ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
24586ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
24596ce3c06aSMatthew G. Knepley #if 1
24606ce3c06aSMatthew 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);
24616ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
24626ce3c06aSMatthew 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);
24636ce3c06aSMatthew G. Knepley       }
24646ce3c06aSMatthew G. Knepley #endif
24656ce3c06aSMatthew G. Knepley     }
24666ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
24676ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
24686ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
2469d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
2470084f9c62SMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5], o, of;
24716ce3c06aSMatthew G. Knepley 
24726ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
24736ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2474d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
2475084f9c62SMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
24766ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
24776ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
24786ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
24796ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
24806ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
2481084f9c62SMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
2482084f9c62SMatthew G. Knepley         coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (o*of < 0 ? 0 : 1);
24836ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
2484084f9c62SMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? -1 : 1;
2485084f9c62SMatthew G. Knepley         coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)]       - fMax)*2 + (o*of < 0 ? 1 : 0);
24866ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
24876ce3c06aSMatthew G. Knepley         coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
24886ce3c06aSMatthew G. Knepley         orntNew[4] = 0;
24896ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
24906ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
24916ce3c06aSMatthew G. Knepley #if 1
24926ce3c06aSMatthew 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);
24936ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
24946ce3c06aSMatthew 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);
24956ce3c06aSMatthew G. Knepley         }
24966ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
24976ce3c06aSMatthew 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);
24986ce3c06aSMatthew G. Knepley         }
24996ce3c06aSMatthew G. Knepley #endif
25006ce3c06aSMatthew G. Knepley       }
25016ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
25026ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
25036ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
25046ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
25056ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
25066ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
25076ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
25086ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
25096ce3c06aSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
25106ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
25116ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
25126ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
25136ce3c06aSMatthew G. Knepley #if 1
25146ce3c06aSMatthew 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);
25156ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
25166ce3c06aSMatthew 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);
25176ce3c06aSMatthew G. Knepley       }
25186ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
25196ce3c06aSMatthew 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);
25206ce3c06aSMatthew G. Knepley       }
25216ce3c06aSMatthew G. Knepley #endif
25226ce3c06aSMatthew G. Knepley     }
25236ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
25246ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2525785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
25266ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
25276ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
25286ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
25296ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
25306ce3c06aSMatthew G. Knepley 
25316ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
25326ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
25336ce3c06aSMatthew G. Knepley       /* A triangle */
25346ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
25356ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
25366ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
25376ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
25386ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
25396ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
25406ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
25416ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
25426ce3c06aSMatthew G. Knepley #if 1
25436ce3c06aSMatthew 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);
25446ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25456ce3c06aSMatthew 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);
25466ce3c06aSMatthew G. Knepley       }
25476ce3c06aSMatthew G. Knepley #endif
25486ce3c06aSMatthew G. Knepley       /* B triangle */
25496ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
25506ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
25516ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
25526ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
25536ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
25546ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
25556ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
25566ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
25576ce3c06aSMatthew G. Knepley #if 1
25586ce3c06aSMatthew 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);
25596ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25606ce3c06aSMatthew 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);
25616ce3c06aSMatthew G. Knepley       }
25626ce3c06aSMatthew G. Knepley #endif
25636ce3c06aSMatthew G. Knepley       /* C triangle */
25646ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
25656ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
25666ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
25676ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
25686ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
25696ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
25706ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
25716ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
25726ce3c06aSMatthew G. Knepley #if 1
25736ce3c06aSMatthew 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);
25746ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25756ce3c06aSMatthew 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);
25766ce3c06aSMatthew G. Knepley       }
25776ce3c06aSMatthew G. Knepley #endif
25786ce3c06aSMatthew G. Knepley       /* D triangle */
25796ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
25806ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
25816ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
25826ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
25836ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
25846ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
25856ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
25866ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
25876ce3c06aSMatthew G. Knepley #if 1
25886ce3c06aSMatthew 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);
25896ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25906ce3c06aSMatthew 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);
25916ce3c06aSMatthew G. Knepley       }
25926ce3c06aSMatthew G. Knepley #endif
25936ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
25946ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
25956ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
25966ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
25979ddff745SMatthew G. Knepley           PetscInt subf;
25986ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
25996ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
26006ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
26016ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
26026ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
26036ce3c06aSMatthew G. Knepley           }
26049ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
26056ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
26069ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
26076ce3c06aSMatthew G. Knepley           } else {
26089ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
26096ce3c06aSMatthew G. Knepley           }
26106ce3c06aSMatthew G. Knepley         }
26116ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
26126ce3c06aSMatthew G. Knepley #if 1
26139ddff745SMatthew 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);
26146ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
26156ce3c06aSMatthew 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);
26166ce3c06aSMatthew G. Knepley         }
26176ce3c06aSMatthew G. Knepley #endif
26186ce3c06aSMatthew G. Knepley       }
26196ce3c06aSMatthew G. Knepley     }
26206ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
26216ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
26226ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
26236ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
26246ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
26256ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
26266ce3c06aSMatthew G. Knepley 
26276ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
26286ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
26296ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
26309ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
26316ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
26329ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
26336ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
26349ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
26356ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
26366ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
26376ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
26386ce3c06aSMatthew G. Knepley #if 1
26396ce3c06aSMatthew 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);
26406ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26416ce3c06aSMatthew 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);
26426ce3c06aSMatthew G. Knepley       }
26436ce3c06aSMatthew G. Knepley #endif
26446ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
26456ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
26466ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
26476ce3c06aSMatthew G. Knepley #if 1
26486ce3c06aSMatthew 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);
26496ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
26506ce3c06aSMatthew 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);
26516ce3c06aSMatthew G. Knepley       }
26526ce3c06aSMatthew G. Knepley #endif
26536ce3c06aSMatthew G. Knepley       ++newp;
26546ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
26559ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
26566ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
26579ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
26586ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
26599ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
26606ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
26616ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
26626ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
26636ce3c06aSMatthew G. Knepley #if 1
26646ce3c06aSMatthew 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);
26656ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26666ce3c06aSMatthew 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);
26676ce3c06aSMatthew G. Knepley       }
26686ce3c06aSMatthew G. Knepley #endif
26696ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
26706ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
26716ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
26726ce3c06aSMatthew G. Knepley #if 1
26736ce3c06aSMatthew 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);
26746ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
26756ce3c06aSMatthew 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);
26766ce3c06aSMatthew G. Knepley       }
26776ce3c06aSMatthew G. Knepley #endif
26786ce3c06aSMatthew G. Knepley       ++newp;
26796ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
26809ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
26816ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
26829ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
26836ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
26849ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
26856ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
26866ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
26876ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
26886ce3c06aSMatthew G. Knepley #if 1
26896ce3c06aSMatthew 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);
26906ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26916ce3c06aSMatthew 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);
26926ce3c06aSMatthew G. Knepley       }
26936ce3c06aSMatthew G. Knepley #endif
26946ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
26956ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
26966ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
26976ce3c06aSMatthew G. Knepley #if 1
26986ce3c06aSMatthew 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);
26996ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
27006ce3c06aSMatthew 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);
27016ce3c06aSMatthew G. Knepley       }
27026ce3c06aSMatthew G. Knepley #endif
27036ce3c06aSMatthew G. Knepley       ++newp;
27046ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
27059ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
27066ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
27079ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
27086ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
27099ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
27106ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
27116ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27126ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
27136ce3c06aSMatthew G. Knepley #if 1
27146ce3c06aSMatthew 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);
27156ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
27166ce3c06aSMatthew 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);
27176ce3c06aSMatthew G. Knepley       }
27186ce3c06aSMatthew G. Knepley #endif
27196ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
27206ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
27216ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
27226ce3c06aSMatthew G. Knepley #if 1
27236ce3c06aSMatthew 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);
27246ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
27256ce3c06aSMatthew 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);
27266ce3c06aSMatthew G. Knepley       }
27276ce3c06aSMatthew G. Knepley #endif
27286ce3c06aSMatthew G. Knepley       ++newp;
27296ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
27309ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
27316ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
27326ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
27339ddff745SMatthew G. Knepley       orntNew[1] = -2;
27349ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
27356ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
27366ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27376ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
27386ce3c06aSMatthew G. Knepley #if 1
27396ce3c06aSMatthew 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);
27406ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
27416ce3c06aSMatthew 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);
27426ce3c06aSMatthew G. Knepley       }
27436ce3c06aSMatthew G. Knepley #endif
27446ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
27456ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
27466ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
27476ce3c06aSMatthew G. Knepley #if 1
27486ce3c06aSMatthew 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);
27496ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
27506ce3c06aSMatthew 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);
27516ce3c06aSMatthew G. Knepley       }
27526ce3c06aSMatthew G. Knepley #endif
27536ce3c06aSMatthew G. Knepley       ++newp;
27546ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
27559ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
27566ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
27576ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
27589ddff745SMatthew G. Knepley       orntNew[1] = 0;
27599ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
27609ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
27616ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27626ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
27636ce3c06aSMatthew G. Knepley #if 1
27646ce3c06aSMatthew 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);
27656ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
27666ce3c06aSMatthew 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);
27676ce3c06aSMatthew G. Knepley       }
27686ce3c06aSMatthew G. Knepley #endif
27696ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
27706ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
27716ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
27726ce3c06aSMatthew G. Knepley #if 1
27736ce3c06aSMatthew 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);
27746ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
27756ce3c06aSMatthew 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);
27766ce3c06aSMatthew G. Knepley       }
27776ce3c06aSMatthew G. Knepley #endif
27786ce3c06aSMatthew G. Knepley       ++newp;
27796ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
27809ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
27816ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
27826ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
27839ddff745SMatthew G. Knepley       orntNew[1] = 0;
27849ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
27856ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
27866ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27876ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
27886ce3c06aSMatthew G. Knepley #if 1
27896ce3c06aSMatthew 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);
27906ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
27916ce3c06aSMatthew 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);
27926ce3c06aSMatthew G. Knepley       }
27936ce3c06aSMatthew G. Knepley #endif
27946ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
27956ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
27966ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
27976ce3c06aSMatthew G. Knepley #if 1
27986ce3c06aSMatthew 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);
27996ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
28006ce3c06aSMatthew 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);
28016ce3c06aSMatthew G. Knepley       }
28026ce3c06aSMatthew G. Knepley #endif
28036ce3c06aSMatthew G. Knepley       ++newp;
28046ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
28059ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
28066ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
28079ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
28086ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
28096ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
28109ddff745SMatthew G. Knepley       orntNew[2] = -2;
28116ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
28126ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
28136ce3c06aSMatthew G. Knepley #if 1
28146ce3c06aSMatthew 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);
28156ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
28166ce3c06aSMatthew 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);
28176ce3c06aSMatthew G. Knepley       }
28186ce3c06aSMatthew G. Knepley #endif
28196ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
28206ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
28216ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
28226ce3c06aSMatthew G. Knepley #if 1
28236ce3c06aSMatthew 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);
28246ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
28256ce3c06aSMatthew 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);
28266ce3c06aSMatthew G. Knepley       }
28276ce3c06aSMatthew G. Knepley #endif
28286ce3c06aSMatthew G. Knepley       ++newp;
28296ce3c06aSMatthew G. Knepley     }
28306ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
28316ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
28326ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
28336ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
28346ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
28356ce3c06aSMatthew G. Knepley 
28366ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
28376ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
28386ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
28396ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
28406ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
28416ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
28426ce3c06aSMatthew G. Knepley 
28436ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
28446ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
28456ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
28466ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
28476ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
28486ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
28496ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
28506ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
28516ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
28526ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
28536ce3c06aSMatthew G. Knepley #if 1
28546ce3c06aSMatthew 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);
28556ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
28566ce3c06aSMatthew 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);
28576ce3c06aSMatthew G. Knepley         }
28586ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
28596ce3c06aSMatthew 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);
28606ce3c06aSMatthew G. Knepley         }
28616ce3c06aSMatthew G. Knepley #endif
28626ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
2863d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
2864084f9c62SMatthew G. Knepley           PetscInt        o, of;
28656ce3c06aSMatthew G. Knepley 
28666ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
28676ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
2868084f9c62SMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
28696ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
28706ce3c06aSMatthew 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]);
2871d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
2872084f9c62SMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
2873084f9c62SMatthew G. Knepley           supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3;
28746ce3c06aSMatthew G. Knepley         }
28756ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
28766ce3c06aSMatthew G. Knepley #if 1
28776ce3c06aSMatthew 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);
28786ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
28796ce3c06aSMatthew 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);
28806ce3c06aSMatthew G. Knepley         }
28816ce3c06aSMatthew G. Knepley #endif
28826ce3c06aSMatthew G. Knepley       }
28836ce3c06aSMatthew G. Knepley     }
28846ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
28856ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
28866ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
28876ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
28886ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
28896ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
28906ce3c06aSMatthew G. Knepley 
28916ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
28926ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
28936ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
2894b598a9d5SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
28956ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
2896b598a9d5SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
28976ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
2898b598a9d5SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
28996ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
2900b598a9d5SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r]       - fMax);
29016ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
29026ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
29036ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
29046ce3c06aSMatthew G. Knepley #if 1
29056ce3c06aSMatthew 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);
29066ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
29076ce3c06aSMatthew 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);
29086ce3c06aSMatthew G. Knepley         }
29096ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
29106ce3c06aSMatthew 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);
29116ce3c06aSMatthew G. Knepley         }
29126ce3c06aSMatthew G. Knepley #endif
29136ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
29146ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
29156ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
29166ce3c06aSMatthew G. Knepley #if 1
29176ce3c06aSMatthew 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);
29186ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
29196ce3c06aSMatthew 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);
29206ce3c06aSMatthew G. Knepley         }
29216ce3c06aSMatthew G. Knepley #endif
29226ce3c06aSMatthew G. Knepley       }
29236ce3c06aSMatthew G. Knepley     }
29246ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
29256ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
29266ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
29276ce3c06aSMatthew G. Knepley 
29286ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
29296ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
29306ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
29316ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
29326ce3c06aSMatthew G. Knepley 
29336ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
29346ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
29356ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
29366ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
29376ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
29386ce3c06aSMatthew G. Knepley #if 1
29396ce3c06aSMatthew 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);
29406ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
29416ce3c06aSMatthew 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);
29426ce3c06aSMatthew G. Knepley         }
29436ce3c06aSMatthew G. Knepley #endif
29446ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
29456ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
29466ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
29476ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
29486ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
29496ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
29506ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
29516ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
29526ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
29536ce3c06aSMatthew G. Knepley           } else {
29546ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
29556ce3c06aSMatthew G. Knepley           }
29566ce3c06aSMatthew G. Knepley         }
29576ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
29586ce3c06aSMatthew G. Knepley #if 1
29596ce3c06aSMatthew 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);
29606ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
29616ce3c06aSMatthew 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);
29626ce3c06aSMatthew G. Knepley         }
29636ce3c06aSMatthew G. Knepley #endif
29646ce3c06aSMatthew G. Knepley       }
29656ce3c06aSMatthew G. Knepley     }
29666ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
29676ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
29686ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
29696ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
29706ce3c06aSMatthew G. Knepley 
29716ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
29726ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
29736ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
29746ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
29756ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
29766ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
29776ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
29786ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
29796ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
29806ce3c06aSMatthew G. Knepley 
29816ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
29826ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
29836ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
29846ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
29856ce3c06aSMatthew G. Knepley #if 1
29866ce3c06aSMatthew 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);
29876ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
29886ce3c06aSMatthew 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);
29896ce3c06aSMatthew G. Knepley         }
29906ce3c06aSMatthew G. Knepley #endif
29916ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
29926ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
29936ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
29946ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
29956ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
29966ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
29976ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
29986ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
29996ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
30009ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
30016ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
30026ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
30036ce3c06aSMatthew G. Knepley             } else {
30046ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
30056ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
30066ce3c06aSMatthew G. Knepley             }
30076ce3c06aSMatthew G. Knepley           } else {
3008b598a9d5SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
30096ce3c06aSMatthew G. Knepley           }
30106ce3c06aSMatthew G. Knepley         }
30116ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
30126ce3c06aSMatthew G. Knepley #if 1
30136ce3c06aSMatthew 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);
30146ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
30156ce3c06aSMatthew 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);
30166ce3c06aSMatthew G. Knepley         }
30176ce3c06aSMatthew G. Knepley #endif
30186ce3c06aSMatthew G. Knepley       }
30196ce3c06aSMatthew G. Knepley     }
30206ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
30216ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
30226ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
30236ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
30246ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
30256ce3c06aSMatthew G. Knepley 
30266ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
30276ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
30286ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
30296ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
30306ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
30316ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
30326ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
30336ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
30346ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
30356ce3c06aSMatthew G. Knepley #if 1
30366ce3c06aSMatthew 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);
30376ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
30386ce3c06aSMatthew 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);
30396ce3c06aSMatthew G. Knepley       }
30406ce3c06aSMatthew G. Knepley #endif
30416ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
30426ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
30436ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
30446ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
30456ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
30466ce3c06aSMatthew G. Knepley #if 1
30476ce3c06aSMatthew 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);
30486ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30496ce3c06aSMatthew 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);
30506ce3c06aSMatthew G. Knepley       }
30516ce3c06aSMatthew G. Knepley #endif
30526ce3c06aSMatthew G. Knepley     }
30536ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
30546ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
30556ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
30566ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
30576ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
30586ce3c06aSMatthew G. Knepley 
30596ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
30606ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
30616ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
30626ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
30636ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
30646ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
30656ce3c06aSMatthew G. Knepley #if 1
30666ce3c06aSMatthew 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);
30676ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
30686ce3c06aSMatthew 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);
30696ce3c06aSMatthew G. Knepley       }
30706ce3c06aSMatthew G. Knepley #endif
30716ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
30726ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
30736ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
30746ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
30756ce3c06aSMatthew 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]);
30766ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
30776ce3c06aSMatthew G. Knepley       }
30786ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
30796ce3c06aSMatthew G. Knepley #if 1
30806ce3c06aSMatthew 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);
30816ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
30826ce3c06aSMatthew 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);
30836ce3c06aSMatthew G. Knepley       }
30846ce3c06aSMatthew G. Knepley #endif
30856ce3c06aSMatthew G. Knepley     }
30866ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
30876ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
30886ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
3089623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
30906ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
30916ce3c06aSMatthew G. Knepley 
30926ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
30936ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
30946ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
30956ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
30966ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
30976ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
30986ce3c06aSMatthew G. Knepley #if 1
30996ce3c06aSMatthew 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);
31006ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
31016ce3c06aSMatthew 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);
31026ce3c06aSMatthew G. Knepley       }
31036ce3c06aSMatthew G. Knepley #endif
31046ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
31056ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
31066ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
31076ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
31086ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
3109623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
31106ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
31116ce3c06aSMatthew 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]);
3112b598a9d5SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
3113b598a9d5SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
31146ce3c06aSMatthew G. Knepley       }
31156ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
31166ce3c06aSMatthew G. Knepley #if 1
31176ce3c06aSMatthew 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);
31186ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
31196ce3c06aSMatthew 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);
31206ce3c06aSMatthew G. Knepley       }
31216ce3c06aSMatthew G. Knepley #endif
31226ce3c06aSMatthew G. Knepley     }
31236ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
31246ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
31256ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
31266ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
31276ce3c06aSMatthew G. Knepley       PetscInt        size, s;
31286ce3c06aSMatthew G. Knepley 
31296ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
31306ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
31316ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
31326ce3c06aSMatthew G. Knepley         PetscInt r = 0;
31336ce3c06aSMatthew G. Knepley 
31346ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
31356ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
31366ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
31376ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
31386ce3c06aSMatthew G. Knepley       }
31396ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
31406ce3c06aSMatthew G. Knepley #if 1
31416ce3c06aSMatthew 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);
31426ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
31436ce3c06aSMatthew 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);
31446ce3c06aSMatthew G. Knepley       }
31456ce3c06aSMatthew G. Knepley #endif
31466ce3c06aSMatthew G. Knepley     }
31476ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
31486ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
31496ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
31506ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
31516ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
31526ce3c06aSMatthew G. Knepley 
31536ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
31546ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
31556ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
31566ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
31576ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
31586ce3c06aSMatthew G. Knepley         PetscInt r = 0;
31596ce3c06aSMatthew G. Knepley 
31606ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
31616ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
31626ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
31636ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
31646ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
31656ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
31666ce3c06aSMatthew G. Knepley           faceSize += 2;
31676ce3c06aSMatthew G. Knepley         } else {
31686ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
31696ce3c06aSMatthew G. Knepley           ++faceSize;
31706ce3c06aSMatthew G. Knepley         }
31716ce3c06aSMatthew G. Knepley       }
31726ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
31736ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
31746ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
31756ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
31766ce3c06aSMatthew G. Knepley 
31776ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
31786ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
31796ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
31806ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
31816ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
31826ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
31836ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
31846ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
31856ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
31866ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
31876ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
31886ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
31896ce3c06aSMatthew G. Knepley         }
31906ce3c06aSMatthew G. Knepley       }
31916ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
31926ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
31936ce3c06aSMatthew G. Knepley #if 1
31946ce3c06aSMatthew 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);
31956ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
31966ce3c06aSMatthew 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);
31976ce3c06aSMatthew G. Knepley       }
31986ce3c06aSMatthew G. Knepley #endif
31996ce3c06aSMatthew G. Knepley     }
32006ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
32016ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
32026ce3c06aSMatthew G. Knepley     break;
32032eabf88fSMatthew G. Knepley   case 6:
32042eabf88fSMatthew G. Knepley     /* Hex 3D */
32052eabf88fSMatthew G. Knepley     /*
32062eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
32072eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
32082eabf88fSMatthew G. Knepley      |         |         |       |         |         |
32092eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
32102eabf88fSMatthew G. Knepley      |         |         |       |         |         |
32112eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
32122eabf88fSMatthew G. Knepley      |         |         |       |         |         |
32132eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
32142eabf88fSMatthew G. Knepley      |         |         |       |         |         |
32152eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
32162eabf88fSMatthew G. Knepley      */
32172eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
32182eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
32192eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
32202eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
32212eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
32222eabf88fSMatthew G. Knepley 
32232eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
32242eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
32252eabf88fSMatthew G. Knepley       /* A hex */
3226e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
32272eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
32282eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
32292eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3230e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
32312eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
32322eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
32332eabf88fSMatthew G. Knepley       orntNew[3] = 0;
32342eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
32352eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3236e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
32372eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
32382eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
32392eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
32402eabf88fSMatthew G. Knepley #if 1
32412eabf88fSMatthew 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);
32422eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
32432eabf88fSMatthew 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);
32442eabf88fSMatthew G. Knepley       }
32452eabf88fSMatthew G. Knepley #endif
32462eabf88fSMatthew G. Knepley       /* B hex */
3247e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
32482eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
32492eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
32502eabf88fSMatthew G. Knepley       orntNew[1] = 0;
32512eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
3252a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3253e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
32542eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
32552eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
32562eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3257e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
32582eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
32592eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
32602eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
32612eabf88fSMatthew G. Knepley #if 1
32622eabf88fSMatthew 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);
32632eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
32642eabf88fSMatthew 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);
32652eabf88fSMatthew G. Knepley       }
32662eabf88fSMatthew G. Knepley #endif
32672eabf88fSMatthew G. Knepley       /* C hex */
3268e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
32692eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
32702eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
32712eabf88fSMatthew G. Knepley       orntNew[1] = 0;
32722eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3273a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3274e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
32752eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3276e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
32772eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
32782eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
3279a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
32802eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
32812eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
32822eabf88fSMatthew G. Knepley #if 1
32832eabf88fSMatthew 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);
32842eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
32852eabf88fSMatthew 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);
32862eabf88fSMatthew G. Knepley       }
32872eabf88fSMatthew G. Knepley #endif
32882eabf88fSMatthew G. Knepley       /* D hex */
3289e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
32902eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
32912eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
32922eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3293e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
32942eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
32952eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3296a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3297e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
32982eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
32992eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
3300a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
33012eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
33022eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
33032eabf88fSMatthew G. Knepley #if 1
33042eabf88fSMatthew 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);
33052eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33062eabf88fSMatthew 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);
33072eabf88fSMatthew G. Knepley       }
33082eabf88fSMatthew G. Knepley #endif
33092eabf88fSMatthew G. Knepley       /* E hex */
33102eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
3311a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3312e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
33132eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3314e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
33152eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
33162eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
33172eabf88fSMatthew G. Knepley       orntNew[3] = 0;
33182eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3319a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
3320e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
33212eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3322b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
3323b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
33242eabf88fSMatthew G. Knepley #if 1
3325b164cbf2SMatthew 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);
33262eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33272eabf88fSMatthew 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);
33282eabf88fSMatthew G. Knepley       }
33292eabf88fSMatthew G. Knepley #endif
33302eabf88fSMatthew G. Knepley       /* F hex */
33312eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
3332a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3333e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
33342eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3335e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
33362eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
33372eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3338a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
3339e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
33402eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
33412eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3342a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
3343b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
3344b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
33452eabf88fSMatthew G. Knepley #if 1
3346b164cbf2SMatthew 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);
33472eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33482eabf88fSMatthew 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);
33492eabf88fSMatthew G. Knepley       }
33502eabf88fSMatthew G. Knepley #endif
33512eabf88fSMatthew G. Knepley       /* G hex */
33522eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
3353a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3354e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
33552eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
33562eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3357a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
3358e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
33592eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3360e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
33612eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
33622eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3363a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
3364b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
3365b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
33662eabf88fSMatthew G. Knepley #if 1
3367b164cbf2SMatthew 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);
33682eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33692eabf88fSMatthew 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);
33702eabf88fSMatthew G. Knepley       }
33712eabf88fSMatthew G. Knepley #endif
33722eabf88fSMatthew G. Knepley       /* H hex */
33732eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
3374a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3375e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
33762eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
33772eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
3378a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3379e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
33802eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
33812eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3382a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
3383e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
33842eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3385b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
3386b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
33872eabf88fSMatthew G. Knepley #if 1
3388b164cbf2SMatthew 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);
33892eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33902eabf88fSMatthew 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);
33912eabf88fSMatthew G. Knepley       }
33922eabf88fSMatthew G. Knepley #endif
33932eabf88fSMatthew G. Knepley     }
33942eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
33952eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3396785e854fSJed Brown     ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
33972eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
33982eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
3399aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
34002eabf88fSMatthew 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};
34012eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
34022eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3403aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
34042eabf88fSMatthew G. Knepley 
34052eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3406aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
3407a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
3408a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
3409a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
3410a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
3411a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
3412a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
3413a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
3414a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
34152eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3416aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
34172eabf88fSMatthew G. Knepley #if 1
34182eabf88fSMatthew 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);
34192eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
34202eabf88fSMatthew 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);
34212eabf88fSMatthew G. Knepley         }
34222eabf88fSMatthew G. Knepley #endif
34232eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
34242eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
34252eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
34262eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
34272eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
34282eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
34292eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
34302eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
34312eabf88fSMatthew G. Knepley           }
3432a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
34332eabf88fSMatthew G. Knepley         }
34342eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
34352eabf88fSMatthew G. Knepley #if 1
34362eabf88fSMatthew 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);
34372eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
34382eabf88fSMatthew 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);
34392eabf88fSMatthew G. Knepley         }
34402eabf88fSMatthew G. Knepley #endif
34412eabf88fSMatthew G. Knepley       }
34422eabf88fSMatthew G. Knepley     }
34432eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
34442eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
34452eabf88fSMatthew 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};
3446afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
3447afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
34482eabf88fSMatthew G. Knepley 
34492eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3450afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3451afb2665bSMatthew G. Knepley       /* A-D face */
3452afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
3453a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
3454a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3455a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3456afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3457a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3458a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3459a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
3460afb2665bSMatthew G. Knepley       orntNew[3] = -2;
34612eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3462afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
34632eabf88fSMatthew G. Knepley #if 1
34642eabf88fSMatthew 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);
34652eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34662eabf88fSMatthew 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);
34672eabf88fSMatthew G. Knepley       }
34682eabf88fSMatthew G. Knepley #endif
3469afb2665bSMatthew G. Knepley       /* C-D face */
3470afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
3471a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
3472a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3473a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3474afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3475a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3476a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3477a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
3478afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3479afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3480afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3481afb2665bSMatthew G. Knepley #if 1
3482afb2665bSMatthew 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);
3483afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3484afb2665bSMatthew 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);
3485afb2665bSMatthew G. Knepley       }
3486afb2665bSMatthew G. Knepley #endif
3487afb2665bSMatthew G. Knepley       /* B-C face */
3488afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
3489afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
3490afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3491afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
3492afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3493afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3494afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3495afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3496afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3497afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3498afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3499afb2665bSMatthew G. Knepley #if 1
3500afb2665bSMatthew 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);
3501afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3502afb2665bSMatthew 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);
3503afb2665bSMatthew G. Knepley       }
3504afb2665bSMatthew G. Knepley #endif
3505afb2665bSMatthew G. Knepley       /* A-B face */
3506afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
3507afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
3508afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3509afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
3510afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3511afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3512afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3513afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3514afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3515afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3516afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3517afb2665bSMatthew G. Knepley #if 1
3518afb2665bSMatthew 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);
3519afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3520afb2665bSMatthew 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);
3521afb2665bSMatthew G. Knepley       }
3522afb2665bSMatthew G. Knepley #endif
3523afb2665bSMatthew G. Knepley       /* E-F face */
3524afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
3525a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3526afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3527a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
3528a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3529a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
3530afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3531a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3532a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3533afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3534afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3535afb2665bSMatthew G. Knepley #if 1
3536afb2665bSMatthew 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);
3537afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3538afb2665bSMatthew 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);
3539afb2665bSMatthew G. Knepley       }
3540afb2665bSMatthew G. Knepley #endif
3541afb2665bSMatthew G. Knepley       /* F-G face */
3542afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
3543a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3544afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3545a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
3546a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3547a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
3548afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3549a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3550a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3551afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3552afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3553afb2665bSMatthew G. Knepley #if 1
3554afb2665bSMatthew 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);
3555afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3556afb2665bSMatthew 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);
3557afb2665bSMatthew G. Knepley       }
3558afb2665bSMatthew G. Knepley #endif
3559afb2665bSMatthew G. Knepley       /* G-H face */
3560afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
3561afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
3562afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3563afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
3564afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3565afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3566afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3567afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3568afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3569afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3570afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3571afb2665bSMatthew G. Knepley #if 1
3572afb2665bSMatthew 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);
3573afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3574afb2665bSMatthew 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);
3575afb2665bSMatthew G. Knepley       }
3576afb2665bSMatthew G. Knepley #endif
3577afb2665bSMatthew G. Knepley       /* E-H face */
3578afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
3579a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3580afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3581a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
3582a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3583a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
3584afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3585a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3586a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3587afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3588afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3589afb2665bSMatthew G. Knepley #if 1
3590afb2665bSMatthew 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);
3591afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3592afb2665bSMatthew 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);
3593afb2665bSMatthew G. Knepley       }
3594afb2665bSMatthew G. Knepley #endif
3595afb2665bSMatthew G. Knepley       /* A-E face */
3596afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
3597a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
3598a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3599a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3600afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3601a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3602a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3603a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
3604afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3605afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3606afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3607afb2665bSMatthew G. Knepley #if 1
3608afb2665bSMatthew 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);
3609afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3610afb2665bSMatthew 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);
3611afb2665bSMatthew G. Knepley       }
3612afb2665bSMatthew G. Knepley #endif
3613afb2665bSMatthew G. Knepley       /* D-F face */
3614afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
3615afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
3616afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3617afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
3618afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3619afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3620afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3621afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3622afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3623afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3624afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3625afb2665bSMatthew G. Knepley #if 1
3626afb2665bSMatthew 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);
3627afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3628afb2665bSMatthew 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);
3629afb2665bSMatthew G. Knepley       }
3630afb2665bSMatthew G. Knepley #endif
3631afb2665bSMatthew G. Knepley       /* C-G face */
3632afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
3633a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3634afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3635a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
3636a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3637a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
3638afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3639a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3640a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3641afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3642afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3643afb2665bSMatthew G. Knepley #if 1
3644afb2665bSMatthew 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);
3645afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3646afb2665bSMatthew 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);
3647afb2665bSMatthew G. Knepley       }
3648afb2665bSMatthew G. Knepley #endif
3649afb2665bSMatthew G. Knepley       /* B-H face */
3650afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
3651a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3652a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3653a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3654a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3655a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
3656a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3657a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
3658a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3659afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3660afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3661afb2665bSMatthew G. Knepley #if 1
3662afb2665bSMatthew 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);
3663afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3664afb2665bSMatthew 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);
3665afb2665bSMatthew G. Knepley       }
3666afb2665bSMatthew G. Knepley #endif
3667afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
3668afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
36692eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
36702eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
36712eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36722eabf88fSMatthew G. Knepley #if 1
36732eabf88fSMatthew 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);
36742eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
36752eabf88fSMatthew 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);
36762eabf88fSMatthew G. Knepley         }
36772eabf88fSMatthew G. Knepley #endif
36782eabf88fSMatthew G. Knepley       }
36792eabf88fSMatthew G. Knepley     }
36802eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
36812eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
36822eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
36832eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
36842eabf88fSMatthew G. Knepley 
36852eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
36862eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
36872eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
36882eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
36892eabf88fSMatthew G. Knepley 
36902eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
36912eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
36922eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
36932eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
36942eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36952eabf88fSMatthew G. Knepley #if 1
36962eabf88fSMatthew 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);
36972eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
36982eabf88fSMatthew 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);
36992eabf88fSMatthew G. Knepley         }
37002eabf88fSMatthew G. Knepley #endif
37012eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
37022eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
37032eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
37042eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
37052eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
37062eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
37072eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
37082eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
37092eabf88fSMatthew G. Knepley           }
37102eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
37112eabf88fSMatthew G. Knepley         }
37122eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37132eabf88fSMatthew G. Knepley #if 1
37142eabf88fSMatthew 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);
37152eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
37162eabf88fSMatthew 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);
37172eabf88fSMatthew G. Knepley         }
37182eabf88fSMatthew G. Knepley #endif
37192eabf88fSMatthew G. Knepley       }
37202eabf88fSMatthew G. Knepley     }
37212eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
37222eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
37236b852384SMatthew 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};
37242eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
37256b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
37262eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
37272eabf88fSMatthew G. Knepley 
37282eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
37292eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
37302eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
37312eabf88fSMatthew G. Knepley 
37322eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
37332eabf88fSMatthew G. Knepley         coneNew[1] = newv;
37342eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37352eabf88fSMatthew G. Knepley #if 1
37362eabf88fSMatthew 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);
37372eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
37382eabf88fSMatthew 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);
37392eabf88fSMatthew G. Knepley         }
37402eabf88fSMatthew G. Knepley #endif
37412eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
37422eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
37432eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
37442eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
37452eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
37466b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
37476b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
37486b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
37492eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
3750a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
37512eabf88fSMatthew G. Knepley         }
37522eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37532eabf88fSMatthew G. Knepley #if 1
37542eabf88fSMatthew 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);
37552eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
37562eabf88fSMatthew 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);
37572eabf88fSMatthew G. Knepley         }
37582eabf88fSMatthew G. Knepley #endif
37592eabf88fSMatthew G. Knepley       }
37602eabf88fSMatthew G. Knepley     }
37612eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
37622eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
37632eabf88fSMatthew 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};
37642eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
37652eabf88fSMatthew G. Knepley       const PetscInt *cone;
37662eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
37672eabf88fSMatthew G. Knepley 
37682eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
37692eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
37702eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
37712eabf88fSMatthew G. Knepley 
37722eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
37732eabf88fSMatthew G. Knepley         coneNew[1] = newv;
37742eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37752eabf88fSMatthew G. Knepley #if 1
37762eabf88fSMatthew 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);
37772eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
37782eabf88fSMatthew 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);
37792eabf88fSMatthew G. Knepley         }
37802eabf88fSMatthew G. Knepley #endif
37812eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
37822eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37832eabf88fSMatthew G. Knepley #if 1
37842eabf88fSMatthew 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);
37852eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
37862eabf88fSMatthew 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);
37872eabf88fSMatthew G. Knepley         }
37882eabf88fSMatthew G. Knepley #endif
37892eabf88fSMatthew G. Knepley       }
37902eabf88fSMatthew G. Knepley     }
37912eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
37922eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
37932eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
37942eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
37952eabf88fSMatthew G. Knepley       PetscInt        size, s;
37962eabf88fSMatthew G. Knepley 
37972eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
37982eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
37992eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
38002eabf88fSMatthew G. Knepley         PetscInt r = 0;
38012eabf88fSMatthew G. Knepley 
38022eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
38032eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
38042eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
38052eabf88fSMatthew G. Knepley       }
38062eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
38072eabf88fSMatthew G. Knepley #if 1
38082eabf88fSMatthew 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);
38092eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
38102eabf88fSMatthew 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);
38112eabf88fSMatthew G. Knepley       }
38122eabf88fSMatthew G. Knepley #endif
38132eabf88fSMatthew G. Knepley     }
38142eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
38152eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
38162eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
38172eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
38182eabf88fSMatthew G. Knepley       PetscInt        size, s;
38192eabf88fSMatthew G. Knepley 
38202eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
38212eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
38222eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
38232eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
38242eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
38252eabf88fSMatthew G. Knepley         PetscInt r;
38262eabf88fSMatthew G. Knepley 
38272eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3828a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
38292eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
38302eabf88fSMatthew G. Knepley       }
38312eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
38322eabf88fSMatthew G. Knepley #if 1
38332eabf88fSMatthew 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);
38342eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
38352eabf88fSMatthew 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);
38362eabf88fSMatthew G. Knepley       }
38372eabf88fSMatthew G. Knepley #endif
38382eabf88fSMatthew G. Knepley     }
38392eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
38402eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
38412eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
38422eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
38432eabf88fSMatthew G. Knepley       PetscInt        size, s;
38442eabf88fSMatthew G. Knepley 
38452eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
38462eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
38470793999aSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 +  (f - fStart)*4 + r;
38482eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
38492eabf88fSMatthew G. Knepley         PetscInt r;
38502eabf88fSMatthew G. Knepley 
38512eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
38522eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
38532eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
38542eabf88fSMatthew G. Knepley       }
38552eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
38562eabf88fSMatthew G. Knepley #if 1
38572eabf88fSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
38582eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
38592eabf88fSMatthew G. Knepley         if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew);
38602eabf88fSMatthew G. Knepley       }
38612eabf88fSMatthew G. Knepley #endif
38622eabf88fSMatthew G. Knepley     }
38632eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
38642eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
38652eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
38662eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
38672eabf88fSMatthew G. Knepley 
38682eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
38692eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
38702eabf88fSMatthew G. Knepley       }
38712eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38722eabf88fSMatthew G. Knepley     }
3873da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
38742eabf88fSMatthew G. Knepley     break;
387527fcede3SMatthew G. Knepley   case 8:
387627fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
387727fcede3SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
387827fcede3SMatthew G. Knepley     /*
387927fcede3SMatthew G. Knepley      Bottom (viewed from top)    Top
388027fcede3SMatthew G. Knepley      1---------2---------2       7---------2---------6
388127fcede3SMatthew G. Knepley      |         |         |       |         |         |
388227fcede3SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
388327fcede3SMatthew G. Knepley      |         |         |       |         |         |
388427fcede3SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
388527fcede3SMatthew G. Knepley      |         |         |       |         |         |
388627fcede3SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
388727fcede3SMatthew G. Knepley      |         |         |       |         |         |
388827fcede3SMatthew G. Knepley      0---------0---------3       4---------0---------5
388927fcede3SMatthew G. Knepley      */
389027fcede3SMatthew G. Knepley     /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
389127fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
389227fcede3SMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
389327fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
389427fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
389527fcede3SMatthew G. Knepley 
389627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
389727fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
389827fcede3SMatthew G. Knepley       /* A hex */
389927fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
390027fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
390127fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
390227fcede3SMatthew G. Knepley       orntNew[1] = 0;
390327fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
390427fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
390527fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
390627fcede3SMatthew G. Knepley       orntNew[3] = 0;
390727fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
390827fcede3SMatthew G. Knepley       orntNew[4] = 0;
390927fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
391027fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
391127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
391227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
391327fcede3SMatthew G. Knepley #if 1
391427fcede3SMatthew 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);
391527fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
391627fcede3SMatthew 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);
391727fcede3SMatthew G. Knepley       }
391827fcede3SMatthew G. Knepley #endif
391927fcede3SMatthew G. Knepley       /* B hex */
392027fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
392127fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
392227fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
392327fcede3SMatthew G. Knepley       orntNew[1] = 0;
392427fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
392527fcede3SMatthew G. Knepley       orntNew[2] = -1;
392627fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
392727fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
392827fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
392927fcede3SMatthew G. Knepley       orntNew[4] = 0;
393027fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
393127fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
393227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
393327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
393427fcede3SMatthew G. Knepley #if 1
393527fcede3SMatthew 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);
393627fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
393727fcede3SMatthew 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);
393827fcede3SMatthew G. Knepley       }
393927fcede3SMatthew G. Knepley #endif
394027fcede3SMatthew G. Knepley       /* C hex */
394127fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
394227fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
394327fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
394427fcede3SMatthew G. Knepley       orntNew[1] = 0;
394527fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
394627fcede3SMatthew G. Knepley       orntNew[2] = -1;
394727fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
394827fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
394927fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
395027fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
395127fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
395227fcede3SMatthew G. Knepley       orntNew[5] = -4;
395327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
395427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
395527fcede3SMatthew G. Knepley #if 1
395627fcede3SMatthew 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);
395727fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
395827fcede3SMatthew 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);
395927fcede3SMatthew G. Knepley       }
396027fcede3SMatthew G. Knepley #endif
396127fcede3SMatthew G. Knepley       /* D hex */
396227fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
396327fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
396427fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
396527fcede3SMatthew G. Knepley       orntNew[1] = 0;
396627fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
396727fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
396827fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
396927fcede3SMatthew G. Knepley       orntNew[3] = 0;
397027fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
397127fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
397227fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
397327fcede3SMatthew G. Knepley       orntNew[5] = -4;
397427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
397527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
397627fcede3SMatthew G. Knepley #if 1
397727fcede3SMatthew 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);
397827fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
397927fcede3SMatthew 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);
398027fcede3SMatthew G. Knepley       }
398127fcede3SMatthew G. Knepley #endif
398227fcede3SMatthew G. Knepley       /* E hex */
398327fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
398427fcede3SMatthew G. Knepley       orntNew[0] = -4;
398527fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
398627fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
398727fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
398827fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
398927fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
399027fcede3SMatthew G. Knepley       orntNew[3] = 0;
399127fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
399227fcede3SMatthew G. Knepley       orntNew[4] = -1;
399327fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
399427fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
399527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
399627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
399727fcede3SMatthew G. Knepley #if 1
399827fcede3SMatthew 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);
399927fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
400027fcede3SMatthew 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);
400127fcede3SMatthew G. Knepley       }
400227fcede3SMatthew G. Knepley #endif
400327fcede3SMatthew G. Knepley       /* F hex */
400427fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
400527fcede3SMatthew G. Knepley       orntNew[0] = -4;
400627fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
400727fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
400827fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
400927fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
401027fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
401127fcede3SMatthew G. Knepley       orntNew[3] = -1;
401227fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
401327fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
401427fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
401527fcede3SMatthew G. Knepley       orntNew[5] = 1;
401627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
401727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
401827fcede3SMatthew G. Knepley #if 1
401927fcede3SMatthew 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);
402027fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
402127fcede3SMatthew 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);
402227fcede3SMatthew G. Knepley       }
402327fcede3SMatthew G. Knepley #endif
402427fcede3SMatthew G. Knepley       /* G hex */
402527fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
402627fcede3SMatthew G. Knepley       orntNew[0] = -4;
402727fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
402827fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
402927fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
403027fcede3SMatthew G. Knepley       orntNew[2] = 0;
403127fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
403227fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
403327fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
403427fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
403527fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
403627fcede3SMatthew G. Knepley       orntNew[5] = -3;
403727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
403827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
403927fcede3SMatthew G. Knepley #if 1
404027fcede3SMatthew 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);
404127fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
404227fcede3SMatthew 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);
404327fcede3SMatthew G. Knepley       }
404427fcede3SMatthew G. Knepley #endif
404527fcede3SMatthew G. Knepley       /* H hex */
404627fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
404727fcede3SMatthew G. Knepley       orntNew[0] = -4;
404827fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
404927fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
405027fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
405127fcede3SMatthew G. Knepley       orntNew[2] = -1;
405227fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
405327fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
405427fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
405527fcede3SMatthew G. Knepley       orntNew[4] = 3;
405627fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
405727fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
405827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
405927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
406027fcede3SMatthew G. Knepley #if 1
406127fcede3SMatthew 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);
406227fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
406327fcede3SMatthew 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);
406427fcede3SMatthew G. Knepley       }
406527fcede3SMatthew G. Knepley #endif
406627fcede3SMatthew G. Knepley     }
406727fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces: Front, Back, Sides */
406827fcede3SMatthew G. Knepley     /*
406927fcede3SMatthew G. Knepley      3---------2---------2
407027fcede3SMatthew G. Knepley      |         |         |
407127fcede3SMatthew G. Knepley      |    D    2    C    |
407227fcede3SMatthew G. Knepley      |         |         |
407327fcede3SMatthew G. Knepley      3----3----0----1----1
407427fcede3SMatthew G. Knepley      |         |         |
407527fcede3SMatthew G. Knepley      |    A    0    B    |
407627fcede3SMatthew G. Knepley      |         |         |
407727fcede3SMatthew G. Knepley      0---------0---------1
407827fcede3SMatthew G. Knepley      */
407927fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
408027fcede3SMatthew G. Knepley       const PetscInt  newp = (cMax - cStart)*8 + (c - cMax)*4;
408127fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
408227fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
408327fcede3SMatthew G. Knepley 
408427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
408527fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
408627fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
408727fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
408827fcede3SMatthew G. Knepley         PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
408927fcede3SMatthew G. Knepley         PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
409027fcede3SMatthew G. Knepley         PetscInt edgeB = (edgeA+3)%4;
409127fcede3SMatthew G. Knepley         if (ornt[0] != ornt[1]) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent ordering for matching ends of hybrid cell %d: %d != %d", c, ornt[0], ornt[1]);
409227fcede3SMatthew G. Knepley         coneNew[0]         = fStartNew + (cone[0] - fStart)*4 + subfA;
409327fcede3SMatthew G. Knepley         orntNew[0]         = ornt[0];
409427fcede3SMatthew G. Knepley         coneNew[1]         = fStartNew + (cone[1] - fStart)*4 + subfA;
409527fcede3SMatthew G. Knepley         orntNew[1]         = ornt[0];
409627fcede3SMatthew G. Knepley         coneNew[(r+0)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeA+2] - fMax)*2 + (fornt[edgeA] < 0 ? 1 : 0);
409727fcede3SMatthew G. Knepley         orntNew[(r+0)%4+2] = ornt[edgeA];
409827fcede3SMatthew G. Knepley         coneNew[(r+1)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeA;
409927fcede3SMatthew G. Knepley         orntNew[(r+1)%4+2] = 0;
410027fcede3SMatthew G. Knepley         coneNew[(r+2)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeB;
410127fcede3SMatthew G. Knepley         orntNew[(r+2)%4+2] = -2;
410227fcede3SMatthew G. Knepley         coneNew[(r+3)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeB+2] - fMax)*2 + (fornt[edgeB] < 0 ? 0 : 1);
410327fcede3SMatthew G. Knepley         orntNew[(r+3)%4+2] = ornt[edgeB];
410427fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
410527fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
410627fcede3SMatthew G. Knepley #if 1
410727fcede3SMatthew 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);
410827fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
410927fcede3SMatthew 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);
411027fcede3SMatthew G. Knepley         }
411127fcede3SMatthew G. Knepley         for (p = 2; p < 6; ++p) {
411227fcede3SMatthew 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);
411327fcede3SMatthew G. Knepley         }
411427fcede3SMatthew G. Knepley #endif
411527fcede3SMatthew G. Knepley       }
411627fcede3SMatthew G. Knepley     }
411727fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
411827fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
411927fcede3SMatthew G. Knepley     ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
412027fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
412127fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
412227fcede3SMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
412327fcede3SMatthew 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};
412427fcede3SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
412527fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
412627fcede3SMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
412727fcede3SMatthew G. Knepley 
412827fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
412927fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
413027fcede3SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
413127fcede3SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
413227fcede3SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
413327fcede3SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
413427fcede3SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
413527fcede3SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
413627fcede3SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
413727fcede3SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
413827fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
413927fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
414027fcede3SMatthew G. Knepley #if 1
414127fcede3SMatthew 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);
414227fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
414327fcede3SMatthew 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);
414427fcede3SMatthew G. Knepley         }
414527fcede3SMatthew G. Knepley #endif
414627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
414727fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
414827fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
414927fcede3SMatthew G. Knepley           PetscInt subf;
415027fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
415127fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
415227fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
415327fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
415427fcede3SMatthew G. Knepley             if (cone[c] == f) break;
415527fcede3SMatthew G. Knepley           }
415627fcede3SMatthew G. Knepley           subf = GetQuadSubfaceInverse_Static(ornt[c], r);
415727fcede3SMatthew G. Knepley           if (support[s] < cMax) {
415827fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
415927fcede3SMatthew G. Knepley           } else {
416027fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax       - cStart)*8 + (support[s] - cMax)*4 + subf;
416127fcede3SMatthew G. Knepley           }
416227fcede3SMatthew G. Knepley         }
416327fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
416427fcede3SMatthew G. Knepley #if 1
416527fcede3SMatthew 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);
416627fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
416727fcede3SMatthew 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);
416827fcede3SMatthew G. Knepley         }
416927fcede3SMatthew G. Knepley #endif
417027fcede3SMatthew G. Knepley       }
417127fcede3SMatthew G. Knepley     }
417227fcede3SMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
417327fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
417427fcede3SMatthew 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};
417527fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
417627fcede3SMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
417727fcede3SMatthew G. Knepley 
417827fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
417927fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
418027fcede3SMatthew G. Knepley       /* A-D face */
418127fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
418227fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
418327fcede3SMatthew G. Knepley       orntNew[0] = 0;
418427fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
418527fcede3SMatthew G. Knepley       orntNew[1] = 0;
418627fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
418727fcede3SMatthew G. Knepley       orntNew[2] = -2;
418827fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
418927fcede3SMatthew G. Knepley       orntNew[3] = -2;
419027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
419127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
419227fcede3SMatthew G. Knepley #if 1
419327fcede3SMatthew 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);
419427fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
419527fcede3SMatthew 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);
419627fcede3SMatthew G. Knepley       }
419727fcede3SMatthew G. Knepley #endif
419827fcede3SMatthew G. Knepley       /* C-D face */
419927fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
420027fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
420127fcede3SMatthew G. Knepley       orntNew[0] = 0;
420227fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
420327fcede3SMatthew G. Knepley       orntNew[1] = 0;
420427fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
420527fcede3SMatthew G. Knepley       orntNew[2] = -2;
420627fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
420727fcede3SMatthew G. Knepley       orntNew[3] = -2;
420827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
420927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
421027fcede3SMatthew G. Knepley #if 1
421127fcede3SMatthew 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);
421227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
421327fcede3SMatthew 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);
421427fcede3SMatthew G. Knepley       }
421527fcede3SMatthew G. Knepley #endif
421627fcede3SMatthew G. Knepley       /* B-C face */
421727fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
421827fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
421927fcede3SMatthew G. Knepley       orntNew[0] = -2;
422027fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
422127fcede3SMatthew G. Knepley       orntNew[1] = 0;
422227fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
422327fcede3SMatthew G. Knepley       orntNew[2] = 0;
422427fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
422527fcede3SMatthew G. Knepley       orntNew[3] = -2;
422627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
422727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
422827fcede3SMatthew G. Knepley #if 1
422927fcede3SMatthew 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);
423027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
423127fcede3SMatthew 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);
423227fcede3SMatthew G. Knepley       }
423327fcede3SMatthew G. Knepley #endif
423427fcede3SMatthew G. Knepley       /* A-B face */
423527fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
423627fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
423727fcede3SMatthew G. Knepley       orntNew[0] = -2;
423827fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
423927fcede3SMatthew G. Knepley       orntNew[1] = 0;
424027fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
424127fcede3SMatthew G. Knepley       orntNew[2] = 0;
424227fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
424327fcede3SMatthew G. Knepley       orntNew[3] = -2;
424427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
424527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
424627fcede3SMatthew G. Knepley #if 1
424727fcede3SMatthew 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);
424827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
424927fcede3SMatthew 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);
425027fcede3SMatthew G. Knepley       }
425127fcede3SMatthew G. Knepley #endif
425227fcede3SMatthew G. Knepley       /* E-F face */
425327fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
425427fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
425527fcede3SMatthew G. Knepley       orntNew[0] = -2;
425627fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
425727fcede3SMatthew G. Knepley       orntNew[1] = -2;
425827fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
425927fcede3SMatthew G. Knepley       orntNew[2] = 0;
426027fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
426127fcede3SMatthew G. Knepley       orntNew[3] = 0;
426227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
426327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
426427fcede3SMatthew G. Knepley #if 1
426527fcede3SMatthew 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);
426627fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
426727fcede3SMatthew 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);
426827fcede3SMatthew G. Knepley       }
426927fcede3SMatthew G. Knepley #endif
427027fcede3SMatthew G. Knepley       /* F-G face */
427127fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
427227fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
427327fcede3SMatthew G. Knepley       orntNew[0] = -2;
427427fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
427527fcede3SMatthew G. Knepley       orntNew[1] = -2;
427627fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
427727fcede3SMatthew G. Knepley       orntNew[2] = 0;
427827fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
427927fcede3SMatthew G. Knepley       orntNew[3] = 0;
428027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
428127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
428227fcede3SMatthew G. Knepley #if 1
428327fcede3SMatthew 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);
428427fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
428527fcede3SMatthew 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);
428627fcede3SMatthew G. Knepley       }
428727fcede3SMatthew G. Knepley #endif
428827fcede3SMatthew G. Knepley       /* G-H face */
428927fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
429027fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
429127fcede3SMatthew G. Knepley       orntNew[0] = -2;
429227fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
429327fcede3SMatthew G. Knepley       orntNew[1] = 0;
429427fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
429527fcede3SMatthew G. Knepley       orntNew[2] = 0;
429627fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
429727fcede3SMatthew G. Knepley       orntNew[3] = -2;
429827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
429927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
430027fcede3SMatthew G. Knepley #if 1
430127fcede3SMatthew 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);
430227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
430327fcede3SMatthew 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);
430427fcede3SMatthew G. Knepley       }
430527fcede3SMatthew G. Knepley #endif
430627fcede3SMatthew G. Knepley       /* E-H face */
430727fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
430827fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
430927fcede3SMatthew G. Knepley       orntNew[0] = -2;
431027fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
431127fcede3SMatthew G. Knepley       orntNew[1] = -2;
431227fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
431327fcede3SMatthew G. Knepley       orntNew[2] = 0;
431427fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
431527fcede3SMatthew G. Knepley       orntNew[3] = 0;
431627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
431727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
431827fcede3SMatthew G. Knepley #if 1
431927fcede3SMatthew 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);
432027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
432127fcede3SMatthew 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);
432227fcede3SMatthew G. Knepley       }
432327fcede3SMatthew G. Knepley #endif
432427fcede3SMatthew G. Knepley       /* A-E face */
432527fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
432627fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
432727fcede3SMatthew G. Knepley       orntNew[0] = 0;
432827fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
432927fcede3SMatthew G. Knepley       orntNew[1] = 0;
433027fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
433127fcede3SMatthew G. Knepley       orntNew[2] = -2;
433227fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
433327fcede3SMatthew G. Knepley       orntNew[3] = -2;
433427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
433527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
433627fcede3SMatthew G. Knepley #if 1
433727fcede3SMatthew 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);
433827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
433927fcede3SMatthew 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);
434027fcede3SMatthew G. Knepley       }
434127fcede3SMatthew G. Knepley #endif
434227fcede3SMatthew G. Knepley       /* D-F face */
434327fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
434427fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
434527fcede3SMatthew G. Knepley       orntNew[0] = -2;
434627fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
434727fcede3SMatthew G. Knepley       orntNew[1] = 0;
434827fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
434927fcede3SMatthew G. Knepley       orntNew[2] = 0;
435027fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
435127fcede3SMatthew G. Knepley       orntNew[3] = -2;
435227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
435327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
435427fcede3SMatthew G. Knepley #if 1
435527fcede3SMatthew 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);
435627fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
435727fcede3SMatthew 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);
435827fcede3SMatthew G. Knepley       }
435927fcede3SMatthew G. Knepley #endif
436027fcede3SMatthew G. Knepley       /* C-G face */
436127fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
436227fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
436327fcede3SMatthew G. Knepley       orntNew[0] = -2;
436427fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
436527fcede3SMatthew G. Knepley       orntNew[1] = -2;
436627fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
436727fcede3SMatthew G. Knepley       orntNew[2] = 0;
436827fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
436927fcede3SMatthew G. Knepley       orntNew[3] = 0;
437027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
437127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
437227fcede3SMatthew G. Knepley #if 1
437327fcede3SMatthew 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);
437427fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
437527fcede3SMatthew 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);
437627fcede3SMatthew G. Knepley       }
437727fcede3SMatthew G. Knepley #endif
437827fcede3SMatthew G. Knepley       /* B-H face */
437927fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
438027fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
438127fcede3SMatthew G. Knepley       orntNew[0] = 0;
438227fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
438327fcede3SMatthew G. Knepley       orntNew[1] = -2;
438427fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
438527fcede3SMatthew G. Knepley       orntNew[2] = -2;
438627fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
438727fcede3SMatthew G. Knepley       orntNew[3] = 0;
438827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
438927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
439027fcede3SMatthew G. Knepley #if 1
439127fcede3SMatthew 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);
439227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
439327fcede3SMatthew 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);
439427fcede3SMatthew G. Knepley       }
439527fcede3SMatthew G. Knepley #endif
439627fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
439727fcede3SMatthew G. Knepley         newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
439827fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
439927fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
440027fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
440127fcede3SMatthew G. Knepley #if 1
440227fcede3SMatthew 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);
440327fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
440427fcede3SMatthew 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);
440527fcede3SMatthew G. Knepley         }
440627fcede3SMatthew G. Knepley #endif
440727fcede3SMatthew G. Knepley       }
440827fcede3SMatthew G. Knepley     }
440927fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
441027fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
441127fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
441227fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
441327fcede3SMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
441427fcede3SMatthew G. Knepley 
441527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
441627fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
441727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
441827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
441927fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
442027fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
442127fcede3SMatthew G. Knepley 
442227fcede3SMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
442327fcede3SMatthew G. Knepley         orntNew[0]   = ornt[0];
442427fcede3SMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
442527fcede3SMatthew G. Knepley         orntNew[1]   = ornt[1];
442627fcede3SMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
442727fcede3SMatthew G. Knepley         orntNew[2+r] = 0;
442827fcede3SMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd      - eMax) + (f - fMax);
442927fcede3SMatthew G. Knepley         orntNew[3-r] = 0;
443027fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
443127fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
443227fcede3SMatthew G. Knepley #if 1
443327fcede3SMatthew 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);
443427fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
443527fcede3SMatthew 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);
443627fcede3SMatthew G. Knepley         }
443727fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
443827fcede3SMatthew 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);
443927fcede3SMatthew G. Knepley         }
444027fcede3SMatthew G. Knepley #endif
444127fcede3SMatthew G. Knepley         for (s = 0; s < size; ++s) {
444227fcede3SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
444327fcede3SMatthew G. Knepley 
444427fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
444527fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
444627fcede3SMatthew G. Knepley           for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
444727fcede3SMatthew G. Knepley           if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]);
444827fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
444927fcede3SMatthew G. Knepley           supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%4;
445027fcede3SMatthew G. Knepley         }
445127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
445227fcede3SMatthew G. Knepley #if 1
445327fcede3SMatthew 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);
445427fcede3SMatthew G. Knepley         for (p = 0; p < size; ++p) {
445527fcede3SMatthew 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);
445627fcede3SMatthew G. Knepley         }
445727fcede3SMatthew G. Knepley #endif
445827fcede3SMatthew G. Knepley       }
445927fcede3SMatthew G. Knepley     }
446027fcede3SMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
446127fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
446227fcede3SMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
446327fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
446427fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
446527fcede3SMatthew G. Knepley       PetscInt        supportNew[2];
446627fcede3SMatthew G. Knepley 
446727fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
446827fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
446927fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
447027fcede3SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
447127fcede3SMatthew G. Knepley         orntNew[0] = 0;
447227fcede3SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
447327fcede3SMatthew G. Knepley         orntNew[1] = 0;
447427fcede3SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
447527fcede3SMatthew G. Knepley         orntNew[2] = 0;
447627fcede3SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd                                   - fMax) + (c - cMax);
447727fcede3SMatthew G. Knepley         orntNew[3] = 0;
447827fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
447927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
448027fcede3SMatthew G. Knepley #if 1
448127fcede3SMatthew 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);
448227fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
448327fcede3SMatthew 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);
448427fcede3SMatthew G. Knepley         }
448527fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
448627fcede3SMatthew 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);
448727fcede3SMatthew G. Knepley         }
448827fcede3SMatthew G. Knepley #endif
448927fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
449027fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
449127fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
449227fcede3SMatthew G. Knepley #if 1
449327fcede3SMatthew 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);
449427fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
449527fcede3SMatthew 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);
449627fcede3SMatthew G. Knepley         }
449727fcede3SMatthew G. Knepley #endif
449827fcede3SMatthew G. Knepley       }
449927fcede3SMatthew G. Knepley     }
450027fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
450127fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
450227fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
450327fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
450427fcede3SMatthew G. Knepley 
450527fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
450627fcede3SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
450727fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
450827fcede3SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
450927fcede3SMatthew G. Knepley 
451027fcede3SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
451127fcede3SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
451227fcede3SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
451327fcede3SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
451427fcede3SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
451527fcede3SMatthew G. Knepley #if 1
451627fcede3SMatthew 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);
451727fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
451827fcede3SMatthew 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);
451927fcede3SMatthew G. Knepley         }
452027fcede3SMatthew G. Knepley #endif
452127fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
452227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
452327fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
452427fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
452527fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
452627fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
452727fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
452827fcede3SMatthew G. Knepley             if (cone[c] == e) break;
452927fcede3SMatthew G. Knepley           }
453027fcede3SMatthew G. Knepley           if (support[s] < fMax) {
453127fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
453227fcede3SMatthew G. Knepley           } else {
453327fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
453427fcede3SMatthew G. Knepley           }
453527fcede3SMatthew G. Knepley         }
453627fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
453727fcede3SMatthew G. Knepley #if 1
453827fcede3SMatthew 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);
453927fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
454027fcede3SMatthew 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);
454127fcede3SMatthew G. Knepley         }
454227fcede3SMatthew G. Knepley #endif
454327fcede3SMatthew G. Knepley       }
454427fcede3SMatthew G. Knepley     }
454527fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
454627fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
454727fcede3SMatthew 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};
454827fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
454927fcede3SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
455027fcede3SMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
455127fcede3SMatthew G. Knepley 
455227fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
455327fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
455427fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
455527fcede3SMatthew G. Knepley 
455627fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
455727fcede3SMatthew G. Knepley         coneNew[1] = newv;
455827fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
455927fcede3SMatthew G. Knepley #if 1
456027fcede3SMatthew 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);
456127fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
456227fcede3SMatthew 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);
456327fcede3SMatthew G. Knepley         }
456427fcede3SMatthew G. Knepley #endif
456527fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
456627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
456727fcede3SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
456827fcede3SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
456927fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
457027fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
457127fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
457227fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
457327fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
457427fcede3SMatthew G. Knepley           if (support[s] < cMax) {
457527fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
457627fcede3SMatthew G. Knepley           } else {
457727fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadEdgeInverse_Static(orntCell[c], r);
457827fcede3SMatthew G. Knepley           }
457927fcede3SMatthew G. Knepley         }
458027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
458127fcede3SMatthew G. Knepley #if 1
458227fcede3SMatthew 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);
458327fcede3SMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
458427fcede3SMatthew 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);
458527fcede3SMatthew G. Knepley         }
458627fcede3SMatthew G. Knepley #endif
458727fcede3SMatthew G. Knepley       }
458827fcede3SMatthew G. Knepley     }
458927fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
459027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
459127fcede3SMatthew 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};
459227fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
459327fcede3SMatthew G. Knepley       const PetscInt *cone;
459427fcede3SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
459527fcede3SMatthew G. Knepley 
459627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
459727fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
459827fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
459927fcede3SMatthew G. Knepley 
460027fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
460127fcede3SMatthew G. Knepley         coneNew[1] = newv;
460227fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
460327fcede3SMatthew G. Knepley #if 1
460427fcede3SMatthew 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);
460527fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
460627fcede3SMatthew 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);
460727fcede3SMatthew G. Knepley         }
460827fcede3SMatthew G. Knepley #endif
460927fcede3SMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
461027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
461127fcede3SMatthew G. Knepley #if 1
461227fcede3SMatthew 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);
461327fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
461427fcede3SMatthew 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);
461527fcede3SMatthew G. Knepley         }
461627fcede3SMatthew G. Knepley #endif
461727fcede3SMatthew G. Knepley       }
461827fcede3SMatthew G. Knepley     }
461927fcede3SMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
462027fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
462127fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
462227fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
462327fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
462427fcede3SMatthew G. Knepley 
462527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
462627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
462727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
462827fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
462927fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
463027fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
463127fcede3SMatthew G. Knepley #if 1
463227fcede3SMatthew 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);
463327fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
463427fcede3SMatthew 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);
463527fcede3SMatthew G. Knepley       }
463627fcede3SMatthew G. Knepley #endif
463727fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
463827fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
463927fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
464027fcede3SMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
464127fcede3SMatthew 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]);
464227fcede3SMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
464327fcede3SMatthew G. Knepley       }
464427fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
464527fcede3SMatthew G. Knepley #if 1
464627fcede3SMatthew 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);
464727fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
464827fcede3SMatthew 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);
464927fcede3SMatthew G. Knepley       }
465027fcede3SMatthew G. Knepley #endif
465127fcede3SMatthew G. Knepley     }
465227fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
465327fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
465427fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
465527fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
465627fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
465727fcede3SMatthew G. Knepley 
465827fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
465927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
466027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
466127fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
466227fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
466327fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
466427fcede3SMatthew G. Knepley #if 1
466527fcede3SMatthew 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);
466627fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
466727fcede3SMatthew 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);
466827fcede3SMatthew G. Knepley       }
466927fcede3SMatthew G. Knepley #endif
467027fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
467127fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
467227fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
467327fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
467427fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
467527fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
467627fcede3SMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
467727fcede3SMatthew 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]);
467827fcede3SMatthew G. Knepley         supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadSubfaceInverse_Static(cornt[0], c-2);
467927fcede3SMatthew G. Knepley       }
468027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
468127fcede3SMatthew G. Knepley #if 1
468227fcede3SMatthew 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);
468327fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
468427fcede3SMatthew 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);
468527fcede3SMatthew G. Knepley       }
468627fcede3SMatthew G. Knepley #endif
468727fcede3SMatthew G. Knepley     }
468827fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
468927fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
469027fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
469127fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
469227fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size;
469327fcede3SMatthew G. Knepley 
469427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
469527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr);
469627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr);
469727fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
469827fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
469927fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
470027fcede3SMatthew G. Knepley #if 1
470127fcede3SMatthew 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);
470227fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
470327fcede3SMatthew 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);
470427fcede3SMatthew G. Knepley       }
470527fcede3SMatthew G. Knepley #endif
470627fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
470727fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
470827fcede3SMatthew G. Knepley       supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
470927fcede3SMatthew G. Knepley       supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
471027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
471127fcede3SMatthew G. Knepley #if 1
471227fcede3SMatthew 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);
471327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
471427fcede3SMatthew 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);
471527fcede3SMatthew G. Knepley       }
471627fcede3SMatthew G. Knepley #endif
471727fcede3SMatthew G. Knepley     }
471827fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
471927fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
472027fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
472127fcede3SMatthew G. Knepley       const PetscInt *support, *cone;
472227fcede3SMatthew G. Knepley       PetscInt        size, s;
472327fcede3SMatthew G. Knepley 
472427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
472527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
472627fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
472727fcede3SMatthew G. Knepley         PetscInt r = 0;
472827fcede3SMatthew G. Knepley 
472927fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
473027fcede3SMatthew G. Knepley         if (cone[1] == v) r = 1;
473127fcede3SMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
473227fcede3SMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
473327fcede3SMatthew G. Knepley       }
473427fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
473527fcede3SMatthew G. Knepley #if 1
473627fcede3SMatthew 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);
473727fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
473827fcede3SMatthew 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);
473927fcede3SMatthew G. Knepley       }
474027fcede3SMatthew G. Knepley #endif
474127fcede3SMatthew G. Knepley     }
474227fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
474327fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
474427fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
474527fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
474627fcede3SMatthew G. Knepley       PetscInt        size, s;
474727fcede3SMatthew G. Knepley 
474827fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
474927fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
475027fcede3SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
475127fcede3SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
475227fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
475327fcede3SMatthew G. Knepley         PetscInt r;
475427fcede3SMatthew G. Knepley 
475527fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
475627fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
475727fcede3SMatthew G. Knepley         if (support[s] < fMax) {
475827fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
475927fcede3SMatthew G. Knepley         } else {
476027fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
476127fcede3SMatthew G. Knepley         }
476227fcede3SMatthew G. Knepley       }
476327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
476427fcede3SMatthew G. Knepley #if 1
476527fcede3SMatthew 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);
476627fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
476727fcede3SMatthew 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);
476827fcede3SMatthew G. Knepley       }
476927fcede3SMatthew G. Knepley #endif
477027fcede3SMatthew G. Knepley     }
477127fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
477227fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
477327fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
477427fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
477527fcede3SMatthew G. Knepley       PetscInt        size, s;
477627fcede3SMatthew G. Knepley 
477727fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
477827fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
477927fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 +  (f - fStart)*4 + r;
478027fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
478127fcede3SMatthew G. Knepley         PetscInt r;
478227fcede3SMatthew G. Knepley 
478327fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
478427fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
478527fcede3SMatthew G. Knepley         if (support[s] < cMax) {
478627fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
478727fcede3SMatthew G. Knepley         } else {
478827fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax       - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
478927fcede3SMatthew G. Knepley         }
479027fcede3SMatthew G. Knepley       }
479127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
479227fcede3SMatthew G. Knepley #if 1
479327fcede3SMatthew 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);
479427fcede3SMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
479527fcede3SMatthew 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);
479627fcede3SMatthew G. Knepley       }
479727fcede3SMatthew G. Knepley #endif
479827fcede3SMatthew G. Knepley     }
479927fcede3SMatthew G. Knepley     /* Cell vertices have 6 supports */
480027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
480127fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
480227fcede3SMatthew G. Knepley       PetscInt       supportNew[6];
480327fcede3SMatthew G. Knepley 
480427fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
480527fcede3SMatthew G. Knepley         supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
480627fcede3SMatthew G. Knepley       }
480727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
480827fcede3SMatthew G. Knepley     }
480927fcede3SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
481027fcede3SMatthew G. Knepley     break;
481175d3a19aSMatthew G. Knepley   default:
481275d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
481375d3a19aSMatthew G. Knepley   }
481475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
481575d3a19aSMatthew G. Knepley }
481675d3a19aSMatthew G. Knepley 
481775d3a19aSMatthew G. Knepley #undef __FUNCT__
481875d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates"
481986150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
482075d3a19aSMatthew G. Knepley {
482175d3a19aSMatthew G. Knepley   PetscSection   coordSection, coordSectionNew;
482275d3a19aSMatthew G. Knepley   Vec            coordinates, coordinatesNew;
482375d3a19aSMatthew G. Knepley   PetscScalar   *coords, *coordsNew;
48243478d7aaSMatthew G. Knepley   const PetscInt numVertices = depthSize ? depthSize[0] : 0;
482527fcede3SMatthew G. Knepley   PetscInt       dim, depth, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
482675d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
482775d3a19aSMatthew G. Knepley 
482875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
482975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
483075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
483175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
4832b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
483375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
483475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
483527fcede3SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr);
48363478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);}
483775d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);
4838f719d809SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
483975d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
484075d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
484175d3a19aSMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr);
48423478d7aaSMatthew G. Knepley   ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
484327fcede3SMatthew G. Knepley   if (cMax < 0) cMax = cEnd;
484475d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
4845b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
484675d3a19aSMatthew G. Knepley   /* All vertices have the dim coordinates */
48473478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
484875d3a19aSMatthew G. Knepley     ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr);
484975d3a19aSMatthew G. Knepley     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr);
485075d3a19aSMatthew G. Knepley   }
485175d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
4852f719d809SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr);
485375d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
485475d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
485575d3a19aSMatthew G. Knepley   ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr);
485675d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
485775d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
485875d3a19aSMatthew G. Knepley   ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr);
485975d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
486075d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
4861b5da9499SMatthew G. Knepley   switch (refiner) {
48623478d7aaSMatthew G. Knepley   case 0: break;
4863b5da9499SMatthew G. Knepley   case 6: /* Hex 3D */
4864d856d60fSMatthew G. Knepley   case 8: /* Hybrid Hex 3D */
4865b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
4866d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
486727fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
4868b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
4869b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
4870b5da9499SMatthew G. Knepley 
4871b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
4872b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
4873b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
4874b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
4875b5da9499SMatthew G. Knepley       }
4876b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
4877b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
4878b5da9499SMatthew G. Knepley       }
4879b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
4880b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
4881b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
4882b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
4883b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
4884b5da9499SMatthew G. Knepley       }
4885b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
4886b5da9499SMatthew G. Knepley     }
4887b5da9499SMatthew G. Knepley   case 2: /* Hex 2D */
4888b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
488927fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
489027fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
4891b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
4892b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
4893b5da9499SMatthew G. Knepley 
4894b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
4895b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
4896b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
4897b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
4898b5da9499SMatthew G. Knepley       }
4899b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
4900b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
4901b5da9499SMatthew G. Knepley       }
4902b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
4903b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
4904b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
4905b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
4906b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
4907b5da9499SMatthew G. Knepley       }
4908b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
4909b5da9499SMatthew G. Knepley     }
4910b5da9499SMatthew G. Knepley   case 1: /* Simplicial 2D */
4911b5da9499SMatthew G. Knepley   case 3: /* Hybrid Simplicial 2D */
4912b5da9499SMatthew G. Knepley   case 5: /* Simplicial 3D */
49136ce3c06aSMatthew G. Knepley   case 7: /* Hybrid Simplicial 3D */
4914b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
4915b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
4916b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
4917b5da9499SMatthew G. Knepley       const PetscInt *cone;
4918b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
4919b5da9499SMatthew G. Knepley 
4920b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
4921b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
4922b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
4923b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
4924b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
4925b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
4926b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
4927b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]);
4928b5da9499SMatthew G. Knepley       }
4929b5da9499SMatthew G. Knepley     }
493075d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
493175d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
493275d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
493375d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
493475d3a19aSMatthew G. Knepley 
493575d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
493675d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
493775d3a19aSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
493875d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
493975d3a19aSMatthew G. Knepley       }
494075d3a19aSMatthew G. Knepley     }
4941b5da9499SMatthew G. Knepley     break;
4942b5da9499SMatthew G. Knepley   default:
4943b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
494475d3a19aSMatthew G. Knepley   }
494575d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
494675d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
494775d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
494875d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
494975d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
495075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
495175d3a19aSMatthew G. Knepley }
495275d3a19aSMatthew G. Knepley 
495375d3a19aSMatthew G. Knepley #undef __FUNCT__
495475d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF"
495586150812SJed Brown static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
495675d3a19aSMatthew G. Knepley {
495775d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
495875d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
495975d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
496075d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
496175d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
496275d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
496375d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
496475d3a19aSMatthew G. Knepley 
496575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
496675d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
4967785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
496875d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
496975d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
497075d3a19aSMatthew G. Knepley   }
497175d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
4972785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &ranksNew);CHKERRQ(ierr);
4973785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &localPointsNew);CHKERRQ(ierr);
4974785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
497575d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
497675d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
497775d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
497875d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
497975d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
498075d3a19aSMatthew G. Knepley   }
498175d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
498275d3a19aSMatthew G. Knepley   ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);
498375d3a19aSMatthew G. Knepley   ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
498475d3a19aSMatthew G. Knepley   ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
498575d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
498675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
498775d3a19aSMatthew G. Knepley }
498875d3a19aSMatthew G. Knepley 
498975d3a19aSMatthew G. Knepley #undef __FUNCT__
499075d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF"
499186150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
499275d3a19aSMatthew G. Knepley {
499375d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
499475d3a19aSMatthew G. Knepley   IS                 processRanks;
499575d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
499675d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
499775d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
499875d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
499975d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
500075d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
500175d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
50027ba685a0SMatthew G. Knepley   PetscInt           depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
50037ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
500475d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
500575d3a19aSMatthew G. Knepley 
500675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
500775d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
500875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
500975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
501075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
501175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
501275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
501375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
50143478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
501575d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
501675d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
501775d3a19aSMatthew G. Knepley   /* Caculate size of new SF */
501875d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
501975d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
502075d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
502175d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
502275d3a19aSMatthew G. Knepley 
502375d3a19aSMatthew G. Knepley     switch (refiner) {
502475d3a19aSMatthew G. Knepley     case 1:
502575d3a19aSMatthew G. Knepley       /* Simplicial 2D */
502675d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
502775d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
502875d3a19aSMatthew G. Knepley         ++numLeavesNew;
502975d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
503075d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
5031d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
503275d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
503375d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
503475d3a19aSMatthew G. Knepley         numLeavesNew += 4 + 3;
503575d3a19aSMatthew G. Knepley       }
503675d3a19aSMatthew G. Knepley       break;
503775d3a19aSMatthew G. Knepley     case 2:
503875d3a19aSMatthew G. Knepley       /* Hex 2D */
503975d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
504075d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
504175d3a19aSMatthew G. Knepley         ++numLeavesNew;
504275d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
504375d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
5044d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
504575d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5046455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
5047455d6cd4SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
504875d3a19aSMatthew G. Knepley       }
504975d3a19aSMatthew G. Knepley       break;
5050b5da9499SMatthew G. Knepley     case 5:
5051b5da9499SMatthew G. Knepley       /* Simplicial 3D */
5052b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5053b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
5054b5da9499SMatthew G. Knepley         ++numLeavesNew;
5055b5da9499SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
5056b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
5057b5da9499SMatthew G. Knepley         numLeavesNew += 2 + 1;
5058b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
5059b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
5060b5da9499SMatthew G. Knepley         numLeavesNew += 4 + 3;
5061b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5062b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
5063b5da9499SMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
5064b5da9499SMatthew G. Knepley       }
5065b5da9499SMatthew G. Knepley       break;
50666ce3c06aSMatthew G. Knepley     case 7:
50676ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
50686ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
50696ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
50706ce3c06aSMatthew G. Knepley         ++numLeavesNew;
50716ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
50726ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
50736ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
50746ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
50756ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
50766ce3c06aSMatthew G. Knepley         ++numLeavesNew;
50776ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
50786ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
50796ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
50806ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
50816ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
50826ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
50836ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
50846ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
50856ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
50866ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
50876ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
50886ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
50896ce3c06aSMatthew G. Knepley       }
50906ce3c06aSMatthew G. Knepley       break;
50912eabf88fSMatthew G. Knepley     case 6:
50922eabf88fSMatthew G. Knepley       /* Hex 3D */
50932eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
50942eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
50952eabf88fSMatthew G. Knepley         ++numLeavesNew;
50962eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
50972eabf88fSMatthew G. Knepley         /* Old edges add new edges, and vertex */
50982eabf88fSMatthew G. Knepley         numLeavesNew += 2 + 1;
50992eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
51002eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
51012eabf88fSMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
51022eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
51032eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
51042eabf88fSMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
51052eabf88fSMatthew G. Knepley       }
51062eabf88fSMatthew G. Knepley       break;
510727fcede3SMatthew G. Knepley     case 8:
510827fcede3SMatthew G. Knepley       /* Hybrid Hex 3D */
510927fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
511027fcede3SMatthew G. Knepley         /* Old vertices stay the same */
511127fcede3SMatthew G. Knepley         ++numLeavesNew;
511227fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
511327fcede3SMatthew G. Knepley         /* Interior edges add new edges, and vertex */
511427fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
511527fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
511627fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
511727fcede3SMatthew G. Knepley         ++numLeavesNew;
511827fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
511927fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
512027fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
512127fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
512227fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
512327fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
512427fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
512527fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
512627fcede3SMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
512727fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
512827fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
512927fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
513027fcede3SMatthew G. Knepley       }
513127fcede3SMatthew G. Knepley       break;
513275d3a19aSMatthew G. Knepley     default:
513375d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
513475d3a19aSMatthew G. Knepley     }
513575d3a19aSMatthew G. Knepley   }
513675d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
513775d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
513875d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
5139dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
5140dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
514175d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
514275d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
514375d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
514475d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
514575d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
514675d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
514775d3a19aSMatthew G. Knepley   }
514875d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
514975d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
515075d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
515175d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
515275d3a19aSMatthew G. Knepley 
515375d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
515475d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
515575d3a19aSMatthew G. Knepley 
515675d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
515775d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
515875d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
515975d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
516075d3a19aSMatthew G. Knepley 
516175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
516275d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
516375d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
516475d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
516575d3a19aSMatthew G. Knepley   }
516675d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
516775d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
516875d3a19aSMatthew G. Knepley   /* Calculate new point SF */
5169785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew,    &localPointsNew);CHKERRQ(ierr);
5170785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
517175d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
517275d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
517375d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
517475d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
517575d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
517675d3a19aSMatthew G. Knepley 
517775d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
517875d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
517975d3a19aSMatthew G. Knepley     switch (refiner) {
518075d3a19aSMatthew G. Knepley     case 1:
518175d3a19aSMatthew G. Knepley       /* Simplicial 2D */
518275d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
518375d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
518475d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
518575d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
518675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
518775d3a19aSMatthew G. Knepley         ++m;
518875d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
518975d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
519075d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
519175d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
519275d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
519375d3a19aSMatthew G. Knepley         ++m;
519475d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
519575d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
519675d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
519775d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
519875d3a19aSMatthew G. Knepley         }
519975d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
520075d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
520175d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
520275d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
520375d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
520475d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
520575d3a19aSMatthew G. Knepley         }
520675d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
520775d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*3     + r;
520875d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
520975d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
521075d3a19aSMatthew G. Knepley         }
521175d3a19aSMatthew G. Knepley       }
521275d3a19aSMatthew G. Knepley       break;
521375d3a19aSMatthew G. Knepley     case 2:
521475d3a19aSMatthew G. Knepley       /* Hex 2D */
521575d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
521675d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
521775d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
521875d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
521975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
522075d3a19aSMatthew G. Knepley         ++m;
522175d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
522275d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
522375d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
522475d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
522575d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
522675d3a19aSMatthew G. Knepley         ++m;
522775d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
522875d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
522975d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
523075d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
523175d3a19aSMatthew G. Knepley         }
523275d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5233455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
523475d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
523575d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
523675d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
523775d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
523875d3a19aSMatthew G. Knepley         }
523975d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
524075d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*4     + r;
524175d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r;
524275d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
524375d3a19aSMatthew G. Knepley         }
5244455d6cd4SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
5245*149f48fdSMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (vEnd - vStart)               + (fEnd - fStart)                    + (p  - cStart)     + r;
5246*149f48fdSMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0]  + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
5247455d6cd4SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5248455d6cd4SMatthew G. Knepley         }
524975d3a19aSMatthew G. Knepley       }
525075d3a19aSMatthew G. Knepley       break;
525175d3a19aSMatthew G. Knepley     case 3:
525275d3a19aSMatthew G. Knepley       /* Hybrid simplicial 2D */
525375d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
525475d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
525575d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
525675d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
525775d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
525875d3a19aSMatthew G. Knepley         ++m;
525975d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
526075d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
526175d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
526275d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
526375d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
526475d3a19aSMatthew G. Knepley         ++m;
526575d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
526675d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
526775d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
526875d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
526975d3a19aSMatthew G. Knepley         }
527075d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
527175d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
527275d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
527375d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
527475d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
527575d3a19aSMatthew G. Knepley         ++m;
527675d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
527775d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
527875d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
527975d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
528075d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
528175d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
528275d3a19aSMatthew G. Knepley         }
528375d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
528475d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
528575d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
528675d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
528775d3a19aSMatthew G. Knepley         }
528875d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
528975d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
529075d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
529175d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
529275d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
529375d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
529475d3a19aSMatthew G. Knepley         }
529575d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
529675d3a19aSMatthew 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]);
529775d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
529875d3a19aSMatthew G. Knepley         ++m;
529975d3a19aSMatthew G. Knepley       }
530075d3a19aSMatthew G. Knepley       break;
5301b5da9499SMatthew G. Knepley     case 5:
5302b5da9499SMatthew G. Knepley       /* Simplicial 3D */
5303b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5304b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
5305b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
5306b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5307b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5308b5da9499SMatthew G. Knepley         ++m;
530987fe6628SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
5310b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
5311b5da9499SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5312b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
5313b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
5314b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5315b5da9499SMatthew G. Knepley         }
5316b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
5317b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
5318b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5319b5da9499SMatthew G. Knepley         ++m;
5320b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
5321b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
5322b5da9499SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5323b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
5324b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
5325b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5326b5da9499SMatthew G. Knepley         }
5327b5da9499SMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
5328b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*3     + r;
5329b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r;
5330b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5331b5da9499SMatthew G. Knepley         }
5332b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5333b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
5334b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
5335b5da9499SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
5336b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
5337b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5338b5da9499SMatthew G. Knepley         }
5339b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
5340b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*8     + r;
5341b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r;
5342b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5343b5da9499SMatthew G. Knepley         }
5344b5da9499SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
5345b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*3                    + (p  - cStart)*1     + r;
5346b5da9499SMatthew 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;
5347b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5348b5da9499SMatthew G. Knepley         }
5349b5da9499SMatthew G. Knepley       }
5350b5da9499SMatthew G. Knepley       break;
53516ce3c06aSMatthew G. Knepley     case 7:
53526ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
53536ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
53546ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
53556ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
53566ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
53576ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
53586ce3c06aSMatthew G. Knepley         ++m;
53596ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
53606ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
53616ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
53626ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
53636ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
53646ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
53656ce3c06aSMatthew G. Knepley         }
53666ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
53676ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
53686ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
53696ce3c06aSMatthew G. Knepley         ++m;
53706ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
53716ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
53726ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
53736ce3c06aSMatthew 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]);
53746ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
53756ce3c06aSMatthew G. Knepley         ++m;
53766ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
53776ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
53786ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
53796ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
53806ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
53816ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
53826ce3c06aSMatthew G. Knepley         }
53836ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
53846ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
53856ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
53866ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
53876ce3c06aSMatthew G. Knepley         }
53886ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
53896ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
53906ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5391899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
5392899f98d0SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r;
53936ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
53946ce3c06aSMatthew G. Knepley         }
5395899f98d0SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - fMax);
5396899f98d0SMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
53976ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
539809b1338fSMatthew G. Knepley         ++m;
53996ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
54006ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
54016ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
54026ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
54036ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
54046ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54056ce3c06aSMatthew G. Knepley         }
54066ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
54076ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
54086ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
54096ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54106ce3c06aSMatthew G. Knepley         }
54116ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + r;
54126ce3c06aSMatthew 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;
54136ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
541409b1338fSMatthew G. Knepley         ++m;
54156ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
54166ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
54176ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
54186ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
54196ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
54206ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54216ce3c06aSMatthew G. Knepley         }
54226ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
5423899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*3                            + r;
5424899f98d0SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r;
54256ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54266ce3c06aSMatthew G. Knepley         }
54276ce3c06aSMatthew G. Knepley       }
54286ce3c06aSMatthew G. Knepley       break;
54292eabf88fSMatthew G. Knepley     case 6:
54302eabf88fSMatthew G. Knepley       /* Hex 3D */
54312eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
54322eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
54332eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
54342eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
54352eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
54362eabf88fSMatthew G. Knepley         ++m;
54372eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
54382eabf88fSMatthew G. Knepley         /* Old edges add new edges and vertex */
54392eabf88fSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
54402eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
54412eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
54422eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54432eabf88fSMatthew G. Knepley         }
54442eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
54452eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
54462eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
54472eabf88fSMatthew G. Knepley         ++m;
54482eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
54492eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
54502eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
54512eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
54522eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
54532eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54542eabf88fSMatthew G. Knepley         }
54552eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
54562eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*4     + r;
54572eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r;
54582eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54592eabf88fSMatthew G. Knepley         }
54602eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (p  - fStart);
54612eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]);
54622eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
54632eabf88fSMatthew G. Knepley         ++m;
54642eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
54652eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
54662eabf88fSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
54672eabf88fSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
54682eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
54692eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54702eabf88fSMatthew G. Knepley         }
54712eabf88fSMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
54722eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*12     + r;
54732eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r;
54742eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54752eabf88fSMatthew G. Knepley         }
54762eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
54772eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*4                    + (p  - cStart)*6     + r;
54782eabf88fSMatthew 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;
54792eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54802eabf88fSMatthew G. Knepley         }
54812eabf88fSMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
54822eabf88fSMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eEnd - eStart)              + (fEnd - fStart)                    + (p  - cStart)     + r;
54832eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
54842eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54852eabf88fSMatthew G. Knepley         }
54862eabf88fSMatthew G. Knepley       }
54872eabf88fSMatthew G. Knepley       break;
548827fcede3SMatthew G. Knepley     case 8:
548927fcede3SMatthew G. Knepley       /* Hybrid Hex 3D */
549027fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
549127fcede3SMatthew G. Knepley         /* Interior vertices stay the same */
549227fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
549327fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
549427fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
549527fcede3SMatthew G. Knepley         ++m;
549627fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
549727fcede3SMatthew G. Knepley         /* Interior edges add new edges and vertex */
549827fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
549927fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
550027fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
550127fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
550227fcede3SMatthew G. Knepley         }
550327fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
550427fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
550527fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
550627fcede3SMatthew G. Knepley         ++m;
550727fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
550827fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
550927fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (p  - eMax);
551027fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rp - rdepthMaxOld[n*(depth+1)+1]);
551127fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
551227fcede3SMatthew G. Knepley         ++m;
551327fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
551427fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
551527fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
551627fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
551727fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
551827fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
551927fcede3SMatthew G. Knepley         }
552027fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
552127fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*4     + r;
552227fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
552327fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
552427fcede3SMatthew G. Knepley         }
552527fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eMax                        - eStart)     + (p  - fStart);
552627fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
552727fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
552827fcede3SMatthew G. Knepley         ++m;
552927fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
553027fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
553127fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
553227fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
553327fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r;
553427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
553527fcede3SMatthew G. Knepley         }
553627fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (fEnd                                          - fMax);
553727fcede3SMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]);
553827fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
553927fcede3SMatthew G. Knepley         ++m;
554027fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
554127fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
554227fcede3SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
554327fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
554427fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
554527fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
554627fcede3SMatthew G. Knepley         }
554727fcede3SMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
554827fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*12     + r;
554927fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
555027fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
555127fcede3SMatthew G. Knepley         }
555227fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
555327fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (p  - cStart)*6     + r;
555427fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*6 + r;
555527fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
555627fcede3SMatthew G. Knepley         }
555727fcede3SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
555827fcede3SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eMax                        - eStart)     + (fMax                              - fStart)     + (p  - cStart)     + r;
555927fcede3SMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r;
556027fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
556127fcede3SMatthew G. Knepley         }
556227fcede3SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
556327fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
556427fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
556527fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
556627fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
556727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
556827fcede3SMatthew G. Knepley         }
556927fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
557027fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*4                            + r;
557127fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
557227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
557327fcede3SMatthew G. Knepley         }
557427fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (fEnd                                          - fMax)                              + (p  - cMax);
557527fcede3SMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]);
557627fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
557727fcede3SMatthew G. Knepley         ++m;
557827fcede3SMatthew G. Knepley       }
557927fcede3SMatthew G. Knepley       break;
558075d3a19aSMatthew G. Knepley     default:
558175d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
558275d3a19aSMatthew G. Knepley     }
558375d3a19aSMatthew G. Knepley   }
558409b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
558575d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
558675d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
558775d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
558875d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
558906a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
559075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
559175d3a19aSMatthew G. Knepley }
559275d3a19aSMatthew G. Knepley 
559375d3a19aSMatthew G. Knepley #undef __FUNCT__
559475d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels"
559586150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
559675d3a19aSMatthew G. Knepley {
559775d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
55987ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
55997ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
560075d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
560175d3a19aSMatthew G. Knepley 
560275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
560375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
560475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
560575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
560675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
5607d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
56083478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
560975d3a19aSMatthew G. Knepley   ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
561075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
561175d3a19aSMatthew G. Knepley   switch (refiner) {
56123478d7aaSMatthew G. Knepley   case 0: break;
561358b8852aSMatthew G. Knepley   case 7:
561458b8852aSMatthew G. Knepley   case 8:
561558b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
561675d3a19aSMatthew G. Knepley   case 3:
561758b8852aSMatthew G. Knepley   case 4:
561875d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
561975d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
562075d3a19aSMatthew G. Knepley   }
562175d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
562275d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
562375d3a19aSMatthew G. Knepley     const char     *lname;
562475d3a19aSMatthew G. Knepley     PetscBool       isDepth;
562575d3a19aSMatthew G. Knepley     IS              valueIS;
562675d3a19aSMatthew G. Knepley     const PetscInt *values;
562775d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
562875d3a19aSMatthew G. Knepley 
562975d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr);
563075d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
563175d3a19aSMatthew G. Knepley     if (isDepth) continue;
563275d3a19aSMatthew G. Knepley     ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr);
563375d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr);
563475d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
563575d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
563675d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
563775d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
563875d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
563975d3a19aSMatthew G. Knepley       IS              pointIS;
564075d3a19aSMatthew G. Knepley       const PetscInt *points;
564175d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
564275d3a19aSMatthew G. Knepley 
564375d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
564475d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
564575d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
564675d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
564775d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
564875d3a19aSMatthew G. Knepley         switch (refiner) {
564975d3a19aSMatthew G. Knepley         case 1:
565075d3a19aSMatthew G. Knepley           /* Simplicial 2D */
565175d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
565275d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
565375d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
565475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
565575d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
565675d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
565775d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
565875d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
565975d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
566075d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
566175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
566275d3a19aSMatthew G. Knepley             }
566375d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
566475d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
566575d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
566675d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
566775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
566875d3a19aSMatthew G. Knepley             }
566975d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
567075d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
567175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
567275d3a19aSMatthew G. Knepley             }
567375d3a19aSMatthew G. Knepley           }
567475d3a19aSMatthew G. Knepley           break;
567575d3a19aSMatthew G. Knepley         case 2:
567675d3a19aSMatthew G. Knepley           /* Hex 2D */
567775d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
567875d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
567975d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
568075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
568175d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
568275d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
568375d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
568475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
568575d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
568675d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
568775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
568875d3a19aSMatthew G. Knepley             }
568975d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
569075d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
569175d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
569275d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
569375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
569475d3a19aSMatthew G. Knepley             }
569575d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
569675d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
569775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
569875d3a19aSMatthew G. Knepley             }
569975d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
570075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
570175d3a19aSMatthew G. Knepley           }
570275d3a19aSMatthew G. Knepley           break;
570375d3a19aSMatthew G. Knepley         case 3:
570475d3a19aSMatthew G. Knepley           /* Hybrid simplicial 2D */
570575d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
570675d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
570775d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
570875d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
570975d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
571075d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
571175d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
571275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
571375d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
571475d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
571575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
571675d3a19aSMatthew G. Knepley             }
571775d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
571875d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
571975d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
572075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
572175d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
572275d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
572375d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
572475d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
572575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
572675d3a19aSMatthew G. Knepley             }
572775d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
572875d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
572975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
573075d3a19aSMatthew G. Knepley             }
573175d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
573275d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
573375d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
573475d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
573575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
573675d3a19aSMatthew G. Knepley             }
573775d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
573875d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
573975d3a19aSMatthew G. Knepley           }
574075d3a19aSMatthew G. Knepley           break;
5741b5da9499SMatthew G. Knepley         case 5:
5742b5da9499SMatthew G. Knepley           /* Simplicial 3D */
5743b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
5744b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
5745b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
5746b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5747b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
5748b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
5749b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
5750b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
5751b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5752b5da9499SMatthew G. Knepley             }
5753b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
5754b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5755b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
5756b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
5757b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
5758b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
5759b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5760b5da9499SMatthew G. Knepley             }
5761b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
5762b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
5763b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5764b5da9499SMatthew G. Knepley             }
5765b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
5766b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
5767b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
5768b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
5769b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5770b5da9499SMatthew G. Knepley             }
5771b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
5772b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
5773b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5774b5da9499SMatthew G. Knepley             }
5775b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
5776b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
5777b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5778b5da9499SMatthew G. Knepley             }
5779b5da9499SMatthew G. Knepley           }
5780b5da9499SMatthew G. Knepley           break;
57816ce3c06aSMatthew G. Knepley         case 7:
57826ce3c06aSMatthew G. Knepley           /* Hybrid Simplicial 3D */
57836ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
57846ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
57856ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
57866ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
57876ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
57886ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
57896ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
57906ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
57916ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
57926ce3c06aSMatthew G. Knepley             }
57936ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
57946ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
57956ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
57966ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
57976ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
57986ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
57996ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
58006ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
58016ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
58026ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
58036ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58046ce3c06aSMatthew G. Knepley             }
58056ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
58066ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
58076ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58086ce3c06aSMatthew G. Knepley             }
58096ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
58106ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
58116ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
58126ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
58136ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58146ce3c06aSMatthew G. Knepley             }
58156ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
58166ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58176ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
58186ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
58196ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
58206ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
58216ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58226ce3c06aSMatthew G. Knepley             }
58236ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
58246ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
58256ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58266ce3c06aSMatthew G. Knepley             }
58276ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
58286ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
582958b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
58306ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
58316ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
58326ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
58336ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58346ce3c06aSMatthew G. Knepley             }
58356ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
58366ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
58376ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58386ce3c06aSMatthew G. Knepley             }
58396ce3c06aSMatthew G. Knepley           }
58406ce3c06aSMatthew G. Knepley           break;
58412eabf88fSMatthew G. Knepley         case 6:
58422eabf88fSMatthew G. Knepley           /* Hex 3D */
58432eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
58442eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
58452eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
58462eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
584719d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
58482eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
58492eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
58502eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
58512eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58522eabf88fSMatthew G. Knepley             }
58532eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
58542eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58552eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
58562eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
58572eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
58582eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
58592eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58602eabf88fSMatthew G. Knepley             }
58612eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
58622eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
58632eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58642eabf88fSMatthew G. Knepley             }
58652eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
58662eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58672eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
58682eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
58692eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
58702eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
58712eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58722eabf88fSMatthew G. Knepley             }
58732eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
58742eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
58752eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58762eabf88fSMatthew G. Knepley             }
58772eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
58782eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
58792eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58802eabf88fSMatthew G. Knepley             }
58812eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
58822eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58832eabf88fSMatthew G. Knepley           }
58842eabf88fSMatthew G. Knepley           break;
588527fcede3SMatthew G. Knepley         case 8:
588627fcede3SMatthew G. Knepley           /* Hybrid Hex 3D */
588727fcede3SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
588827fcede3SMatthew G. Knepley             /* Interior vertices stay the same */
588927fcede3SMatthew G. Knepley             newp = vStartNew + (p - vStart);
589027fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
589127fcede3SMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
589227fcede3SMatthew G. Knepley             /* Interior edges add new edges and vertex */
589327fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
589427fcede3SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
589527fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
589627fcede3SMatthew G. Knepley             }
589727fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
589827fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
589927fcede3SMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
590027fcede3SMatthew G. Knepley             /* Hybrid edges stay the same */
590127fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
590227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
590327fcede3SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
590427fcede3SMatthew G. Knepley             /* Interior faces add new faces, edges, and vertex */
590527fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
590627fcede3SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
590727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
590827fcede3SMatthew G. Knepley             }
590927fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
591027fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
591127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
591227fcede3SMatthew G. Knepley             }
591327fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
591427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
591527fcede3SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
591627fcede3SMatthew G. Knepley             /* Hybrid faces add new faces and edges */
591727fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
591827fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
591927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
592027fcede3SMatthew G. Knepley             }
592127fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
592227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
592327fcede3SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
592427fcede3SMatthew G. Knepley             /* Interior cells add new cells, faces, edges, and vertex */
592527fcede3SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
592627fcede3SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
592727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
592827fcede3SMatthew G. Knepley             }
592927fcede3SMatthew G. Knepley             for (r = 0; r < 12; ++r) {
593027fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
593127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
593227fcede3SMatthew G. Knepley             }
593327fcede3SMatthew G. Knepley             for (r = 0; r < 6; ++r) {
593427fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
593527fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
593627fcede3SMatthew G. Knepley             }
593727fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
593827fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
593927fcede3SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
594027fcede3SMatthew G. Knepley             /* Hybrid cells add new cells, faces, and edges */
594127fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
594227fcede3SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
594327fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
594427fcede3SMatthew G. Knepley             }
594527fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
594627fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
594727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
594827fcede3SMatthew G. Knepley             }
594927fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
595027fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
595127fcede3SMatthew G. Knepley           }
595227fcede3SMatthew G. Knepley           break;
595375d3a19aSMatthew G. Knepley         default:
595475d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
595575d3a19aSMatthew G. Knepley         }
595675d3a19aSMatthew G. Knepley       }
595775d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
595875d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
595975d3a19aSMatthew G. Knepley     }
596075d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
596175d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
596275d3a19aSMatthew G. Knepley     if (0) {
596375d3a19aSMatthew G. Knepley       ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr);
596475d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
596575d3a19aSMatthew G. Knepley       ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
596675d3a19aSMatthew G. Knepley     }
596775d3a19aSMatthew G. Knepley   }
596875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
596975d3a19aSMatthew G. Knepley }
597075d3a19aSMatthew G. Knepley 
597175d3a19aSMatthew G. Knepley #undef __FUNCT__
5972509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexRefineUniform_Internal"
597375d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
5974509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
597575d3a19aSMatthew G. Knepley {
597675d3a19aSMatthew G. Knepley   DM             rdm;
597775d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
597875d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
597975d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
598075d3a19aSMatthew G. Knepley 
598175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
598275d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
598375d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
598475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
598575d3a19aSMatthew G. Knepley   ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr);
598675d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
598775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
5988785e854fSJed Brown   ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr);
598975d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
599075d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
599175d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
599275d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
599375d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
599475d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
599575d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
599675d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
599775d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
599875d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
599975d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
600075d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
600175d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
600275d3a19aSMatthew G. Knepley   /* Step 6: Set coordinates for vertices */
600375d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
600475d3a19aSMatthew G. Knepley   /* Step 7: Create pointSF */
600575d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
600675d3a19aSMatthew G. Knepley   /* Step 8: Create labels */
600775d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
600875d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
600975d3a19aSMatthew G. Knepley 
601075d3a19aSMatthew G. Knepley   *dmRefined = rdm;
601175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
601275d3a19aSMatthew G. Knepley }
601375d3a19aSMatthew G. Knepley 
601475d3a19aSMatthew G. Knepley #undef __FUNCT__
601575d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform"
601675d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
601775d3a19aSMatthew G. Knepley {
601875d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
601975d3a19aSMatthew G. Knepley 
602075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
602175d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
602275d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
602375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
602475d3a19aSMatthew G. Knepley }
602575d3a19aSMatthew G. Knepley 
602675d3a19aSMatthew G. Knepley #undef __FUNCT__
602775d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform"
602875d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
602975d3a19aSMatthew G. Knepley {
603075d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
603175d3a19aSMatthew G. Knepley 
603275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
603375d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
603475d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
603575d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
603675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
603775d3a19aSMatthew G. Knepley }
603875d3a19aSMatthew G. Knepley 
603975d3a19aSMatthew G. Knepley #undef __FUNCT__
604075d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit"
604175d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
604275d3a19aSMatthew G. Knepley {
604375d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
604475d3a19aSMatthew G. Knepley 
604575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
604675d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
604775d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
604875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
604975d3a19aSMatthew G. Knepley }
605075d3a19aSMatthew G. Knepley 
605175d3a19aSMatthew G. Knepley #undef __FUNCT__
605275d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit"
605375d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
605475d3a19aSMatthew G. Knepley {
605575d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
605675d3a19aSMatthew G. Knepley 
605775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
605875d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
605975d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
606075d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
606175d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
606275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
606375d3a19aSMatthew G. Knepley }
606475d3a19aSMatthew G. Knepley 
606575d3a19aSMatthew G. Knepley #undef __FUNCT__
6066509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Internal"
6067509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
606875d3a19aSMatthew G. Knepley {
60693478d7aaSMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax;
607075d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
607175d3a19aSMatthew G. Knepley 
607275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
607375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
60743478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
60753478d7aaSMatthew G. Knepley   if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);}
607675d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
607775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr);
607875d3a19aSMatthew G. Knepley   switch (dim) {
607975d3a19aSMatthew G. Knepley   case 2:
608075d3a19aSMatthew G. Knepley     switch (coneSize) {
608175d3a19aSMatthew G. Knepley     case 3:
608275d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 3; /* Hybrid */
608375d3a19aSMatthew G. Knepley       else *cellRefiner = 1; /* Triangular */
608475d3a19aSMatthew G. Knepley       break;
608575d3a19aSMatthew G. Knepley     case 4:
608675d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 4; /* Hybrid */
608775d3a19aSMatthew G. Knepley       else *cellRefiner = 2; /* Quadrilateral */
608875d3a19aSMatthew G. Knepley       break;
608975d3a19aSMatthew G. Knepley     default:
609075d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
609175d3a19aSMatthew G. Knepley     }
609275d3a19aSMatthew G. Knepley     break;
6093b5da9499SMatthew G. Knepley   case 3:
6094b5da9499SMatthew G. Knepley     switch (coneSize) {
6095b5da9499SMatthew G. Knepley     case 4:
6096b5da9499SMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 7; /* Hybrid */
6097b5da9499SMatthew G. Knepley       else *cellRefiner = 5; /* Tetrahedral */
6098b5da9499SMatthew G. Knepley       break;
60992eabf88fSMatthew G. Knepley     case 6:
61002eabf88fSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 8; /* Hybrid */
61012eabf88fSMatthew G. Knepley       else *cellRefiner = 6; /* hexahedral */
61022eabf88fSMatthew G. Knepley       break;
6103b5da9499SMatthew G. Knepley     default:
6104b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
6105b5da9499SMatthew G. Knepley     }
6106b5da9499SMatthew G. Knepley     break;
610775d3a19aSMatthew G. Knepley   default:
610875d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
610975d3a19aSMatthew G. Knepley   }
611075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
611175d3a19aSMatthew G. Knepley }
6112