xref: /petsc/src/dm/impls/plex/plexrefine.c (revision ba3c3d50c0f2b09995ee6adcc2d5ee15f4ced80b)
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 */
60149f48fdSMatthew 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;
64a97b51b8SMatthew G. Knepley   case 4:
65a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
66a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
67a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
68a97b51b8SMatthew G. Knepley     /* Quadrilateral */
69a97b51b8SMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart;                 /* Add a vertex on every face and cell */
70a97b51b8SMatthew G. Knepley     depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart);                         /* Every face is split into 2 faces, and 4 faces are added for each cell */
71a97b51b8SMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart);                                             /* Every cell split into 4 cells */
72a97b51b8SMatthew G. Knepley     /* Segment Prisms */
73a97b51b8SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
74a97b51b8SMatthew G. Knepley     depthSize[1] +=   (fEnd - fMax)  +   (cEnd - cMax);                           /* Every hybrid face remains and 1 faces is added for each hybrid cell */
75a97b51b8SMatthew G. Knepley     depthSize[2] += 2*(cEnd - cMax);                                              /* Every hybrid cell split into 2 cells */
76a97b51b8SMatthew G. Knepley     break;
77b5da9499SMatthew G. Knepley   case 5:
78b5da9499SMatthew G. Knepley     /* Simplicial 3D */
79b5da9499SMatthew G. Knepley     depthSize[0] =    vEnd - vStart  +    eEnd - eStart;                    /* Add a vertex on every edge */
80b5da9499SMatthew 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 */
81b5da9499SMatthew G. Knepley     depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart);                   /* Every face split into 4 faces and 8 faces are added for each cell */
82b5da9499SMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                       /* Every cell split into 8 cells */
83b5da9499SMatthew G. Knepley     break;
84b5da9499SMatthew G. Knepley   case 7:
85b5da9499SMatthew G. Knepley     /* Hybrid Simplicial 3D */
86b5da9499SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
876ce3c06aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
88b5da9499SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
89dae4404aSMatthew G. Knepley     /* Tetrahedra */
90dae4404aSMatthew G. Knepley     depthSize[0]  =    vEnd - vStart  +    eMax - eStart;                    /* Add a vertex on every interior edge */
91dae4404aSMatthew 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 */
92dae4404aSMatthew G. Knepley     depthSize[2]  = 4*(fMax - fStart) + 8*(cMax - cStart);                   /* Every interior face split into 4 faces, 8 faces added for each interior cell */
93dae4404aSMatthew G. Knepley     depthSize[3]  = 8*(cMax - cStart);                                       /* Every interior cell split into 8 cells */
94dae4404aSMatthew G. Knepley     /* Triangular Prisms */
95dae4404aSMatthew G. Knepley     depthSize[0] += 0;                                                       /* No hybrid vertices */
96dae4404aSMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax);                     /* Every hybrid edge remains, 1 edge for every hybrid face */
976ce3c06aSMatthew 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 */
98dae4404aSMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                         /* Every hybrid cell split into 4 cells */
99b5da9499SMatthew G. Knepley     break;
1006ce3c06aSMatthew G. Knepley   case 6:
1016ce3c06aSMatthew G. Knepley     /* Hex 3D */
1026ce3c06aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
1036ce3c06aSMatthew 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 */
1046ce3c06aSMatthew 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 */
1056ce3c06aSMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                             /* Every cell split into 8 cells */
1066ce3c06aSMatthew G. Knepley     break;
10727fcede3SMatthew G. Knepley   case 8:
10827fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
10927fcede3SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
11027fcede3SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
11127fcede3SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
11227fcede3SMatthew G. Knepley     /* Hexahedra */
11327fcede3SMatthew G. Knepley     depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
11427fcede3SMatthew 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 */
11527fcede3SMatthew 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 */
11627fcede3SMatthew G. Knepley     depthSize[3] = 8*(cMax - cStart);                                             /* Every cell split into 8 cells */
11727fcede3SMatthew G. Knepley     /* Quadrilateral Prisms */
11827fcede3SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
11927fcede3SMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax)   +   (cEnd - cMax);      /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
12027fcede3SMatthew 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 */
12127fcede3SMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                              /* Every hybrid cell split into 4 cells */
12227fcede3SMatthew G. Knepley     break;
12375d3a19aSMatthew G. Knepley   default:
12475d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
12575d3a19aSMatthew G. Knepley   }
12675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
12775d3a19aSMatthew G. Knepley }
12875d3a19aSMatthew G. Knepley 
12942525629SMatthew G. Knepley /* Return triangle edge for orientation o, if it is r for o == 0 */
13042525629SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
131518a8359SMatthew G. Knepley   return (o < 0 ? 2-(o+r) : o+r)%3;
132518a8359SMatthew G. Knepley }
133de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
134de65f515SMatthew G. Knepley   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
135de65f515SMatthew G. Knepley }
136518a8359SMatthew G. Knepley 
137518a8359SMatthew G. Knepley /* Return triangle subface for orientation o, if it is r for o == 0 */
138518a8359SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
1394bae88c7SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%3;
14042525629SMatthew G. Knepley }
141de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
142de65f515SMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 3+s-o)%3;
143de65f515SMatthew G. Knepley }
14442525629SMatthew G. Knepley 
145431647a4SMatthew G. Knepley /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */
146431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) {
147431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+r) : o+r)%3;
148431647a4SMatthew G. Knepley }
149431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) {
150431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+s) : 3+s-o)%3;
151431647a4SMatthew G. Knepley }
152431647a4SMatthew G. Knepley 
15342525629SMatthew G. Knepley 
154e3f8b1d6SMatthew G. Knepley /* Return quad edge for orientation o, if it is r for o == 0 */
155e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
156e3f8b1d6SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%4;
157e3f8b1d6SMatthew G. Knepley }
158d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
159d6d937efSMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 4+s-o)%4;
160d6d937efSMatthew G. Knepley }
161e3f8b1d6SMatthew G. Knepley 
162e3f8b1d6SMatthew G. Knepley /* Return quad subface for orientation o, if it is r for o == 0 */
163e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
1644bae88c7SMatthew G. Knepley   return (o < 0 ? 4-(o+r) : o+r)%4;
16542525629SMatthew G. Knepley }
166d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
167d6d937efSMatthew G. Knepley   return (o < 0 ? 4-(o+s) : 4+s-o)%4;
168d6d937efSMatthew G. Knepley }
16942525629SMatthew G. Knepley 
17075d3a19aSMatthew G. Knepley #undef __FUNCT__
17175d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetConeSizes"
17286150812SJed Brown static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
17375d3a19aSMatthew G. Knepley {
174b5da9499SMatthew 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;
17575d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
17675d3a19aSMatthew G. Knepley 
17775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
1782a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
17975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
18075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
18175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
18275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
18375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
18475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
1852a5d0125SJed Brown   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
18675d3a19aSMatthew G. Knepley   switch (refiner) {
18775d3a19aSMatthew G. Knepley   case 1:
18875d3a19aSMatthew G. Knepley     /* Simplicial 2D */
18975d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
19075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
19175d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
19275d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
19375d3a19aSMatthew G. Knepley 
19475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
19575d3a19aSMatthew G. Knepley       }
19675d3a19aSMatthew G. Knepley     }
19775d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
19875d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
19975d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
20075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
20175d3a19aSMatthew G. Knepley         PetscInt       size;
20275d3a19aSMatthew G. Knepley 
20375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
20475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
20575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
20675d3a19aSMatthew G. Knepley       }
20775d3a19aSMatthew G. Knepley     }
20875d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
20975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
21075d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
21175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
21275d3a19aSMatthew G. Knepley 
21375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
21475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
21575d3a19aSMatthew G. Knepley       }
21675d3a19aSMatthew G. Knepley     }
21775d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
21875d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
21975d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
22075d3a19aSMatthew G. Knepley       PetscInt       size;
22175d3a19aSMatthew G. Knepley 
22275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
22375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
22475d3a19aSMatthew G. Knepley     }
22575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
22675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
22775d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
22875d3a19aSMatthew G. Knepley       PetscInt       size;
22975d3a19aSMatthew G. Knepley 
23075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
23175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
23275d3a19aSMatthew G. Knepley     }
23375d3a19aSMatthew G. Knepley     break;
23475d3a19aSMatthew G. Knepley   case 2:
23575d3a19aSMatthew G. Knepley     /* Hex 2D */
23675d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
23775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
23875d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
239149f48fdSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
24075d3a19aSMatthew G. Knepley 
24175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
24275d3a19aSMatthew G. Knepley       }
24375d3a19aSMatthew G. Knepley     }
24475d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
24575d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
24675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
24775d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
24875d3a19aSMatthew G. Knepley         PetscInt       size;
24975d3a19aSMatthew G. Knepley 
25075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
25175d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
25275d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
25375d3a19aSMatthew G. Knepley       }
25475d3a19aSMatthew G. Knepley     }
25575d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
25675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
25775d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
25875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
25975d3a19aSMatthew G. Knepley 
26075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
26175d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
26275d3a19aSMatthew G. Knepley       }
26375d3a19aSMatthew G. Knepley     }
26475d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
26575d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
26675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
26775d3a19aSMatthew G. Knepley       PetscInt       size;
26875d3a19aSMatthew G. Knepley 
26975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
27075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
27175d3a19aSMatthew G. Knepley     }
27275d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
27375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
27475d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
27575d3a19aSMatthew G. Knepley       PetscInt       size;
27675d3a19aSMatthew G. Knepley 
27775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
27875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
27975d3a19aSMatthew G. Knepley     }
28075d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
28175d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
28275d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
28375d3a19aSMatthew G. Knepley 
28475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
28575d3a19aSMatthew G. Knepley     }
28675d3a19aSMatthew G. Knepley     break;
28775d3a19aSMatthew G. Knepley   case 3:
288d963de37SMatthew G. Knepley     /* Hybrid Simplicial 2D */
28975d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
29075d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
29175d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
29275d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
29375d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
29475d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
29575d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
29675d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
29775d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
29875d3a19aSMatthew G. Knepley 
29975d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
30075d3a19aSMatthew G. Knepley       }
30175d3a19aSMatthew G. Knepley     }
30275d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
30375d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
30475d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
30575d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
30675d3a19aSMatthew G. Knepley 
30775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
30875d3a19aSMatthew G. Knepley       }
30975d3a19aSMatthew G. Knepley     }
31075d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
31175d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
31275d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
31375d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
31475d3a19aSMatthew G. Knepley         PetscInt       size;
31575d3a19aSMatthew G. Knepley 
31675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
31775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
31875d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
31975d3a19aSMatthew G. Knepley       }
32075d3a19aSMatthew G. Knepley     }
32175d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
32275d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
32375d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
32475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
32575d3a19aSMatthew G. Knepley 
32675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
32775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
32875d3a19aSMatthew G. Knepley       }
32975d3a19aSMatthew G. Knepley     }
33075d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
33175d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
33275d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
33375d3a19aSMatthew G. Knepley       PetscInt       size;
33475d3a19aSMatthew G. Knepley 
33575d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
33675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
33775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
33875d3a19aSMatthew G. Knepley     }
33975d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
34075d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
34175d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
34275d3a19aSMatthew G. Knepley 
34375d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
34475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
34575d3a19aSMatthew G. Knepley     }
34675d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
34775d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
34875d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
34975d3a19aSMatthew G. Knepley       PetscInt       size;
35075d3a19aSMatthew G. Knepley 
35175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
35275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
35375d3a19aSMatthew G. Knepley     }
35475d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
35575d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
35675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
35775d3a19aSMatthew G. Knepley       const PetscInt *support;
35875d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
35975d3a19aSMatthew G. Knepley 
36075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
36175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
36275d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36375d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
36475d3a19aSMatthew G. Knepley         else newSize += 2;
36575d3a19aSMatthew G. Knepley       }
36675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
36775d3a19aSMatthew G. Knepley     }
36875d3a19aSMatthew G. Knepley     break;
369a97b51b8SMatthew G. Knepley   case 4:
370a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
371a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
372a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
373a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
374a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
375a97b51b8SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
376a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
377a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
378a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
379a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
380a97b51b8SMatthew G. Knepley 
381a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
382a97b51b8SMatthew G. Knepley       }
383a97b51b8SMatthew G. Knepley     }
384a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
385a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
386a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
387a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
388a97b51b8SMatthew G. Knepley 
389a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
390a97b51b8SMatthew G. Knepley       }
391a97b51b8SMatthew G. Knepley     }
392a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
393a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
394a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
395a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
396a97b51b8SMatthew G. Knepley         PetscInt       size;
397a97b51b8SMatthew G. Knepley 
398a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
399a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
400a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
401a97b51b8SMatthew G. Knepley       }
402a97b51b8SMatthew G. Knepley     }
403a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
404a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
405a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
406a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
407a97b51b8SMatthew G. Knepley 
408a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
409a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
410a97b51b8SMatthew G. Knepley       }
411a97b51b8SMatthew G. Knepley     }
412a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
413a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
414a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
415a97b51b8SMatthew G. Knepley       PetscInt       size;
416a97b51b8SMatthew G. Knepley 
417a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
418a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
419a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
420a97b51b8SMatthew G. Knepley     }
421a97b51b8SMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
422a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
423a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
424a97b51b8SMatthew G. Knepley 
425a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
426a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
427a97b51b8SMatthew G. Knepley     }
428a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
429a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
430a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
431a97b51b8SMatthew G. Knepley       PetscInt       size;
432a97b51b8SMatthew G. Knepley 
433a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
434a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
435a97b51b8SMatthew G. Knepley     }
436a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
437a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
438a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
439a97b51b8SMatthew G. Knepley       PetscInt       size;
440a97b51b8SMatthew G. Knepley 
441a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
442a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
443a97b51b8SMatthew G. Knepley     }
444a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
445a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
446a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
447a97b51b8SMatthew G. Knepley 
448a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
449a97b51b8SMatthew G. Knepley     }
450a97b51b8SMatthew G. Knepley     break;
451b5da9499SMatthew G. Knepley   case 5:
452b5da9499SMatthew G. Knepley     /* Simplicial 3D */
453b5da9499SMatthew G. Knepley     /* All cells have 4 faces */
454b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
455b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
456dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
457b5da9499SMatthew G. Knepley 
458b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
459b5da9499SMatthew G. Knepley       }
460b5da9499SMatthew G. Knepley     }
461b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
462b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
463b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
464b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
465b5da9499SMatthew G. Knepley         PetscInt       size;
466b5da9499SMatthew G. Knepley 
467b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
468b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
469b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
470b5da9499SMatthew G. Knepley       }
471b5da9499SMatthew G. Knepley     }
4729ddff745SMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
473b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
474b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
475b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
476b5da9499SMatthew G. Knepley 
477b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
478b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
479b5da9499SMatthew G. Knepley       }
480b5da9499SMatthew G. Knepley     }
481b5da9499SMatthew G. Knepley     /* Split edges have 2 vertices and the same faces */
482b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
483b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
484b5da9499SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
485b5da9499SMatthew G. Knepley         PetscInt       size;
486b5da9499SMatthew G. Knepley 
487b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
488b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
489b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
490b5da9499SMatthew G. Knepley       }
491b5da9499SMatthew G. Knepley     }
492b5da9499SMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
493b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
494b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
495b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
496b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
497b5da9499SMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
498b5da9499SMatthew G. Knepley 
499b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
500b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
501b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
502b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
503b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
504b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
505b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
506b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
50786f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
5089ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
509b5da9499SMatthew G. Knepley           if (er == eint[c]) {
510b5da9499SMatthew G. Knepley             intFaces += 1;
511b5da9499SMatthew G. Knepley           } else {
512b5da9499SMatthew G. Knepley             intFaces += 2;
513b5da9499SMatthew G. Knepley           }
514b5da9499SMatthew G. Knepley         }
515b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
516b5da9499SMatthew G. Knepley       }
517b5da9499SMatthew G. Knepley     }
5189ddff745SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
519b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
520b5da9499SMatthew G. Knepley       const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
521b5da9499SMatthew G. Knepley 
522b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
523b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
524b5da9499SMatthew G. Knepley     }
525b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
526b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
527b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
528b5da9499SMatthew G. Knepley       PetscInt       size;
529b5da9499SMatthew G. Knepley 
530b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
531b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
532b5da9499SMatthew G. Knepley     }
533b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
534b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
535b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
536b5da9499SMatthew G. Knepley       PetscInt       size, *star = NULL, starSize, s, cellSize = 0;
537b5da9499SMatthew G. Knepley 
538b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
539b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
540b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
541b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
542b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
543b5da9499SMatthew G. Knepley 
544b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
545b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
546b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
547b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
548b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
54942525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
550b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
551b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
552b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
55342525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
55442525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
555b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
556b5da9499SMatthew G. Knepley         }
557b5da9499SMatthew G. Knepley       }
558b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
559b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr);
560b5da9499SMatthew G. Knepley     }
561b5da9499SMatthew G. Knepley     break;
562dae4404aSMatthew G. Knepley   case 7:
5636ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
5646ce3c06aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
5656ce3c06aSMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
566dae4404aSMatthew G. Knepley     /* Interior cells have 4 faces */
567dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
568dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
569dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
570dae4404aSMatthew G. Knepley 
571dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
572dae4404aSMatthew G. Knepley       }
573dae4404aSMatthew G. Knepley     }
574dae4404aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
575dae4404aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
576dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
577dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
578dae4404aSMatthew G. Knepley 
579dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr);
580dae4404aSMatthew G. Knepley       }
581dae4404aSMatthew G. Knepley     }
5826ce3c06aSMatthew G. Knepley     /* Interior split faces have 3 edges and the same cells as the parent */
583dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
584dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
585dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
586dae4404aSMatthew G. Knepley         PetscInt       size;
587dae4404aSMatthew G. Knepley 
588dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
589dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
590dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
591dae4404aSMatthew G. Knepley       }
592dae4404aSMatthew G. Knepley     }
593dae4404aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
594dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
595dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
596dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
597dae4404aSMatthew G. Knepley 
598dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
599dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
600dae4404aSMatthew G. Knepley       }
601dae4404aSMatthew G. Knepley     }
6026ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
6036ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
6046ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
6056ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
6066ce3c06aSMatthew G. Knepley         PetscInt       size;
6076ce3c06aSMatthew G. Knepley 
6086ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
6096ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
6106ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6116ce3c06aSMatthew G. Knepley       }
6126ce3c06aSMatthew G. Knepley     }
6136ce3c06aSMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
6146ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
6156ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
6166ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
6176ce3c06aSMatthew G. Knepley 
6186ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
6196ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
6206ce3c06aSMatthew G. Knepley       }
6216ce3c06aSMatthew G. Knepley     }
6226ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces */
623dae4404aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
624dae4404aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
625dae4404aSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
626dae4404aSMatthew G. Knepley         PetscInt       size;
627dae4404aSMatthew G. Knepley 
628dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
629dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
630dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
631dae4404aSMatthew G. Knepley       }
632dae4404aSMatthew G. Knepley     }
6336ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
634dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
635dae4404aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
636dae4404aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
637dae4404aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
638dae4404aSMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
639dae4404aSMatthew G. Knepley 
640dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
641dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
642dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
643dae4404aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
644dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
645dae4404aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
646dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
647dae4404aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
6486ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
649dae4404aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
6509ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
651dae4404aSMatthew G. Knepley             if (er == eint[c]) {
652dae4404aSMatthew G. Knepley               intFaces += 1;
653dae4404aSMatthew G. Knepley             } else {
654dae4404aSMatthew G. Knepley               intFaces += 2;
655dae4404aSMatthew G. Knepley             }
6566ce3c06aSMatthew G. Knepley           } else {
6576ce3c06aSMatthew G. Knepley             intFaces += 1;
6586ce3c06aSMatthew G. Knepley           }
659dae4404aSMatthew G. Knepley         }
660dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
661dae4404aSMatthew G. Knepley       }
662dae4404aSMatthew G. Knepley     }
6636ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
664dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
665dae4404aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
666dae4404aSMatthew G. Knepley 
667dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
668dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
669dae4404aSMatthew G. Knepley     }
6706ce3c06aSMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
671dae4404aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
6726ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
6736ce3c06aSMatthew G. Knepley       PetscInt       size;
6746ce3c06aSMatthew G. Knepley 
6756ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6766ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
6776ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6786ce3c06aSMatthew G. Knepley     }
6796ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
6806ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
6816ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
682dae4404aSMatthew G. Knepley       PetscInt       size;
683dae4404aSMatthew G. Knepley 
684dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
685dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
6866ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr);
687dae4404aSMatthew G. Knepley     }
6886ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
689dae4404aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
690dae4404aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
691dae4404aSMatthew G. Knepley       PetscInt       size;
692dae4404aSMatthew G. Knepley 
693dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
694dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
695dae4404aSMatthew G. Knepley     }
6966ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
6976ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
6986ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
699dae4404aSMatthew G. Knepley       const PetscInt *support;
7006ce3c06aSMatthew G. Knepley       PetscInt        size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
701dae4404aSMatthew G. Knepley 
7026ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
7036ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
704dae4404aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
7056ce3c06aSMatthew G. Knepley         if (support[s] < fMax) faceSize += 2;
7066ce3c06aSMatthew G. Knepley         else                   faceSize += 1;
707dae4404aSMatthew G. Knepley       }
7086ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
7096ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
7106ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
7116ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
7126ce3c06aSMatthew G. Knepley 
7136ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
7146ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
7156ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
7166ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
7176ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
7186ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
7196ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
7206ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
7216ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
7226ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
7236ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
7246ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
7256ce3c06aSMatthew G. Knepley         }
7266ce3c06aSMatthew G. Knepley       }
7276ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
7286ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr);
729dae4404aSMatthew G. Knepley     }
730dae4404aSMatthew G. Knepley     break;
7312eabf88fSMatthew G. Knepley   case 6:
7322eabf88fSMatthew G. Knepley     /* Hex 3D */
7332eabf88fSMatthew G. Knepley     /* All cells have 6 faces */
7342eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
7352eabf88fSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
7362eabf88fSMatthew G. Knepley         const PetscInt newp = (c - cStart)*8 + r;
7372eabf88fSMatthew G. Knepley 
7382eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
7392eabf88fSMatthew G. Knepley       }
7402eabf88fSMatthew G. Knepley     }
7412eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
7422eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
7432eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
7442eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
7452eabf88fSMatthew G. Knepley         PetscInt       size;
7462eabf88fSMatthew G. Knepley 
7472eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
7482eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
7492eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
7502eabf88fSMatthew G. Knepley       }
7512eabf88fSMatthew G. Knepley     }
7522eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
7532eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
7542eabf88fSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
7552eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
7562eabf88fSMatthew G. Knepley 
7572eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
7582eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
7592eabf88fSMatthew G. Knepley       }
7602eabf88fSMatthew G. Knepley     }
7612eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
7622eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
7632eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
7642eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
7652eabf88fSMatthew G. Knepley         PetscInt       size;
7662eabf88fSMatthew G. Knepley 
7672eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
7682eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
7692eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
7702eabf88fSMatthew G. Knepley       }
7712eabf88fSMatthew G. Knepley     }
7722eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
7732eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
7742eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
7752eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
7762eabf88fSMatthew G. Knepley         PetscInt       size;
7772eabf88fSMatthew G. Knepley 
7782eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
7792eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
7802eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
7812eabf88fSMatthew G. Knepley       }
7822eabf88fSMatthew G. Knepley     }
7832eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
7842eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
7852eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
7862eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
7872eabf88fSMatthew G. Knepley 
7882eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
7892eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
7902eabf88fSMatthew G. Knepley       }
7912eabf88fSMatthew G. Knepley     }
7922eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
7932eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
7942eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
7952eabf88fSMatthew G. Knepley       PetscInt       size;
7962eabf88fSMatthew G. Knepley 
7972eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
7982eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
7992eabf88fSMatthew G. Knepley     }
8002eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
8012eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
8022eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
8032eabf88fSMatthew G. Knepley       PetscInt       size;
8042eabf88fSMatthew G. Knepley 
8052eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
8062eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
8072eabf88fSMatthew G. Knepley     }
8082eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
8092eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
8102eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
8112eabf88fSMatthew G. Knepley       PetscInt       size;
8122eabf88fSMatthew G. Knepley 
8132eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
8142eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
8152eabf88fSMatthew G. Knepley     }
8162eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
8172eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
8182eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
8192eabf88fSMatthew G. Knepley 
8202eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
8212eabf88fSMatthew G. Knepley     }
8222eabf88fSMatthew G. Knepley     break;
82327fcede3SMatthew G. Knepley   case 8:
82427fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
82527fcede3SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
82627fcede3SMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
82727fcede3SMatthew G. Knepley     /* Interior cells have 6 faces */
82827fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
82927fcede3SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
83027fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
83127fcede3SMatthew G. Knepley 
83227fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
83327fcede3SMatthew G. Knepley       }
83427fcede3SMatthew G. Knepley     }
83527fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces */
83627fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
83727fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
83827fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
83927fcede3SMatthew G. Knepley 
84027fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
84127fcede3SMatthew G. Knepley       }
84227fcede3SMatthew G. Knepley     }
84327fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
84427fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
84527fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
84627fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
84727fcede3SMatthew G. Knepley         PetscInt       size;
84827fcede3SMatthew G. Knepley 
84927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
85027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
85127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
85227fcede3SMatthew G. Knepley       }
85327fcede3SMatthew G. Knepley     }
85427fcede3SMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
85527fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
85627fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
85727fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
85827fcede3SMatthew G. Knepley 
85927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
86027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
86127fcede3SMatthew G. Knepley       }
86227fcede3SMatthew G. Knepley     }
86327fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
86427fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
86527fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
86627fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
86727fcede3SMatthew G. Knepley         PetscInt       size;
86827fcede3SMatthew G. Knepley 
86927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
87027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
87127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
87227fcede3SMatthew G. Knepley       }
87327fcede3SMatthew G. Knepley     }
87427fcede3SMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
87527fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
87627fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
87727fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
87827fcede3SMatthew G. Knepley 
87927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
88027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
88127fcede3SMatthew G. Knepley       }
88227fcede3SMatthew G. Knepley     }
88327fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
88427fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
88527fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
88627fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
88727fcede3SMatthew G. Knepley         PetscInt       size;
88827fcede3SMatthew G. Knepley 
88927fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
89027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
89127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
89227fcede3SMatthew G. Knepley       }
89327fcede3SMatthew G. Knepley     }
89427fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
89527fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
89627fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
89727fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
89827fcede3SMatthew G. Knepley         PetscInt       size;
89927fcede3SMatthew G. Knepley 
90027fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
90127fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
90227fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
90327fcede3SMatthew G. Knepley       }
90427fcede3SMatthew G. Knepley     }
90527fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
90627fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
90727fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
90827fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
90927fcede3SMatthew G. Knepley 
91027fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
91127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
91227fcede3SMatthew G. Knepley       }
91327fcede3SMatthew G. Knepley     }
91427fcede3SMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
91527fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
91627fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
91727fcede3SMatthew G. Knepley       PetscInt       size;
91827fcede3SMatthew G. Knepley 
91927fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
92027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
92127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
92227fcede3SMatthew G. Knepley     }
92327fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
92427fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
92527fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
92627fcede3SMatthew G. Knepley       PetscInt       size;
92727fcede3SMatthew G. Knepley 
92827fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
92927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
93027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
93127fcede3SMatthew G. Knepley     }
93227fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
93327fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
93427fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
93527fcede3SMatthew G. Knepley 
93627fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
93727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
93827fcede3SMatthew G. Knepley     }
93927fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
94027fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
94127fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
94227fcede3SMatthew G. Knepley       PetscInt       size;
94327fcede3SMatthew G. Knepley 
94427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
94527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
94627fcede3SMatthew G. Knepley     }
94727fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
94827fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
94927fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
95027fcede3SMatthew G. Knepley       PetscInt       size;
95127fcede3SMatthew G. Knepley 
95227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
95327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
95427fcede3SMatthew G. Knepley     }
95527fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
95627fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
95727fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
95827fcede3SMatthew G. Knepley       PetscInt       size;
95927fcede3SMatthew G. Knepley 
96027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
96127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
96227fcede3SMatthew G. Knepley     }
96327fcede3SMatthew G. Knepley     /* Interior cell vertices have 6 supports */
96427fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
96527fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
96627fcede3SMatthew G. Knepley 
96727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
96827fcede3SMatthew G. Knepley     }
96927fcede3SMatthew G. Knepley     break;
97075d3a19aSMatthew G. Knepley   default:
97175d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
97275d3a19aSMatthew G. Knepley   }
97375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
97475d3a19aSMatthew G. Knepley }
97575d3a19aSMatthew G. Knepley 
97675d3a19aSMatthew G. Knepley #undef __FUNCT__
97775d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCones"
97886150812SJed Brown static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
97975d3a19aSMatthew G. Knepley {
980b5da9499SMatthew G. Knepley   const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
9816ce3c06aSMatthew G. Knepley   PetscInt        cStart,    cEnd,    cMax,    vStart,    vEnd, vMax, fStart,    fEnd,    fMax,    eStart,    eEnd,    eMax;
9826ce3c06aSMatthew G. Knepley   PetscInt        cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew,    fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
9836ce3c06aSMatthew G. Knepley   PetscInt        depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
98475d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
98575d3a19aSMatthew G. Knepley 
98675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
9872a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
98875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
98975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
99075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
99175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
99275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
99375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
99475d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
99575d3a19aSMatthew G. Knepley   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
99675d3a19aSMatthew G. Knepley   switch (refiner) {
99775d3a19aSMatthew G. Knepley   case 1:
99875d3a19aSMatthew G. Knepley     /* Simplicial 2D */
99975d3a19aSMatthew G. Knepley     /*
100075d3a19aSMatthew G. Knepley      2
100175d3a19aSMatthew G. Knepley      |\
100275d3a19aSMatthew G. Knepley      | \
100375d3a19aSMatthew G. Knepley      |  \
100475d3a19aSMatthew G. Knepley      |   \
100575d3a19aSMatthew G. Knepley      | C  \
100675d3a19aSMatthew G. Knepley      |     \
100775d3a19aSMatthew G. Knepley      |      \
100875d3a19aSMatthew G. Knepley      2---1---1
100975d3a19aSMatthew G. Knepley      |\  D  / \
101075d3a19aSMatthew G. Knepley      | 2   0   \
101175d3a19aSMatthew G. Knepley      |A \ /  B  \
101275d3a19aSMatthew G. Knepley      0---0-------1
101375d3a19aSMatthew G. Knepley      */
101475d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
101575d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
101675d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
101775d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
101875d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
101975d3a19aSMatthew G. Knepley 
102075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
102175d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
102275d3a19aSMatthew G. Knepley       /* A triangle */
102375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
102475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
102575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
102675d3a19aSMatthew G. Knepley       orntNew[1] = -2;
102775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
102875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
102975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
103075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
103175d3a19aSMatthew G. Knepley #if 1
103275d3a19aSMatthew 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);
103375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
103475d3a19aSMatthew 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);
103575d3a19aSMatthew G. Knepley       }
103675d3a19aSMatthew G. Knepley #endif
103775d3a19aSMatthew G. Knepley       /* B triangle */
103875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
103975d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
104075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
104175d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
104275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
104375d3a19aSMatthew G. Knepley       orntNew[2] = -2;
104475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
104575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
104675d3a19aSMatthew G. Knepley #if 1
104775d3a19aSMatthew 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);
104875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
104975d3a19aSMatthew 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);
105075d3a19aSMatthew G. Knepley       }
105175d3a19aSMatthew G. Knepley #endif
105275d3a19aSMatthew G. Knepley       /* C triangle */
105375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
105475d3a19aSMatthew G. Knepley       orntNew[0] = -2;
105575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
105675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
105775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
105875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
105975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
106075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
106175d3a19aSMatthew G. Knepley #if 1
106275d3a19aSMatthew 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);
106375d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
106475d3a19aSMatthew 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);
106575d3a19aSMatthew G. Knepley       }
106675d3a19aSMatthew G. Knepley #endif
106775d3a19aSMatthew G. Knepley       /* D triangle */
106875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
106975d3a19aSMatthew G. Knepley       orntNew[0] = 0;
107075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
107175d3a19aSMatthew G. Knepley       orntNew[1] = 0;
107275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
107375d3a19aSMatthew G. Knepley       orntNew[2] = 0;
107475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
107575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
107675d3a19aSMatthew G. Knepley #if 1
107775d3a19aSMatthew 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);
107875d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
107975d3a19aSMatthew 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);
108075d3a19aSMatthew G. Knepley       }
108175d3a19aSMatthew G. Knepley #endif
108275d3a19aSMatthew G. Knepley     }
108375d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
108475d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1085785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
108675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
108775d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
108875d3a19aSMatthew G. Knepley 
108975d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
109075d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1091297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
109275d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
109375d3a19aSMatthew G. Knepley 
109475d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
109575d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
109675d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
109775d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
109875d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
109975d3a19aSMatthew G. Knepley #if 1
110075d3a19aSMatthew 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);
110175d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
110275d3a19aSMatthew 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);
110375d3a19aSMatthew G. Knepley         }
110475d3a19aSMatthew G. Knepley #endif
110575d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
110675d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
110775d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
110875d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
110975d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1110297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
111175d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
111275d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
111375d3a19aSMatthew G. Knepley           }
1114297d2bf4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
111575d3a19aSMatthew G. Knepley         }
111675d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
111775d3a19aSMatthew G. Knepley #if 1
111875d3a19aSMatthew 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);
111975d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
112075d3a19aSMatthew 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);
112175d3a19aSMatthew G. Knepley         }
112275d3a19aSMatthew G. Knepley #endif
112375d3a19aSMatthew G. Knepley       }
112475d3a19aSMatthew G. Knepley     }
112575d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
112675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
112775d3a19aSMatthew G. Knepley       const PetscInt *cone;
112875d3a19aSMatthew G. Knepley 
112975d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
113075d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
113175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
113275d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
113375d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
113475d3a19aSMatthew G. Knepley 
113575d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
113675d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
113775d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
113875d3a19aSMatthew G. Knepley #if 1
113975d3a19aSMatthew 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);
114075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
114175d3a19aSMatthew 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);
114275d3a19aSMatthew G. Knepley         }
114375d3a19aSMatthew G. Knepley #endif
114475d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
114575d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
114675d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
114775d3a19aSMatthew G. Knepley #if 1
114875d3a19aSMatthew 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);
114975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
115075d3a19aSMatthew 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);
115175d3a19aSMatthew G. Knepley         }
115275d3a19aSMatthew G. Knepley #endif
115375d3a19aSMatthew G. Knepley       }
115475d3a19aSMatthew G. Knepley     }
115575d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
115675d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
115775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
115875d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
115975d3a19aSMatthew G. Knepley       PetscInt        size, s;
116075d3a19aSMatthew G. Knepley 
116175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
116275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
116375d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
116475d3a19aSMatthew G. Knepley         PetscInt r = 0;
116575d3a19aSMatthew G. Knepley 
116675d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
116775d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
116875d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
116975d3a19aSMatthew G. Knepley       }
117075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
117175d3a19aSMatthew G. Knepley #if 1
117275d3a19aSMatthew 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);
117375d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
117475d3a19aSMatthew 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);
117575d3a19aSMatthew G. Knepley       }
117675d3a19aSMatthew G. Knepley #endif
117775d3a19aSMatthew G. Knepley     }
117875d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
117975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
118075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
118175d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
118275d3a19aSMatthew G. Knepley       PetscInt        size, s;
118375d3a19aSMatthew G. Knepley 
118475d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
118575d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
118675d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
118775d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
118875d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
118975d3a19aSMatthew G. Knepley         PetscInt r = 0;
119075d3a19aSMatthew G. Knepley 
119175d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
119275d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
119375d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
119475d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
119575d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
119675d3a19aSMatthew G. Knepley       }
119775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
119875d3a19aSMatthew G. Knepley #if 1
119975d3a19aSMatthew 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);
120075d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
120175d3a19aSMatthew 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);
120275d3a19aSMatthew G. Knepley       }
120375d3a19aSMatthew G. Knepley #endif
120475d3a19aSMatthew G. Knepley     }
120575d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
120675d3a19aSMatthew G. Knepley     break;
120775d3a19aSMatthew G. Knepley   case 2:
120875d3a19aSMatthew G. Knepley     /* Hex 2D */
120975d3a19aSMatthew G. Knepley     /*
121075d3a19aSMatthew G. Knepley      3---------2---------2
121175d3a19aSMatthew G. Knepley      |         |         |
121275d3a19aSMatthew G. Knepley      |    D    2    C    |
121375d3a19aSMatthew G. Knepley      |         |         |
121475d3a19aSMatthew G. Knepley      3----3----0----1----1
121575d3a19aSMatthew G. Knepley      |         |         |
121675d3a19aSMatthew G. Knepley      |    A    0    B    |
121775d3a19aSMatthew G. Knepley      |         |         |
121875d3a19aSMatthew G. Knepley      0---------0---------1
121975d3a19aSMatthew G. Knepley      */
122075d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
122175d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
122275d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
122375d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
122475d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
122575d3a19aSMatthew G. Knepley 
122675d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
122775d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
122875d3a19aSMatthew G. Knepley       /* A quad */
122975d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
123075d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
123175d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
123275d3a19aSMatthew G. Knepley       orntNew[1] = 0;
123375d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
123475d3a19aSMatthew G. Knepley       orntNew[2] = -2;
123575d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
123675d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
123775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
123875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
123975d3a19aSMatthew G. Knepley #if 1
124075d3a19aSMatthew 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);
124175d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
124275d3a19aSMatthew 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);
124375d3a19aSMatthew G. Knepley       }
124475d3a19aSMatthew G. Knepley #endif
124575d3a19aSMatthew G. Knepley       /* B quad */
124675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
124775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
124875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
124975d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
125075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
125175d3a19aSMatthew G. Knepley       orntNew[2] = 0;
125275d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
125375d3a19aSMatthew G. Knepley       orntNew[3] = -2;
125475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
125575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
125675d3a19aSMatthew G. Knepley #if 1
125775d3a19aSMatthew 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);
125875d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
125975d3a19aSMatthew 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);
126075d3a19aSMatthew G. Knepley       }
126175d3a19aSMatthew G. Knepley #endif
126275d3a19aSMatthew G. Knepley       /* C quad */
126375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
126475d3a19aSMatthew G. Knepley       orntNew[0] = -2;
126575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
126675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
126775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
126875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
126975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
127075d3a19aSMatthew G. Knepley       orntNew[3] = 0;
127175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
127275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
127375d3a19aSMatthew G. Knepley #if 1
127475d3a19aSMatthew 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);
127575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
127675d3a19aSMatthew 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);
127775d3a19aSMatthew G. Knepley       }
127875d3a19aSMatthew G. Knepley #endif
127975d3a19aSMatthew G. Knepley       /* D quad */
128075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
128175d3a19aSMatthew G. Knepley       orntNew[0] = 0;
128275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
128375d3a19aSMatthew G. Knepley       orntNew[1] = -2;
128475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
128575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
128675d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
128775d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
128875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
128975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
129075d3a19aSMatthew G. Knepley #if 1
129175d3a19aSMatthew 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);
129275d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
129375d3a19aSMatthew 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);
129475d3a19aSMatthew G. Knepley       }
129575d3a19aSMatthew G. Knepley #endif
129675d3a19aSMatthew G. Knepley     }
129775d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
129875d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1299785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
130075d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
130175d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
130275d3a19aSMatthew G. Knepley 
130375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
130475d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1305455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
130675d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
130775d3a19aSMatthew G. Knepley 
130875d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
130975d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
131075d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
131175d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
131275d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
131375d3a19aSMatthew G. Knepley #if 1
131475d3a19aSMatthew 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);
131575d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
131675d3a19aSMatthew 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);
131775d3a19aSMatthew G. Knepley         }
131875d3a19aSMatthew G. Knepley #endif
131975d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
132075d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
132175d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
132275d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
132375d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1324455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
132575d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
132675d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
132775d3a19aSMatthew G. Knepley           }
1328455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
132975d3a19aSMatthew G. Knepley         }
133075d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
133175d3a19aSMatthew G. Knepley #if 1
133275d3a19aSMatthew 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);
133375d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
133475d3a19aSMatthew 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);
133575d3a19aSMatthew G. Knepley         }
133675d3a19aSMatthew G. Knepley #endif
133775d3a19aSMatthew G. Knepley       }
133875d3a19aSMatthew G. Knepley     }
133975d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
134075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
134175d3a19aSMatthew G. Knepley       const PetscInt *cone;
134275d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
134375d3a19aSMatthew G. Knepley 
134475d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
134575d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
134675d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
134775d3a19aSMatthew G. Knepley 
134875d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
134975d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
135075d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
135175d3a19aSMatthew G. Knepley #if 1
135275d3a19aSMatthew 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);
135375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
135475d3a19aSMatthew 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);
135575d3a19aSMatthew G. Knepley         }
135675d3a19aSMatthew G. Knepley #endif
135775d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
135875d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
135975d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
136075d3a19aSMatthew G. Knepley #if 1
136175d3a19aSMatthew 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);
136275d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
136375d3a19aSMatthew 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);
136475d3a19aSMatthew G. Knepley         }
136575d3a19aSMatthew G. Knepley #endif
136675d3a19aSMatthew G. Knepley       }
136775d3a19aSMatthew G. Knepley     }
136875d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
136975d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
137075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
137175d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
137275d3a19aSMatthew G. Knepley       PetscInt        size, s;
137375d3a19aSMatthew G. Knepley 
137475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
137575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
137675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
137775d3a19aSMatthew G. Knepley         PetscInt r = 0;
137875d3a19aSMatthew G. Knepley 
137975d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
138075d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
138175d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
138275d3a19aSMatthew G. Knepley       }
138375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
138475d3a19aSMatthew G. Knepley #if 1
138575d3a19aSMatthew 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);
138675d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
138775d3a19aSMatthew 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);
138875d3a19aSMatthew G. Knepley       }
138975d3a19aSMatthew G. Knepley #endif
139075d3a19aSMatthew G. Knepley     }
139175d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
139275d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
139375d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
139475d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
139575d3a19aSMatthew G. Knepley       PetscInt        size, s;
139675d3a19aSMatthew G. Knepley 
139775d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
139875d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
139975d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
140075d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
140175d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
140275d3a19aSMatthew G. Knepley         PetscInt r = 0;
140375d3a19aSMatthew G. Knepley 
140475d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
140575d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
140675d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
140775d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
140875d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
140975d3a19aSMatthew G. Knepley       }
141075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
141175d3a19aSMatthew G. Knepley #if 1
141275d3a19aSMatthew 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);
141375d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
141475d3a19aSMatthew 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);
141575d3a19aSMatthew G. Knepley       }
141675d3a19aSMatthew G. Knepley #endif
141775d3a19aSMatthew G. Knepley     }
141875d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
141975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
142075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
142175d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
142275d3a19aSMatthew G. Knepley 
142375d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
142475d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
142575d3a19aSMatthew G. Knepley       }
142675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
142775d3a19aSMatthew G. Knepley     }
1428da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
142975d3a19aSMatthew G. Knepley     break;
143075d3a19aSMatthew G. Knepley   case 3:
1431149f48fdSMatthew G. Knepley     /* Hybrid Simplicial 2D */
143275d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
143375d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
143475d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
143575d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
1436149f48fdSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
143775d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
143875d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
143975d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
144075d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
144175d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
144275d3a19aSMatthew G. Knepley 
144375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
144475d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
144575d3a19aSMatthew G. Knepley       /* A triangle */
144675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
144775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
144875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
144975d3a19aSMatthew G. Knepley       orntNew[1] = -2;
145075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
145175d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
145275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
145375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
145475d3a19aSMatthew G. Knepley #if 1
1455149f48fdSMatthew 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);
145675d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1457149f48fdSMatthew 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);
145875d3a19aSMatthew G. Knepley       }
145975d3a19aSMatthew G. Knepley #endif
146075d3a19aSMatthew G. Knepley       /* B triangle */
146175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
146275d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
146375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
146475d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
146575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
146675d3a19aSMatthew G. Knepley       orntNew[2] = -2;
146775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
146875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
146975d3a19aSMatthew G. Knepley #if 1
1470a97b51b8SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew);
147175d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1472a97b51b8SMatthew 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);
147375d3a19aSMatthew G. Knepley       }
147475d3a19aSMatthew G. Knepley #endif
147575d3a19aSMatthew G. Knepley       /* C triangle */
147675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
147775d3a19aSMatthew G. Knepley       orntNew[0] = -2;
147875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
147975d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
148075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
148175d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
148275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
148375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
148475d3a19aSMatthew G. Knepley #if 1
1485a97b51b8SMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew);
148675d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1487a97b51b8SMatthew 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);
148875d3a19aSMatthew G. Knepley       }
148975d3a19aSMatthew G. Knepley #endif
149075d3a19aSMatthew G. Knepley       /* D triangle */
149175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
149275d3a19aSMatthew G. Knepley       orntNew[0] = 0;
149375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
149475d3a19aSMatthew G. Knepley       orntNew[1] = 0;
149575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
149675d3a19aSMatthew G. Knepley       orntNew[2] = 0;
149775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
149875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
149975d3a19aSMatthew G. Knepley #if 1
1500a97b51b8SMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew);
150175d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1502a97b51b8SMatthew 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);
150375d3a19aSMatthew G. Knepley       }
150475d3a19aSMatthew G. Knepley #endif
150575d3a19aSMatthew G. Knepley     }
150675d3a19aSMatthew G. Knepley     /*
150775d3a19aSMatthew G. Knepley      2----3----3
150875d3a19aSMatthew G. Knepley      |         |
150975d3a19aSMatthew G. Knepley      |    B    |
151075d3a19aSMatthew G. Knepley      |         |
151175d3a19aSMatthew G. Knepley      0----4--- 1
151275d3a19aSMatthew G. Knepley      |         |
151375d3a19aSMatthew G. Knepley      |    A    |
151475d3a19aSMatthew G. Knepley      |         |
151575d3a19aSMatthew G. Knepley      0----2----1
151675d3a19aSMatthew G. Knepley      */
151775d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
151875d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
151975d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
152075d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
1521ea00e70eSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4], r;
152275d3a19aSMatthew G. Knepley 
152375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
152475d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1525ea00e70eSMatthew G. Knepley       r    = (ornt[0] < 0 ? 1 : 0);
152675d3a19aSMatthew G. Knepley       /* A quad */
1527ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + r;
152875d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
1529ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + r;
153075d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
1531ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax);
1532ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
1533ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
1534ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
153575d3a19aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
153675d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
153775d3a19aSMatthew G. Knepley #if 1
153875d3a19aSMatthew 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);
153975d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
154075d3a19aSMatthew 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);
154175d3a19aSMatthew G. Knepley       }
154275d3a19aSMatthew G. Knepley #endif
154375d3a19aSMatthew G. Knepley       /* B quad */
1544ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + 1-r;
154575d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
1546ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + 1-r;
154775d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
1548ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
1549ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
1550ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax);
1551ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
155275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
155375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
155475d3a19aSMatthew G. Knepley #if 1
155575d3a19aSMatthew 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);
155675d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
155775d3a19aSMatthew 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);
155875d3a19aSMatthew G. Knepley       }
155975d3a19aSMatthew G. Knepley #endif
156075d3a19aSMatthew G. Knepley     }
156175d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
156275d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1563785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
156475d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
156575d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
156675d3a19aSMatthew G. Knepley 
156775d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
156875d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1569297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
157075d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
157175d3a19aSMatthew G. Knepley 
157275d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
157375d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
157475d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
157575d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
157675d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
157775d3a19aSMatthew G. Knepley #if 1
157875d3a19aSMatthew 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);
157975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
158075d3a19aSMatthew 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);
158175d3a19aSMatthew G. Knepley         }
158275d3a19aSMatthew G. Knepley #endif
158375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
158475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
158575d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
158675d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
158775d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1588297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1589ea00e70eSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == f) break;
1590ea00e70eSMatthew G. Knepley           if (support[s] >= cMax) {
1591ea00e70eSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r);
1592ea00e70eSMatthew G. Knepley           } else {
1593297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
159475d3a19aSMatthew G. Knepley           }
159575d3a19aSMatthew G. Knepley         }
159675d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
159775d3a19aSMatthew G. Knepley #if 1
159875d3a19aSMatthew 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);
159975d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
160075d3a19aSMatthew 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);
160175d3a19aSMatthew G. Knepley         }
160275d3a19aSMatthew G. Knepley #endif
160375d3a19aSMatthew G. Knepley       }
160475d3a19aSMatthew G. Knepley     }
160575d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
160675d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
160775d3a19aSMatthew G. Knepley       const PetscInt *cone;
160875d3a19aSMatthew G. Knepley 
160975d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
161075d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
161175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
161275d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
161375d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
161475d3a19aSMatthew G. Knepley 
161575d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
161675d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
161775d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
161875d3a19aSMatthew G. Knepley #if 1
161975d3a19aSMatthew 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);
162075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
162175d3a19aSMatthew 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);
162275d3a19aSMatthew G. Knepley         }
162375d3a19aSMatthew G. Knepley #endif
162475d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
162575d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
162675d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
162775d3a19aSMatthew G. Knepley #if 1
162875d3a19aSMatthew 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);
162975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
163075d3a19aSMatthew 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);
163175d3a19aSMatthew G. Knepley         }
163275d3a19aSMatthew G. Knepley #endif
163375d3a19aSMatthew G. Knepley       }
163475d3a19aSMatthew G. Knepley     }
163575d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
163675d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
163775d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
1638ea00e70eSMatthew G. Knepley       const PetscInt *cone, *ornt;
163975d3a19aSMatthew G. Knepley       const PetscInt *support;
164075d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
164175d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
164275d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
164375d3a19aSMatthew G. Knepley 
164475d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
164575d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
164675d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
164775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
164875d3a19aSMatthew G. Knepley #if 1
164975d3a19aSMatthew 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);
165075d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
165175d3a19aSMatthew 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);
165275d3a19aSMatthew G. Knepley       }
165375d3a19aSMatthew G. Knepley #endif
165475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
165575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
165675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
165775d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1658ea00e70eSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
165975d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
166075d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
166175d3a19aSMatthew G. Knepley         }
1662ea00e70eSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r);
166375d3a19aSMatthew G. Knepley       }
166475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
166575d3a19aSMatthew G. Knepley #if 1
166675d3a19aSMatthew 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);
166775d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
166875d3a19aSMatthew 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);
166975d3a19aSMatthew G. Knepley       }
167075d3a19aSMatthew G. Knepley #endif
167175d3a19aSMatthew G. Knepley     }
167275d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
167375d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
167475d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
167575d3a19aSMatthew G. Knepley       const PetscInt *cone;
167675d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
167775d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
167875d3a19aSMatthew G. Knepley 
167975d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
168075d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
168175d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
168275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
168375d3a19aSMatthew G. Knepley #if 1
168475d3a19aSMatthew 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);
168575d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
168675d3a19aSMatthew 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);
168775d3a19aSMatthew G. Knepley       }
168875d3a19aSMatthew G. Knepley #endif
168975d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
169075d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
169175d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
169275d3a19aSMatthew G. Knepley #if 1
169375d3a19aSMatthew 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);
169475d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
169575d3a19aSMatthew 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);
169675d3a19aSMatthew G. Knepley       }
169775d3a19aSMatthew G. Knepley #endif
169875d3a19aSMatthew G. Knepley     }
169975d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
170075d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
170175d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
170275d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
170375d3a19aSMatthew G. Knepley       PetscInt        size, s;
170475d3a19aSMatthew G. Knepley 
170575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
170675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
170775d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
170875d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
170975d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
171075d3a19aSMatthew G. Knepley         } else {
171175d3a19aSMatthew G. Knepley           PetscInt r = 0;
171275d3a19aSMatthew G. Knepley 
171375d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
171475d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
171575d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
171675d3a19aSMatthew G. Knepley         }
171775d3a19aSMatthew G. Knepley       }
171875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
171975d3a19aSMatthew G. Knepley #if 1
172075d3a19aSMatthew 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);
172175d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
172275d3a19aSMatthew 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);
172375d3a19aSMatthew G. Knepley       }
172475d3a19aSMatthew G. Knepley #endif
172575d3a19aSMatthew G. Knepley     }
172675d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
172775d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
172875d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
172975d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
173075d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
173175d3a19aSMatthew G. Knepley 
173275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
173375d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
173475d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
173575d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
173675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
173775d3a19aSMatthew G. Knepley         PetscInt r = 0;
173875d3a19aSMatthew G. Knepley 
173975d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
174075d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
174175d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
174275d3a19aSMatthew G. Knepley 
174375d3a19aSMatthew G. Knepley           newSize += 1;
174475d3a19aSMatthew G. Knepley         } else {
174575d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
174675d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
174775d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
174875d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
174975d3a19aSMatthew G. Knepley 
175075d3a19aSMatthew G. Knepley           newSize += 2;
175175d3a19aSMatthew G. Knepley         }
175275d3a19aSMatthew G. Knepley       }
175375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
175475d3a19aSMatthew G. Knepley #if 1
175575d3a19aSMatthew 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);
175675d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
175775d3a19aSMatthew 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);
175875d3a19aSMatthew G. Knepley       }
175975d3a19aSMatthew G. Knepley #endif
176075d3a19aSMatthew G. Knepley     }
176175d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
176275d3a19aSMatthew G. Knepley     break;
1763a97b51b8SMatthew G. Knepley   case 4:
1764a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
1765a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
1766a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
1767a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
1768a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
1769a97b51b8SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
1770a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
1771a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
1772a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
1773a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
1774a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1775a97b51b8SMatthew G. Knepley 
1776a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1777a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1778a97b51b8SMatthew G. Knepley       /* A quad */
1779a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1780a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1781a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
1782a97b51b8SMatthew G. Knepley       orntNew[1] = 0;
1783a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
1784a97b51b8SMatthew G. Knepley       orntNew[2] = -2;
1785a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
1786a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
1787a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1788a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1789a97b51b8SMatthew G. Knepley #if 1
1790a97b51b8SMatthew 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);
1791a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1792a97b51b8SMatthew 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);
1793a97b51b8SMatthew G. Knepley       }
1794a97b51b8SMatthew G. Knepley #endif
1795a97b51b8SMatthew G. Knepley       /* B quad */
1796a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1797a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1798a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1799a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1800a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
1801a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
1802a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
1803a97b51b8SMatthew G. Knepley       orntNew[3] = -2;
1804a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1805a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1806a97b51b8SMatthew G. Knepley #if 1
1807a97b51b8SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew);
1808a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1809a97b51b8SMatthew 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);
1810a97b51b8SMatthew G. Knepley       }
1811a97b51b8SMatthew G. Knepley #endif
1812a97b51b8SMatthew G. Knepley       /* C quad */
1813a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
1814a97b51b8SMatthew G. Knepley       orntNew[0] = -2;
1815a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1816a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1817a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
1818a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
1819a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
1820a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
1821a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1822a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1823a97b51b8SMatthew G. Knepley #if 1
1824a97b51b8SMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew);
1825a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1826a97b51b8SMatthew 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);
1827a97b51b8SMatthew G. Knepley       }
1828a97b51b8SMatthew G. Knepley #endif
1829a97b51b8SMatthew G. Knepley       /* D quad */
1830a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
1831a97b51b8SMatthew G. Knepley       orntNew[0] = 0;
1832a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
1833a97b51b8SMatthew G. Knepley       orntNew[1] = -2;
1834a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
1835a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
1836a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
1837a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
1838a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1839a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1840a97b51b8SMatthew G. Knepley #if 1
1841a97b51b8SMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew);
1842a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1843a97b51b8SMatthew 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);
1844a97b51b8SMatthew G. Knepley       }
1845a97b51b8SMatthew G. Knepley #endif
1846a97b51b8SMatthew G. Knepley     }
1847a97b51b8SMatthew G. Knepley     /*
1848a97b51b8SMatthew G. Knepley      2----3----3
1849a97b51b8SMatthew G. Knepley      |         |
1850a97b51b8SMatthew G. Knepley      |    B    |
1851a97b51b8SMatthew G. Knepley      |         |
1852a97b51b8SMatthew G. Knepley      0----4--- 1
1853a97b51b8SMatthew G. Knepley      |         |
1854a97b51b8SMatthew G. Knepley      |    A    |
1855a97b51b8SMatthew G. Knepley      |         |
1856a97b51b8SMatthew G. Knepley      0----2----1
1857a97b51b8SMatthew G. Knepley      */
1858a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
1859a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
1860a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
1861a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
1862a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1863a97b51b8SMatthew G. Knepley 
1864a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1865a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1866a97b51b8SMatthew G. Knepley       /* A quad */
1867a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1868a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1869a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1870a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1871a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax);
1872a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
1873a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
1874a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
1875a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1876a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1877a97b51b8SMatthew G. Knepley #if 1
1878a97b51b8SMatthew 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);
1879a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1880a97b51b8SMatthew 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);
1881a97b51b8SMatthew G. Knepley       }
1882a97b51b8SMatthew G. Knepley #endif
1883a97b51b8SMatthew G. Knepley       /* B quad */
1884a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1885a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1886a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1887a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1888a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
1889a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
1890a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax);
1891a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
1892a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1893a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1894a97b51b8SMatthew G. Knepley #if 1
1895a97b51b8SMatthew 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);
1896a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1897a97b51b8SMatthew 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);
1898a97b51b8SMatthew G. Knepley       }
1899a97b51b8SMatthew G. Knepley #endif
1900a97b51b8SMatthew G. Knepley     }
1901a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
1902a97b51b8SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1903a97b51b8SMatthew G. Knepley     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
1904a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
1905a97b51b8SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
1906a97b51b8SMatthew G. Knepley 
1907a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
1908a97b51b8SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1909a97b51b8SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
1910a97b51b8SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
1911a97b51b8SMatthew G. Knepley 
1912a97b51b8SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
1913a97b51b8SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
1914a97b51b8SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
1915a97b51b8SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
1916a97b51b8SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1917a97b51b8SMatthew G. Knepley #if 1
1918a97b51b8SMatthew 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);
1919a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
1920a97b51b8SMatthew 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);
1921a97b51b8SMatthew G. Knepley         }
1922a97b51b8SMatthew G. Knepley #endif
1923a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
1924a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1925a97b51b8SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
1926a97b51b8SMatthew G. Knepley           if (support[s] >= cMax) {
1927a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
1928a97b51b8SMatthew G. Knepley           } else {
1929a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
1930a97b51b8SMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1931a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1932a97b51b8SMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
1933a97b51b8SMatthew G. Knepley               if (cone[c] == f) break;
1934a97b51b8SMatthew G. Knepley             }
1935a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
1936a97b51b8SMatthew G. Knepley           }
1937a97b51b8SMatthew G. Knepley         }
1938a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
1939a97b51b8SMatthew G. Knepley #if 1
1940a97b51b8SMatthew 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);
1941a97b51b8SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
1942a97b51b8SMatthew 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);
1943a97b51b8SMatthew G. Knepley         }
1944a97b51b8SMatthew G. Knepley #endif
1945a97b51b8SMatthew G. Knepley       }
1946a97b51b8SMatthew G. Knepley     }
1947a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
1948a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
1949a97b51b8SMatthew G. Knepley       const PetscInt *cone;
1950a97b51b8SMatthew G. Knepley 
1951a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1952a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
1953a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
1954a97b51b8SMatthew G. Knepley         PetscInt       coneNew[2], supportNew[2];
1955a97b51b8SMatthew G. Knepley 
1956a97b51b8SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
1957a97b51b8SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fMax    - fStart) + (c - cStart);
1958a97b51b8SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1959a97b51b8SMatthew G. Knepley #if 1
1960a97b51b8SMatthew 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);
1961a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
1962a97b51b8SMatthew 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);
1963a97b51b8SMatthew G. Knepley         }
1964a97b51b8SMatthew G. Knepley #endif
1965a97b51b8SMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
1966a97b51b8SMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
1967a97b51b8SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1968a97b51b8SMatthew G. Knepley #if 1
1969a97b51b8SMatthew 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);
1970a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
1971a97b51b8SMatthew 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);
1972a97b51b8SMatthew G. Knepley         }
1973a97b51b8SMatthew G. Knepley #endif
1974a97b51b8SMatthew G. Knepley       }
1975a97b51b8SMatthew G. Knepley     }
1976a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
1977a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
1978a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
1979a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
1980a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
1981a97b51b8SMatthew G. Knepley       PetscInt        size, s, r;
1982a97b51b8SMatthew G. Knepley 
1983a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
1984a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
1985a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
1986a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1987a97b51b8SMatthew G. Knepley #if 1
1988a97b51b8SMatthew 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);
1989a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1990a97b51b8SMatthew 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);
1991a97b51b8SMatthew G. Knepley       }
1992a97b51b8SMatthew G. Knepley #endif
1993a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
1994a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1995a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
1996a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1997a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r) {
1998a97b51b8SMatthew G. Knepley           if (cone[r+2] == f) break;
1999a97b51b8SMatthew G. Knepley         }
2000a97b51b8SMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2001a97b51b8SMatthew G. Knepley       }
2002a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2003a97b51b8SMatthew G. Knepley #if 1
2004a97b51b8SMatthew 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);
2005a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2006a97b51b8SMatthew 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);
2007a97b51b8SMatthew G. Knepley       }
2008a97b51b8SMatthew G. Knepley #endif
2009a97b51b8SMatthew G. Knepley     }
2010a97b51b8SMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
2011a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2012a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
2013a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2014a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2015a97b51b8SMatthew G. Knepley 
2016a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2017a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
2018a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
2019a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2020a97b51b8SMatthew G. Knepley #if 1
2021a97b51b8SMatthew 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);
2022a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2023a97b51b8SMatthew 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);
2024a97b51b8SMatthew G. Knepley       }
2025a97b51b8SMatthew G. Knepley #endif
2026a97b51b8SMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
2027a97b51b8SMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
2028a97b51b8SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2029a97b51b8SMatthew G. Knepley #if 1
2030a97b51b8SMatthew 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);
2031a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2032a97b51b8SMatthew 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);
2033a97b51b8SMatthew G. Knepley       }
2034a97b51b8SMatthew G. Knepley #endif
2035a97b51b8SMatthew G. Knepley     }
2036a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
2037a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2038a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2039a97b51b8SMatthew G. Knepley       const PetscInt *support, *cone;
2040a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2041a97b51b8SMatthew G. Knepley 
2042a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2043a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2044a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2045a97b51b8SMatthew G. Knepley         if (support[s] >= fMax) {
2046a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax);
2047a97b51b8SMatthew G. Knepley         } else {
2048a97b51b8SMatthew G. Knepley           PetscInt r = 0;
2049a97b51b8SMatthew G. Knepley 
2050a97b51b8SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2051a97b51b8SMatthew G. Knepley           if (cone[1] == v) r = 1;
2052a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2053a97b51b8SMatthew G. Knepley         }
2054a97b51b8SMatthew G. Knepley       }
2055a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2056a97b51b8SMatthew G. Knepley #if 1
2057a97b51b8SMatthew 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);
2058a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2059a97b51b8SMatthew 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);
2060a97b51b8SMatthew G. Knepley       }
2061a97b51b8SMatthew G. Knepley #endif
2062a97b51b8SMatthew G. Knepley     }
2063a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
2064a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2065a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
2066a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2067a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2068a97b51b8SMatthew G. Knepley 
2069a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2070a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2071a97b51b8SMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2072a97b51b8SMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2073a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2074a97b51b8SMatthew G. Knepley         PetscInt r = 0;
2075a97b51b8SMatthew G. Knepley 
2076a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2077a97b51b8SMatthew G. Knepley         if (support[s] >= cMax) {
2078a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax);
2079a97b51b8SMatthew G. Knepley         } else {
2080a97b51b8SMatthew G. Knepley           if      (cone[1] == f) r = 1;
2081a97b51b8SMatthew G. Knepley           else if (cone[2] == f) r = 2;
2082a97b51b8SMatthew G. Knepley           else if (cone[3] == f) r = 3;
2083a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r;
2084a97b51b8SMatthew G. Knepley         }
2085a97b51b8SMatthew G. Knepley       }
2086a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2087a97b51b8SMatthew G. Knepley #if 1
2088a97b51b8SMatthew 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);
2089a97b51b8SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
2090a97b51b8SMatthew 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);
2091a97b51b8SMatthew G. Knepley       }
2092a97b51b8SMatthew G. Knepley #endif
2093a97b51b8SMatthew G. Knepley     }
2094a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
2095a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2096a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
2097a97b51b8SMatthew G. Knepley       PetscInt       supportNew[4];
2098a97b51b8SMatthew G. Knepley 
2099a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2100a97b51b8SMatthew G. Knepley         supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2101a97b51b8SMatthew G. Knepley       }
2102a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2103a97b51b8SMatthew G. Knepley     }
2104a97b51b8SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2105a97b51b8SMatthew G. Knepley     break;
2106b5da9499SMatthew G. Knepley   case 5:
2107b5da9499SMatthew G. Knepley     /* Simplicial 3D */
2108b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
2109b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
2110b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2111b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
2112b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2113b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2114b5da9499SMatthew G. Knepley 
2115b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2116b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2117b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
2118518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
2119b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2120518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
2121b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2122518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
2123b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2124b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2125b5da9499SMatthew G. Knepley       orntNew[3] = 0;
2126b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2127b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2128b5da9499SMatthew G. Knepley #if 1
2129b5da9499SMatthew 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);
2130b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2131b5da9499SMatthew 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);
2132b5da9499SMatthew G. Knepley       }
2133b5da9499SMatthew G. Knepley #endif
2134b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
2135518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
2136b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2137518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
2138b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2139b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2140b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2141518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
2142b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2143b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2144b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2145b5da9499SMatthew G. Knepley #if 1
2146b5da9499SMatthew 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);
2147b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2148b5da9499SMatthew 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);
2149b5da9499SMatthew G. Knepley       }
2150b5da9499SMatthew G. Knepley #endif
2151b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
2152518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
2153b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2154b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2155b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2156518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
2157b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2158518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
2159b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2160b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2161b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2162b5da9499SMatthew G. Knepley #if 1
2163b5da9499SMatthew 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);
2164b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2165b5da9499SMatthew 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);
2166b5da9499SMatthew G. Knepley       }
2167b5da9499SMatthew G. Knepley #endif
2168b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
2169b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2170b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2171518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
2172b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2173518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
2174b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2175518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
2176b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2177b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2178b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2179b5da9499SMatthew G. Knepley #if 1
2180b5da9499SMatthew 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);
2181b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2182b5da9499SMatthew 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);
2183b5da9499SMatthew G. Knepley       }
2184b5da9499SMatthew G. Knepley #endif
2185b5da9499SMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
2186b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2187b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2188fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
2189db2c6090SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
2190fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2191fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
2192fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2193fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
2194b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
2195b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
2196b5da9499SMatthew G. Knepley #if 1
2197b5da9499SMatthew 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);
2198b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2199b5da9499SMatthew 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);
2200b5da9499SMatthew G. Knepley       }
2201b5da9499SMatthew G. Knepley #endif
2202b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
2203b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2204b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2205fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2206fac4ab25SMatthew G. Knepley       orntNew[1] = 1;
2207fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
2208b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2209fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
2210db2c6090SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
2211b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
2212b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
2213b5da9499SMatthew G. Knepley #if 1
2214b5da9499SMatthew 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);
2215b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2216b5da9499SMatthew 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);
2217b5da9499SMatthew G. Knepley       }
2218b5da9499SMatthew G. Knepley #endif
2219b5da9499SMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
2220b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2221b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2222fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
2223db2c6090SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
2224fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2225fac4ab25SMatthew G. Knepley       orntNew[2] = -3;
2226fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
2227fac4ab25SMatthew G. Knepley       orntNew[3] = -2;
2228b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
2229b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
2230b5da9499SMatthew G. Knepley #if 1
2231b5da9499SMatthew 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);
2232b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2233b5da9499SMatthew 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);
2234b5da9499SMatthew G. Knepley       }
2235b5da9499SMatthew G. Knepley #endif
2236b5da9499SMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
2237b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2238b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2239fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2240b5da9499SMatthew G. Knepley       orntNew[1] = -3;
2241fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
2242db2c6090SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
2243fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2244fac4ab25SMatthew G. Knepley       orntNew[3] = -3;
2245b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
2246b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
2247b5da9499SMatthew G. Knepley #if 1
2248b5da9499SMatthew 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);
2249b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2250b5da9499SMatthew 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);
2251b5da9499SMatthew G. Knepley       }
2252b5da9499SMatthew G. Knepley #endif
2253b5da9499SMatthew G. Knepley     }
2254b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
2255b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2256785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
2257b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2258b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
2259b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2260b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
2261b5da9499SMatthew G. Knepley 
2262b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2263b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
2264b5da9499SMatthew G. Knepley       /* A triangle */
2265b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
2266b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2267b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2268b5da9499SMatthew G. Knepley       orntNew[1] = -2;
2269b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
2270b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2271b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2272b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2273b5da9499SMatthew G. Knepley #if 1
2274b5da9499SMatthew 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);
2275b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2276b5da9499SMatthew 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);
2277b5da9499SMatthew G. Knepley       }
2278b5da9499SMatthew G. Knepley #endif
2279b5da9499SMatthew G. Knepley       /* B triangle */
2280b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
2281b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2282b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
2283b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2284b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2285b5da9499SMatthew G. Knepley       orntNew[2] = -2;
2286b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2287b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2288b5da9499SMatthew G. Knepley #if 1
2289b5da9499SMatthew 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);
2290b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2291b5da9499SMatthew 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);
2292b5da9499SMatthew G. Knepley       }
2293b5da9499SMatthew G. Knepley #endif
2294b5da9499SMatthew G. Knepley       /* C triangle */
2295b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2296b5da9499SMatthew G. Knepley       orntNew[0] = -2;
2297b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
2298b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2299b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
2300b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2301b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2302b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2303b5da9499SMatthew G. Knepley #if 1
2304b5da9499SMatthew 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);
2305b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2306b5da9499SMatthew 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);
2307b5da9499SMatthew G. Knepley       }
2308b5da9499SMatthew G. Knepley #endif
2309b5da9499SMatthew G. Knepley       /* D triangle */
2310b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2311b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2312b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2313b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2314b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2315b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2316b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2317b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2318b5da9499SMatthew G. Knepley #if 1
2319b5da9499SMatthew 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);
2320b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2321b5da9499SMatthew 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);
2322b5da9499SMatthew G. Knepley       }
2323b5da9499SMatthew G. Knepley #endif
2324b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2325b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2326b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2327b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2328219f7b90SMatthew G. Knepley           PetscInt subf;
2329b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2330b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2331b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2332b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2333b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
2334b5da9499SMatthew G. Knepley           }
2335219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
2336219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
2337b5da9499SMatthew G. Knepley         }
2338b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
2339b5da9499SMatthew G. Knepley #if 1
23409ddff745SMatthew 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);
2341b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2342b5da9499SMatthew 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);
2343b5da9499SMatthew G. Knepley         }
2344b5da9499SMatthew G. Knepley #endif
2345b5da9499SMatthew G. Knepley       }
2346b5da9499SMatthew G. Knepley     }
2347b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
2348b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2349b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
2350b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2351b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
2352b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
2353b5da9499SMatthew G. Knepley 
2354b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2355b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2356b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
23574bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2358b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
23594bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2360b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
23614bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
2362b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2363b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2364b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2365b5da9499SMatthew G. Knepley #if 1
2366b5da9499SMatthew 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);
2367b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2368b5da9499SMatthew 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);
2369b5da9499SMatthew G. Knepley       }
2370b5da9499SMatthew G. Knepley #endif
2371b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
2372b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
2373b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2374b5da9499SMatthew G. Knepley #if 1
2375b5da9499SMatthew 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);
2376b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2377b5da9499SMatthew 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);
2378b5da9499SMatthew G. Knepley       }
2379b5da9499SMatthew G. Knepley #endif
2380b5da9499SMatthew G. Knepley       ++newp;
2381b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
23824bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2383b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
23844bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
2385b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
23864bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2387b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2388b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2389b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2390b5da9499SMatthew G. Knepley #if 1
23914bb260e2SMatthew 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);
2392b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2393b5da9499SMatthew 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);
2394b5da9499SMatthew G. Knepley       }
2395b5da9499SMatthew G. Knepley #endif
2396b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
2397b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
2398b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2399b5da9499SMatthew G. Knepley #if 1
2400b5da9499SMatthew 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);
2401b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2402b5da9499SMatthew 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);
2403b5da9499SMatthew G. Knepley       }
2404b5da9499SMatthew G. Knepley #endif
2405b5da9499SMatthew G. Knepley       ++newp;
2406b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
24074bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
2408b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
24094bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2410b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
24114bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
2412b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
2413b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2414b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2415b5da9499SMatthew G. Knepley #if 1
2416b5da9499SMatthew 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);
2417b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2418b5da9499SMatthew 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);
2419b5da9499SMatthew G. Knepley       }
2420b5da9499SMatthew G. Knepley #endif
2421b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
2422b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2423b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2424b5da9499SMatthew G. Knepley #if 1
2425b5da9499SMatthew 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);
2426b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2427b5da9499SMatthew 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);
2428b5da9499SMatthew G. Knepley       }
2429b5da9499SMatthew G. Knepley #endif
2430b5da9499SMatthew G. Knepley       ++newp;
2431b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
24324bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
2433b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
24344bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2435b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
24364bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2437b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2438b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2439b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2440b5da9499SMatthew G. Knepley #if 1
2441b5da9499SMatthew 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);
2442b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2443b5da9499SMatthew 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);
2444b5da9499SMatthew G. Knepley       }
2445b5da9499SMatthew G. Knepley #endif
2446b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
2447b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2448b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2449b5da9499SMatthew G. Knepley #if 1
2450b5da9499SMatthew 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);
2451b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2452b5da9499SMatthew 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);
2453b5da9499SMatthew G. Knepley       }
2454b5da9499SMatthew G. Knepley #endif
2455b5da9499SMatthew G. Knepley       ++newp;
2456b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
24574bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2458b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
2459b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
24604bb260e2SMatthew G. Knepley       orntNew[1] = -2;
24614bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2462b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2463b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2464b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2465b5da9499SMatthew G. Knepley #if 1
2466b5da9499SMatthew 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);
2467b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2468b5da9499SMatthew 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);
2469b5da9499SMatthew G. Knepley       }
2470b5da9499SMatthew G. Knepley #endif
2471b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2472b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2473b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2474b5da9499SMatthew G. Knepley #if 1
2475b5da9499SMatthew 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);
2476b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2477b5da9499SMatthew 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);
2478b5da9499SMatthew G. Knepley       }
2479b5da9499SMatthew G. Knepley #endif
2480b5da9499SMatthew G. Knepley       ++newp;
2481b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
24824bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2483b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2484b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
24854bb260e2SMatthew G. Knepley       orntNew[1] = 0;
24864bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
24872baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
2488b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2489b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2490b5da9499SMatthew G. Knepley #if 1
2491b5da9499SMatthew 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);
2492b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2493b5da9499SMatthew 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);
2494b5da9499SMatthew G. Knepley       }
2495b5da9499SMatthew G. Knepley #endif
2496b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2497b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2498b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2499b5da9499SMatthew G. Knepley #if 1
2500b5da9499SMatthew 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);
2501b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2502b5da9499SMatthew 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);
2503b5da9499SMatthew G. Knepley       }
2504b5da9499SMatthew G. Knepley #endif
2505b5da9499SMatthew G. Knepley       ++newp;
2506b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
25074bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2508b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
2509b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2510fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
25114bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2512b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
2513b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2514b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2515b5da9499SMatthew G. Knepley #if 1
2516b5da9499SMatthew 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);
2517b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2518b5da9499SMatthew 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);
2519b5da9499SMatthew G. Knepley       }
2520b5da9499SMatthew G. Knepley #endif
2521b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2522b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2523b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2524b5da9499SMatthew G. Knepley #if 1
2525b5da9499SMatthew 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);
2526b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2527b5da9499SMatthew 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);
2528b5da9499SMatthew G. Knepley       }
2529b5da9499SMatthew G. Knepley #endif
2530b5da9499SMatthew G. Knepley       ++newp;
2531b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
25324bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2533b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
25344bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2535b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
2536b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
25374bb260e2SMatthew G. Knepley       orntNew[2] = -2;
2538b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2539b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2540b5da9499SMatthew G. Knepley #if 1
2541b5da9499SMatthew 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);
2542b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2543b5da9499SMatthew 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);
2544b5da9499SMatthew G. Knepley       }
2545b5da9499SMatthew G. Knepley #endif
2546b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2547b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2548b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2549b5da9499SMatthew G. Knepley #if 1
2550b5da9499SMatthew 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);
2551b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2552b5da9499SMatthew 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);
2553b5da9499SMatthew G. Knepley       }
2554b5da9499SMatthew G. Knepley #endif
2555b5da9499SMatthew G. Knepley       ++newp;
2556b5da9499SMatthew G. Knepley     }
2557b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
2558b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2559b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
2560b5da9499SMatthew G. Knepley 
2561b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2562b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
2563b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2564b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2565b5da9499SMatthew G. Knepley 
2566b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
2567b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2568b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2569b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2570b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2571b5da9499SMatthew G. Knepley #if 1
2572b5da9499SMatthew 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);
2573b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2574b5da9499SMatthew 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);
2575b5da9499SMatthew G. Knepley         }
2576b5da9499SMatthew G. Knepley #endif
2577b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
2578b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2579b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2580b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2581b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2582b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2583b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2584b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
2585b5da9499SMatthew G. Knepley           }
2586b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
2587b5da9499SMatthew G. Knepley         }
2588b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2589b5da9499SMatthew G. Knepley #if 1
2590b5da9499SMatthew 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);
2591b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2592b5da9499SMatthew 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);
2593b5da9499SMatthew G. Knepley         }
2594b5da9499SMatthew G. Knepley #endif
2595b5da9499SMatthew G. Knepley       }
2596b5da9499SMatthew G. Knepley     }
259786f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
2598b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2599b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2600b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
2601b5da9499SMatthew G. Knepley 
2602b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2603b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2604b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
2605b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
2606b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
2607b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
2608b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
2609b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
2610b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
2611b5da9499SMatthew G. Knepley 
2612b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2613b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
2614b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
2615b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2616b5da9499SMatthew G. Knepley #if 1
2617b5da9499SMatthew 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);
2618b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2619b5da9499SMatthew 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);
2620b5da9499SMatthew G. Knepley         }
2621b5da9499SMatthew G. Knepley #endif
2622b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
2623b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
2624b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2625b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2626b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2627b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2628b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
262986f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
26309ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
2631b5da9499SMatthew G. Knepley           if (er == eint[c]) {
2632b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
2633b5da9499SMatthew G. Knepley           } else {
2634b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
2635b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
2636b5da9499SMatthew G. Knepley           }
2637b5da9499SMatthew G. Knepley         }
2638b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2639b5da9499SMatthew G. Knepley #if 1
2640b5da9499SMatthew 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);
2641b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
2642b5da9499SMatthew 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);
2643b5da9499SMatthew G. Knepley         }
2644b5da9499SMatthew G. Knepley #endif
2645b5da9499SMatthew G. Knepley       }
2646b5da9499SMatthew G. Knepley     }
2647b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
2648b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2649b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2650b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
26514a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
2652b5da9499SMatthew G. Knepley 
2653b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2654b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2655b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
265642525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
2657b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2658b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
265942525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
2660b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2661b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2662b5da9499SMatthew G. Knepley #if 1
2663b5da9499SMatthew 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);
2664b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2665b5da9499SMatthew 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);
2666b5da9499SMatthew G. Knepley       }
2667b5da9499SMatthew G. Knepley #endif
2668b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
2669b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
2670b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
2671b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
2672b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2673b5da9499SMatthew G. Knepley #if 1
2674b5da9499SMatthew 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);
2675b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2676b5da9499SMatthew 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);
2677b5da9499SMatthew G. Knepley       }
2678b5da9499SMatthew G. Knepley #endif
2679b5da9499SMatthew G. Knepley     }
2680b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
2681b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2682b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2683b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
2684b5da9499SMatthew G. Knepley       PetscInt        size, s;
2685b5da9499SMatthew G. Knepley 
2686b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2687b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2688b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2689b5da9499SMatthew G. Knepley         PetscInt r = 0;
2690b5da9499SMatthew G. Knepley 
2691b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2692b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
2693b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
2694b5da9499SMatthew G. Knepley       }
2695b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2696b5da9499SMatthew G. Knepley #if 1
2697b5da9499SMatthew 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);
2698b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2699b5da9499SMatthew 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);
2700b5da9499SMatthew G. Knepley       }
2701b5da9499SMatthew G. Knepley #endif
2702b5da9499SMatthew G. Knepley     }
2703b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
2704b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2705b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
2706b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
2707b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
2708b5da9499SMatthew G. Knepley 
2709b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
2710b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2711b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
2712b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
2713b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2714b5da9499SMatthew G. Knepley         PetscInt r = 0;
2715b5da9499SMatthew G. Knepley 
2716b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2717b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2718b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
2719b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
2720b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
2721b5da9499SMatthew G. Knepley       }
2722b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2723b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
2724b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
2725b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
2726b5da9499SMatthew G. Knepley 
2727b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
2728b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
2729b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2730b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
2731b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
273242525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
2733b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
2734b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2735b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
273642525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
273742525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
2738b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
2739b5da9499SMatthew G. Knepley         }
2740b5da9499SMatthew G. Knepley       }
2741b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2742b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2743b5da9499SMatthew G. Knepley #if 1
2744b5da9499SMatthew 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);
2745b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
2746b5da9499SMatthew 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);
2747b5da9499SMatthew G. Knepley       }
2748b5da9499SMatthew G. Knepley #endif
2749b5da9499SMatthew G. Knepley     }
2750b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2751b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
2752b5da9499SMatthew G. Knepley     break;
27536ce3c06aSMatthew G. Knepley   case 7:
27546ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
27556ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
27566ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
27576ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
27586ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
27596ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
27606ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
27616ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
27626ce3c06aSMatthew G. Knepley 
27636ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
27646ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
27656ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
27666ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
27676ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
27686ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
27696ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
27706ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
27716ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
27726ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
27736ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
27746ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
27756ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
27766ce3c06aSMatthew G. Knepley #if 1
27776ce3c06aSMatthew 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);
27786ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
27796ce3c06aSMatthew 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);
27806ce3c06aSMatthew G. Knepley       }
27816ce3c06aSMatthew G. Knepley #endif
27826ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
27836ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
27846ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
27856ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
27866ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
27876ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
27886ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
27896ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
27906ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
27916ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
27926ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
27936ce3c06aSMatthew G. Knepley #if 1
27946ce3c06aSMatthew 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);
27956ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
27966ce3c06aSMatthew 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);
27976ce3c06aSMatthew G. Knepley       }
27986ce3c06aSMatthew G. Knepley #endif
27996ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
28006ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
28016ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
28026ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
28036ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
28046ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
28056ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
28066ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
28076ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
28086ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
28096ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
28106ce3c06aSMatthew G. Knepley #if 1
28116ce3c06aSMatthew 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);
28126ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
28136ce3c06aSMatthew 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);
28146ce3c06aSMatthew G. Knepley       }
28156ce3c06aSMatthew G. Knepley #endif
28166ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
28176ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
28186ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
28196ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
28206ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
28216ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
28226ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
28236ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
28246ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
28256ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
28266ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
28276ce3c06aSMatthew G. Knepley #if 1
28286ce3c06aSMatthew 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);
28296ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
28306ce3c06aSMatthew 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);
28316ce3c06aSMatthew G. Knepley       }
28326ce3c06aSMatthew G. Knepley #endif
28336ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
28346ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
28356ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
28369ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
28379ddff745SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
28389ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
28399ddff745SMatthew G. Knepley       orntNew[2] = 0;
28409ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
28419ddff745SMatthew G. Knepley       orntNew[3] = 2;
28426ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
28436ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
28446ce3c06aSMatthew G. Knepley #if 1
28456ce3c06aSMatthew 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);
28466ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
28476ce3c06aSMatthew 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);
28486ce3c06aSMatthew G. Knepley       }
28496ce3c06aSMatthew G. Knepley #endif
28506ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
28516ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
28526ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
28539ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
28549ddff745SMatthew G. Knepley       orntNew[1] = 1;
28559ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
28566ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
28579ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
28589ddff745SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
28596ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
28606ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
28616ce3c06aSMatthew G. Knepley #if 1
28626ce3c06aSMatthew 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);
28636ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
28646ce3c06aSMatthew 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);
28656ce3c06aSMatthew G. Knepley       }
28666ce3c06aSMatthew G. Knepley #endif
28676ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
28686ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
28696ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
28709ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
28719ddff745SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
28729ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
28739ddff745SMatthew G. Knepley       orntNew[2] = -3;
28749ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
28759ddff745SMatthew G. Knepley       orntNew[3] = -2;
28766ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
28776ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
28786ce3c06aSMatthew G. Knepley #if 1
28796ce3c06aSMatthew 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);
28806ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
28816ce3c06aSMatthew 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);
28826ce3c06aSMatthew G. Knepley       }
28836ce3c06aSMatthew G. Knepley #endif
28846ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
28856ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
28866ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
28879ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
28886ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
28899ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
28909ddff745SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
28919ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
28929ddff745SMatthew G. Knepley       orntNew[3] = -3;
28936ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
28946ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
28956ce3c06aSMatthew G. Knepley #if 1
28966ce3c06aSMatthew 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);
28976ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
28986ce3c06aSMatthew 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);
28996ce3c06aSMatthew G. Knepley       }
29006ce3c06aSMatthew G. Knepley #endif
29016ce3c06aSMatthew G. Knepley     }
29026ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
29036ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
29046ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
2905d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
29063b61eb6dSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5], o, of, i;
29076ce3c06aSMatthew G. Knepley 
29086ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
29096ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2910d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
2911084f9c62SMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
29126ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
29136ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
29146ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
29156ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
29166ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
2917084f9c62SMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? -1 : 1;
29183b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], r)       + 2;
29193b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)]       - fMax)*2 + (o*of < 0 ? 1 : 0);
29203b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
29213b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2;
29223b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
29233b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
29243b61eb6dSMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
29253b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2;
29263b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (o*of < 0 ? 0 : 1);
29273b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
29286ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
29296ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
29306ce3c06aSMatthew G. Knepley #if 1
29316ce3c06aSMatthew 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);
29326ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
29336ce3c06aSMatthew 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);
29346ce3c06aSMatthew G. Knepley         }
29356ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
29366ce3c06aSMatthew 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);
29376ce3c06aSMatthew G. Knepley         }
29386ce3c06aSMatthew G. Knepley #endif
29396ce3c06aSMatthew G. Knepley       }
29406ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
29416ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
29426ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
29436ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
29443b61eb6dSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
29456ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
29463b61eb6dSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
29476ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
29483b61eb6dSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
29496ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
29506ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
29516ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
29526ce3c06aSMatthew G. Knepley #if 1
29536ce3c06aSMatthew 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);
29546ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
29556ce3c06aSMatthew 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);
29566ce3c06aSMatthew G. Knepley       }
29576ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
29586ce3c06aSMatthew 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);
29596ce3c06aSMatthew G. Knepley       }
29606ce3c06aSMatthew G. Knepley #endif
29616ce3c06aSMatthew G. Knepley     }
29626ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
29636ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2964785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
29656ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
29666ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
29676ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
29686ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
29696ce3c06aSMatthew G. Knepley 
29706ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
29716ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
29726ce3c06aSMatthew G. Knepley       /* A triangle */
29736ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
29746ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
29756ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
29766ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
29776ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
29786ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
29796ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
29806ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
29816ce3c06aSMatthew G. Knepley #if 1
29826ce3c06aSMatthew 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);
29836ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
29846ce3c06aSMatthew 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);
29856ce3c06aSMatthew G. Knepley       }
29866ce3c06aSMatthew G. Knepley #endif
29876ce3c06aSMatthew G. Knepley       /* B triangle */
29886ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
29896ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
29906ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
29916ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
29926ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
29936ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
29946ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
29956ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
29966ce3c06aSMatthew G. Knepley #if 1
29976ce3c06aSMatthew 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);
29986ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
29996ce3c06aSMatthew 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);
30006ce3c06aSMatthew G. Knepley       }
30016ce3c06aSMatthew G. Knepley #endif
30026ce3c06aSMatthew G. Knepley       /* C triangle */
30036ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
30046ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
30056ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
30066ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
30076ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
30086ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
30096ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
30106ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
30116ce3c06aSMatthew G. Knepley #if 1
30126ce3c06aSMatthew 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);
30136ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
30146ce3c06aSMatthew 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);
30156ce3c06aSMatthew G. Knepley       }
30166ce3c06aSMatthew G. Knepley #endif
30176ce3c06aSMatthew G. Knepley       /* D triangle */
30186ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
30196ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
30206ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
30216ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
30226ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
30236ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
30246ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
30256ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
30266ce3c06aSMatthew G. Knepley #if 1
30276ce3c06aSMatthew 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);
30286ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
30296ce3c06aSMatthew 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);
30306ce3c06aSMatthew G. Knepley       }
30316ce3c06aSMatthew G. Knepley #endif
30326ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
30336ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
30346ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
30356ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
30369ddff745SMatthew G. Knepley           PetscInt subf;
30376ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
30386ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
30396ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
30406ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
30416ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
30426ce3c06aSMatthew G. Knepley           }
30439ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
30446ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
30459ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
30466ce3c06aSMatthew G. Knepley           } else {
30479ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
30486ce3c06aSMatthew G. Knepley           }
30496ce3c06aSMatthew G. Knepley         }
30506ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
30516ce3c06aSMatthew G. Knepley #if 1
30529ddff745SMatthew 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);
30536ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
30546ce3c06aSMatthew 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);
30556ce3c06aSMatthew G. Knepley         }
30566ce3c06aSMatthew G. Knepley #endif
30576ce3c06aSMatthew G. Knepley       }
30586ce3c06aSMatthew G. Knepley     }
30596ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
30606ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
30616ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
30626ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
30636ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
30646ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
30656ce3c06aSMatthew G. Knepley 
30666ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
30676ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
30686ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
30699ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
30706ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
30719ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
30726ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
30739ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
30746ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
30756ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
30766ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
30776ce3c06aSMatthew G. Knepley #if 1
30786ce3c06aSMatthew 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);
30796ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
30806ce3c06aSMatthew 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);
30816ce3c06aSMatthew G. Knepley       }
30826ce3c06aSMatthew G. Knepley #endif
30836ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
30846ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
30856ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
30866ce3c06aSMatthew G. Knepley #if 1
30876ce3c06aSMatthew 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);
30886ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
30896ce3c06aSMatthew 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);
30906ce3c06aSMatthew G. Knepley       }
30916ce3c06aSMatthew G. Knepley #endif
30926ce3c06aSMatthew G. Knepley       ++newp;
30936ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
30949ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
30956ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
30969ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
30976ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
30989ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
30996ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
31006ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
31016ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
31026ce3c06aSMatthew G. Knepley #if 1
31036ce3c06aSMatthew 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);
31046ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31056ce3c06aSMatthew 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);
31066ce3c06aSMatthew G. Knepley       }
31076ce3c06aSMatthew G. Knepley #endif
31086ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
31096ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
31106ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
31116ce3c06aSMatthew G. Knepley #if 1
31126ce3c06aSMatthew 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);
31136ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
31146ce3c06aSMatthew 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);
31156ce3c06aSMatthew G. Knepley       }
31166ce3c06aSMatthew G. Knepley #endif
31176ce3c06aSMatthew G. Knepley       ++newp;
31186ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
31199ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
31206ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
31219ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
31226ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
31239ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
31246ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
31256ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
31266ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
31276ce3c06aSMatthew G. Knepley #if 1
31286ce3c06aSMatthew 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);
31296ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31306ce3c06aSMatthew 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);
31316ce3c06aSMatthew G. Knepley       }
31326ce3c06aSMatthew G. Knepley #endif
31336ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
31346ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
31356ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
31366ce3c06aSMatthew G. Knepley #if 1
31376ce3c06aSMatthew 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);
31386ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
31396ce3c06aSMatthew 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);
31406ce3c06aSMatthew G. Knepley       }
31416ce3c06aSMatthew G. Knepley #endif
31426ce3c06aSMatthew G. Knepley       ++newp;
31436ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
31449ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
31456ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
31469ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
31476ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
31489ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
31496ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
31506ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
31516ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
31526ce3c06aSMatthew G. Knepley #if 1
31536ce3c06aSMatthew 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);
31546ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31556ce3c06aSMatthew 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);
31566ce3c06aSMatthew G. Knepley       }
31576ce3c06aSMatthew G. Knepley #endif
31586ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
31596ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
31606ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
31616ce3c06aSMatthew G. Knepley #if 1
31626ce3c06aSMatthew 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);
31636ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
31646ce3c06aSMatthew 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);
31656ce3c06aSMatthew G. Knepley       }
31666ce3c06aSMatthew G. Knepley #endif
31676ce3c06aSMatthew G. Knepley       ++newp;
31686ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
31699ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
31706ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
31716ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
31729ddff745SMatthew G. Knepley       orntNew[1] = -2;
31739ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
31746ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
31756ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
31766ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
31776ce3c06aSMatthew G. Knepley #if 1
31786ce3c06aSMatthew 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);
31796ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31806ce3c06aSMatthew 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);
31816ce3c06aSMatthew G. Knepley       }
31826ce3c06aSMatthew G. Knepley #endif
31836ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
31846ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
31856ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
31866ce3c06aSMatthew G. Knepley #if 1
31876ce3c06aSMatthew 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);
31886ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
31896ce3c06aSMatthew 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);
31906ce3c06aSMatthew G. Knepley       }
31916ce3c06aSMatthew G. Knepley #endif
31926ce3c06aSMatthew G. Knepley       ++newp;
31936ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
31949ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
31956ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
31966ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
31979ddff745SMatthew G. Knepley       orntNew[1] = 0;
31989ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
31999ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
32006ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32016ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32026ce3c06aSMatthew G. Knepley #if 1
32036ce3c06aSMatthew 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);
32046ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32056ce3c06aSMatthew 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);
32066ce3c06aSMatthew G. Knepley       }
32076ce3c06aSMatthew G. Knepley #endif
32086ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
32096ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
32106ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32116ce3c06aSMatthew G. Knepley #if 1
32126ce3c06aSMatthew 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);
32136ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32146ce3c06aSMatthew 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);
32156ce3c06aSMatthew G. Knepley       }
32166ce3c06aSMatthew G. Knepley #endif
32176ce3c06aSMatthew G. Knepley       ++newp;
32186ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
32199ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
32206ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
32216ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
32229ddff745SMatthew G. Knepley       orntNew[1] = 0;
32239ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
32246ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
32256ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32266ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32276ce3c06aSMatthew G. Knepley #if 1
32286ce3c06aSMatthew 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);
32296ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32306ce3c06aSMatthew 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);
32316ce3c06aSMatthew G. Knepley       }
32326ce3c06aSMatthew G. Knepley #endif
32336ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
32346ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
32356ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32366ce3c06aSMatthew G. Knepley #if 1
32376ce3c06aSMatthew 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);
32386ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32396ce3c06aSMatthew 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);
32406ce3c06aSMatthew G. Knepley       }
32416ce3c06aSMatthew G. Knepley #endif
32426ce3c06aSMatthew G. Knepley       ++newp;
32436ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
32449ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
32456ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
32469ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
32476ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
32486ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
32499ddff745SMatthew G. Knepley       orntNew[2] = -2;
32506ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32516ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32526ce3c06aSMatthew G. Knepley #if 1
32536ce3c06aSMatthew 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);
32546ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32556ce3c06aSMatthew 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);
32566ce3c06aSMatthew G. Knepley       }
32576ce3c06aSMatthew G. Knepley #endif
32586ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
32596ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
32606ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32616ce3c06aSMatthew G. Knepley #if 1
32626ce3c06aSMatthew 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);
32636ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32646ce3c06aSMatthew 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);
32656ce3c06aSMatthew G. Knepley       }
32666ce3c06aSMatthew G. Knepley #endif
32676ce3c06aSMatthew G. Knepley       ++newp;
32686ce3c06aSMatthew G. Knepley     }
32696ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
32706ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
32716ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
32726ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
32736ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
32746ce3c06aSMatthew G. Knepley 
32756ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
32766ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
32776ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
32786ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
32796ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
32806ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
32816ce3c06aSMatthew G. Knepley 
32826ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
32836ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
32846ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
32856ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
32866ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
32876ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
32886ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
32896ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
32906ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32916ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32926ce3c06aSMatthew G. Knepley #if 1
32936ce3c06aSMatthew 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);
32946ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
32956ce3c06aSMatthew 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);
32966ce3c06aSMatthew G. Knepley         }
32976ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
32986ce3c06aSMatthew 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);
32996ce3c06aSMatthew G. Knepley         }
33006ce3c06aSMatthew G. Knepley #endif
33016ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
3302d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
3303084f9c62SMatthew G. Knepley           PetscInt        o, of;
33046ce3c06aSMatthew G. Knepley 
33056ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
33066ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
3307084f9c62SMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
33086ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
33096ce3c06aSMatthew 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]);
3310d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
3311084f9c62SMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
3312084f9c62SMatthew 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;
33136ce3c06aSMatthew G. Knepley         }
33146ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33156ce3c06aSMatthew G. Knepley #if 1
33166ce3c06aSMatthew 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);
33176ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
33186ce3c06aSMatthew 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);
33196ce3c06aSMatthew G. Knepley         }
33206ce3c06aSMatthew G. Knepley #endif
33216ce3c06aSMatthew G. Knepley       }
33226ce3c06aSMatthew G. Knepley     }
33236ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
33246ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
33256ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
33266ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
33276ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
33286ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
33296ce3c06aSMatthew G. Knepley 
33306ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
33316ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
33326ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3333b598a9d5SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
33346ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
3335b598a9d5SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
33366ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
3337b598a9d5SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
33386ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
3339b598a9d5SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r]       - fMax);
33406ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
33416ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
33426ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
33436ce3c06aSMatthew G. Knepley #if 1
33446ce3c06aSMatthew 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);
33456ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
33466ce3c06aSMatthew 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);
33476ce3c06aSMatthew G. Knepley         }
33486ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
33496ce3c06aSMatthew 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);
33506ce3c06aSMatthew G. Knepley         }
33516ce3c06aSMatthew G. Knepley #endif
33526ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
33536ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
33546ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
33556ce3c06aSMatthew G. Knepley #if 1
33566ce3c06aSMatthew 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);
33576ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
33586ce3c06aSMatthew 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);
33596ce3c06aSMatthew G. Knepley         }
33606ce3c06aSMatthew G. Knepley #endif
33616ce3c06aSMatthew G. Knepley       }
33626ce3c06aSMatthew G. Knepley     }
33636ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
33646ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
33656ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
33666ce3c06aSMatthew G. Knepley 
33676ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
33686ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
33696ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
33706ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
33716ce3c06aSMatthew G. Knepley 
33726ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
33736ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
33746ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
33756ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
33766ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33776ce3c06aSMatthew G. Knepley #if 1
33786ce3c06aSMatthew 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);
33796ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
33806ce3c06aSMatthew 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);
33816ce3c06aSMatthew G. Knepley         }
33826ce3c06aSMatthew G. Knepley #endif
33836ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
33846ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
33856ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
33866ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
33876ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
33886ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
33896ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
33906ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
33916ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
33926ce3c06aSMatthew G. Knepley           } else {
33936ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
33946ce3c06aSMatthew G. Knepley           }
33956ce3c06aSMatthew G. Knepley         }
33966ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
33976ce3c06aSMatthew G. Knepley #if 1
33986ce3c06aSMatthew 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);
33996ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
34006ce3c06aSMatthew 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);
34016ce3c06aSMatthew G. Knepley         }
34026ce3c06aSMatthew G. Knepley #endif
34036ce3c06aSMatthew G. Knepley       }
34046ce3c06aSMatthew G. Knepley     }
34056ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
34066ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
34076ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
34086ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
34096ce3c06aSMatthew G. Knepley 
34106ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
34116ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
34126ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
34136ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
34146ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
34156ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
34166ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
34176ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
34186ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
34196ce3c06aSMatthew G. Knepley 
34206ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
34216ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
34226ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
34236ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34246ce3c06aSMatthew G. Knepley #if 1
34256ce3c06aSMatthew 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);
34266ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34276ce3c06aSMatthew 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);
34286ce3c06aSMatthew G. Knepley         }
34296ce3c06aSMatthew G. Knepley #endif
34306ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
34316ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
34326ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
34336ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
34346ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
34356ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
34366ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
34376ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
34386ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
34399ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
34406ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
34416ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
34426ce3c06aSMatthew G. Knepley             } else {
34436ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
34446ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
34456ce3c06aSMatthew G. Knepley             }
34466ce3c06aSMatthew G. Knepley           } else {
3447b598a9d5SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
34486ce3c06aSMatthew G. Knepley           }
34496ce3c06aSMatthew G. Knepley         }
34506ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
34516ce3c06aSMatthew G. Knepley #if 1
34526ce3c06aSMatthew 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);
34536ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
34546ce3c06aSMatthew 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);
34556ce3c06aSMatthew G. Knepley         }
34566ce3c06aSMatthew G. Knepley #endif
34576ce3c06aSMatthew G. Knepley       }
34586ce3c06aSMatthew G. Knepley     }
34596ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
34606ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
34616ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
34626ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
34636ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
34646ce3c06aSMatthew G. Knepley 
34656ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
34666ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
34676ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
34686ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
34696ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
34706ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
34716ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
34726ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
34736ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34746ce3c06aSMatthew G. Knepley #if 1
34756ce3c06aSMatthew 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);
34766ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
34776ce3c06aSMatthew 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);
34786ce3c06aSMatthew G. Knepley       }
34796ce3c06aSMatthew G. Knepley #endif
34806ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
34816ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
34826ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
34836ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
34846ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
34856ce3c06aSMatthew G. Knepley #if 1
34866ce3c06aSMatthew 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);
34876ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34886ce3c06aSMatthew 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);
34896ce3c06aSMatthew G. Knepley       }
34906ce3c06aSMatthew G. Knepley #endif
34916ce3c06aSMatthew G. Knepley     }
34926ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
34936ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
34946ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
34956ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
34966ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
34976ce3c06aSMatthew G. Knepley 
34986ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
34996ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
35006ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
35016ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
35026ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
35036ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35046ce3c06aSMatthew G. Knepley #if 1
35056ce3c06aSMatthew 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);
35066ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
35076ce3c06aSMatthew 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);
35086ce3c06aSMatthew G. Knepley       }
35096ce3c06aSMatthew G. Knepley #endif
35106ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
35116ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
35126ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
35136ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
35146ce3c06aSMatthew 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]);
35156ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
35166ce3c06aSMatthew G. Knepley       }
35176ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35186ce3c06aSMatthew G. Knepley #if 1
35196ce3c06aSMatthew 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);
35206ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
35216ce3c06aSMatthew 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);
35226ce3c06aSMatthew G. Knepley       }
35236ce3c06aSMatthew G. Knepley #endif
35246ce3c06aSMatthew G. Knepley     }
35256ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
35266ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
35276ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
3528623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
35296ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
35306ce3c06aSMatthew G. Knepley 
35316ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
35326ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
35336ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
35346ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
35356ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
35366ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35376ce3c06aSMatthew G. Knepley #if 1
35386ce3c06aSMatthew 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);
35396ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
35406ce3c06aSMatthew 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);
35416ce3c06aSMatthew G. Knepley       }
35426ce3c06aSMatthew G. Knepley #endif
35436ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
35446ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
35456ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
35466ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
35476ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
3548623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
35496ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
35506ce3c06aSMatthew 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]);
3551b598a9d5SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
3552b598a9d5SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
35536ce3c06aSMatthew G. Knepley       }
35546ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35556ce3c06aSMatthew G. Knepley #if 1
35566ce3c06aSMatthew 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);
35576ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
35586ce3c06aSMatthew 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);
35596ce3c06aSMatthew G. Knepley       }
35606ce3c06aSMatthew G. Knepley #endif
35616ce3c06aSMatthew G. Knepley     }
35626ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
35636ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
35646ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
35656ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
35666ce3c06aSMatthew G. Knepley       PetscInt        size, s;
35676ce3c06aSMatthew G. Knepley 
35686ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
35696ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
35706ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
35716ce3c06aSMatthew G. Knepley         PetscInt r = 0;
35726ce3c06aSMatthew G. Knepley 
35736ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
35746ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
35756ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
35766ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
35776ce3c06aSMatthew G. Knepley       }
35786ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35796ce3c06aSMatthew G. Knepley #if 1
35806ce3c06aSMatthew 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);
35816ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
35826ce3c06aSMatthew 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);
35836ce3c06aSMatthew G. Knepley       }
35846ce3c06aSMatthew G. Knepley #endif
35856ce3c06aSMatthew G. Knepley     }
35866ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
35876ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
35886ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
35896ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
35906ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
35916ce3c06aSMatthew G. Knepley 
35926ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
35936ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
35946ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
35956ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
35966ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
35976ce3c06aSMatthew G. Knepley         PetscInt r = 0;
35986ce3c06aSMatthew G. Knepley 
35996ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
36006ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
36016ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36026ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
36036ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
36046ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
36056ce3c06aSMatthew G. Knepley           faceSize += 2;
36066ce3c06aSMatthew G. Knepley         } else {
36076ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
36086ce3c06aSMatthew G. Knepley           ++faceSize;
36096ce3c06aSMatthew G. Knepley         }
36106ce3c06aSMatthew G. Knepley       }
36116ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
36126ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
36136ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
36146ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
36156ce3c06aSMatthew G. Knepley 
36166ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
36176ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
36186ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
36196ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
36206ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
36216ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
36226ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
36236ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
36246ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
36256ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
36266ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
36276ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
36286ce3c06aSMatthew G. Knepley         }
36296ce3c06aSMatthew G. Knepley       }
36306ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
36316ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36326ce3c06aSMatthew G. Knepley #if 1
36336ce3c06aSMatthew 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);
36346ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
36356ce3c06aSMatthew 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);
36366ce3c06aSMatthew G. Knepley       }
36376ce3c06aSMatthew G. Knepley #endif
36386ce3c06aSMatthew G. Knepley     }
36396ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
36406ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
36416ce3c06aSMatthew G. Knepley     break;
36422eabf88fSMatthew G. Knepley   case 6:
36432eabf88fSMatthew G. Knepley     /* Hex 3D */
36442eabf88fSMatthew G. Knepley     /*
36452eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
36462eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
36472eabf88fSMatthew G. Knepley      |         |         |       |         |         |
36482eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
36492eabf88fSMatthew G. Knepley      |         |         |       |         |         |
36502eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
36512eabf88fSMatthew G. Knepley      |         |         |       |         |         |
36522eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
36532eabf88fSMatthew G. Knepley      |         |         |       |         |         |
36542eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
36552eabf88fSMatthew G. Knepley      */
36562eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
36572eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
36582eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
36592eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
36602eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
36612eabf88fSMatthew G. Knepley 
36622eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
36632eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
36642eabf88fSMatthew G. Knepley       /* A hex */
3665e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
36662eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
36672eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
36682eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3669e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
36702eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
36712eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
36722eabf88fSMatthew G. Knepley       orntNew[3] = 0;
36732eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
36742eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3675e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
36762eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
36772eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
36782eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
36792eabf88fSMatthew G. Knepley #if 1
36802eabf88fSMatthew 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);
36812eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
36822eabf88fSMatthew 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);
36832eabf88fSMatthew G. Knepley       }
36842eabf88fSMatthew G. Knepley #endif
36852eabf88fSMatthew G. Knepley       /* B hex */
3686e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
36872eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
36882eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
36892eabf88fSMatthew G. Knepley       orntNew[1] = 0;
36902eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
3691a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3692e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
36932eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
36942eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
36952eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3696e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
36972eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
36982eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
36992eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
37002eabf88fSMatthew G. Knepley #if 1
37012eabf88fSMatthew 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);
37022eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
37032eabf88fSMatthew 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);
37042eabf88fSMatthew G. Knepley       }
37052eabf88fSMatthew G. Knepley #endif
37062eabf88fSMatthew G. Knepley       /* C hex */
3707e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
37082eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
37092eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
37102eabf88fSMatthew G. Knepley       orntNew[1] = 0;
37112eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3712a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3713e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
37142eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3715e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
37162eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
37172eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
3718a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
37192eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
37202eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
37212eabf88fSMatthew G. Knepley #if 1
37222eabf88fSMatthew 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);
37232eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
37242eabf88fSMatthew 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);
37252eabf88fSMatthew G. Knepley       }
37262eabf88fSMatthew G. Knepley #endif
37272eabf88fSMatthew G. Knepley       /* D hex */
3728e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
37292eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
37302eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
37312eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3732e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
37332eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
37342eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3735a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3736e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
37372eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
37382eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
3739a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
37402eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
37412eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
37422eabf88fSMatthew G. Knepley #if 1
37432eabf88fSMatthew 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);
37442eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
37452eabf88fSMatthew 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);
37462eabf88fSMatthew G. Knepley       }
37472eabf88fSMatthew G. Knepley #endif
37482eabf88fSMatthew G. Knepley       /* E hex */
37492eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
3750a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3751e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
37522eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3753e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
37542eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
37552eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
37562eabf88fSMatthew G. Knepley       orntNew[3] = 0;
37572eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3758a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
3759e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
37602eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3761b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
3762b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
37632eabf88fSMatthew G. Knepley #if 1
3764b164cbf2SMatthew 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);
37652eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
37662eabf88fSMatthew 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);
37672eabf88fSMatthew G. Knepley       }
37682eabf88fSMatthew G. Knepley #endif
37692eabf88fSMatthew G. Knepley       /* F hex */
37702eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
3771a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3772e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
37732eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3774e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
37752eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
37762eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3777a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
3778e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
37792eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
37802eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3781a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
3782b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
3783b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
37842eabf88fSMatthew G. Knepley #if 1
3785b164cbf2SMatthew 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);
37862eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
37872eabf88fSMatthew 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);
37882eabf88fSMatthew G. Knepley       }
37892eabf88fSMatthew G. Knepley #endif
37902eabf88fSMatthew G. Knepley       /* G hex */
37912eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
3792a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3793e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
37942eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
37952eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3796a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
3797e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
37982eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3799e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
38002eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
38012eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3802a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
3803b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
3804b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
38052eabf88fSMatthew G. Knepley #if 1
3806b164cbf2SMatthew 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);
38072eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38082eabf88fSMatthew 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);
38092eabf88fSMatthew G. Knepley       }
38102eabf88fSMatthew G. Knepley #endif
38112eabf88fSMatthew G. Knepley       /* H hex */
38122eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
3813a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3814e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
38152eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
38162eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
3817a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3818e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
38192eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
38202eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3821a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
3822e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
38232eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3824b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
3825b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
38262eabf88fSMatthew G. Knepley #if 1
3827b164cbf2SMatthew 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);
38282eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38292eabf88fSMatthew 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);
38302eabf88fSMatthew G. Knepley       }
38312eabf88fSMatthew G. Knepley #endif
38322eabf88fSMatthew G. Knepley     }
38332eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
38342eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3835785e854fSJed Brown     ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
38362eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
38372eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
3838aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
38392eabf88fSMatthew 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};
38402eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
38412eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3842aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
38432eabf88fSMatthew G. Knepley 
38442eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3845aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
3846a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
3847a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
3848a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
3849a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
3850a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
3851a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
3852a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
3853a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
38542eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3855aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
38562eabf88fSMatthew G. Knepley #if 1
38572eabf88fSMatthew 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);
38582eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
38592eabf88fSMatthew 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);
38602eabf88fSMatthew G. Knepley         }
38612eabf88fSMatthew G. Knepley #endif
38622eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
38632eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
38642eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
38652eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
38662eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
38672eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
38682eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
38692eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
38702eabf88fSMatthew G. Knepley           }
3871a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
38722eabf88fSMatthew G. Knepley         }
38732eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
38742eabf88fSMatthew G. Knepley #if 1
38752eabf88fSMatthew 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);
38762eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
38772eabf88fSMatthew 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);
38782eabf88fSMatthew G. Knepley         }
38792eabf88fSMatthew G. Knepley #endif
38802eabf88fSMatthew G. Knepley       }
38812eabf88fSMatthew G. Knepley     }
38822eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
38832eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
38842eabf88fSMatthew 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};
3885afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
3886afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
38872eabf88fSMatthew G. Knepley 
38882eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3889afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3890afb2665bSMatthew G. Knepley       /* A-D face */
3891afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
3892a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
3893a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3894a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3895afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3896a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3897a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3898a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
3899afb2665bSMatthew G. Knepley       orntNew[3] = -2;
39002eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3901afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
39022eabf88fSMatthew G. Knepley #if 1
39032eabf88fSMatthew 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);
39042eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
39052eabf88fSMatthew 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);
39062eabf88fSMatthew G. Knepley       }
39072eabf88fSMatthew G. Knepley #endif
3908afb2665bSMatthew G. Knepley       /* C-D face */
3909afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
3910a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
3911a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3912a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3913afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3914a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3915a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3916a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
3917afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3918afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3919afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3920afb2665bSMatthew G. Knepley #if 1
3921afb2665bSMatthew 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);
3922afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3923afb2665bSMatthew 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);
3924afb2665bSMatthew G. Knepley       }
3925afb2665bSMatthew G. Knepley #endif
3926afb2665bSMatthew G. Knepley       /* B-C face */
3927afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
3928afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
3929afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3930afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
3931afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3932afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3933afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3934afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3935afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3936afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3937afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3938afb2665bSMatthew G. Knepley #if 1
3939afb2665bSMatthew 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);
3940afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3941afb2665bSMatthew 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);
3942afb2665bSMatthew G. Knepley       }
3943afb2665bSMatthew G. Knepley #endif
3944afb2665bSMatthew G. Knepley       /* A-B face */
3945afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
3946afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
3947afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3948afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
3949afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3950afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3951afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3952afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3953afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3954afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3955afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3956afb2665bSMatthew G. Knepley #if 1
3957afb2665bSMatthew 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);
3958afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3959afb2665bSMatthew 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);
3960afb2665bSMatthew G. Knepley       }
3961afb2665bSMatthew G. Knepley #endif
3962afb2665bSMatthew G. Knepley       /* E-F face */
3963afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
3964a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3965afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3966a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
3967a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3968a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
3969afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3970a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3971a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3972afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3973afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3974afb2665bSMatthew G. Knepley #if 1
3975afb2665bSMatthew 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);
3976afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3977afb2665bSMatthew 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);
3978afb2665bSMatthew G. Knepley       }
3979afb2665bSMatthew G. Knepley #endif
3980afb2665bSMatthew G. Knepley       /* F-G face */
3981afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
3982a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3983afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3984a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
3985a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3986a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
3987afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3988a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3989a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3990afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3991afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3992afb2665bSMatthew G. Knepley #if 1
3993afb2665bSMatthew 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);
3994afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3995afb2665bSMatthew 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);
3996afb2665bSMatthew G. Knepley       }
3997afb2665bSMatthew G. Knepley #endif
3998afb2665bSMatthew G. Knepley       /* G-H face */
3999afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
4000afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
4001afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4002afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
4003afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4004afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4005afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4006afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4007afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4008afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4009afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4010afb2665bSMatthew G. Knepley #if 1
4011afb2665bSMatthew 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);
4012afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4013afb2665bSMatthew 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);
4014afb2665bSMatthew G. Knepley       }
4015afb2665bSMatthew G. Knepley #endif
4016afb2665bSMatthew G. Knepley       /* E-H face */
4017afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
4018a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4019afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4020a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
4021a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4022a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
4023afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4024a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4025a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4026afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4027afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4028afb2665bSMatthew G. Knepley #if 1
4029afb2665bSMatthew 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);
4030afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4031afb2665bSMatthew 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);
4032afb2665bSMatthew G. Knepley       }
4033afb2665bSMatthew G. Knepley #endif
4034afb2665bSMatthew G. Knepley       /* A-E face */
4035afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
4036a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
4037a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4038a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4039afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4040a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4041a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4042a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
4043afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4044afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4045afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4046afb2665bSMatthew G. Knepley #if 1
4047afb2665bSMatthew 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);
4048afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4049afb2665bSMatthew 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);
4050afb2665bSMatthew G. Knepley       }
4051afb2665bSMatthew G. Knepley #endif
4052afb2665bSMatthew G. Knepley       /* D-F face */
4053afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
4054afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
4055afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4056afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
4057afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4058afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4059afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4060afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4061afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4062afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4063afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4064afb2665bSMatthew G. Knepley #if 1
4065afb2665bSMatthew 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);
4066afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4067afb2665bSMatthew 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);
4068afb2665bSMatthew G. Knepley       }
4069afb2665bSMatthew G. Knepley #endif
4070afb2665bSMatthew G. Knepley       /* C-G face */
4071afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
4072a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4073afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4074a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
4075a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4076a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
4077afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4078a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4079a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4080afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4081afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4082afb2665bSMatthew G. Knepley #if 1
4083afb2665bSMatthew 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);
4084afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4085afb2665bSMatthew 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);
4086afb2665bSMatthew G. Knepley       }
4087afb2665bSMatthew G. Knepley #endif
4088afb2665bSMatthew G. Knepley       /* B-H face */
4089afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
4090a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4091a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4092a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4093a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4094a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
4095a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4096a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
4097a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4098afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4099afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4100afb2665bSMatthew G. Knepley #if 1
4101afb2665bSMatthew 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);
4102afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4103afb2665bSMatthew 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);
4104afb2665bSMatthew G. Knepley       }
4105afb2665bSMatthew G. Knepley #endif
4106afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
4107afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
41082eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
41092eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
41102eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
41112eabf88fSMatthew G. Knepley #if 1
41122eabf88fSMatthew 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);
41132eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
41142eabf88fSMatthew 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);
41152eabf88fSMatthew G. Knepley         }
41162eabf88fSMatthew G. Knepley #endif
41172eabf88fSMatthew G. Knepley       }
41182eabf88fSMatthew G. Knepley     }
41192eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
41202eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
41212eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
41222eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
41232eabf88fSMatthew G. Knepley 
41242eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
41252eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
41262eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
41272eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
41282eabf88fSMatthew G. Knepley 
41292eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
41302eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
41312eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
41322eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
41332eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
41342eabf88fSMatthew G. Knepley #if 1
41352eabf88fSMatthew 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);
41362eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
41372eabf88fSMatthew 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);
41382eabf88fSMatthew G. Knepley         }
41392eabf88fSMatthew G. Knepley #endif
41402eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
41412eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
41422eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
41432eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
41442eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
41452eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
41462eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
41472eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
41482eabf88fSMatthew G. Knepley           }
41492eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
41502eabf88fSMatthew G. Knepley         }
41512eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
41522eabf88fSMatthew G. Knepley #if 1
41532eabf88fSMatthew 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);
41542eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
41552eabf88fSMatthew 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);
41562eabf88fSMatthew G. Knepley         }
41572eabf88fSMatthew G. Knepley #endif
41582eabf88fSMatthew G. Knepley       }
41592eabf88fSMatthew G. Knepley     }
41602eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
41612eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
41626b852384SMatthew 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};
41632eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
41646b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
41652eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
41662eabf88fSMatthew G. Knepley 
41672eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
41682eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
41692eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
41702eabf88fSMatthew G. Knepley 
41712eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
41722eabf88fSMatthew G. Knepley         coneNew[1] = newv;
41732eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
41742eabf88fSMatthew G. Knepley #if 1
41752eabf88fSMatthew 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);
41762eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
41772eabf88fSMatthew 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);
41782eabf88fSMatthew G. Knepley         }
41792eabf88fSMatthew G. Knepley #endif
41802eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
41812eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
41822eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
41832eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
41842eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
41856b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
41866b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
41876b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
41882eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
4189a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
41902eabf88fSMatthew G. Knepley         }
41912eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
41922eabf88fSMatthew G. Knepley #if 1
41932eabf88fSMatthew 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);
41942eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
41952eabf88fSMatthew 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);
41962eabf88fSMatthew G. Knepley         }
41972eabf88fSMatthew G. Knepley #endif
41982eabf88fSMatthew G. Knepley       }
41992eabf88fSMatthew G. Knepley     }
42002eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
42012eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
42022eabf88fSMatthew 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};
42032eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
42042eabf88fSMatthew G. Knepley       const PetscInt *cone;
42052eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
42062eabf88fSMatthew G. Knepley 
42072eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
42082eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
42092eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
42102eabf88fSMatthew G. Knepley 
42112eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
42122eabf88fSMatthew G. Knepley         coneNew[1] = newv;
42132eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
42142eabf88fSMatthew G. Knepley #if 1
42152eabf88fSMatthew 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);
42162eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
42172eabf88fSMatthew 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);
42182eabf88fSMatthew G. Knepley         }
42192eabf88fSMatthew G. Knepley #endif
42202eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
42212eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
42222eabf88fSMatthew G. Knepley #if 1
42232eabf88fSMatthew 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);
42242eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
42252eabf88fSMatthew 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);
42262eabf88fSMatthew G. Knepley         }
42272eabf88fSMatthew G. Knepley #endif
42282eabf88fSMatthew G. Knepley       }
42292eabf88fSMatthew G. Knepley     }
42302eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
42312eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
42322eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
42332eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
42342eabf88fSMatthew G. Knepley       PetscInt        size, s;
42352eabf88fSMatthew G. Knepley 
42362eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
42372eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
42382eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
42392eabf88fSMatthew G. Knepley         PetscInt r = 0;
42402eabf88fSMatthew G. Knepley 
42412eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
42422eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
42432eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
42442eabf88fSMatthew G. Knepley       }
42452eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
42462eabf88fSMatthew G. Knepley #if 1
42472eabf88fSMatthew 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);
42482eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
42492eabf88fSMatthew 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);
42502eabf88fSMatthew G. Knepley       }
42512eabf88fSMatthew G. Knepley #endif
42522eabf88fSMatthew G. Knepley     }
42532eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
42542eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
42552eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
42562eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
42572eabf88fSMatthew G. Knepley       PetscInt        size, s;
42582eabf88fSMatthew G. Knepley 
42592eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
42602eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
42612eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
42622eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
42632eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
42642eabf88fSMatthew G. Knepley         PetscInt r;
42652eabf88fSMatthew G. Knepley 
42662eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4267a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
42682eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
42692eabf88fSMatthew G. Knepley       }
42702eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
42712eabf88fSMatthew G. Knepley #if 1
42722eabf88fSMatthew 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);
42732eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
42742eabf88fSMatthew 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);
42752eabf88fSMatthew G. Knepley       }
42762eabf88fSMatthew G. Knepley #endif
42772eabf88fSMatthew G. Knepley     }
42782eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
42792eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
42802eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
42812eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
42822eabf88fSMatthew G. Knepley       PetscInt        size, s;
42832eabf88fSMatthew G. Knepley 
42842eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
42852eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
42860793999aSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 +  (f - fStart)*4 + r;
42872eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
42882eabf88fSMatthew G. Knepley         PetscInt r;
42892eabf88fSMatthew G. Knepley 
42902eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
42912eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
42922eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
42932eabf88fSMatthew G. Knepley       }
42942eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
42952eabf88fSMatthew G. Knepley #if 1
42962eabf88fSMatthew 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);
42972eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
42982eabf88fSMatthew 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);
42992eabf88fSMatthew G. Knepley       }
43002eabf88fSMatthew G. Knepley #endif
43012eabf88fSMatthew G. Knepley     }
43022eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
43032eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
43042eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
43052eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
43062eabf88fSMatthew G. Knepley 
43072eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
43082eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
43092eabf88fSMatthew G. Knepley       }
43102eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
43112eabf88fSMatthew G. Knepley     }
4312da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
43132eabf88fSMatthew G. Knepley     break;
431427fcede3SMatthew G. Knepley   case 8:
431527fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
431627fcede3SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
431727fcede3SMatthew G. Knepley     /*
431827fcede3SMatthew G. Knepley      Bottom (viewed from top)    Top
431927fcede3SMatthew G. Knepley      1---------2---------2       7---------2---------6
432027fcede3SMatthew G. Knepley      |         |         |       |         |         |
432127fcede3SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
432227fcede3SMatthew G. Knepley      |         |         |       |         |         |
432327fcede3SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
432427fcede3SMatthew G. Knepley      |         |         |       |         |         |
432527fcede3SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
432627fcede3SMatthew G. Knepley      |         |         |       |         |         |
432727fcede3SMatthew G. Knepley      0---------0---------3       4---------0---------5
432827fcede3SMatthew G. Knepley      */
432927fcede3SMatthew G. Knepley     /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
433027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
433127fcede3SMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
433227fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
433327fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
433427fcede3SMatthew G. Knepley 
433527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
433627fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
433727fcede3SMatthew G. Knepley       /* A hex */
433827fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
433927fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
434027fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
434127fcede3SMatthew G. Knepley       orntNew[1] = 0;
434227fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
434327fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
434427fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
434527fcede3SMatthew G. Knepley       orntNew[3] = 0;
434627fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
434727fcede3SMatthew G. Knepley       orntNew[4] = 0;
434827fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
434927fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
435027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
435127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
435227fcede3SMatthew G. Knepley #if 1
435327fcede3SMatthew 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);
435427fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
435527fcede3SMatthew 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);
435627fcede3SMatthew G. Knepley       }
435727fcede3SMatthew G. Knepley #endif
435827fcede3SMatthew G. Knepley       /* B hex */
435927fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
436027fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
436127fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
436227fcede3SMatthew G. Knepley       orntNew[1] = 0;
436327fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
436427fcede3SMatthew G. Knepley       orntNew[2] = -1;
436527fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
436627fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
436727fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
436827fcede3SMatthew G. Knepley       orntNew[4] = 0;
436927fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
437027fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
437127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
437227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
437327fcede3SMatthew G. Knepley #if 1
437427fcede3SMatthew 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);
437527fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
437627fcede3SMatthew 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);
437727fcede3SMatthew G. Knepley       }
437827fcede3SMatthew G. Knepley #endif
437927fcede3SMatthew G. Knepley       /* C hex */
438027fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
438127fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
438227fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
438327fcede3SMatthew G. Knepley       orntNew[1] = 0;
438427fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
438527fcede3SMatthew G. Knepley       orntNew[2] = -1;
438627fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
438727fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
438827fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
438927fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
439027fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
439127fcede3SMatthew G. Knepley       orntNew[5] = -4;
439227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
439327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
439427fcede3SMatthew G. Knepley #if 1
439527fcede3SMatthew 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);
439627fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
439727fcede3SMatthew 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);
439827fcede3SMatthew G. Knepley       }
439927fcede3SMatthew G. Knepley #endif
440027fcede3SMatthew G. Knepley       /* D hex */
440127fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
440227fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
440327fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
440427fcede3SMatthew G. Knepley       orntNew[1] = 0;
440527fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
440627fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
440727fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
440827fcede3SMatthew G. Knepley       orntNew[3] = 0;
440927fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
441027fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
441127fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
441227fcede3SMatthew G. Knepley       orntNew[5] = -4;
441327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
441427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
441527fcede3SMatthew G. Knepley #if 1
441627fcede3SMatthew 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);
441727fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
441827fcede3SMatthew 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);
441927fcede3SMatthew G. Knepley       }
442027fcede3SMatthew G. Knepley #endif
442127fcede3SMatthew G. Knepley       /* E hex */
442227fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
442327fcede3SMatthew G. Knepley       orntNew[0] = -4;
442427fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
442527fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
442627fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
442727fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
442827fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
442927fcede3SMatthew G. Knepley       orntNew[3] = 0;
443027fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
443127fcede3SMatthew G. Knepley       orntNew[4] = -1;
443227fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
443327fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
443427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
443527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
443627fcede3SMatthew G. Knepley #if 1
443727fcede3SMatthew 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);
443827fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
443927fcede3SMatthew 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);
444027fcede3SMatthew G. Knepley       }
444127fcede3SMatthew G. Knepley #endif
444227fcede3SMatthew G. Knepley       /* F hex */
444327fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
444427fcede3SMatthew G. Knepley       orntNew[0] = -4;
444527fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
444627fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
444727fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
444827fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
444927fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
445027fcede3SMatthew G. Knepley       orntNew[3] = -1;
445127fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
445227fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
445327fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
445427fcede3SMatthew G. Knepley       orntNew[5] = 1;
445527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
445627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
445727fcede3SMatthew G. Knepley #if 1
445827fcede3SMatthew 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);
445927fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
446027fcede3SMatthew 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);
446127fcede3SMatthew G. Knepley       }
446227fcede3SMatthew G. Knepley #endif
446327fcede3SMatthew G. Knepley       /* G hex */
446427fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
446527fcede3SMatthew G. Knepley       orntNew[0] = -4;
446627fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
446727fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
446827fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
446927fcede3SMatthew G. Knepley       orntNew[2] = 0;
447027fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
447127fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
447227fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
447327fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
447427fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
447527fcede3SMatthew G. Knepley       orntNew[5] = -3;
447627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
447727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
447827fcede3SMatthew G. Knepley #if 1
447927fcede3SMatthew 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);
448027fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
448127fcede3SMatthew 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);
448227fcede3SMatthew G. Knepley       }
448327fcede3SMatthew G. Knepley #endif
448427fcede3SMatthew G. Knepley       /* H hex */
448527fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
448627fcede3SMatthew G. Knepley       orntNew[0] = -4;
448727fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
448827fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
448927fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
449027fcede3SMatthew G. Knepley       orntNew[2] = -1;
449127fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
449227fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
449327fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
449427fcede3SMatthew G. Knepley       orntNew[4] = 3;
449527fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
449627fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
449727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
449827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
449927fcede3SMatthew G. Knepley #if 1
450027fcede3SMatthew 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);
450127fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
450227fcede3SMatthew 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);
450327fcede3SMatthew G. Knepley       }
450427fcede3SMatthew G. Knepley #endif
450527fcede3SMatthew G. Knepley     }
450627fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces: Front, Back, Sides */
450727fcede3SMatthew G. Knepley     /*
450827fcede3SMatthew G. Knepley      3---------2---------2
450927fcede3SMatthew G. Knepley      |         |         |
451027fcede3SMatthew G. Knepley      |    D    2    C    |
451127fcede3SMatthew G. Knepley      |         |         |
451227fcede3SMatthew G. Knepley      3----3----0----1----1
451327fcede3SMatthew G. Knepley      |         |         |
451427fcede3SMatthew G. Knepley      |    A    0    B    |
451527fcede3SMatthew G. Knepley      |         |         |
451627fcede3SMatthew G. Knepley      0---------0---------1
451727fcede3SMatthew G. Knepley      */
451827fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
451927fcede3SMatthew G. Knepley       const PetscInt  newp = (cMax - cStart)*8 + (c - cMax)*4;
452027fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
452127fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
452227fcede3SMatthew G. Knepley 
452327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
452427fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
452527fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
452627fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
452727fcede3SMatthew G. Knepley         PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
452827fcede3SMatthew G. Knepley         PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
452927fcede3SMatthew G. Knepley         PetscInt edgeB = (edgeA+3)%4;
453027fcede3SMatthew 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]);
453127fcede3SMatthew G. Knepley         coneNew[0]         = fStartNew + (cone[0] - fStart)*4 + subfA;
453227fcede3SMatthew G. Knepley         orntNew[0]         = ornt[0];
453327fcede3SMatthew G. Knepley         coneNew[1]         = fStartNew + (cone[1] - fStart)*4 + subfA;
453427fcede3SMatthew G. Knepley         orntNew[1]         = ornt[0];
453527fcede3SMatthew G. Knepley         coneNew[(r+0)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeA+2] - fMax)*2 + (fornt[edgeA] < 0 ? 1 : 0);
453627fcede3SMatthew G. Knepley         orntNew[(r+0)%4+2] = ornt[edgeA];
453727fcede3SMatthew G. Knepley         coneNew[(r+1)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeA;
453827fcede3SMatthew G. Knepley         orntNew[(r+1)%4+2] = 0;
453927fcede3SMatthew G. Knepley         coneNew[(r+2)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeB;
454027fcede3SMatthew G. Knepley         orntNew[(r+2)%4+2] = -2;
454127fcede3SMatthew G. Knepley         coneNew[(r+3)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeB+2] - fMax)*2 + (fornt[edgeB] < 0 ? 0 : 1);
454227fcede3SMatthew G. Knepley         orntNew[(r+3)%4+2] = ornt[edgeB];
454327fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
454427fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
454527fcede3SMatthew G. Knepley #if 1
454627fcede3SMatthew 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);
454727fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
454827fcede3SMatthew 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);
454927fcede3SMatthew G. Knepley         }
455027fcede3SMatthew G. Knepley         for (p = 2; p < 6; ++p) {
455127fcede3SMatthew 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);
455227fcede3SMatthew G. Knepley         }
455327fcede3SMatthew G. Knepley #endif
455427fcede3SMatthew G. Knepley       }
455527fcede3SMatthew G. Knepley     }
455627fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
455727fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
455827fcede3SMatthew G. Knepley     ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
455927fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
456027fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
456127fcede3SMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
456227fcede3SMatthew 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};
456327fcede3SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
456427fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
456527fcede3SMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
456627fcede3SMatthew G. Knepley 
456727fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
456827fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
456927fcede3SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
457027fcede3SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
457127fcede3SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
457227fcede3SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
457327fcede3SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
457427fcede3SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
457527fcede3SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
457627fcede3SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
457727fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
457827fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
457927fcede3SMatthew G. Knepley #if 1
458027fcede3SMatthew 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);
458127fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
458227fcede3SMatthew 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);
458327fcede3SMatthew G. Knepley         }
458427fcede3SMatthew G. Knepley #endif
458527fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
458627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
458727fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
458827fcede3SMatthew G. Knepley           PetscInt subf;
458927fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
459027fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
459127fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
459227fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
459327fcede3SMatthew G. Knepley             if (cone[c] == f) break;
459427fcede3SMatthew G. Knepley           }
459527fcede3SMatthew G. Knepley           subf = GetQuadSubfaceInverse_Static(ornt[c], r);
459627fcede3SMatthew G. Knepley           if (support[s] < cMax) {
459727fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
459827fcede3SMatthew G. Knepley           } else {
459927fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax       - cStart)*8 + (support[s] - cMax)*4 + subf;
460027fcede3SMatthew G. Knepley           }
460127fcede3SMatthew G. Knepley         }
460227fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
460327fcede3SMatthew G. Knepley #if 1
460427fcede3SMatthew 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);
460527fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
460627fcede3SMatthew 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);
460727fcede3SMatthew G. Knepley         }
460827fcede3SMatthew G. Knepley #endif
460927fcede3SMatthew G. Knepley       }
461027fcede3SMatthew G. Knepley     }
461127fcede3SMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
461227fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
461327fcede3SMatthew 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};
461427fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
461527fcede3SMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
461627fcede3SMatthew G. Knepley 
461727fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
461827fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
461927fcede3SMatthew G. Knepley       /* A-D face */
462027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
462127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
462227fcede3SMatthew G. Knepley       orntNew[0] = 0;
462327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
462427fcede3SMatthew G. Knepley       orntNew[1] = 0;
462527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
462627fcede3SMatthew G. Knepley       orntNew[2] = -2;
462727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
462827fcede3SMatthew G. Knepley       orntNew[3] = -2;
462927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
463027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
463127fcede3SMatthew G. Knepley #if 1
463227fcede3SMatthew 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);
463327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
463427fcede3SMatthew 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);
463527fcede3SMatthew G. Knepley       }
463627fcede3SMatthew G. Knepley #endif
463727fcede3SMatthew G. Knepley       /* C-D face */
463827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
463927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
464027fcede3SMatthew G. Knepley       orntNew[0] = 0;
464127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
464227fcede3SMatthew G. Knepley       orntNew[1] = 0;
464327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
464427fcede3SMatthew G. Knepley       orntNew[2] = -2;
464527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
464627fcede3SMatthew G. Knepley       orntNew[3] = -2;
464727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
464827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
464927fcede3SMatthew G. Knepley #if 1
465027fcede3SMatthew 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);
465127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
465227fcede3SMatthew 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);
465327fcede3SMatthew G. Knepley       }
465427fcede3SMatthew G. Knepley #endif
465527fcede3SMatthew G. Knepley       /* B-C face */
465627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
465727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
465827fcede3SMatthew G. Knepley       orntNew[0] = -2;
465927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
466027fcede3SMatthew G. Knepley       orntNew[1] = 0;
466127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
466227fcede3SMatthew G. Knepley       orntNew[2] = 0;
466327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
466427fcede3SMatthew G. Knepley       orntNew[3] = -2;
466527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
466627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
466727fcede3SMatthew G. Knepley #if 1
466827fcede3SMatthew 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);
466927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
467027fcede3SMatthew 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);
467127fcede3SMatthew G. Knepley       }
467227fcede3SMatthew G. Knepley #endif
467327fcede3SMatthew G. Knepley       /* A-B face */
467427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
467527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
467627fcede3SMatthew G. Knepley       orntNew[0] = -2;
467727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
467827fcede3SMatthew G. Knepley       orntNew[1] = 0;
467927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
468027fcede3SMatthew G. Knepley       orntNew[2] = 0;
468127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
468227fcede3SMatthew G. Knepley       orntNew[3] = -2;
468327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
468427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
468527fcede3SMatthew G. Knepley #if 1
468627fcede3SMatthew 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);
468727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
468827fcede3SMatthew 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);
468927fcede3SMatthew G. Knepley       }
469027fcede3SMatthew G. Knepley #endif
469127fcede3SMatthew G. Knepley       /* E-F face */
469227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
469327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
469427fcede3SMatthew G. Knepley       orntNew[0] = -2;
469527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
469627fcede3SMatthew G. Knepley       orntNew[1] = -2;
469727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
469827fcede3SMatthew G. Knepley       orntNew[2] = 0;
469927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
470027fcede3SMatthew G. Knepley       orntNew[3] = 0;
470127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
470227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
470327fcede3SMatthew G. Knepley #if 1
470427fcede3SMatthew 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);
470527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
470627fcede3SMatthew 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);
470727fcede3SMatthew G. Knepley       }
470827fcede3SMatthew G. Knepley #endif
470927fcede3SMatthew G. Knepley       /* F-G face */
471027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
471127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
471227fcede3SMatthew G. Knepley       orntNew[0] = -2;
471327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
471427fcede3SMatthew G. Knepley       orntNew[1] = -2;
471527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
471627fcede3SMatthew G. Knepley       orntNew[2] = 0;
471727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
471827fcede3SMatthew G. Knepley       orntNew[3] = 0;
471927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
472027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
472127fcede3SMatthew G. Knepley #if 1
472227fcede3SMatthew 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);
472327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
472427fcede3SMatthew 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);
472527fcede3SMatthew G. Knepley       }
472627fcede3SMatthew G. Knepley #endif
472727fcede3SMatthew G. Knepley       /* G-H face */
472827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
472927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
473027fcede3SMatthew G. Knepley       orntNew[0] = -2;
473127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
473227fcede3SMatthew G. Knepley       orntNew[1] = 0;
473327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
473427fcede3SMatthew G. Knepley       orntNew[2] = 0;
473527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
473627fcede3SMatthew G. Knepley       orntNew[3] = -2;
473727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
473827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
473927fcede3SMatthew G. Knepley #if 1
474027fcede3SMatthew 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);
474127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
474227fcede3SMatthew 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);
474327fcede3SMatthew G. Knepley       }
474427fcede3SMatthew G. Knepley #endif
474527fcede3SMatthew G. Knepley       /* E-H face */
474627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
474727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
474827fcede3SMatthew G. Knepley       orntNew[0] = -2;
474927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
475027fcede3SMatthew G. Knepley       orntNew[1] = -2;
475127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
475227fcede3SMatthew G. Knepley       orntNew[2] = 0;
475327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
475427fcede3SMatthew G. Knepley       orntNew[3] = 0;
475527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
475627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
475727fcede3SMatthew G. Knepley #if 1
475827fcede3SMatthew 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);
475927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
476027fcede3SMatthew 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);
476127fcede3SMatthew G. Knepley       }
476227fcede3SMatthew G. Knepley #endif
476327fcede3SMatthew G. Knepley       /* A-E face */
476427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
476527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
476627fcede3SMatthew G. Knepley       orntNew[0] = 0;
476727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
476827fcede3SMatthew G. Knepley       orntNew[1] = 0;
476927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
477027fcede3SMatthew G. Knepley       orntNew[2] = -2;
477127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
477227fcede3SMatthew G. Knepley       orntNew[3] = -2;
477327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
477427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
477527fcede3SMatthew G. Knepley #if 1
477627fcede3SMatthew 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);
477727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
477827fcede3SMatthew 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);
477927fcede3SMatthew G. Knepley       }
478027fcede3SMatthew G. Knepley #endif
478127fcede3SMatthew G. Knepley       /* D-F face */
478227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
478327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
478427fcede3SMatthew G. Knepley       orntNew[0] = -2;
478527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
478627fcede3SMatthew G. Knepley       orntNew[1] = 0;
478727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
478827fcede3SMatthew G. Knepley       orntNew[2] = 0;
478927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
479027fcede3SMatthew G. Knepley       orntNew[3] = -2;
479127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
479227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
479327fcede3SMatthew G. Knepley #if 1
479427fcede3SMatthew 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);
479527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
479627fcede3SMatthew 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);
479727fcede3SMatthew G. Knepley       }
479827fcede3SMatthew G. Knepley #endif
479927fcede3SMatthew G. Knepley       /* C-G face */
480027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
480127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
480227fcede3SMatthew G. Knepley       orntNew[0] = -2;
480327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
480427fcede3SMatthew G. Knepley       orntNew[1] = -2;
480527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
480627fcede3SMatthew G. Knepley       orntNew[2] = 0;
480727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
480827fcede3SMatthew G. Knepley       orntNew[3] = 0;
480927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
481027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
481127fcede3SMatthew G. Knepley #if 1
481227fcede3SMatthew 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);
481327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
481427fcede3SMatthew 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);
481527fcede3SMatthew G. Knepley       }
481627fcede3SMatthew G. Knepley #endif
481727fcede3SMatthew G. Knepley       /* B-H face */
481827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
481927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
482027fcede3SMatthew G. Knepley       orntNew[0] = 0;
482127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
482227fcede3SMatthew G. Knepley       orntNew[1] = -2;
482327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
482427fcede3SMatthew G. Knepley       orntNew[2] = -2;
482527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
482627fcede3SMatthew G. Knepley       orntNew[3] = 0;
482727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
482827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
482927fcede3SMatthew G. Knepley #if 1
483027fcede3SMatthew 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);
483127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
483227fcede3SMatthew 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);
483327fcede3SMatthew G. Knepley       }
483427fcede3SMatthew G. Knepley #endif
483527fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
483627fcede3SMatthew G. Knepley         newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
483727fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
483827fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
483927fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
484027fcede3SMatthew G. Knepley #if 1
484127fcede3SMatthew 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);
484227fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
484327fcede3SMatthew 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);
484427fcede3SMatthew G. Knepley         }
484527fcede3SMatthew G. Knepley #endif
484627fcede3SMatthew G. Knepley       }
484727fcede3SMatthew G. Knepley     }
484827fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
484927fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
485027fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
485127fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
485227fcede3SMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
485327fcede3SMatthew G. Knepley 
485427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
485527fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
485627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
485727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
485827fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
485927fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
486027fcede3SMatthew G. Knepley 
486127fcede3SMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
486227fcede3SMatthew G. Knepley         orntNew[0]   = ornt[0];
486327fcede3SMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
486427fcede3SMatthew G. Knepley         orntNew[1]   = ornt[1];
486527fcede3SMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
486627fcede3SMatthew G. Knepley         orntNew[2+r] = 0;
486727fcede3SMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd      - eMax) + (f - fMax);
486827fcede3SMatthew G. Knepley         orntNew[3-r] = 0;
486927fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
487027fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
487127fcede3SMatthew G. Knepley #if 1
487227fcede3SMatthew 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);
487327fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
487427fcede3SMatthew 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);
487527fcede3SMatthew G. Knepley         }
487627fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
487727fcede3SMatthew 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);
487827fcede3SMatthew G. Knepley         }
487927fcede3SMatthew G. Knepley #endif
488027fcede3SMatthew G. Knepley         for (s = 0; s < size; ++s) {
488127fcede3SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
488227fcede3SMatthew G. Knepley 
488327fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
488427fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
488527fcede3SMatthew G. Knepley           for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
488627fcede3SMatthew 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]);
488727fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
488827fcede3SMatthew 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;
488927fcede3SMatthew G. Knepley         }
489027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
489127fcede3SMatthew G. Knepley #if 1
489227fcede3SMatthew 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);
489327fcede3SMatthew G. Knepley         for (p = 0; p < size; ++p) {
489427fcede3SMatthew 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);
489527fcede3SMatthew G. Knepley         }
489627fcede3SMatthew G. Knepley #endif
489727fcede3SMatthew G. Knepley       }
489827fcede3SMatthew G. Knepley     }
489927fcede3SMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
490027fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
490127fcede3SMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
490227fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
490327fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
490427fcede3SMatthew G. Knepley       PetscInt        supportNew[2];
490527fcede3SMatthew G. Knepley 
490627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
490727fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
490827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
490927fcede3SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
491027fcede3SMatthew G. Knepley         orntNew[0] = 0;
491127fcede3SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
491227fcede3SMatthew G. Knepley         orntNew[1] = 0;
491327fcede3SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
491427fcede3SMatthew G. Knepley         orntNew[2] = 0;
491527fcede3SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd                                   - fMax) + (c - cMax);
491627fcede3SMatthew G. Knepley         orntNew[3] = 0;
491727fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
491827fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
491927fcede3SMatthew G. Knepley #if 1
492027fcede3SMatthew 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);
492127fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
492227fcede3SMatthew 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);
492327fcede3SMatthew G. Knepley         }
492427fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
492527fcede3SMatthew 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);
492627fcede3SMatthew G. Knepley         }
492727fcede3SMatthew G. Knepley #endif
492827fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
492927fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
493027fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
493127fcede3SMatthew G. Knepley #if 1
493227fcede3SMatthew 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);
493327fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
493427fcede3SMatthew 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);
493527fcede3SMatthew G. Knepley         }
493627fcede3SMatthew G. Knepley #endif
493727fcede3SMatthew G. Knepley       }
493827fcede3SMatthew G. Knepley     }
493927fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
494027fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
494127fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
494227fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
494327fcede3SMatthew G. Knepley 
494427fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
494527fcede3SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
494627fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
494727fcede3SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
494827fcede3SMatthew G. Knepley 
494927fcede3SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
495027fcede3SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
495127fcede3SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
495227fcede3SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
495327fcede3SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
495427fcede3SMatthew G. Knepley #if 1
495527fcede3SMatthew 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);
495627fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
495727fcede3SMatthew 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);
495827fcede3SMatthew G. Knepley         }
495927fcede3SMatthew G. Knepley #endif
496027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
496127fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
496227fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
496327fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
496427fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
496527fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
496627fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
496727fcede3SMatthew G. Knepley             if (cone[c] == e) break;
496827fcede3SMatthew G. Knepley           }
496927fcede3SMatthew G. Knepley           if (support[s] < fMax) {
497027fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
497127fcede3SMatthew G. Knepley           } else {
497227fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
497327fcede3SMatthew G. Knepley           }
497427fcede3SMatthew G. Knepley         }
497527fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
497627fcede3SMatthew G. Knepley #if 1
497727fcede3SMatthew 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);
497827fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
497927fcede3SMatthew 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);
498027fcede3SMatthew G. Knepley         }
498127fcede3SMatthew G. Knepley #endif
498227fcede3SMatthew G. Knepley       }
498327fcede3SMatthew G. Knepley     }
498427fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
498527fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
498627fcede3SMatthew 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};
498727fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
498827fcede3SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
498927fcede3SMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
499027fcede3SMatthew G. Knepley 
499127fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
499227fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
499327fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
499427fcede3SMatthew G. Knepley 
499527fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
499627fcede3SMatthew G. Knepley         coneNew[1] = newv;
499727fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
499827fcede3SMatthew G. Knepley #if 1
499927fcede3SMatthew 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);
500027fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
500127fcede3SMatthew 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);
500227fcede3SMatthew G. Knepley         }
500327fcede3SMatthew G. Knepley #endif
500427fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
500527fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
500627fcede3SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
500727fcede3SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
500827fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
500927fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
501027fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
501127fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
501227fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
501327fcede3SMatthew G. Knepley           if (support[s] < cMax) {
501427fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
501527fcede3SMatthew G. Knepley           } else {
501627fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadEdgeInverse_Static(orntCell[c], r);
501727fcede3SMatthew G. Knepley           }
501827fcede3SMatthew G. Knepley         }
501927fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
502027fcede3SMatthew G. Knepley #if 1
502127fcede3SMatthew 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);
502227fcede3SMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
502327fcede3SMatthew 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);
502427fcede3SMatthew G. Knepley         }
502527fcede3SMatthew G. Knepley #endif
502627fcede3SMatthew G. Knepley       }
502727fcede3SMatthew G. Knepley     }
502827fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
502927fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
503027fcede3SMatthew 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};
503127fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
503227fcede3SMatthew G. Knepley       const PetscInt *cone;
503327fcede3SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
503427fcede3SMatthew G. Knepley 
503527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
503627fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
503727fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
503827fcede3SMatthew G. Knepley 
503927fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
504027fcede3SMatthew G. Knepley         coneNew[1] = newv;
504127fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
504227fcede3SMatthew G. Knepley #if 1
504327fcede3SMatthew 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);
504427fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
504527fcede3SMatthew 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);
504627fcede3SMatthew G. Knepley         }
504727fcede3SMatthew G. Knepley #endif
504827fcede3SMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
504927fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
505027fcede3SMatthew G. Knepley #if 1
505127fcede3SMatthew 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);
505227fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
505327fcede3SMatthew 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);
505427fcede3SMatthew G. Knepley         }
505527fcede3SMatthew G. Knepley #endif
505627fcede3SMatthew G. Knepley       }
505727fcede3SMatthew G. Knepley     }
505827fcede3SMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
505927fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
506027fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
506127fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
506227fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
506327fcede3SMatthew G. Knepley 
506427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
506527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
506627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
506727fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
506827fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
506927fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
507027fcede3SMatthew G. Knepley #if 1
507127fcede3SMatthew 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);
507227fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
507327fcede3SMatthew 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);
507427fcede3SMatthew G. Knepley       }
507527fcede3SMatthew G. Knepley #endif
507627fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
507727fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
507827fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
507927fcede3SMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
508027fcede3SMatthew 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]);
508127fcede3SMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
508227fcede3SMatthew G. Knepley       }
508327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
508427fcede3SMatthew G. Knepley #if 1
508527fcede3SMatthew 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);
508627fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
508727fcede3SMatthew 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);
508827fcede3SMatthew G. Knepley       }
508927fcede3SMatthew G. Knepley #endif
509027fcede3SMatthew G. Knepley     }
509127fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
509227fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
509327fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
509427fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
509527fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
509627fcede3SMatthew G. Knepley 
509727fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
509827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
509927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
510027fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
510127fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
510227fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
510327fcede3SMatthew G. Knepley #if 1
510427fcede3SMatthew 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);
510527fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
510627fcede3SMatthew 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);
510727fcede3SMatthew G. Knepley       }
510827fcede3SMatthew G. Knepley #endif
510927fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
511027fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
511127fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
511227fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
511327fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
511427fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
511527fcede3SMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
511627fcede3SMatthew 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]);
511727fcede3SMatthew 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);
511827fcede3SMatthew G. Knepley       }
511927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
512027fcede3SMatthew G. Knepley #if 1
512127fcede3SMatthew 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);
512227fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
512327fcede3SMatthew 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);
512427fcede3SMatthew G. Knepley       }
512527fcede3SMatthew G. Knepley #endif
512627fcede3SMatthew G. Knepley     }
512727fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
512827fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
512927fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
513027fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
513127fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size;
513227fcede3SMatthew G. Knepley 
513327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
513427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr);
513527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr);
513627fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
513727fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
513827fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
513927fcede3SMatthew G. Knepley #if 1
514027fcede3SMatthew 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);
514127fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
514227fcede3SMatthew 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);
514327fcede3SMatthew G. Knepley       }
514427fcede3SMatthew G. Knepley #endif
514527fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
514627fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
514727fcede3SMatthew G. Knepley       supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
514827fcede3SMatthew G. Knepley       supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
514927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
515027fcede3SMatthew G. Knepley #if 1
515127fcede3SMatthew 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);
515227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
515327fcede3SMatthew 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);
515427fcede3SMatthew G. Knepley       }
515527fcede3SMatthew G. Knepley #endif
515627fcede3SMatthew G. Knepley     }
515727fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
515827fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
515927fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
516027fcede3SMatthew G. Knepley       const PetscInt *support, *cone;
516127fcede3SMatthew G. Knepley       PetscInt        size, s;
516227fcede3SMatthew G. Knepley 
516327fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
516427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
516527fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
516627fcede3SMatthew G. Knepley         PetscInt r = 0;
516727fcede3SMatthew G. Knepley 
516827fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
516927fcede3SMatthew G. Knepley         if (cone[1] == v) r = 1;
517027fcede3SMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
517127fcede3SMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
517227fcede3SMatthew G. Knepley       }
517327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
517427fcede3SMatthew G. Knepley #if 1
517527fcede3SMatthew 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);
517627fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
517727fcede3SMatthew 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);
517827fcede3SMatthew G. Knepley       }
517927fcede3SMatthew G. Knepley #endif
518027fcede3SMatthew G. Knepley     }
518127fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
518227fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
518327fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
518427fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
518527fcede3SMatthew G. Knepley       PetscInt        size, s;
518627fcede3SMatthew G. Knepley 
518727fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
518827fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
518927fcede3SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
519027fcede3SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
519127fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
519227fcede3SMatthew G. Knepley         PetscInt r;
519327fcede3SMatthew G. Knepley 
519427fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
519527fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
519627fcede3SMatthew G. Knepley         if (support[s] < fMax) {
519727fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
519827fcede3SMatthew G. Knepley         } else {
519927fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
520027fcede3SMatthew G. Knepley         }
520127fcede3SMatthew G. Knepley       }
520227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
520327fcede3SMatthew G. Knepley #if 1
520427fcede3SMatthew 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);
520527fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
520627fcede3SMatthew 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);
520727fcede3SMatthew G. Knepley       }
520827fcede3SMatthew G. Knepley #endif
520927fcede3SMatthew G. Knepley     }
521027fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
521127fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
521227fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
521327fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
521427fcede3SMatthew G. Knepley       PetscInt        size, s;
521527fcede3SMatthew G. Knepley 
521627fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
521727fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
521827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 +  (f - fStart)*4 + r;
521927fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
522027fcede3SMatthew G. Knepley         PetscInt r;
522127fcede3SMatthew G. Knepley 
522227fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
522327fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
522427fcede3SMatthew G. Knepley         if (support[s] < cMax) {
522527fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
522627fcede3SMatthew G. Knepley         } else {
522727fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax       - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
522827fcede3SMatthew G. Knepley         }
522927fcede3SMatthew G. Knepley       }
523027fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
523127fcede3SMatthew G. Knepley #if 1
523227fcede3SMatthew 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);
523327fcede3SMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
523427fcede3SMatthew 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);
523527fcede3SMatthew G. Knepley       }
523627fcede3SMatthew G. Knepley #endif
523727fcede3SMatthew G. Knepley     }
523827fcede3SMatthew G. Knepley     /* Cell vertices have 6 supports */
523927fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
524027fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
524127fcede3SMatthew G. Knepley       PetscInt       supportNew[6];
524227fcede3SMatthew G. Knepley 
524327fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
524427fcede3SMatthew G. Knepley         supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
524527fcede3SMatthew G. Knepley       }
524627fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
524727fcede3SMatthew G. Knepley     }
524827fcede3SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
524927fcede3SMatthew G. Knepley     break;
525075d3a19aSMatthew G. Knepley   default:
525175d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
525275d3a19aSMatthew G. Knepley   }
525375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
525475d3a19aSMatthew G. Knepley }
525575d3a19aSMatthew G. Knepley 
525675d3a19aSMatthew G. Knepley #undef __FUNCT__
525775d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates"
525886150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
525975d3a19aSMatthew G. Knepley {
526075d3a19aSMatthew G. Knepley   PetscSection   coordSection, coordSectionNew;
526175d3a19aSMatthew G. Knepley   Vec            coordinates, coordinatesNew;
526275d3a19aSMatthew G. Knepley   PetscScalar   *coords, *coordsNew;
52633478d7aaSMatthew G. Knepley   const PetscInt numVertices = depthSize ? depthSize[0] : 0;
526427fcede3SMatthew G. Knepley   PetscInt       dim, depth, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
526575d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
526675d3a19aSMatthew G. Knepley 
526775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
526875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
526975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
527075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
5271b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
527275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
527375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
527427fcede3SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr);
52753478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);}
527675d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);
5277f719d809SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
527875d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
527975d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
528075d3a19aSMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr);
52813478d7aaSMatthew G. Knepley   ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
528227fcede3SMatthew G. Knepley   if (cMax < 0) cMax = cEnd;
528375d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
5284b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
528575d3a19aSMatthew G. Knepley   /* All vertices have the dim coordinates */
52863478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
528775d3a19aSMatthew G. Knepley     ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr);
528875d3a19aSMatthew G. Knepley     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr);
528975d3a19aSMatthew G. Knepley   }
529075d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
5291f719d809SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr);
529275d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
529375d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
529475d3a19aSMatthew G. Knepley   ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr);
529575d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
529675d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
529775d3a19aSMatthew G. Knepley   ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr);
529875d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
529975d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
5300b5da9499SMatthew G. Knepley   switch (refiner) {
53013478d7aaSMatthew G. Knepley   case 0: break;
5302b5da9499SMatthew G. Knepley   case 6: /* Hex 3D */
5303d856d60fSMatthew G. Knepley   case 8: /* Hybrid Hex 3D */
5304b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
5305d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
530627fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
5307b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
5308b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
5309b5da9499SMatthew G. Knepley 
5310b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5311b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
5312b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
5313b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
5314b5da9499SMatthew G. Knepley       }
5315b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
5316b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
5317b5da9499SMatthew G. Knepley       }
5318b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5319b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
5320b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
5321b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
5322b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
5323b5da9499SMatthew G. Knepley       }
5324b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5325b5da9499SMatthew G. Knepley     }
5326b5da9499SMatthew G. Knepley   case 2: /* Hex 2D */
5327a97b51b8SMatthew G. Knepley   case 4: /* Hybrid Hex 2D */
5328b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
532927fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
533027fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
5331b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
5332b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
5333b5da9499SMatthew G. Knepley 
5334b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5335b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
5336b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
5337b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
5338b5da9499SMatthew G. Knepley       }
5339b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
5340b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
5341b5da9499SMatthew G. Knepley       }
5342b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5343b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
5344b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
5345b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
5346b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
5347b5da9499SMatthew G. Knepley       }
5348b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5349b5da9499SMatthew G. Knepley     }
5350b5da9499SMatthew G. Knepley   case 1: /* Simplicial 2D */
5351b5da9499SMatthew G. Knepley   case 3: /* Hybrid Simplicial 2D */
5352b5da9499SMatthew G. Knepley   case 5: /* Simplicial 3D */
53536ce3c06aSMatthew G. Knepley   case 7: /* Hybrid Simplicial 3D */
5354b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
5355b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
5356b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
5357b5da9499SMatthew G. Knepley       const PetscInt *cone;
5358b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
5359b5da9499SMatthew G. Knepley 
5360b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
5361b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
5362b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
5363b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
5364b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
5365b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5366b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
5367b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]);
5368b5da9499SMatthew G. Knepley       }
5369b5da9499SMatthew G. Knepley     }
537075d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
537175d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
537275d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
537375d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
537475d3a19aSMatthew G. Knepley 
537575d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
537675d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
537775d3a19aSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
537875d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
537975d3a19aSMatthew G. Knepley       }
538075d3a19aSMatthew G. Knepley     }
5381b5da9499SMatthew G. Knepley     break;
5382b5da9499SMatthew G. Knepley   default:
5383b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
538475d3a19aSMatthew G. Knepley   }
538575d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
538675d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
538775d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
538875d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
538975d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
539075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
539175d3a19aSMatthew G. Knepley }
539275d3a19aSMatthew G. Knepley 
539375d3a19aSMatthew G. Knepley #undef __FUNCT__
539475d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF"
539586150812SJed Brown static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
539675d3a19aSMatthew G. Knepley {
539775d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
539875d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
539975d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
540075d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
540175d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
540275d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
540375d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
540475d3a19aSMatthew G. Knepley 
540575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
540675d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
5407785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
540875d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
540975d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
541075d3a19aSMatthew G. Knepley   }
541175d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
5412785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &ranksNew);CHKERRQ(ierr);
5413785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &localPointsNew);CHKERRQ(ierr);
5414785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
541575d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
541675d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
541775d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
541875d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
541975d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
542075d3a19aSMatthew G. Knepley   }
542175d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
542275d3a19aSMatthew G. Knepley   ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);
542375d3a19aSMatthew G. Knepley   ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
542475d3a19aSMatthew G. Knepley   ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
542575d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
542675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
542775d3a19aSMatthew G. Knepley }
542875d3a19aSMatthew G. Knepley 
542975d3a19aSMatthew G. Knepley #undef __FUNCT__
543075d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF"
543186150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
543275d3a19aSMatthew G. Knepley {
543375d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
543475d3a19aSMatthew G. Knepley   IS                 processRanks;
543575d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
543675d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
543775d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
543875d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
543975d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
544075d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
544175d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
54427ba685a0SMatthew G. Knepley   PetscInt           depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
54437ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
544475d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
544575d3a19aSMatthew G. Knepley 
544675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
544775d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
544875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
544975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
545075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
545175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
545275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
545375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
54543478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
545575d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
545675d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
545775d3a19aSMatthew G. Knepley   /* Caculate size of new SF */
545875d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
545975d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
546075d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
546175d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
546275d3a19aSMatthew G. Knepley 
546375d3a19aSMatthew G. Knepley     switch (refiner) {
546475d3a19aSMatthew G. Knepley     case 1:
546575d3a19aSMatthew G. Knepley       /* Simplicial 2D */
546675d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
546775d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
546875d3a19aSMatthew G. Knepley         ++numLeavesNew;
546975d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
547075d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
5471d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
547275d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
547375d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
547475d3a19aSMatthew G. Knepley         numLeavesNew += 4 + 3;
547575d3a19aSMatthew G. Knepley       }
547675d3a19aSMatthew G. Knepley       break;
5477a97b51b8SMatthew G. Knepley     case 3:
5478a97b51b8SMatthew G. Knepley       /* Hybrid Simplicial 2D */
5479a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5480a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
5481a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5482a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5483a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
5484a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5485a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5486a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
5487a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5488a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5489a97b51b8SMatthew G. Knepley         /* Interior cells add new cells and interior faces */
5490a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 3;
5491a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
5492a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
5493a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5494a97b51b8SMatthew G. Knepley       }
5495a97b51b8SMatthew G. Knepley       break;
549675d3a19aSMatthew G. Knepley     case 2:
549775d3a19aSMatthew G. Knepley       /* Hex 2D */
549875d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
549975d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
550075d3a19aSMatthew G. Knepley         ++numLeavesNew;
550175d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
550275d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
5503d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
550475d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5505455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
5506455d6cd4SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
550775d3a19aSMatthew G. Knepley       }
550875d3a19aSMatthew G. Knepley       break;
5509a97b51b8SMatthew G. Knepley     case 4:
5510a97b51b8SMatthew G. Knepley       /* Hybrid Hex 2D */
5511a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5512a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
5513a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5514a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5515a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
5516a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5517a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5518a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
5519a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5520a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5521a97b51b8SMatthew G. Knepley         /* Interior cells add new cells, interior faces, and vertex */
5522a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
5523a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
5524a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
5525a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5526a97b51b8SMatthew G. Knepley       }
5527a97b51b8SMatthew G. Knepley       break;
5528b5da9499SMatthew G. Knepley     case 5:
5529b5da9499SMatthew G. Knepley       /* Simplicial 3D */
5530b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5531b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
5532b5da9499SMatthew G. Knepley         ++numLeavesNew;
5533b5da9499SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
5534b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
5535b5da9499SMatthew G. Knepley         numLeavesNew += 2 + 1;
5536b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
5537b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
5538b5da9499SMatthew G. Knepley         numLeavesNew += 4 + 3;
5539b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5540b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
5541b5da9499SMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
5542b5da9499SMatthew G. Knepley       }
5543b5da9499SMatthew G. Knepley       break;
55446ce3c06aSMatthew G. Knepley     case 7:
55456ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
55466ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
55476ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
55486ce3c06aSMatthew G. Knepley         ++numLeavesNew;
55496ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
55506ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
55516ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
55526ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
55536ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
55546ce3c06aSMatthew G. Knepley         ++numLeavesNew;
55556ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
55566ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
55576ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
55586ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
55596ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
55606ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
55616ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
55626ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
55636ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
55646ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
55656ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
55666ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
55676ce3c06aSMatthew G. Knepley       }
55686ce3c06aSMatthew G. Knepley       break;
55692eabf88fSMatthew G. Knepley     case 6:
55702eabf88fSMatthew G. Knepley       /* Hex 3D */
55712eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
55722eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
55732eabf88fSMatthew G. Knepley         ++numLeavesNew;
55742eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
55752eabf88fSMatthew G. Knepley         /* Old edges add new edges, and vertex */
55762eabf88fSMatthew G. Knepley         numLeavesNew += 2 + 1;
55772eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
55782eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
55792eabf88fSMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
55802eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
55812eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
55822eabf88fSMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
55832eabf88fSMatthew G. Knepley       }
55842eabf88fSMatthew G. Knepley       break;
558527fcede3SMatthew G. Knepley     case 8:
558627fcede3SMatthew G. Knepley       /* Hybrid Hex 3D */
558727fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
558827fcede3SMatthew G. Knepley         /* Old vertices stay the same */
558927fcede3SMatthew G. Knepley         ++numLeavesNew;
559027fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
559127fcede3SMatthew G. Knepley         /* Interior edges add new edges, and vertex */
559227fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
559327fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
559427fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
559527fcede3SMatthew G. Knepley         ++numLeavesNew;
559627fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
559727fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
559827fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
559927fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
560027fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
560127fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
560227fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
560327fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
560427fcede3SMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
560527fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
560627fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
560727fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
560827fcede3SMatthew G. Knepley       }
560927fcede3SMatthew G. Knepley       break;
561075d3a19aSMatthew G. Knepley     default:
561175d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
561275d3a19aSMatthew G. Knepley     }
561375d3a19aSMatthew G. Knepley   }
561475d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
561575d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
561675d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
5617dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
5618dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
561975d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
562075d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
562175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
562275d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
562375d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
562475d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
562575d3a19aSMatthew G. Knepley   }
562675d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
562775d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
562875d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
562975d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
563075d3a19aSMatthew G. Knepley 
563175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
563275d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
563375d3a19aSMatthew G. Knepley 
563475d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
563575d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
563675d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
563775d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
563875d3a19aSMatthew G. Knepley 
563975d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
564075d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
564175d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
564275d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
564375d3a19aSMatthew G. Knepley   }
564475d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
564575d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
564675d3a19aSMatthew G. Knepley   /* Calculate new point SF */
5647785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew,    &localPointsNew);CHKERRQ(ierr);
5648785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
564975d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
565075d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
565175d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
565275d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
565375d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
565475d3a19aSMatthew G. Knepley 
565575d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
565675d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
565775d3a19aSMatthew G. Knepley     switch (refiner) {
565875d3a19aSMatthew G. Knepley     case 1:
565975d3a19aSMatthew G. Knepley       /* Simplicial 2D */
566075d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
566175d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
566275d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
566375d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
566475d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
566575d3a19aSMatthew G. Knepley         ++m;
566675d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
566775d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
566875d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
566975d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
567075d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
567175d3a19aSMatthew G. Knepley         ++m;
567275d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
567375d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
567475d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
567575d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
567675d3a19aSMatthew G. Knepley         }
567775d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
567875d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
567975d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
568075d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
568175d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
568275d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
568375d3a19aSMatthew G. Knepley         }
568475d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
568575d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*3     + r;
568675d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
568775d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
568875d3a19aSMatthew G. Knepley         }
568975d3a19aSMatthew G. Knepley       }
569075d3a19aSMatthew G. Knepley       break;
569175d3a19aSMatthew G. Knepley     case 2:
569275d3a19aSMatthew G. Knepley       /* Hex 2D */
569375d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
569475d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
569575d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
569675d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
569775d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
569875d3a19aSMatthew G. Knepley         ++m;
569975d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
570075d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
570175d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
570275d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
570375d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
570475d3a19aSMatthew G. Knepley         ++m;
570575d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
570675d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
570775d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
570875d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
570975d3a19aSMatthew G. Knepley         }
571075d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5711455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
571275d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
571375d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
571475d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
571575d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
571675d3a19aSMatthew G. Knepley         }
571775d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
571875d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*4     + r;
571975d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r;
572075d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
572175d3a19aSMatthew G. Knepley         }
5722455d6cd4SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
5723149f48fdSMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (vEnd - vStart)               + (fEnd - fStart)                    + (p  - cStart)     + r;
5724149f48fdSMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0]  + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
5725455d6cd4SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5726455d6cd4SMatthew G. Knepley         }
572775d3a19aSMatthew G. Knepley       }
572875d3a19aSMatthew G. Knepley       break;
572975d3a19aSMatthew G. Knepley     case 3:
573075d3a19aSMatthew G. Knepley       /* Hybrid simplicial 2D */
573175d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
573275d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
573375d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
573475d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
573575d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
573675d3a19aSMatthew G. Knepley         ++m;
573775d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
573875d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
573975d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
574075d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
574175d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
574275d3a19aSMatthew G. Knepley         ++m;
574375d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
574475d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
574575d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
574675d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
574775d3a19aSMatthew G. Knepley         }
574875d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
574975d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
575075d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
575175d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
575275d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
575375d3a19aSMatthew G. Knepley         ++m;
575475d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
575575d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
575675d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
575775d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
575875d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
575975d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
576075d3a19aSMatthew G. Knepley         }
576175d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
576275d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
576375d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
576475d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
576575d3a19aSMatthew G. Knepley         }
576675d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
576775d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
576875d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
576975d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
577075d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
577175d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
577275d3a19aSMatthew G. Knepley         }
577375d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
577475d3a19aSMatthew 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]);
577575d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
577675d3a19aSMatthew G. Knepley         ++m;
577775d3a19aSMatthew G. Knepley       }
577875d3a19aSMatthew G. Knepley       break;
5779a97b51b8SMatthew G. Knepley     case 4:
5780a97b51b8SMatthew G. Knepley       /* Hybrid Hex 2D */
5781a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5782a97b51b8SMatthew G. Knepley         /* Old vertices stay the same */
5783a97b51b8SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
5784a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5785a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5786a97b51b8SMatthew G. Knepley         ++m;
5787a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5788a97b51b8SMatthew G. Knepley         /* Old interior faces add new faces and vertex */
5789a97b51b8SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
5790a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
5791a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5792a97b51b8SMatthew G. Knepley         ++m;
5793a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5794a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
5795a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
5796a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5797a97b51b8SMatthew G. Knepley         }
5798a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5799a97b51b8SMatthew G. Knepley         /* Old hybrid faces stay the same */
5800a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
5801a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
5802a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5803a97b51b8SMatthew G. Knepley         ++m;
5804a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5805a97b51b8SMatthew G. Knepley         /* Old interior cells add new cells, interior faces, and vertex */
5806a97b51b8SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)               + (fEnd - fStart)                    + (p  - cStart);
5807a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0]  + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]);
5808a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5809a97b51b8SMatthew G. Knepley         ++m;
5810a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5811a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
5812a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5813a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5814a97b51b8SMatthew G. Knepley         }
5815a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5816a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*4     + r;
5817a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r;
5818a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5819a97b51b8SMatthew G. Knepley         }
5820a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5821a97b51b8SMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
5822a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5823a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
5824a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5825a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5826a97b51b8SMatthew G. Knepley         }
5827a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*4     + (p  - cMax);
5828a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth]);
5829a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5830a97b51b8SMatthew G. Knepley         ++m;
5831a97b51b8SMatthew G. Knepley       }
5832a97b51b8SMatthew G. Knepley       break;
5833b5da9499SMatthew G. Knepley     case 5:
5834b5da9499SMatthew G. Knepley       /* Simplicial 3D */
5835b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5836b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
5837b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
5838b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5839b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5840b5da9499SMatthew G. Knepley         ++m;
584187fe6628SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
5842b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
5843b5da9499SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5844b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
5845b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
5846b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5847b5da9499SMatthew G. Knepley         }
5848b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
5849b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
5850b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5851b5da9499SMatthew G. Knepley         ++m;
5852b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
5853b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
5854b5da9499SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5855b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
5856b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
5857b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5858b5da9499SMatthew G. Knepley         }
5859b5da9499SMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
5860b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*3     + r;
5861b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r;
5862b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5863b5da9499SMatthew G. Knepley         }
5864b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5865b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
5866b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
5867b5da9499SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
5868b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
5869b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5870b5da9499SMatthew G. Knepley         }
5871b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
5872b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*8     + r;
5873b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r;
5874b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5875b5da9499SMatthew G. Knepley         }
5876b5da9499SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
5877b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*3                    + (p  - cStart)*1     + r;
5878b5da9499SMatthew 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;
5879b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5880b5da9499SMatthew G. Knepley         }
5881b5da9499SMatthew G. Knepley       }
5882b5da9499SMatthew G. Knepley       break;
58836ce3c06aSMatthew G. Knepley     case 7:
58846ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
58856ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
58866ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
58876ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
58886ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
58896ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
58906ce3c06aSMatthew G. Knepley         ++m;
58916ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
58926ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
58936ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
58946ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
58956ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
58966ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
58976ce3c06aSMatthew G. Knepley         }
58986ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
58996ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
59006ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
59016ce3c06aSMatthew G. Knepley         ++m;
59026ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
59036ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
59046ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
59057d5cd7d5SMatthew 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)+1]);
59066ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
59076ce3c06aSMatthew G. Knepley         ++m;
59086ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
59096ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
59106ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
59116ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
59126ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
59136ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59146ce3c06aSMatthew G. Knepley         }
59156ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
59166ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
59176ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
59186ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59196ce3c06aSMatthew G. Knepley         }
59206ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
59216ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
59226ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5923899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
5924899f98d0SMatthew 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;
59256ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59266ce3c06aSMatthew G. Knepley         }
59277d5cd7d5SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (eEnd                                    - eMax)                        + (p  - fMax);
59287d5cd7d5SMatthew 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]) + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
59296ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
593009b1338fSMatthew G. Knepley         ++m;
59316ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
59326ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
59336ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
59346ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
59356ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
59366ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59376ce3c06aSMatthew G. Knepley         }
59386ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
59396ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
59406ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
59416ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59426ce3c06aSMatthew G. Knepley         }
59436ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + r;
59446ce3c06aSMatthew 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;
59456ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
594609b1338fSMatthew G. Knepley         ++m;
59476ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
59486ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
59496ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
59506ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
59516ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
59526ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59536ce3c06aSMatthew G. Knepley         }
59546ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
5955899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*3                            + r;
5956899f98d0SMatthew 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;
59576ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59586ce3c06aSMatthew G. Knepley         }
59596ce3c06aSMatthew G. Knepley       }
59606ce3c06aSMatthew G. Knepley       break;
59612eabf88fSMatthew G. Knepley     case 6:
59622eabf88fSMatthew G. Knepley       /* Hex 3D */
59632eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
59642eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
59652eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
59662eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
59672eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
59682eabf88fSMatthew G. Knepley         ++m;
59692eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
59702eabf88fSMatthew G. Knepley         /* Old edges add new edges and vertex */
59712eabf88fSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
59722eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
59732eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
59742eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59752eabf88fSMatthew G. Knepley         }
59762eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
59772eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
59782eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
59792eabf88fSMatthew G. Knepley         ++m;
59802eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
59812eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
59822eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
59832eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
59842eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
59852eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59862eabf88fSMatthew G. Knepley         }
59872eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
59882eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*4     + r;
59892eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r;
59902eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59912eabf88fSMatthew G. Knepley         }
59922eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (p  - fStart);
59932eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]);
59942eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
59952eabf88fSMatthew G. Knepley         ++m;
59962eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
59972eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
59982eabf88fSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
59992eabf88fSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
60002eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
60012eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
60022eabf88fSMatthew G. Knepley         }
60032eabf88fSMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
60042eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*12     + r;
60052eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r;
60062eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
60072eabf88fSMatthew G. Knepley         }
60082eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
60092eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*4                    + (p  - cStart)*6     + r;
60102eabf88fSMatthew 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;
60112eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
60122eabf88fSMatthew G. Knepley         }
60132eabf88fSMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
60142eabf88fSMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eEnd - eStart)              + (fEnd - fStart)                    + (p  - cStart)     + r;
60152eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
60162eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
60172eabf88fSMatthew G. Knepley         }
60182eabf88fSMatthew G. Knepley       }
60192eabf88fSMatthew G. Knepley       break;
602027fcede3SMatthew G. Knepley     case 8:
602127fcede3SMatthew G. Knepley       /* Hybrid Hex 3D */
602227fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
602327fcede3SMatthew G. Knepley         /* Interior vertices stay the same */
602427fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
602527fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
602627fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
602727fcede3SMatthew G. Knepley         ++m;
602827fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
602927fcede3SMatthew G. Knepley         /* Interior edges add new edges and vertex */
603027fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
603127fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
603227fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
603327fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
603427fcede3SMatthew G. Knepley         }
603527fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
603627fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
603727fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
603827fcede3SMatthew G. Knepley         ++m;
603927fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
604027fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
604127fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (p  - eMax);
604227fcede3SMatthew 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]);
604327fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
604427fcede3SMatthew G. Knepley         ++m;
604527fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
604627fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
604727fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
604827fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
604927fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
605027fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
605127fcede3SMatthew G. Knepley         }
605227fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
605327fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*4     + r;
605427fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
605527fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
605627fcede3SMatthew G. Knepley         }
605727fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eMax                        - eStart)     + (p  - fStart);
605827fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
605927fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
606027fcede3SMatthew G. Knepley         ++m;
606127fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
606227fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
606327fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
606427fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
606527fcede3SMatthew 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;
606627fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
606727fcede3SMatthew G. Knepley         }
606827fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (fEnd                                          - fMax);
606927fcede3SMatthew 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]);
607027fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
607127fcede3SMatthew G. Knepley         ++m;
607227fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
607327fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
607427fcede3SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
607527fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
607627fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
607727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
607827fcede3SMatthew G. Knepley         }
607927fcede3SMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
608027fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*12     + r;
608127fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
608227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
608327fcede3SMatthew G. Knepley         }
608427fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
608527fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (p  - cStart)*6     + r;
608627fcede3SMatthew 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;
608727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
608827fcede3SMatthew G. Knepley         }
608927fcede3SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
609027fcede3SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eMax                        - eStart)     + (fMax                              - fStart)     + (p  - cStart)     + r;
609127fcede3SMatthew 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;
609227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
609327fcede3SMatthew G. Knepley         }
609427fcede3SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
609527fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
609627fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
609727fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
609827fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
609927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
610027fcede3SMatthew G. Knepley         }
610127fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
610227fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*4                            + r;
610327fcede3SMatthew 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;
610427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
610527fcede3SMatthew G. Knepley         }
610627fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (fEnd                                          - fMax)                              + (p  - cMax);
610727fcede3SMatthew 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]);
610827fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
610927fcede3SMatthew G. Knepley         ++m;
611027fcede3SMatthew G. Knepley       }
611127fcede3SMatthew G. Knepley       break;
611275d3a19aSMatthew G. Knepley     default:
611375d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
611475d3a19aSMatthew G. Knepley     }
611575d3a19aSMatthew G. Knepley   }
611609b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
611775d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
611875d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
6119*ba3c3d50SMatthew G. Knepley   {
6120*ba3c3d50SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
6121*ba3c3d50SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
6122*ba3c3d50SMatthew G. Knepley 
6123*ba3c3d50SMatthew G. Knepley     /* SF needs sorted leaves to correct calculate Gather */
6124*ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr);
6125*ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr);
6126*ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr);
6127*ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) idx[i] = i;
6128*ba3c3d50SMatthew G. Knepley     ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr);
6129*ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
6130*ba3c3d50SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
6131*ba3c3d50SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
6132*ba3c3d50SMatthew G. Knepley     }
6133*ba3c3d50SMatthew G. Knepley     ltmp            = localPointsNew;
6134*ba3c3d50SMatthew G. Knepley     localPointsNew  = lp;
6135*ba3c3d50SMatthew G. Knepley     rtmp            = remotePointsNew;
6136*ba3c3d50SMatthew G. Knepley     remotePointsNew = rp;
6137*ba3c3d50SMatthew G. Knepley     ierr = PetscFree(idx);CHKERRQ(ierr);
6138*ba3c3d50SMatthew G. Knepley     ierr = PetscFree(ltmp);CHKERRQ(ierr);
6139*ba3c3d50SMatthew G. Knepley     ierr = PetscFree(rtmp);CHKERRQ(ierr);
6140*ba3c3d50SMatthew G. Knepley   }
614175d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
614275d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
614306a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
614475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
614575d3a19aSMatthew G. Knepley }
614675d3a19aSMatthew G. Knepley 
614775d3a19aSMatthew G. Knepley #undef __FUNCT__
614875d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels"
614986150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
615075d3a19aSMatthew G. Knepley {
615175d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
61527ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
61537ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
615475d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
615575d3a19aSMatthew G. Knepley 
615675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
615775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
615875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
615975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
616075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
6161d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
61623478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
616375d3a19aSMatthew G. Knepley   ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
616475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
616575d3a19aSMatthew G. Knepley   switch (refiner) {
61663478d7aaSMatthew G. Knepley   case 0: break;
616758b8852aSMatthew G. Knepley   case 7:
616858b8852aSMatthew G. Knepley   case 8:
616958b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
617075d3a19aSMatthew G. Knepley   case 3:
617158b8852aSMatthew G. Knepley   case 4:
617275d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
617375d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
617475d3a19aSMatthew G. Knepley   }
617575d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
617675d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
617775d3a19aSMatthew G. Knepley     const char     *lname;
617875d3a19aSMatthew G. Knepley     PetscBool       isDepth;
617975d3a19aSMatthew G. Knepley     IS              valueIS;
618075d3a19aSMatthew G. Knepley     const PetscInt *values;
618175d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
618275d3a19aSMatthew G. Knepley 
618375d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr);
618475d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
618575d3a19aSMatthew G. Knepley     if (isDepth) continue;
618675d3a19aSMatthew G. Knepley     ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr);
618775d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr);
618875d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
618975d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
619075d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
619175d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
619275d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
619375d3a19aSMatthew G. Knepley       IS              pointIS;
619475d3a19aSMatthew G. Knepley       const PetscInt *points;
619575d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
619675d3a19aSMatthew G. Knepley 
619775d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
619875d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
619975d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
620075d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
620175d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
620275d3a19aSMatthew G. Knepley         switch (refiner) {
620375d3a19aSMatthew G. Knepley         case 1:
620475d3a19aSMatthew G. Knepley           /* Simplicial 2D */
620575d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
620675d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
620775d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
620875d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
620975d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
621075d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
621175d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
621275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
621375d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
621475d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
621575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
621675d3a19aSMatthew G. Knepley             }
621775d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
621875d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
621975d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
622075d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
622175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
622275d3a19aSMatthew G. Knepley             }
622375d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
622475d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
622575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
622675d3a19aSMatthew G. Knepley             }
622775d3a19aSMatthew G. Knepley           }
622875d3a19aSMatthew G. Knepley           break;
622975d3a19aSMatthew G. Knepley         case 2:
623075d3a19aSMatthew G. Knepley           /* Hex 2D */
623175d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
623275d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
623375d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
623475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
623575d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
623675d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
623775d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
623875d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
623975d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
624075d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
624175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
624275d3a19aSMatthew G. Knepley             }
624375d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
624475d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
624575d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
624675d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
624775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
624875d3a19aSMatthew G. Knepley             }
624975d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
625075d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
625175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
625275d3a19aSMatthew G. Knepley             }
625375d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
625475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
625575d3a19aSMatthew G. Knepley           }
625675d3a19aSMatthew G. Knepley           break;
625775d3a19aSMatthew G. Knepley         case 3:
625875d3a19aSMatthew G. Knepley           /* Hybrid simplicial 2D */
625975d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
626075d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
626175d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
626275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
626375d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
626475d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
626575d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
626675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
626775d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
626875d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
626975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
627075d3a19aSMatthew G. Knepley             }
627175d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
627275d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
627375d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
627475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
627575d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
627675d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
627775d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
627875d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
627975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
628075d3a19aSMatthew G. Knepley             }
628175d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
628275d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
628375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
628475d3a19aSMatthew G. Knepley             }
628575d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
628675d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
628775d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
628875d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
628975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
629075d3a19aSMatthew G. Knepley             }
629175d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
629275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
629375d3a19aSMatthew G. Knepley           }
629475d3a19aSMatthew G. Knepley           break;
6295a97b51b8SMatthew G. Knepley         case 4:
6296a97b51b8SMatthew G. Knepley           /* Hybrid Hex 2D */
6297a97b51b8SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
6298a97b51b8SMatthew G. Knepley             /* Old vertices stay the same */
6299a97b51b8SMatthew G. Knepley             newp = vStartNew + (p - vStart);
6300a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6301a97b51b8SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
6302a97b51b8SMatthew G. Knepley             /* Old interior faces add new faces and vertex */
6303a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
6304a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6305a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6306a97b51b8SMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
6307a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6308a97b51b8SMatthew G. Knepley             }
6309a97b51b8SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
6310a97b51b8SMatthew G. Knepley             /* Old hybrid faces stay the same */
6311a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
6312a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6313a97b51b8SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
6314a97b51b8SMatthew G. Knepley             /* Old interior cells add new cells, interior faces, and vertex */
6315a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6316a97b51b8SMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
6317a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6318a97b51b8SMatthew G. Knepley             }
6319a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6320a97b51b8SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
6321a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6322a97b51b8SMatthew G. Knepley             }
6323a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
6324a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6325a97b51b8SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
6326a97b51b8SMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
6327a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6328a97b51b8SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
6329a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6330a97b51b8SMatthew G. Knepley             }
6331a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
6332a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6333a97b51b8SMatthew G. Knepley           }
6334a97b51b8SMatthew G. Knepley           break;
6335b5da9499SMatthew G. Knepley         case 5:
6336b5da9499SMatthew G. Knepley           /* Simplicial 3D */
6337b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
6338b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
6339b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
6340b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6341b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
6342b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
6343b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6344b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
6345b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6346b5da9499SMatthew G. Knepley             }
6347b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
6348b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6349b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
6350b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
6351b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6352b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
6353b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6354b5da9499SMatthew G. Knepley             }
6355b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
6356b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
6357b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6358b5da9499SMatthew G. Knepley             }
6359b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
6360b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
6361b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
6362b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
6363b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6364b5da9499SMatthew G. Knepley             }
6365b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
6366b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
6367b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6368b5da9499SMatthew G. Knepley             }
6369b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
6370b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
6371b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6372b5da9499SMatthew G. Knepley             }
6373b5da9499SMatthew G. Knepley           }
6374b5da9499SMatthew G. Knepley           break;
63756ce3c06aSMatthew G. Knepley         case 7:
63766ce3c06aSMatthew G. Knepley           /* Hybrid Simplicial 3D */
63776ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
63786ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
63796ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
63806ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63816ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
63826ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
63836ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
63846ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
63856ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63866ce3c06aSMatthew G. Knepley             }
63876ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
63886ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63896ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
63906ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
63916ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
63926ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63936ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
63946ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
63956ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
63966ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
63976ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63986ce3c06aSMatthew G. Knepley             }
63996ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
64006ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
64016ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64026ce3c06aSMatthew G. Knepley             }
64036ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
64046ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
64056ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
64066ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
64076ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64086ce3c06aSMatthew G. Knepley             }
64096ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
64106ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64116ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
64126ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
64136ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
64146ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
64156ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64166ce3c06aSMatthew G. Knepley             }
64176ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
64186ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
64196ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64206ce3c06aSMatthew G. Knepley             }
64216ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
64226ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
642358b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
64246ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
64256ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
64266ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
64276ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64286ce3c06aSMatthew G. Knepley             }
64296ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
64306ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
64316ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64326ce3c06aSMatthew G. Knepley             }
64336ce3c06aSMatthew G. Knepley           }
64346ce3c06aSMatthew G. Knepley           break;
64352eabf88fSMatthew G. Knepley         case 6:
64362eabf88fSMatthew G. Knepley           /* Hex 3D */
64372eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
64382eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
64392eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
64402eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
644119d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
64422eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
64432eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
64442eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
64452eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64462eabf88fSMatthew G. Knepley             }
64472eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
64482eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64492eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
64502eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
64512eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
64522eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
64532eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64542eabf88fSMatthew G. Knepley             }
64552eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
64562eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
64572eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64582eabf88fSMatthew G. Knepley             }
64592eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
64602eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64612eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
64622eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
64632eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
64642eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
64652eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64662eabf88fSMatthew G. Knepley             }
64672eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
64682eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
64692eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64702eabf88fSMatthew G. Knepley             }
64712eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
64722eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
64732eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64742eabf88fSMatthew G. Knepley             }
64752eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
64762eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64772eabf88fSMatthew G. Knepley           }
64782eabf88fSMatthew G. Knepley           break;
647927fcede3SMatthew G. Knepley         case 8:
648027fcede3SMatthew G. Knepley           /* Hybrid Hex 3D */
648127fcede3SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
648227fcede3SMatthew G. Knepley             /* Interior vertices stay the same */
648327fcede3SMatthew G. Knepley             newp = vStartNew + (p - vStart);
648427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
648527fcede3SMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
648627fcede3SMatthew G. Knepley             /* Interior edges add new edges and vertex */
648727fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
648827fcede3SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
648927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
649027fcede3SMatthew G. Knepley             }
649127fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
649227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
649327fcede3SMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
649427fcede3SMatthew G. Knepley             /* Hybrid edges stay the same */
649527fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
649627fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
649727fcede3SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
649827fcede3SMatthew G. Knepley             /* Interior faces add new faces, edges, and vertex */
649927fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
650027fcede3SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
650127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
650227fcede3SMatthew G. Knepley             }
650327fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
650427fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
650527fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
650627fcede3SMatthew G. Knepley             }
650727fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
650827fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
650927fcede3SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
651027fcede3SMatthew G. Knepley             /* Hybrid faces add new faces and edges */
651127fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
651227fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
651327fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
651427fcede3SMatthew G. Knepley             }
651527fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
651627fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
651727fcede3SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
651827fcede3SMatthew G. Knepley             /* Interior cells add new cells, faces, edges, and vertex */
651927fcede3SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
652027fcede3SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
652127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
652227fcede3SMatthew G. Knepley             }
652327fcede3SMatthew G. Knepley             for (r = 0; r < 12; ++r) {
652427fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
652527fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
652627fcede3SMatthew G. Knepley             }
652727fcede3SMatthew G. Knepley             for (r = 0; r < 6; ++r) {
652827fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
652927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
653027fcede3SMatthew G. Knepley             }
653127fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
653227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
653327fcede3SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
653427fcede3SMatthew G. Knepley             /* Hybrid cells add new cells, faces, and edges */
653527fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
653627fcede3SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
653727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
653827fcede3SMatthew G. Knepley             }
653927fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
654027fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
654127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
654227fcede3SMatthew G. Knepley             }
654327fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
654427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
654527fcede3SMatthew G. Knepley           }
654627fcede3SMatthew G. Knepley           break;
654775d3a19aSMatthew G. Knepley         default:
654875d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
654975d3a19aSMatthew G. Knepley         }
655075d3a19aSMatthew G. Knepley       }
655175d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
655275d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
655375d3a19aSMatthew G. Knepley     }
655475d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
655575d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
655675d3a19aSMatthew G. Knepley     if (0) {
655775d3a19aSMatthew G. Knepley       ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr);
655875d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
655975d3a19aSMatthew G. Knepley       ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
656075d3a19aSMatthew G. Knepley     }
656175d3a19aSMatthew G. Knepley   }
656275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
656375d3a19aSMatthew G. Knepley }
656475d3a19aSMatthew G. Knepley 
656575d3a19aSMatthew G. Knepley #undef __FUNCT__
6566509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexRefineUniform_Internal"
656775d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
6568509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
656975d3a19aSMatthew G. Knepley {
657075d3a19aSMatthew G. Knepley   DM             rdm;
657175d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
657275d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
657375d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
657475d3a19aSMatthew G. Knepley 
657575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
657675d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
657775d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
657875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
657975d3a19aSMatthew G. Knepley   ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr);
658075d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
658175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
6582785e854fSJed Brown   ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr);
658375d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
658475d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
658575d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
658675d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
658775d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
658875d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
658975d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
659075d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
659175d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
659275d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
659375d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
659475d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
659575d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
659675d3a19aSMatthew G. Knepley   /* Step 6: Set coordinates for vertices */
659775d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
659875d3a19aSMatthew G. Knepley   /* Step 7: Create pointSF */
659975d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
660075d3a19aSMatthew G. Knepley   /* Step 8: Create labels */
660175d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
660275d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
660375d3a19aSMatthew G. Knepley 
660475d3a19aSMatthew G. Knepley   *dmRefined = rdm;
660575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
660675d3a19aSMatthew G. Knepley }
660775d3a19aSMatthew G. Knepley 
660875d3a19aSMatthew G. Knepley #undef __FUNCT__
660975d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform"
661075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
661175d3a19aSMatthew G. Knepley {
661275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
661375d3a19aSMatthew G. Knepley 
661475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
661575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
661675d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
661775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
661875d3a19aSMatthew G. Knepley }
661975d3a19aSMatthew G. Knepley 
662075d3a19aSMatthew G. Knepley #undef __FUNCT__
662175d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform"
662275d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
662375d3a19aSMatthew G. Knepley {
662475d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
662575d3a19aSMatthew G. Knepley 
662675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
662775d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
662875d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
662975d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
663075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
663175d3a19aSMatthew G. Knepley }
663275d3a19aSMatthew G. Knepley 
663375d3a19aSMatthew G. Knepley #undef __FUNCT__
663475d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit"
663575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
663675d3a19aSMatthew G. Knepley {
663775d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
663875d3a19aSMatthew G. Knepley 
663975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
664075d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
664175d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
664275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
664375d3a19aSMatthew G. Knepley }
664475d3a19aSMatthew G. Knepley 
664575d3a19aSMatthew G. Knepley #undef __FUNCT__
664675d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit"
664775d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
664875d3a19aSMatthew G. Knepley {
664975d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
665075d3a19aSMatthew G. Knepley 
665175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
665275d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
665375d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
665475d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
665575d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
665675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
665775d3a19aSMatthew G. Knepley }
665875d3a19aSMatthew G. Knepley 
665975d3a19aSMatthew G. Knepley #undef __FUNCT__
6660509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Internal"
6661509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
666275d3a19aSMatthew G. Knepley {
66633478d7aaSMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax;
666475d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
666575d3a19aSMatthew G. Knepley 
666675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
666775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
66683478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
66693478d7aaSMatthew G. Knepley   if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);}
667075d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
667175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr);
667275d3a19aSMatthew G. Knepley   switch (dim) {
667375d3a19aSMatthew G. Knepley   case 2:
667475d3a19aSMatthew G. Knepley     switch (coneSize) {
667575d3a19aSMatthew G. Knepley     case 3:
667675d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 3; /* Hybrid */
667775d3a19aSMatthew G. Knepley       else *cellRefiner = 1; /* Triangular */
667875d3a19aSMatthew G. Knepley       break;
667975d3a19aSMatthew G. Knepley     case 4:
668075d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 4; /* Hybrid */
668175d3a19aSMatthew G. Knepley       else *cellRefiner = 2; /* Quadrilateral */
668275d3a19aSMatthew G. Knepley       break;
668375d3a19aSMatthew G. Knepley     default:
668475d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
668575d3a19aSMatthew G. Knepley     }
668675d3a19aSMatthew G. Knepley     break;
6687b5da9499SMatthew G. Knepley   case 3:
6688b5da9499SMatthew G. Knepley     switch (coneSize) {
6689b5da9499SMatthew G. Knepley     case 4:
6690b5da9499SMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 7; /* Hybrid */
6691b5da9499SMatthew G. Knepley       else *cellRefiner = 5; /* Tetrahedral */
6692b5da9499SMatthew G. Knepley       break;
66932eabf88fSMatthew G. Knepley     case 6:
66942eabf88fSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 8; /* Hybrid */
66952eabf88fSMatthew G. Knepley       else *cellRefiner = 6; /* hexahedral */
66962eabf88fSMatthew G. Knepley       break;
6697b5da9499SMatthew G. Knepley     default:
6698b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
6699b5da9499SMatthew G. Knepley     }
6700b5da9499SMatthew G. Knepley     break;
670175d3a19aSMatthew G. Knepley   default:
670275d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
670375d3a19aSMatthew G. Knepley   }
670475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
670575d3a19aSMatthew G. Knepley }
6706