xref: /petsc/src/dm/impls/plex/plexrefine.c (revision 27fcede3b58cccfda3b877b7444613fa5a07068e)
175d3a19aSMatthew G. Knepley #include <petsc-private/dmpleximpl.h>   /*I      "petscdmplex.h"   I*/
275d3a19aSMatthew G. Knepley #include <petscsf.h>
375d3a19aSMatthew G. Knepley 
475d3a19aSMatthew G. Knepley #undef __FUNCT__
575d3a19aSMatthew G. Knepley #define __FUNCT__ "GetDepthStart_Private"
675d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart)
775d3a19aSMatthew G. Knepley {
875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
975d3a19aSMatthew G. Knepley   if (cStart) *cStart = 0;
1075d3a19aSMatthew G. Knepley   if (vStart) *vStart = depthSize[depth];
1175d3a19aSMatthew G. Knepley   if (fStart) *fStart = depthSize[depth] + depthSize[0];
1275d3a19aSMatthew G. Knepley   if (eStart) *eStart = depthSize[depth] + depthSize[0] + depthSize[depth-1];
1375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
1475d3a19aSMatthew G. Knepley }
1575d3a19aSMatthew G. Knepley 
1675d3a19aSMatthew G. Knepley #undef __FUNCT__
1775d3a19aSMatthew G. Knepley #define __FUNCT__ "GetDepthEnd_Private"
1875d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd)
1975d3a19aSMatthew G. Knepley {
2075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
2175d3a19aSMatthew G. Knepley   if (cEnd) *cEnd = depthSize[depth];
2275d3a19aSMatthew G. Knepley   if (vEnd) *vEnd = depthSize[depth] + depthSize[0];
2375d3a19aSMatthew G. Knepley   if (fEnd) *fEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1];
2475d3a19aSMatthew G. Knepley   if (eEnd) *eEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1];
2575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
2675d3a19aSMatthew G. Knepley }
2775d3a19aSMatthew G. Knepley 
2875d3a19aSMatthew G. Knepley #undef __FUNCT__
2975d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerGetSizes"
3086150812SJed Brown static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[])
3175d3a19aSMatthew G. Knepley {
326ce3c06aSMatthew G. Knepley   PetscInt       cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
3375d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
3475d3a19aSMatthew G. Knepley 
3575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
3675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
3775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
3875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
3975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
4075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
4175d3a19aSMatthew G. Knepley   switch (refiner) {
423478d7aaSMatthew G. Knepley   case 0:
433478d7aaSMatthew G. Knepley     break;
4475d3a19aSMatthew G. Knepley   case 1:
4575d3a19aSMatthew G. Knepley     /* Simplicial 2D */
4675d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart;         /* Add a vertex on every face */
4775d3a19aSMatthew G. Knepley     depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */
4875d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                     /* Every cell split into 4 cells */
4975d3a19aSMatthew G. Knepley     break;
5075d3a19aSMatthew G. Knepley   case 3:
51d963de37SMatthew G. Knepley     /* Hybrid Simplicial 2D */
5275d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
5375d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
5475d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart;                                         /* Add a vertex on every face, but not hybrid faces */
5575d3a19aSMatthew G. Knepley     depthSize[1] = 2*(fMax - fStart) + 3*(cMax - cStart) + (fEnd - fMax) + (cEnd - cMax); /* Every interior face is split into 2 faces, 3 faces are added for each interior cell, and one in each hybrid cell */
5675d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax);                                   /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */
5775d3a19aSMatthew G. Knepley     break;
5875d3a19aSMatthew G. Knepley   case 2:
5975d3a19aSMatthew G. Knepley     /* Hex 2D */
6075d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + cEnd - cStart + fEnd - fStart; /* Add a vertex on every face and cell */
6175d3a19aSMatthew G. Knepley     depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart);         /* Every face is split into 2 faces and 4 faces are added for each cell */
6275d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                             /* Every cell split into 4 cells */
6375d3a19aSMatthew G. Knepley     break;
64b5da9499SMatthew G. Knepley   case 5:
65b5da9499SMatthew G. Knepley     /* Simplicial 3D */
66b5da9499SMatthew G. Knepley     depthSize[0] =    vEnd - vStart  +    eEnd - eStart;                    /* Add a vertex on every edge */
67b5da9499SMatthew G. Knepley     depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + (cEnd - cStart); /* Every edge is split into 2 edges, 3 edges are added for each face, and 1 edge for each cell */
68b5da9499SMatthew G. Knepley     depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart);                   /* Every face split into 4 faces and 8 faces are added for each cell */
69b5da9499SMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                       /* Every cell split into 8 cells */
70b5da9499SMatthew G. Knepley     break;
71b5da9499SMatthew G. Knepley   case 7:
72b5da9499SMatthew G. Knepley     /* Hybrid Simplicial 3D */
73b5da9499SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
746ce3c06aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
75b5da9499SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
76dae4404aSMatthew G. Knepley     /* Tetrahedra */
77dae4404aSMatthew G. Knepley     depthSize[0]  =    vEnd - vStart  +    eMax - eStart;                    /* Add a vertex on every interior edge */
78dae4404aSMatthew G. Knepley     depthSize[1]  = 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart); /* Every interior edge split into 2 edges, 3 edges added for each interior face, 1 edge for each interior cell */
79dae4404aSMatthew G. Knepley     depthSize[2]  = 4*(fMax - fStart) + 8*(cMax - cStart);                   /* Every interior face split into 4 faces, 8 faces added for each interior cell */
80dae4404aSMatthew G. Knepley     depthSize[3]  = 8*(cMax - cStart);                                       /* Every interior cell split into 8 cells */
81dae4404aSMatthew G. Knepley     /* Triangular Prisms */
82dae4404aSMatthew G. Knepley     depthSize[0] += 0;                                                       /* No hybrid vertices */
83dae4404aSMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax);                     /* Every hybrid edge remains, 1 edge for every hybrid face */
846ce3c06aSMatthew G. Knepley     depthSize[2] += 2*(fEnd - fMax)   + 3*(cEnd - cMax);                     /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */
85dae4404aSMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                         /* Every hybrid cell split into 4 cells */
86b5da9499SMatthew G. Knepley     break;
876ce3c06aSMatthew G. Knepley   case 6:
886ce3c06aSMatthew G. Knepley     /* Hex 3D */
896ce3c06aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
906ce3c06aSMatthew G. Knepley     depthSize[1] = 2*(eEnd - eStart) +  4*(fEnd - fStart) + 6*(cEnd - cStart);    /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */
916ce3c06aSMatthew G. Knepley     depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart);                        /* Every face is split into 4 faces, and 12 faces are added for each cell */
926ce3c06aSMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                             /* Every cell split into 8 cells */
936ce3c06aSMatthew G. Knepley     break;
94*27fcede3SMatthew G. Knepley   case 8:
95*27fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
96*27fcede3SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
97*27fcede3SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
98*27fcede3SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
99*27fcede3SMatthew G. Knepley     /* Hexahedra */
100*27fcede3SMatthew G. Knepley     depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
101*27fcede3SMatthew 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 */
102*27fcede3SMatthew 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 */
103*27fcede3SMatthew G. Knepley     depthSize[3] = 8*(cMax - cStart);                                             /* Every cell split into 8 cells */
104*27fcede3SMatthew G. Knepley     /* Quadrilateral Prisms */
105*27fcede3SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
106*27fcede3SMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax)   +   (cEnd - cMax);      /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
107*27fcede3SMatthew 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 */
108*27fcede3SMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                              /* Every hybrid cell split into 4 cells */
109*27fcede3SMatthew G. Knepley     break;
11075d3a19aSMatthew G. Knepley   default:
11175d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
11275d3a19aSMatthew G. Knepley   }
11375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
11475d3a19aSMatthew G. Knepley }
11575d3a19aSMatthew G. Knepley 
11642525629SMatthew G. Knepley /* Return triangle edge for orientation o, if it is r for o == 0 */
11742525629SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
118518a8359SMatthew G. Knepley   return (o < 0 ? 2-(o+r) : o+r)%3;
119518a8359SMatthew G. Knepley }
120de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
121de65f515SMatthew G. Knepley   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
122de65f515SMatthew G. Knepley }
123518a8359SMatthew G. Knepley 
124518a8359SMatthew G. Knepley /* Return triangle subface for orientation o, if it is r for o == 0 */
125518a8359SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
1264bae88c7SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%3;
12742525629SMatthew G. Knepley }
128de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
129de65f515SMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 3+s-o)%3;
130de65f515SMatthew G. Knepley }
13142525629SMatthew G. Knepley 
132431647a4SMatthew G. Knepley /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */
133431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) {
134431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+r) : o+r)%3;
135431647a4SMatthew G. Knepley }
136431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) {
137431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+s) : 3+s-o)%3;
138431647a4SMatthew G. Knepley }
139431647a4SMatthew G. Knepley 
14042525629SMatthew G. Knepley 
141e3f8b1d6SMatthew G. Knepley /* Return quad edge for orientation o, if it is r for o == 0 */
142e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
143e3f8b1d6SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%4;
144e3f8b1d6SMatthew G. Knepley }
145d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
146d6d937efSMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 4+s-o)%4;
147d6d937efSMatthew G. Knepley }
148e3f8b1d6SMatthew G. Knepley 
149e3f8b1d6SMatthew G. Knepley /* Return quad subface for orientation o, if it is r for o == 0 */
150e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
1514bae88c7SMatthew G. Knepley   return (o < 0 ? 4-(o+r) : o+r)%4;
15242525629SMatthew G. Knepley }
153d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
154d6d937efSMatthew G. Knepley   return (o < 0 ? 4-(o+s) : 4+s-o)%4;
155d6d937efSMatthew G. Knepley }
15642525629SMatthew G. Knepley 
15775d3a19aSMatthew G. Knepley #undef __FUNCT__
15875d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetConeSizes"
15986150812SJed Brown static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
16075d3a19aSMatthew G. Knepley {
161b5da9499SMatthew G. Knepley   PetscInt       depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r;
16275d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
16375d3a19aSMatthew G. Knepley 
16475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
16575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
16675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
16775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
16875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
16975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
17075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
1713478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
17275d3a19aSMatthew G. Knepley   switch (refiner) {
1733478d7aaSMatthew G. Knepley   case 0: break;
17475d3a19aSMatthew G. Knepley   case 1:
17575d3a19aSMatthew G. Knepley     /* Simplicial 2D */
17675d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
17775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
17875d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
17975d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
18075d3a19aSMatthew G. Knepley 
18175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
18275d3a19aSMatthew G. Knepley       }
18375d3a19aSMatthew G. Knepley     }
18475d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
18575d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
18675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
18775d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
18875d3a19aSMatthew G. Knepley         PetscInt       size;
18975d3a19aSMatthew G. Knepley 
19075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
19175d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
19275d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
19375d3a19aSMatthew G. Knepley       }
19475d3a19aSMatthew G. Knepley     }
19575d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
19675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
19775d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
19875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
19975d3a19aSMatthew G. Knepley 
20075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
20175d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
20275d3a19aSMatthew G. Knepley       }
20375d3a19aSMatthew G. Knepley     }
20475d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
20575d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
20675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
20775d3a19aSMatthew G. Knepley       PetscInt       size;
20875d3a19aSMatthew G. Knepley 
20975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
21075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
21175d3a19aSMatthew G. Knepley     }
21275d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
21375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
21475d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
21575d3a19aSMatthew G. Knepley       PetscInt       size;
21675d3a19aSMatthew G. Knepley 
21775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
21875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
21975d3a19aSMatthew G. Knepley     }
22075d3a19aSMatthew G. Knepley     break;
22175d3a19aSMatthew G. Knepley   case 2:
22275d3a19aSMatthew G. Knepley     /* Hex 2D */
22375d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
22475d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
22575d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
22675d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
22775d3a19aSMatthew G. Knepley 
22875d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
22975d3a19aSMatthew G. Knepley       }
23075d3a19aSMatthew G. Knepley     }
23175d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
23275d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
23375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
23475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
23575d3a19aSMatthew G. Knepley         PetscInt       size;
23675d3a19aSMatthew G. Knepley 
23775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
23875d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
23975d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
24075d3a19aSMatthew G. Knepley       }
24175d3a19aSMatthew G. Knepley     }
24275d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
24375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
24475d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
24575d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
24675d3a19aSMatthew G. Knepley 
24775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
24875d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
24975d3a19aSMatthew G. Knepley       }
25075d3a19aSMatthew G. Knepley     }
25175d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
25275d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
25375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
25475d3a19aSMatthew G. Knepley       PetscInt       size;
25575d3a19aSMatthew G. Knepley 
25675d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
25775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
25875d3a19aSMatthew G. Knepley     }
25975d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
26075d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
26175d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
26275d3a19aSMatthew G. Knepley       PetscInt       size;
26375d3a19aSMatthew G. Knepley 
26475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
26575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
26675d3a19aSMatthew G. Knepley     }
26775d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
26875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
26975d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
27075d3a19aSMatthew G. Knepley 
27175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
27275d3a19aSMatthew G. Knepley     }
27375d3a19aSMatthew G. Knepley     break;
27475d3a19aSMatthew G. Knepley   case 3:
275d963de37SMatthew G. Knepley     /* Hybrid Simplicial 2D */
27675d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
27775d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
27875d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
27975d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
28075d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
28175d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
28275d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
28375d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
28475d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
28575d3a19aSMatthew G. Knepley 
28675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
28775d3a19aSMatthew G. Knepley       }
28875d3a19aSMatthew G. Knepley     }
28975d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
29075d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
29175d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
29275d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
29375d3a19aSMatthew G. Knepley 
29475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
29575d3a19aSMatthew G. Knepley       }
29675d3a19aSMatthew G. Knepley     }
29775d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
29875d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
29975d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
30075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
30175d3a19aSMatthew G. Knepley         PetscInt       size;
30275d3a19aSMatthew G. Knepley 
30375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
30475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
30575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
30675d3a19aSMatthew G. Knepley       }
30775d3a19aSMatthew G. Knepley     }
30875d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
30975d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
31075d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
31175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
31275d3a19aSMatthew G. Knepley 
31375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
31475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
31575d3a19aSMatthew G. Knepley       }
31675d3a19aSMatthew G. Knepley     }
31775d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
31875d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
31975d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
32075d3a19aSMatthew G. Knepley       PetscInt       size;
32175d3a19aSMatthew G. Knepley 
32275d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
32375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
32475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
32575d3a19aSMatthew G. Knepley     }
32675d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
32775d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
32875d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
32975d3a19aSMatthew G. Knepley 
33075d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
33175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
33275d3a19aSMatthew G. Knepley     }
33375d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
33475d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
33575d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
33675d3a19aSMatthew G. Knepley       PetscInt       size;
33775d3a19aSMatthew G. Knepley 
33875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
33975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
34075d3a19aSMatthew G. Knepley     }
34175d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
34275d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
34375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
34475d3a19aSMatthew G. Knepley       const PetscInt *support;
34575d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
34675d3a19aSMatthew G. Knepley 
34775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
34875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
34975d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
35075d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
35175d3a19aSMatthew G. Knepley         else newSize += 2;
35275d3a19aSMatthew G. Knepley       }
35375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
35475d3a19aSMatthew G. Knepley     }
35575d3a19aSMatthew G. Knepley     break;
356b5da9499SMatthew G. Knepley   case 5:
357b5da9499SMatthew G. Knepley     /* Simplicial 3D */
358b5da9499SMatthew G. Knepley     /* All cells have 4 faces */
359b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
360b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
361dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
362b5da9499SMatthew G. Knepley 
363b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
364b5da9499SMatthew G. Knepley       }
365b5da9499SMatthew G. Knepley     }
366b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
367b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
368b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
369b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
370b5da9499SMatthew G. Knepley         PetscInt       size;
371b5da9499SMatthew G. Knepley 
372b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
373b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
374b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
375b5da9499SMatthew G. Knepley       }
376b5da9499SMatthew G. Knepley     }
3779ddff745SMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
378b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
379b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
380b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
381b5da9499SMatthew G. Knepley 
382b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
383b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
384b5da9499SMatthew G. Knepley       }
385b5da9499SMatthew G. Knepley     }
386b5da9499SMatthew G. Knepley     /* Split edges have 2 vertices and the same faces */
387b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
388b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
389b5da9499SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
390b5da9499SMatthew G. Knepley         PetscInt       size;
391b5da9499SMatthew G. Knepley 
392b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
393b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
394b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
395b5da9499SMatthew G. Knepley       }
396b5da9499SMatthew G. Knepley     }
397b5da9499SMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
398b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
399b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
400b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
401b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
402b5da9499SMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
403b5da9499SMatthew G. Knepley 
404b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
405b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
406b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
407b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
408b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
409b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
410b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
411b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
41286f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
4139ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
414b5da9499SMatthew G. Knepley           if (er == eint[c]) {
415b5da9499SMatthew G. Knepley             intFaces += 1;
416b5da9499SMatthew G. Knepley           } else {
417b5da9499SMatthew G. Knepley             intFaces += 2;
418b5da9499SMatthew G. Knepley           }
419b5da9499SMatthew G. Knepley         }
420b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
421b5da9499SMatthew G. Knepley       }
422b5da9499SMatthew G. Knepley     }
4239ddff745SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
424b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
425b5da9499SMatthew G. Knepley       const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
426b5da9499SMatthew G. Knepley 
427b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
428b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
429b5da9499SMatthew G. Knepley     }
430b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
431b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
432b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
433b5da9499SMatthew G. Knepley       PetscInt       size;
434b5da9499SMatthew G. Knepley 
435b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
436b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
437b5da9499SMatthew G. Knepley     }
438b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
439b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
440b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
441b5da9499SMatthew G. Knepley       PetscInt       size, *star = NULL, starSize, s, cellSize = 0;
442b5da9499SMatthew G. Knepley 
443b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
444b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
445b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
446b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
447b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
448b5da9499SMatthew G. Knepley 
449b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
450b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
451b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
452b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
453b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
45442525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
455b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
456b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
457b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
45842525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
45942525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
460b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
461b5da9499SMatthew G. Knepley         }
462b5da9499SMatthew G. Knepley       }
463b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
464b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr);
465b5da9499SMatthew G. Knepley     }
466b5da9499SMatthew G. Knepley     break;
467dae4404aSMatthew G. Knepley   case 7:
4686ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
4696ce3c06aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
4706ce3c06aSMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
471dae4404aSMatthew G. Knepley     /* Interior cells have 4 faces */
472dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
473dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
474dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
475dae4404aSMatthew G. Knepley 
476dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
477dae4404aSMatthew G. Knepley       }
478dae4404aSMatthew G. Knepley     }
479dae4404aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
480dae4404aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
481dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
482dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
483dae4404aSMatthew G. Knepley 
484dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr);
485dae4404aSMatthew G. Knepley       }
486dae4404aSMatthew G. Knepley     }
4876ce3c06aSMatthew G. Knepley     /* Interior split faces have 3 edges and the same cells as the parent */
488dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
489dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
490dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
491dae4404aSMatthew G. Knepley         PetscInt       size;
492dae4404aSMatthew G. Knepley 
493dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
494dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
495dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
496dae4404aSMatthew G. Knepley       }
497dae4404aSMatthew G. Knepley     }
498dae4404aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
499dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
500dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
501dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
502dae4404aSMatthew G. Knepley 
503dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
504dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
505dae4404aSMatthew G. Knepley       }
506dae4404aSMatthew G. Knepley     }
5076ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
5086ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
5096ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
5106ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
5116ce3c06aSMatthew G. Knepley         PetscInt       size;
5126ce3c06aSMatthew G. Knepley 
5136ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
5146ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
5156ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
5166ce3c06aSMatthew G. Knepley       }
5176ce3c06aSMatthew G. Knepley     }
5186ce3c06aSMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
5196ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
5206ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
5216ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
5226ce3c06aSMatthew G. Knepley 
5236ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
5246ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
5256ce3c06aSMatthew G. Knepley       }
5266ce3c06aSMatthew G. Knepley     }
5276ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces */
528dae4404aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
529dae4404aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
530dae4404aSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
531dae4404aSMatthew G. Knepley         PetscInt       size;
532dae4404aSMatthew G. Knepley 
533dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
534dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
535dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
536dae4404aSMatthew G. Knepley       }
537dae4404aSMatthew G. Knepley     }
5386ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
539dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
540dae4404aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
541dae4404aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
542dae4404aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
543dae4404aSMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
544dae4404aSMatthew G. Knepley 
545dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
546dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
547dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
548dae4404aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
549dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
550dae4404aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
551dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
552dae4404aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
5536ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
554dae4404aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
5559ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
556dae4404aSMatthew G. Knepley             if (er == eint[c]) {
557dae4404aSMatthew G. Knepley               intFaces += 1;
558dae4404aSMatthew G. Knepley             } else {
559dae4404aSMatthew G. Knepley               intFaces += 2;
560dae4404aSMatthew G. Knepley             }
5616ce3c06aSMatthew G. Knepley           } else {
5626ce3c06aSMatthew G. Knepley             intFaces += 1;
5636ce3c06aSMatthew G. Knepley           }
564dae4404aSMatthew G. Knepley         }
565dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
566dae4404aSMatthew G. Knepley       }
567dae4404aSMatthew G. Knepley     }
5686ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
569dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
570dae4404aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
571dae4404aSMatthew G. Knepley 
572dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
573dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
574dae4404aSMatthew G. Knepley     }
5756ce3c06aSMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
576dae4404aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
5776ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
5786ce3c06aSMatthew G. Knepley       PetscInt       size;
5796ce3c06aSMatthew G. Knepley 
5806ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
5816ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
5826ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
5836ce3c06aSMatthew G. Knepley     }
5846ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
5856ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
5866ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
587dae4404aSMatthew G. Knepley       PetscInt       size;
588dae4404aSMatthew G. Knepley 
589dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
590dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
5916ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr);
592dae4404aSMatthew G. Knepley     }
5936ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
594dae4404aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
595dae4404aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
596dae4404aSMatthew G. Knepley       PetscInt       size;
597dae4404aSMatthew G. Knepley 
598dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
599dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
600dae4404aSMatthew G. Knepley     }
6016ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
6026ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
6036ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
604dae4404aSMatthew G. Knepley       const PetscInt *support;
6056ce3c06aSMatthew G. Knepley       PetscInt        size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
606dae4404aSMatthew G. Knepley 
6076ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
6086ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
609dae4404aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
6106ce3c06aSMatthew G. Knepley         if (support[s] < fMax) faceSize += 2;
6116ce3c06aSMatthew G. Knepley         else                   faceSize += 1;
612dae4404aSMatthew G. Knepley       }
6136ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
6146ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
6156ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
6166ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
6176ce3c06aSMatthew G. Knepley 
6186ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
6196ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
6206ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
6216ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
6226ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
6236ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
6246ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
6256ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
6266ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
6276ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
6286ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
6296ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
6306ce3c06aSMatthew G. Knepley         }
6316ce3c06aSMatthew G. Knepley       }
6326ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
6336ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr);
634dae4404aSMatthew G. Knepley     }
635dae4404aSMatthew G. Knepley     break;
6362eabf88fSMatthew G. Knepley   case 6:
6372eabf88fSMatthew G. Knepley     /* Hex 3D */
6382eabf88fSMatthew G. Knepley     /* All cells have 6 faces */
6392eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6402eabf88fSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
6412eabf88fSMatthew G. Knepley         const PetscInt newp = (c - cStart)*8 + r;
6422eabf88fSMatthew G. Knepley 
6432eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
6442eabf88fSMatthew G. Knepley       }
6452eabf88fSMatthew G. Knepley     }
6462eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
6472eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
6482eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
6492eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
6502eabf88fSMatthew G. Knepley         PetscInt       size;
6512eabf88fSMatthew G. Knepley 
6522eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
6532eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
6542eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6552eabf88fSMatthew G. Knepley       }
6562eabf88fSMatthew G. Knepley     }
6572eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
6582eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6592eabf88fSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
6602eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
6612eabf88fSMatthew G. Knepley 
6622eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
6632eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
6642eabf88fSMatthew G. Knepley       }
6652eabf88fSMatthew G. Knepley     }
6662eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
6672eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
6682eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
6692eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
6702eabf88fSMatthew G. Knepley         PetscInt       size;
6712eabf88fSMatthew G. Knepley 
6722eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6732eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
6742eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
6752eabf88fSMatthew G. Knepley       }
6762eabf88fSMatthew G. Knepley     }
6772eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
6782eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
6792eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
6802eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
6812eabf88fSMatthew G. Knepley         PetscInt       size;
6822eabf88fSMatthew G. Knepley 
6832eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6842eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
6852eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
6862eabf88fSMatthew G. Knepley       }
6872eabf88fSMatthew G. Knepley     }
6882eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
6892eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
6902eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
6912eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
6922eabf88fSMatthew G. Knepley 
6932eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
6942eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
6952eabf88fSMatthew G. Knepley       }
6962eabf88fSMatthew G. Knepley     }
6972eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
6982eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
6992eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
7002eabf88fSMatthew G. Knepley       PetscInt       size;
7012eabf88fSMatthew G. Knepley 
7022eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
7032eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
7042eabf88fSMatthew G. Knepley     }
7052eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
7062eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
7072eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
7082eabf88fSMatthew G. Knepley       PetscInt       size;
7092eabf88fSMatthew G. Knepley 
7102eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
7112eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
7122eabf88fSMatthew G. Knepley     }
7132eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
7142eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
7152eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
7162eabf88fSMatthew G. Knepley       PetscInt       size;
7172eabf88fSMatthew G. Knepley 
7182eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
7192eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
7202eabf88fSMatthew G. Knepley     }
7212eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
7222eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
7232eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
7242eabf88fSMatthew G. Knepley 
7252eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
7262eabf88fSMatthew G. Knepley     }
7272eabf88fSMatthew G. Knepley     break;
728*27fcede3SMatthew G. Knepley   case 8:
729*27fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
730*27fcede3SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
731*27fcede3SMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
732*27fcede3SMatthew G. Knepley     /* Interior cells have 6 faces */
733*27fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
734*27fcede3SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
735*27fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
736*27fcede3SMatthew G. Knepley 
737*27fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
738*27fcede3SMatthew G. Knepley       }
739*27fcede3SMatthew G. Knepley     }
740*27fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces */
741*27fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
742*27fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
743*27fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
744*27fcede3SMatthew G. Knepley 
745*27fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
746*27fcede3SMatthew G. Knepley       }
747*27fcede3SMatthew G. Knepley     }
748*27fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
749*27fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
750*27fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
751*27fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
752*27fcede3SMatthew G. Knepley         PetscInt       size;
753*27fcede3SMatthew G. Knepley 
754*27fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
755*27fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
756*27fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
757*27fcede3SMatthew G. Knepley       }
758*27fcede3SMatthew G. Knepley     }
759*27fcede3SMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
760*27fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
761*27fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
762*27fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
763*27fcede3SMatthew G. Knepley 
764*27fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
765*27fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
766*27fcede3SMatthew G. Knepley       }
767*27fcede3SMatthew G. Knepley     }
768*27fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
769*27fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
770*27fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
771*27fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
772*27fcede3SMatthew G. Knepley         PetscInt       size;
773*27fcede3SMatthew G. Knepley 
774*27fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
775*27fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
776*27fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
777*27fcede3SMatthew G. Knepley       }
778*27fcede3SMatthew G. Knepley     }
779*27fcede3SMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
780*27fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
781*27fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
782*27fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
783*27fcede3SMatthew G. Knepley 
784*27fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
785*27fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
786*27fcede3SMatthew G. Knepley       }
787*27fcede3SMatthew G. Knepley     }
788*27fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
789*27fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
790*27fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
791*27fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
792*27fcede3SMatthew G. Knepley         PetscInt       size;
793*27fcede3SMatthew G. Knepley 
794*27fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
795*27fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
796*27fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
797*27fcede3SMatthew G. Knepley       }
798*27fcede3SMatthew G. Knepley     }
799*27fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
800*27fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
801*27fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
802*27fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
803*27fcede3SMatthew G. Knepley         PetscInt       size;
804*27fcede3SMatthew G. Knepley 
805*27fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
806*27fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
807*27fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
808*27fcede3SMatthew G. Knepley       }
809*27fcede3SMatthew G. Knepley     }
810*27fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
811*27fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
812*27fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
813*27fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
814*27fcede3SMatthew G. Knepley 
815*27fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
816*27fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
817*27fcede3SMatthew G. Knepley       }
818*27fcede3SMatthew G. Knepley     }
819*27fcede3SMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
820*27fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
821*27fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
822*27fcede3SMatthew G. Knepley       PetscInt       size;
823*27fcede3SMatthew G. Knepley 
824*27fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
825*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
826*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
827*27fcede3SMatthew G. Knepley     }
828*27fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
829*27fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
830*27fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
831*27fcede3SMatthew G. Knepley       PetscInt       size;
832*27fcede3SMatthew G. Knepley 
833*27fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
834*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
835*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
836*27fcede3SMatthew G. Knepley     }
837*27fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
838*27fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
839*27fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
840*27fcede3SMatthew G. Knepley 
841*27fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
842*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
843*27fcede3SMatthew G. Knepley     }
844*27fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
845*27fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
846*27fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
847*27fcede3SMatthew G. Knepley       PetscInt       size;
848*27fcede3SMatthew G. Knepley 
849*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
850*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
851*27fcede3SMatthew G. Knepley     }
852*27fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
853*27fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
854*27fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
855*27fcede3SMatthew G. Knepley       PetscInt       size;
856*27fcede3SMatthew G. Knepley 
857*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
858*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
859*27fcede3SMatthew G. Knepley     }
860*27fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
861*27fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
862*27fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
863*27fcede3SMatthew G. Knepley       PetscInt       size;
864*27fcede3SMatthew G. Knepley 
865*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
866*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
867*27fcede3SMatthew G. Knepley     }
868*27fcede3SMatthew G. Knepley     /* Interior cell vertices have 6 supports */
869*27fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
870*27fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
871*27fcede3SMatthew G. Knepley 
872*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
873*27fcede3SMatthew G. Knepley     }
874*27fcede3SMatthew G. Knepley     break;
87575d3a19aSMatthew G. Knepley   default:
87675d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
87775d3a19aSMatthew G. Knepley   }
87875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
87975d3a19aSMatthew G. Knepley }
88075d3a19aSMatthew G. Knepley 
88175d3a19aSMatthew G. Knepley #undef __FUNCT__
88275d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCones"
88386150812SJed Brown static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
88475d3a19aSMatthew G. Knepley {
885b5da9499SMatthew G. Knepley   const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
8866ce3c06aSMatthew G. Knepley   PetscInt        cStart,    cEnd,    cMax,    vStart,    vEnd, vMax, fStart,    fEnd,    fMax,    eStart,    eEnd,    eMax;
8876ce3c06aSMatthew G. Knepley   PetscInt        cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew,    fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
8886ce3c06aSMatthew G. Knepley   PetscInt        depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
88975d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
89075d3a19aSMatthew G. Knepley 
89175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
89275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
89375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
89475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
89575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
89675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
89775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
8983478d7aaSMatthew G. Knepley   if (refiner) {
89975d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
90075d3a19aSMatthew G. Knepley     ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
9013478d7aaSMatthew G. Knepley   }
90275d3a19aSMatthew G. Knepley   switch (refiner) {
9033478d7aaSMatthew G. Knepley   case 0: break;
90475d3a19aSMatthew G. Knepley   case 1:
90575d3a19aSMatthew G. Knepley     /* Simplicial 2D */
90675d3a19aSMatthew G. Knepley     /*
90775d3a19aSMatthew G. Knepley      2
90875d3a19aSMatthew G. Knepley      |\
90975d3a19aSMatthew G. Knepley      | \
91075d3a19aSMatthew G. Knepley      |  \
91175d3a19aSMatthew G. Knepley      |   \
91275d3a19aSMatthew G. Knepley      | C  \
91375d3a19aSMatthew G. Knepley      |     \
91475d3a19aSMatthew G. Knepley      |      \
91575d3a19aSMatthew G. Knepley      2---1---1
91675d3a19aSMatthew G. Knepley      |\  D  / \
91775d3a19aSMatthew G. Knepley      | 2   0   \
91875d3a19aSMatthew G. Knepley      |A \ /  B  \
91975d3a19aSMatthew G. Knepley      0---0-------1
92075d3a19aSMatthew G. Knepley      */
92175d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
92275d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
92375d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
92475d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
92575d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
92675d3a19aSMatthew G. Knepley 
92775d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
92875d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
92975d3a19aSMatthew G. Knepley       /* A triangle */
93075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
93175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
93275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
93375d3a19aSMatthew G. Knepley       orntNew[1] = -2;
93475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
93575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
93675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
93775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
93875d3a19aSMatthew G. Knepley #if 1
93975d3a19aSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
94075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
94175d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
94275d3a19aSMatthew G. Knepley       }
94375d3a19aSMatthew G. Knepley #endif
94475d3a19aSMatthew G. Knepley       /* B triangle */
94575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
94675d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
94775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
94875d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
94975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
95075d3a19aSMatthew G. Knepley       orntNew[2] = -2;
95175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
95275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
95375d3a19aSMatthew G. Knepley #if 1
95475d3a19aSMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
95575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
95675d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
95775d3a19aSMatthew G. Knepley       }
95875d3a19aSMatthew G. Knepley #endif
95975d3a19aSMatthew G. Knepley       /* C triangle */
96075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
96175d3a19aSMatthew G. Knepley       orntNew[0] = -2;
96275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
96375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
96475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
96575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
96675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
96775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
96875d3a19aSMatthew G. Knepley #if 1
96975d3a19aSMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
97075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
97175d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
97275d3a19aSMatthew G. Knepley       }
97375d3a19aSMatthew G. Knepley #endif
97475d3a19aSMatthew G. Knepley       /* D triangle */
97575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
97675d3a19aSMatthew G. Knepley       orntNew[0] = 0;
97775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
97875d3a19aSMatthew G. Knepley       orntNew[1] = 0;
97975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
98075d3a19aSMatthew G. Knepley       orntNew[2] = 0;
98175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
98275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
98375d3a19aSMatthew G. Knepley #if 1
98475d3a19aSMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
98575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
98675d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
98775d3a19aSMatthew G. Knepley       }
98875d3a19aSMatthew G. Knepley #endif
98975d3a19aSMatthew G. Knepley     }
99075d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
99175d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
992785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
99375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
99475d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
99575d3a19aSMatthew G. Knepley 
99675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
99775d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
998297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
99975d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
100075d3a19aSMatthew G. Knepley 
100175d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
100275d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
100375d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
100475d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
100575d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
100675d3a19aSMatthew G. Knepley #if 1
100775d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
100875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
100975d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
101075d3a19aSMatthew G. Knepley         }
101175d3a19aSMatthew G. Knepley #endif
101275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
101375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
101475d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
101575d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
101675d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1017297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
101875d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
101975d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
102075d3a19aSMatthew G. Knepley           }
1021297d2bf4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
102275d3a19aSMatthew G. Knepley         }
102375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
102475d3a19aSMatthew G. Knepley #if 1
102575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
102675d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
102775d3a19aSMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
102875d3a19aSMatthew G. Knepley         }
102975d3a19aSMatthew G. Knepley #endif
103075d3a19aSMatthew G. Knepley       }
103175d3a19aSMatthew G. Knepley     }
103275d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
103375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
103475d3a19aSMatthew G. Knepley       const PetscInt *cone;
103575d3a19aSMatthew G. Knepley 
103675d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
103775d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
103875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
103975d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
104075d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
104175d3a19aSMatthew G. Knepley 
104275d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
104375d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
104475d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
104575d3a19aSMatthew G. Knepley #if 1
104675d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
104775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
104875d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
104975d3a19aSMatthew G. Knepley         }
105075d3a19aSMatthew G. Knepley #endif
105175d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
105275d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
105375d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
105475d3a19aSMatthew G. Knepley #if 1
105575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
105675d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
105775d3a19aSMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
105875d3a19aSMatthew G. Knepley         }
105975d3a19aSMatthew G. Knepley #endif
106075d3a19aSMatthew G. Knepley       }
106175d3a19aSMatthew G. Knepley     }
106275d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
106375d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
106475d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
106575d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
106675d3a19aSMatthew G. Knepley       PetscInt        size, s;
106775d3a19aSMatthew G. Knepley 
106875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
106975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
107075d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
107175d3a19aSMatthew G. Knepley         PetscInt r = 0;
107275d3a19aSMatthew G. Knepley 
107375d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
107475d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
107575d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
107675d3a19aSMatthew G. Knepley       }
107775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
107875d3a19aSMatthew G. Knepley #if 1
107975d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
108075d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
108175d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
108275d3a19aSMatthew G. Knepley       }
108375d3a19aSMatthew G. Knepley #endif
108475d3a19aSMatthew G. Knepley     }
108575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
108675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
108775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
108875d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
108975d3a19aSMatthew G. Knepley       PetscInt        size, s;
109075d3a19aSMatthew G. Knepley 
109175d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
109275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
109375d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
109475d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
109575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
109675d3a19aSMatthew G. Knepley         PetscInt r = 0;
109775d3a19aSMatthew G. Knepley 
109875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
109975d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
110075d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
110175d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
110275d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
110375d3a19aSMatthew G. Knepley       }
110475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
110575d3a19aSMatthew G. Knepley #if 1
110675d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
110775d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
110875d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
110975d3a19aSMatthew G. Knepley       }
111075d3a19aSMatthew G. Knepley #endif
111175d3a19aSMatthew G. Knepley     }
111275d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
111375d3a19aSMatthew G. Knepley     break;
111475d3a19aSMatthew G. Knepley   case 2:
111575d3a19aSMatthew G. Knepley     /* Hex 2D */
111675d3a19aSMatthew G. Knepley     /*
111775d3a19aSMatthew G. Knepley      3---------2---------2
111875d3a19aSMatthew G. Knepley      |         |         |
111975d3a19aSMatthew G. Knepley      |    D    2    C    |
112075d3a19aSMatthew G. Knepley      |         |         |
112175d3a19aSMatthew G. Knepley      3----3----0----1----1
112275d3a19aSMatthew G. Knepley      |         |         |
112375d3a19aSMatthew G. Knepley      |    A    0    B    |
112475d3a19aSMatthew G. Knepley      |         |         |
112575d3a19aSMatthew G. Knepley      0---------0---------1
112675d3a19aSMatthew G. Knepley      */
112775d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
112875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
112975d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
113075d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
113175d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
113275d3a19aSMatthew G. Knepley 
113375d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
113475d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
113575d3a19aSMatthew G. Knepley       /* A quad */
113675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
113775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
113875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
113975d3a19aSMatthew G. Knepley       orntNew[1] = 0;
114075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
114175d3a19aSMatthew G. Knepley       orntNew[2] = -2;
114275d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
114375d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
114475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
114575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
114675d3a19aSMatthew G. Knepley #if 1
114775d3a19aSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
114875d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
114975d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
115075d3a19aSMatthew G. Knepley       }
115175d3a19aSMatthew G. Knepley #endif
115275d3a19aSMatthew G. Knepley       /* B quad */
115375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
115475d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
115575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
115675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
115775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
115875d3a19aSMatthew G. Knepley       orntNew[2] = 0;
115975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
116075d3a19aSMatthew G. Knepley       orntNew[3] = -2;
116175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
116275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
116375d3a19aSMatthew G. Knepley #if 1
116475d3a19aSMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
116575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
116675d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
116775d3a19aSMatthew G. Knepley       }
116875d3a19aSMatthew G. Knepley #endif
116975d3a19aSMatthew G. Knepley       /* C quad */
117075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
117175d3a19aSMatthew G. Knepley       orntNew[0] = -2;
117275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
117375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
117475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
117575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
117675d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
117775d3a19aSMatthew G. Knepley       orntNew[3] = 0;
117875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
117975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
118075d3a19aSMatthew G. Knepley #if 1
118175d3a19aSMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew);
118275d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
118375d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
118475d3a19aSMatthew G. Knepley       }
118575d3a19aSMatthew G. Knepley #endif
118675d3a19aSMatthew G. Knepley       /* D quad */
118775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
118875d3a19aSMatthew G. Knepley       orntNew[0] = 0;
118975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
119075d3a19aSMatthew G. Knepley       orntNew[1] = -2;
119175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
119275d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
119375d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
119475d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
119575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
119675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
119775d3a19aSMatthew G. Knepley #if 1
119875d3a19aSMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
119975d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
120075d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
120175d3a19aSMatthew G. Knepley       }
120275d3a19aSMatthew G. Knepley #endif
120375d3a19aSMatthew G. Knepley     }
120475d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
120575d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1206785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
120775d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
120875d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
120975d3a19aSMatthew G. Knepley 
121075d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
121175d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1212455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
121375d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
121475d3a19aSMatthew G. Knepley 
121575d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
121675d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
121775d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
121875d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
121975d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
122075d3a19aSMatthew G. Knepley #if 1
122175d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
122275d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
122375d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
122475d3a19aSMatthew G. Knepley         }
122575d3a19aSMatthew G. Knepley #endif
122675d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
122775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
122875d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
122975d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
123075d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1231455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
123275d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
123375d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
123475d3a19aSMatthew G. Knepley           }
1235455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
123675d3a19aSMatthew G. Knepley         }
123775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
123875d3a19aSMatthew G. Knepley #if 1
123975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
124075d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
124175d3a19aSMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
124275d3a19aSMatthew G. Knepley         }
124375d3a19aSMatthew G. Knepley #endif
124475d3a19aSMatthew G. Knepley       }
124575d3a19aSMatthew G. Knepley     }
124675d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
124775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
124875d3a19aSMatthew G. Knepley       const PetscInt *cone;
124975d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
125075d3a19aSMatthew G. Knepley 
125175d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
125275d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
125375d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
125475d3a19aSMatthew G. Knepley 
125575d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
125675d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
125775d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
125875d3a19aSMatthew G. Knepley #if 1
125975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
126075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
126175d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
126275d3a19aSMatthew G. Knepley         }
126375d3a19aSMatthew G. Knepley #endif
126475d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
126575d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
126675d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
126775d3a19aSMatthew G. Knepley #if 1
126875d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
126975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
127075d3a19aSMatthew G. Knepley           if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew);
127175d3a19aSMatthew G. Knepley         }
127275d3a19aSMatthew G. Knepley #endif
127375d3a19aSMatthew G. Knepley       }
127475d3a19aSMatthew G. Knepley     }
127575d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
127675d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
127775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
127875d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
127975d3a19aSMatthew G. Knepley       PetscInt        size, s;
128075d3a19aSMatthew G. Knepley 
128175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
128275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
128375d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
128475d3a19aSMatthew G. Knepley         PetscInt r = 0;
128575d3a19aSMatthew G. Knepley 
128675d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
128775d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
128875d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
128975d3a19aSMatthew G. Knepley       }
129075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
129175d3a19aSMatthew G. Knepley #if 1
129275d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
129375d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
129475d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
129575d3a19aSMatthew G. Knepley       }
129675d3a19aSMatthew G. Knepley #endif
129775d3a19aSMatthew G. Knepley     }
129875d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
129975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
130075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
130175d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
130275d3a19aSMatthew G. Knepley       PetscInt        size, s;
130375d3a19aSMatthew G. Knepley 
130475d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
130575d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
130675d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
130775d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
130875d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
130975d3a19aSMatthew G. Knepley         PetscInt r = 0;
131075d3a19aSMatthew G. Knepley 
131175d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
131275d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
131375d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
131475d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
131575d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
131675d3a19aSMatthew G. Knepley       }
131775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
131875d3a19aSMatthew G. Knepley #if 1
131975d3a19aSMatthew G. Knepley       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
132075d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
132175d3a19aSMatthew G. Knepley         if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew);
132275d3a19aSMatthew G. Knepley       }
132375d3a19aSMatthew G. Knepley #endif
132475d3a19aSMatthew G. Knepley     }
132575d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
132675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
132775d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
132875d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
132975d3a19aSMatthew G. Knepley 
133075d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
133175d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
133275d3a19aSMatthew G. Knepley       }
133375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
133475d3a19aSMatthew G. Knepley     }
1335da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
133675d3a19aSMatthew G. Knepley     break;
133775d3a19aSMatthew G. Knepley   case 3:
133875d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
133975d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
134075d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
134175d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
134275d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
134375d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
134475d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
134575d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
134675d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
134775d3a19aSMatthew G. Knepley 
134875d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
134975d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
135075d3a19aSMatthew G. Knepley       /* A triangle */
135175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
135275d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
135375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
135475d3a19aSMatthew G. Knepley       orntNew[1] = -2;
135575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
135675d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
135775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
135875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
135975d3a19aSMatthew G. Knepley #if 1
136075d3a19aSMatthew 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);
136175d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
136275d3a19aSMatthew 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);
136375d3a19aSMatthew G. Knepley       }
136475d3a19aSMatthew G. Knepley #endif
136575d3a19aSMatthew G. Knepley       /* B triangle */
136675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
136775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
136875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
136975d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
137075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
137175d3a19aSMatthew G. Knepley       orntNew[2] = -2;
137275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
137375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
137475d3a19aSMatthew G. Knepley #if 1
137575d3a19aSMatthew 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);
137675d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
137775d3a19aSMatthew 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);
137875d3a19aSMatthew G. Knepley       }
137975d3a19aSMatthew G. Knepley #endif
138075d3a19aSMatthew G. Knepley       /* C triangle */
138175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
138275d3a19aSMatthew G. Knepley       orntNew[0] = -2;
138375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
138475d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
138575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
138675d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
138775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
138875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
138975d3a19aSMatthew G. Knepley #if 1
139075d3a19aSMatthew 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);
139175d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
139275d3a19aSMatthew 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);
139375d3a19aSMatthew G. Knepley       }
139475d3a19aSMatthew G. Knepley #endif
139575d3a19aSMatthew G. Knepley       /* D triangle */
139675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
139775d3a19aSMatthew G. Knepley       orntNew[0] = 0;
139875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
139975d3a19aSMatthew G. Knepley       orntNew[1] = 0;
140075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
140175d3a19aSMatthew G. Knepley       orntNew[2] = 0;
140275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
140375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
140475d3a19aSMatthew G. Knepley #if 1
140575d3a19aSMatthew 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);
140675d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
140775d3a19aSMatthew 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);
140875d3a19aSMatthew G. Knepley       }
140975d3a19aSMatthew G. Knepley #endif
141075d3a19aSMatthew G. Knepley     }
141175d3a19aSMatthew G. Knepley     /*
141275d3a19aSMatthew G. Knepley      2----3----3
141375d3a19aSMatthew G. Knepley      |         |
141475d3a19aSMatthew G. Knepley      |    B    |
141575d3a19aSMatthew G. Knepley      |         |
141675d3a19aSMatthew G. Knepley      0----4--- 1
141775d3a19aSMatthew G. Knepley      |         |
141875d3a19aSMatthew G. Knepley      |    A    |
141975d3a19aSMatthew G. Knepley      |         |
142075d3a19aSMatthew G. Knepley      0----2----1
142175d3a19aSMatthew G. Knepley      */
142275d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
142375d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
142475d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
142575d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
142675d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
142775d3a19aSMatthew G. Knepley 
142875d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
142975d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
143075d3a19aSMatthew G. Knepley       /* A quad */
143175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
143275d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
143375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
143475d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
143575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2] - fMax);
143675d3a19aSMatthew G. Knepley       orntNew[2] = 0;
143775d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
143875d3a19aSMatthew G. Knepley       orntNew[3] = 0;
143975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
144075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
144175d3a19aSMatthew G. Knepley #if 1
144275d3a19aSMatthew 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);
144375d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
144475d3a19aSMatthew 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);
144575d3a19aSMatthew G. Knepley       }
144675d3a19aSMatthew G. Knepley #endif
144775d3a19aSMatthew G. Knepley       /* B quad */
144875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
144975d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
145075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
145175d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
145275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
145375d3a19aSMatthew G. Knepley       orntNew[2] = 0;
145475d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3] - fMax);
145575d3a19aSMatthew G. Knepley       orntNew[3] = 0;
145675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
145775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
145875d3a19aSMatthew G. Knepley #if 1
145975d3a19aSMatthew 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);
146075d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
146175d3a19aSMatthew 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);
146275d3a19aSMatthew G. Knepley       }
146375d3a19aSMatthew G. Knepley #endif
146475d3a19aSMatthew G. Knepley     }
146575d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
146675d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1467785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
146875d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
146975d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
147075d3a19aSMatthew G. Knepley 
147175d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
147275d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1473297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
147475d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
147575d3a19aSMatthew G. Knepley 
147675d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
147775d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
147875d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
147975d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
148075d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
148175d3a19aSMatthew G. Knepley #if 1
148275d3a19aSMatthew 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);
148375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
148475d3a19aSMatthew 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);
148575d3a19aSMatthew G. Knepley         }
148675d3a19aSMatthew G. Knepley #endif
148775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
148875d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
148975d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
149075d3a19aSMatthew G. Knepley           if (support[s] >= cMax) {
149175d3a19aSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
149275d3a19aSMatthew G. Knepley           } else {
149375d3a19aSMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
149475d3a19aSMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1495297d2bf4SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
149675d3a19aSMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
149775d3a19aSMatthew G. Knepley               if (cone[c] == f) break;
149875d3a19aSMatthew G. Knepley             }
1499297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
150075d3a19aSMatthew G. Knepley           }
150175d3a19aSMatthew G. Knepley         }
150275d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
150375d3a19aSMatthew G. Knepley #if 1
150475d3a19aSMatthew 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);
150575d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
150675d3a19aSMatthew 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);
150775d3a19aSMatthew G. Knepley         }
150875d3a19aSMatthew G. Knepley #endif
150975d3a19aSMatthew G. Knepley       }
151075d3a19aSMatthew G. Knepley     }
151175d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
151275d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
151375d3a19aSMatthew G. Knepley       const PetscInt *cone;
151475d3a19aSMatthew G. Knepley 
151575d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
151675d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
151775d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
151875d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
151975d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
152075d3a19aSMatthew G. Knepley 
152175d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
152275d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
152375d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
152475d3a19aSMatthew G. Knepley #if 1
152575d3a19aSMatthew 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);
152675d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
152775d3a19aSMatthew 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);
152875d3a19aSMatthew G. Knepley         }
152975d3a19aSMatthew G. Knepley #endif
153075d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
153175d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
153275d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
153375d3a19aSMatthew G. Knepley #if 1
153475d3a19aSMatthew 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);
153575d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
153675d3a19aSMatthew 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);
153775d3a19aSMatthew G. Knepley         }
153875d3a19aSMatthew G. Knepley #endif
153975d3a19aSMatthew G. Knepley       }
154075d3a19aSMatthew G. Knepley     }
154175d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
154275d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
154375d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
154475d3a19aSMatthew G. Knepley       const PetscInt *cone;
154575d3a19aSMatthew G. Knepley       const PetscInt *support;
154675d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
154775d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
154875d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
154975d3a19aSMatthew G. Knepley 
155075d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
155175d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
155275d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
155375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
155475d3a19aSMatthew G. Knepley #if 1
155575d3a19aSMatthew 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);
155675d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
155775d3a19aSMatthew 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);
155875d3a19aSMatthew G. Knepley       }
155975d3a19aSMatthew G. Knepley #endif
156075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
156175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
156275d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
156375d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
156475d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
156575d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
156675d3a19aSMatthew G. Knepley         }
156775d3a19aSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
156875d3a19aSMatthew G. Knepley       }
156975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
157075d3a19aSMatthew G. Knepley #if 1
157175d3a19aSMatthew 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);
157275d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
157375d3a19aSMatthew 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);
157475d3a19aSMatthew G. Knepley       }
157575d3a19aSMatthew G. Knepley #endif
157675d3a19aSMatthew G. Knepley     }
157775d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
157875d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
157975d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
158075d3a19aSMatthew G. Knepley       const PetscInt *cone;
158175d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
158275d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
158375d3a19aSMatthew G. Knepley 
158475d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
158575d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
158675d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
158775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
158875d3a19aSMatthew G. Knepley #if 1
158975d3a19aSMatthew 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);
159075d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
159175d3a19aSMatthew 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);
159275d3a19aSMatthew G. Knepley       }
159375d3a19aSMatthew G. Knepley #endif
159475d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
159575d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
159675d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);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 < 2; ++p) {
160075d3a19aSMatthew 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);
160175d3a19aSMatthew G. Knepley       }
160275d3a19aSMatthew G. Knepley #endif
160375d3a19aSMatthew G. Knepley     }
160475d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
160575d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
160675d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
160775d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
160875d3a19aSMatthew G. Knepley       PetscInt        size, s;
160975d3a19aSMatthew G. Knepley 
161075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
161175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
161275d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
161375d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
161475d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
161575d3a19aSMatthew G. Knepley         } else {
161675d3a19aSMatthew G. Knepley           PetscInt r = 0;
161775d3a19aSMatthew G. Knepley 
161875d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
161975d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
162075d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
162175d3a19aSMatthew G. Knepley         }
162275d3a19aSMatthew G. Knepley       }
162375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
162475d3a19aSMatthew G. Knepley #if 1
162575d3a19aSMatthew 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);
162675d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
162775d3a19aSMatthew 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);
162875d3a19aSMatthew G. Knepley       }
162975d3a19aSMatthew G. Knepley #endif
163075d3a19aSMatthew G. Knepley     }
163175d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
163275d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
163375d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
163475d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
163575d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
163675d3a19aSMatthew G. Knepley 
163775d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
163875d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
163975d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
164075d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
164175d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
164275d3a19aSMatthew G. Knepley         PetscInt r = 0;
164375d3a19aSMatthew G. Knepley 
164475d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
164575d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
164675d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
164775d3a19aSMatthew G. Knepley 
164875d3a19aSMatthew G. Knepley           newSize += 1;
164975d3a19aSMatthew G. Knepley         } else {
165075d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
165175d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
165275d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
165375d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
165475d3a19aSMatthew G. Knepley 
165575d3a19aSMatthew G. Knepley           newSize += 2;
165675d3a19aSMatthew G. Knepley         }
165775d3a19aSMatthew G. Knepley       }
165875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
165975d3a19aSMatthew G. Knepley #if 1
166075d3a19aSMatthew 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);
166175d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
166275d3a19aSMatthew 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);
166375d3a19aSMatthew G. Knepley       }
166475d3a19aSMatthew G. Knepley #endif
166575d3a19aSMatthew G. Knepley     }
166675d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
166775d3a19aSMatthew G. Knepley     break;
1668b5da9499SMatthew G. Knepley   case 5:
1669b5da9499SMatthew G. Knepley     /* Simplicial 3D */
1670b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
1671b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
1672b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
1673b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
1674b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
1675b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1676b5da9499SMatthew G. Knepley 
1677b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1678b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1679b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
1680518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
1681b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1682518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
1683b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1684518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
1685b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1686b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
1687b5da9499SMatthew G. Knepley       orntNew[3] = 0;
1688b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1689b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1690b5da9499SMatthew G. Knepley #if 1
1691b5da9499SMatthew 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);
1692b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1693b5da9499SMatthew 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);
1694b5da9499SMatthew G. Knepley       }
1695b5da9499SMatthew G. Knepley #endif
1696b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
1697518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
1698b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1699518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
1700b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1701b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
1702b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1703518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
1704b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1705b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1706b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1707b5da9499SMatthew G. Knepley #if 1
1708b5da9499SMatthew 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);
1709b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1710b5da9499SMatthew 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);
1711b5da9499SMatthew G. Knepley       }
1712b5da9499SMatthew G. Knepley #endif
1713b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
1714518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
1715b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1716b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
1717b5da9499SMatthew G. Knepley       orntNew[1] = 0;
1718518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
1719b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1720518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
1721b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1722b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1723b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1724b5da9499SMatthew G. Knepley #if 1
1725b5da9499SMatthew 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);
1726b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1727b5da9499SMatthew 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);
1728b5da9499SMatthew G. Knepley       }
1729b5da9499SMatthew G. Knepley #endif
1730b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
1731b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
1732b5da9499SMatthew G. Knepley       orntNew[0] = 0;
1733518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
1734b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1735518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
1736b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1737518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
1738b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
1739b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1740b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1741b5da9499SMatthew G. Knepley #if 1
1742b5da9499SMatthew 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);
1743b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1744b5da9499SMatthew 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);
1745b5da9499SMatthew G. Knepley       }
1746b5da9499SMatthew G. Knepley #endif
1747b5da9499SMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
1748b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
1749b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1750fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
1751db2c6090SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
1752fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
1753fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
1754fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
1755fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
1756b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
1757b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
1758b5da9499SMatthew G. Knepley #if 1
1759b5da9499SMatthew 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);
1760b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1761b5da9499SMatthew 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);
1762b5da9499SMatthew G. Knepley       }
1763b5da9499SMatthew G. Knepley #endif
1764b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
1765b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
1766b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1767fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
1768fac4ab25SMatthew G. Knepley       orntNew[1] = 1;
1769fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
1770b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1771fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
1772db2c6090SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
1773b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
1774b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
1775b5da9499SMatthew G. Knepley #if 1
1776b5da9499SMatthew 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);
1777b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1778b5da9499SMatthew 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);
1779b5da9499SMatthew G. Knepley       }
1780b5da9499SMatthew G. Knepley #endif
1781b5da9499SMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
1782b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
1783b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1784fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
1785db2c6090SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
1786fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
1787fac4ab25SMatthew G. Knepley       orntNew[2] = -3;
1788fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
1789fac4ab25SMatthew G. Knepley       orntNew[3] = -2;
1790b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
1791b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
1792b5da9499SMatthew G. Knepley #if 1
1793b5da9499SMatthew 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);
1794b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1795b5da9499SMatthew 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);
1796b5da9499SMatthew G. Knepley       }
1797b5da9499SMatthew G. Knepley #endif
1798b5da9499SMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
1799b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
1800b5da9499SMatthew G. Knepley       orntNew[0] = -3;
1801fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
1802b5da9499SMatthew G. Knepley       orntNew[1] = -3;
1803fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
1804db2c6090SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
1805fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
1806fac4ab25SMatthew G. Knepley       orntNew[3] = -3;
1807b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
1808b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
1809b5da9499SMatthew G. Knepley #if 1
1810b5da9499SMatthew 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);
1811b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1812b5da9499SMatthew 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);
1813b5da9499SMatthew G. Knepley       }
1814b5da9499SMatthew G. Knepley #endif
1815b5da9499SMatthew G. Knepley     }
1816b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
1817b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1818785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
1819b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
1820b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
1821b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
1822b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
1823b5da9499SMatthew G. Knepley 
1824b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
1825b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
1826b5da9499SMatthew G. Knepley       /* A triangle */
1827b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
1828b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1829b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
1830b5da9499SMatthew G. Knepley       orntNew[1] = -2;
1831b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
1832b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1833b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1834b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1835b5da9499SMatthew G. Knepley #if 1
1836b5da9499SMatthew 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);
1837b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1838b5da9499SMatthew 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);
1839b5da9499SMatthew G. Knepley       }
1840b5da9499SMatthew G. Knepley #endif
1841b5da9499SMatthew G. Knepley       /* B triangle */
1842b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
1843b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
1844b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
1845b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1846b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
1847b5da9499SMatthew G. Knepley       orntNew[2] = -2;
1848b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1849b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1850b5da9499SMatthew G. Knepley #if 1
1851b5da9499SMatthew 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);
1852b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1853b5da9499SMatthew 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);
1854b5da9499SMatthew G. Knepley       }
1855b5da9499SMatthew G. Knepley #endif
1856b5da9499SMatthew G. Knepley       /* C triangle */
1857b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
1858b5da9499SMatthew G. Knepley       orntNew[0] = -2;
1859b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
1860b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
1861b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
1862b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
1863b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1864b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1865b5da9499SMatthew G. Knepley #if 1
1866b5da9499SMatthew 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);
1867b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1868b5da9499SMatthew 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);
1869b5da9499SMatthew G. Knepley       }
1870b5da9499SMatthew G. Knepley #endif
1871b5da9499SMatthew G. Knepley       /* D triangle */
1872b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
1873b5da9499SMatthew G. Knepley       orntNew[0] = 0;
1874b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
1875b5da9499SMatthew G. Knepley       orntNew[1] = 0;
1876b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
1877b5da9499SMatthew G. Knepley       orntNew[2] = 0;
1878b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1879b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1880b5da9499SMatthew G. Knepley #if 1
1881b5da9499SMatthew 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);
1882b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1883b5da9499SMatthew 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);
1884b5da9499SMatthew G. Knepley       }
1885b5da9499SMatthew G. Knepley #endif
1886b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
1887b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
1888b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
1889b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
1890219f7b90SMatthew G. Knepley           PetscInt subf;
1891b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
1892b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1893b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1894b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
1895b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
1896b5da9499SMatthew G. Knepley           }
1897219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
1898219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
1899b5da9499SMatthew G. Knepley         }
1900b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
1901b5da9499SMatthew G. Knepley #if 1
19029ddff745SMatthew 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);
1903b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
1904b5da9499SMatthew 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);
1905b5da9499SMatthew G. Knepley         }
1906b5da9499SMatthew G. Knepley #endif
1907b5da9499SMatthew G. Knepley       }
1908b5da9499SMatthew G. Knepley     }
1909b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
1910b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
1911b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
1912b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
1913b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
1914b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
1915b5da9499SMatthew G. Knepley 
1916b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1917b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1918b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
19194bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
1920b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
19214bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
1922b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
19234bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
1924b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
1925b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1926b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1927b5da9499SMatthew G. Knepley #if 1
1928b5da9499SMatthew 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);
1929b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1930b5da9499SMatthew 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);
1931b5da9499SMatthew G. Knepley       }
1932b5da9499SMatthew G. Knepley #endif
1933b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
1934b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
1935b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1936b5da9499SMatthew G. Knepley #if 1
1937b5da9499SMatthew 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);
1938b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1939b5da9499SMatthew 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);
1940b5da9499SMatthew G. Knepley       }
1941b5da9499SMatthew G. Knepley #endif
1942b5da9499SMatthew G. Knepley       ++newp;
1943b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
19444bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
1945b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
19464bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
1947b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
19484bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
1949b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
1950b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1951b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1952b5da9499SMatthew G. Knepley #if 1
19534bb260e2SMatthew 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);
1954b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1955b5da9499SMatthew 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);
1956b5da9499SMatthew G. Knepley       }
1957b5da9499SMatthew G. Knepley #endif
1958b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
1959b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
1960b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1961b5da9499SMatthew G. Knepley #if 1
1962b5da9499SMatthew 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);
1963b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1964b5da9499SMatthew 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);
1965b5da9499SMatthew G. Knepley       }
1966b5da9499SMatthew G. Knepley #endif
1967b5da9499SMatthew G. Knepley       ++newp;
1968b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
19694bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
1970b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
19714bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
1972b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
19734bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
1974b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
1975b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
1976b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
1977b5da9499SMatthew G. Knepley #if 1
1978b5da9499SMatthew 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);
1979b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1980b5da9499SMatthew 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);
1981b5da9499SMatthew G. Knepley       }
1982b5da9499SMatthew G. Knepley #endif
1983b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
1984b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
1985b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
1986b5da9499SMatthew G. Knepley #if 1
1987b5da9499SMatthew 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);
1988b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
1989b5da9499SMatthew 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);
1990b5da9499SMatthew G. Knepley       }
1991b5da9499SMatthew G. Knepley #endif
1992b5da9499SMatthew G. Knepley       ++newp;
1993b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
19944bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
1995b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
19964bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
1997b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
19984bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
1999b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2000b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2001b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2002b5da9499SMatthew G. Knepley #if 1
2003b5da9499SMatthew 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);
2004b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2005b5da9499SMatthew 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);
2006b5da9499SMatthew G. Knepley       }
2007b5da9499SMatthew G. Knepley #endif
2008b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
2009b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2010b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2011b5da9499SMatthew G. Knepley #if 1
2012b5da9499SMatthew 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);
2013b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2014b5da9499SMatthew 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);
2015b5da9499SMatthew G. Knepley       }
2016b5da9499SMatthew G. Knepley #endif
2017b5da9499SMatthew G. Knepley       ++newp;
2018b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
20194bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2020b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
2021b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
20224bb260e2SMatthew G. Knepley       orntNew[1] = -2;
20234bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2024b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2025b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2026b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2027b5da9499SMatthew G. Knepley #if 1
2028b5da9499SMatthew 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);
2029b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2030b5da9499SMatthew 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);
2031b5da9499SMatthew G. Knepley       }
2032b5da9499SMatthew G. Knepley #endif
2033b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2034b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2035b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2036b5da9499SMatthew G. Knepley #if 1
2037b5da9499SMatthew 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);
2038b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2039b5da9499SMatthew 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);
2040b5da9499SMatthew G. Knepley       }
2041b5da9499SMatthew G. Knepley #endif
2042b5da9499SMatthew G. Knepley       ++newp;
2043b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
20444bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2045b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2046b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
20474bb260e2SMatthew G. Knepley       orntNew[1] = 0;
20484bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
20492baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
2050b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2051b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2052b5da9499SMatthew G. Knepley #if 1
2053b5da9499SMatthew 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);
2054b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2055b5da9499SMatthew 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);
2056b5da9499SMatthew G. Knepley       }
2057b5da9499SMatthew G. Knepley #endif
2058b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2059b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2060b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2061b5da9499SMatthew G. Knepley #if 1
2062b5da9499SMatthew 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);
2063b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2064b5da9499SMatthew 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);
2065b5da9499SMatthew G. Knepley       }
2066b5da9499SMatthew G. Knepley #endif
2067b5da9499SMatthew G. Knepley       ++newp;
2068b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
20694bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2070b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
2071b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2072fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
20734bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2074b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
2075b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2076b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2077b5da9499SMatthew G. Knepley #if 1
2078b5da9499SMatthew 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);
2079b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2080b5da9499SMatthew 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);
2081b5da9499SMatthew G. Knepley       }
2082b5da9499SMatthew G. Knepley #endif
2083b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2084b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2085b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2086b5da9499SMatthew G. Knepley #if 1
2087b5da9499SMatthew 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);
2088b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2089b5da9499SMatthew 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);
2090b5da9499SMatthew G. Knepley       }
2091b5da9499SMatthew G. Knepley #endif
2092b5da9499SMatthew G. Knepley       ++newp;
2093b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
20944bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2095b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
20964bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2097b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
2098b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
20994bb260e2SMatthew G. Knepley       orntNew[2] = -2;
2100b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2101b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2102b5da9499SMatthew G. Knepley #if 1
2103b5da9499SMatthew 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);
2104b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2105b5da9499SMatthew 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);
2106b5da9499SMatthew G. Knepley       }
2107b5da9499SMatthew G. Knepley #endif
2108b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2109b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2110b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2111b5da9499SMatthew G. Knepley #if 1
2112b5da9499SMatthew 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);
2113b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2114b5da9499SMatthew 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);
2115b5da9499SMatthew G. Knepley       }
2116b5da9499SMatthew G. Knepley #endif
2117b5da9499SMatthew G. Knepley       ++newp;
2118b5da9499SMatthew G. Knepley     }
2119b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
2120b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2121b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
2122b5da9499SMatthew G. Knepley 
2123b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2124b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
2125b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2126b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2127b5da9499SMatthew G. Knepley 
2128b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
2129b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2130b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2131b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2132b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2133b5da9499SMatthew G. Knepley #if 1
2134b5da9499SMatthew 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);
2135b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2136b5da9499SMatthew 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);
2137b5da9499SMatthew G. Knepley         }
2138b5da9499SMatthew G. Knepley #endif
2139b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
2140b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2141b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2142b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2143b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2144b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2145b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2146b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
2147b5da9499SMatthew G. Knepley           }
2148b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
2149b5da9499SMatthew G. Knepley         }
2150b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2151b5da9499SMatthew G. Knepley #if 1
2152b5da9499SMatthew 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);
2153b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2154b5da9499SMatthew 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);
2155b5da9499SMatthew G. Knepley         }
2156b5da9499SMatthew G. Knepley #endif
2157b5da9499SMatthew G. Knepley       }
2158b5da9499SMatthew G. Knepley     }
215986f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
2160b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2161b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2162b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
2163b5da9499SMatthew G. Knepley 
2164b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2165b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2166b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
2167b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
2168b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
2169b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
2170b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
2171b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
2172b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
2173b5da9499SMatthew G. Knepley 
2174b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2175b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
2176b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
2177b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2178b5da9499SMatthew G. Knepley #if 1
2179b5da9499SMatthew 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);
2180b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2181b5da9499SMatthew 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);
2182b5da9499SMatthew G. Knepley         }
2183b5da9499SMatthew G. Knepley #endif
2184b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
2185b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
2186b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2187b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2188b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2189b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2190b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
219186f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
21929ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
2193b5da9499SMatthew G. Knepley           if (er == eint[c]) {
2194b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
2195b5da9499SMatthew G. Knepley           } else {
2196b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
2197b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
2198b5da9499SMatthew G. Knepley           }
2199b5da9499SMatthew G. Knepley         }
2200b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2201b5da9499SMatthew G. Knepley #if 1
2202b5da9499SMatthew 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);
2203b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
2204b5da9499SMatthew 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);
2205b5da9499SMatthew G. Knepley         }
2206b5da9499SMatthew G. Knepley #endif
2207b5da9499SMatthew G. Knepley       }
2208b5da9499SMatthew G. Knepley     }
2209b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
2210b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2211b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2212b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
22134a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
2214b5da9499SMatthew G. Knepley 
2215b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2216b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2217b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
221842525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
2219b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2220b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
222142525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
2222b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2223b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2224b5da9499SMatthew G. Knepley #if 1
2225b5da9499SMatthew 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);
2226b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2227b5da9499SMatthew 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);
2228b5da9499SMatthew G. Knepley       }
2229b5da9499SMatthew G. Knepley #endif
2230b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
2231b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
2232b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
2233b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
2234b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2235b5da9499SMatthew G. Knepley #if 1
2236b5da9499SMatthew 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);
2237b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2238b5da9499SMatthew 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);
2239b5da9499SMatthew G. Knepley       }
2240b5da9499SMatthew G. Knepley #endif
2241b5da9499SMatthew G. Knepley     }
2242b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
2243b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2244b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2245b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
2246b5da9499SMatthew G. Knepley       PetscInt        size, s;
2247b5da9499SMatthew G. Knepley 
2248b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2249b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2250b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2251b5da9499SMatthew G. Knepley         PetscInt r = 0;
2252b5da9499SMatthew G. Knepley 
2253b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2254b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
2255b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
2256b5da9499SMatthew G. Knepley       }
2257b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2258b5da9499SMatthew G. Knepley #if 1
2259b5da9499SMatthew 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);
2260b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2261b5da9499SMatthew 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);
2262b5da9499SMatthew G. Knepley       }
2263b5da9499SMatthew G. Knepley #endif
2264b5da9499SMatthew G. Knepley     }
2265b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
2266b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2267b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
2268b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
2269b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
2270b5da9499SMatthew G. Knepley 
2271b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
2272b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2273b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
2274b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
2275b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2276b5da9499SMatthew G. Knepley         PetscInt r = 0;
2277b5da9499SMatthew G. Knepley 
2278b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2279b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2280b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
2281b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
2282b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
2283b5da9499SMatthew G. Knepley       }
2284b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2285b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
2286b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
2287b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
2288b5da9499SMatthew G. Knepley 
2289b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
2290b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
2291b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2292b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
2293b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
229442525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
2295b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
2296b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2297b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
229842525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
229942525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
2300b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
2301b5da9499SMatthew G. Knepley         }
2302b5da9499SMatthew G. Knepley       }
2303b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2304b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2305b5da9499SMatthew G. Knepley #if 1
2306b5da9499SMatthew 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);
2307b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
2308b5da9499SMatthew 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);
2309b5da9499SMatthew G. Knepley       }
2310b5da9499SMatthew G. Knepley #endif
2311b5da9499SMatthew G. Knepley     }
2312b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2313b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
2314b5da9499SMatthew G. Knepley     break;
23156ce3c06aSMatthew G. Knepley   case 7:
23166ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
23176ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
23186ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
23196ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
23206ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
23216ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
23226ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
23236ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
23246ce3c06aSMatthew G. Knepley 
23256ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
23266ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
23276ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
23286ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
23296ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
23306ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
23316ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
23326ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
23336ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
23346ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
23356ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
23366ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
23376ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
23386ce3c06aSMatthew G. Knepley #if 1
23396ce3c06aSMatthew 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);
23406ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
23416ce3c06aSMatthew 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);
23426ce3c06aSMatthew G. Knepley       }
23436ce3c06aSMatthew G. Knepley #endif
23446ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
23456ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
23466ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
23476ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
23486ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
23496ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
23506ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
23516ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
23526ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
23536ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
23546ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
23556ce3c06aSMatthew G. Knepley #if 1
23566ce3c06aSMatthew 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);
23576ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
23586ce3c06aSMatthew 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);
23596ce3c06aSMatthew G. Knepley       }
23606ce3c06aSMatthew G. Knepley #endif
23616ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
23626ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
23636ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
23646ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
23656ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
23666ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
23676ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
23686ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
23696ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
23706ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
23716ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
23726ce3c06aSMatthew G. Knepley #if 1
23736ce3c06aSMatthew 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);
23746ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
23756ce3c06aSMatthew 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);
23766ce3c06aSMatthew G. Knepley       }
23776ce3c06aSMatthew G. Knepley #endif
23786ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
23796ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
23806ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
23816ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
23826ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
23836ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
23846ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
23856ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
23866ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
23876ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
23886ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
23896ce3c06aSMatthew G. Knepley #if 1
23906ce3c06aSMatthew 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);
23916ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
23926ce3c06aSMatthew 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);
23936ce3c06aSMatthew G. Knepley       }
23946ce3c06aSMatthew G. Knepley #endif
23956ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
23966ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
23976ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
23989ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
23999ddff745SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
24009ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
24019ddff745SMatthew G. Knepley       orntNew[2] = 0;
24029ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
24039ddff745SMatthew G. Knepley       orntNew[3] = 2;
24046ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
24056ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
24066ce3c06aSMatthew G. Knepley #if 1
24076ce3c06aSMatthew 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);
24086ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
24096ce3c06aSMatthew 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);
24106ce3c06aSMatthew G. Knepley       }
24116ce3c06aSMatthew G. Knepley #endif
24126ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
24136ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
24146ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
24159ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
24169ddff745SMatthew G. Knepley       orntNew[1] = 1;
24179ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
24186ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
24199ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
24209ddff745SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
24216ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
24226ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
24236ce3c06aSMatthew G. Knepley #if 1
24246ce3c06aSMatthew 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);
24256ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
24266ce3c06aSMatthew 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);
24276ce3c06aSMatthew G. Knepley       }
24286ce3c06aSMatthew G. Knepley #endif
24296ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
24306ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
24316ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
24329ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
24339ddff745SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
24349ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
24359ddff745SMatthew G. Knepley       orntNew[2] = -3;
24369ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
24379ddff745SMatthew G. Knepley       orntNew[3] = -2;
24386ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
24396ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
24406ce3c06aSMatthew G. Knepley #if 1
24416ce3c06aSMatthew 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);
24426ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
24436ce3c06aSMatthew 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);
24446ce3c06aSMatthew G. Knepley       }
24456ce3c06aSMatthew G. Knepley #endif
24466ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
24476ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
24486ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
24499ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
24506ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
24519ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
24529ddff745SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
24539ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
24549ddff745SMatthew G. Knepley       orntNew[3] = -3;
24556ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
24566ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
24576ce3c06aSMatthew G. Knepley #if 1
24586ce3c06aSMatthew 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);
24596ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
24606ce3c06aSMatthew 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);
24616ce3c06aSMatthew G. Knepley       }
24626ce3c06aSMatthew G. Knepley #endif
24636ce3c06aSMatthew G. Knepley     }
24646ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
24656ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
24666ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
2467d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
24686ce3c06aSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5];
24696ce3c06aSMatthew G. Knepley 
24706ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
24716ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2472d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
24736ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
24746ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
24756ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
24766ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
24776ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
2478d3a1cc75SMatthew G. Knepley         coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? 0 : 1);
24796ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
2480d3a1cc75SMatthew G. Knepley         coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)]       - fMax)*2 + (fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? 1 : 0);
24816ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
24826ce3c06aSMatthew G. Knepley         coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
24836ce3c06aSMatthew G. Knepley         orntNew[4] = 0;
24846ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
24856ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
24866ce3c06aSMatthew G. Knepley #if 1
24876ce3c06aSMatthew 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);
24886ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
24896ce3c06aSMatthew 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);
24906ce3c06aSMatthew G. Knepley         }
24916ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
24926ce3c06aSMatthew 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);
24936ce3c06aSMatthew G. Knepley         }
24946ce3c06aSMatthew G. Knepley #endif
24956ce3c06aSMatthew G. Knepley       }
24966ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
24976ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
24986ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
24996ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
25006ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
25016ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
25026ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
25036ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
25046ce3c06aSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
25056ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
25066ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
25076ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
25086ce3c06aSMatthew G. Knepley #if 1
25096ce3c06aSMatthew 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);
25106ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
25116ce3c06aSMatthew 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);
25126ce3c06aSMatthew G. Knepley       }
25136ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
25146ce3c06aSMatthew 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);
25156ce3c06aSMatthew G. Knepley       }
25166ce3c06aSMatthew G. Knepley #endif
25176ce3c06aSMatthew G. Knepley     }
25186ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
25196ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2520785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
25216ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
25226ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
25236ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
25246ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
25256ce3c06aSMatthew G. Knepley 
25266ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
25276ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
25286ce3c06aSMatthew G. Knepley       /* A triangle */
25296ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
25306ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
25316ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
25326ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
25336ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
25346ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
25356ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
25366ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
25376ce3c06aSMatthew G. Knepley #if 1
25386ce3c06aSMatthew 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);
25396ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25406ce3c06aSMatthew 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);
25416ce3c06aSMatthew G. Knepley       }
25426ce3c06aSMatthew G. Knepley #endif
25436ce3c06aSMatthew G. Knepley       /* B triangle */
25446ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
25456ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
25466ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
25476ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
25486ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
25496ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
25506ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
25516ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
25526ce3c06aSMatthew G. Knepley #if 1
25536ce3c06aSMatthew 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);
25546ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25556ce3c06aSMatthew 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);
25566ce3c06aSMatthew G. Knepley       }
25576ce3c06aSMatthew G. Knepley #endif
25586ce3c06aSMatthew G. Knepley       /* C triangle */
25596ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
25606ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
25616ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
25626ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
25636ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
25646ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
25656ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
25666ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
25676ce3c06aSMatthew G. Knepley #if 1
25686ce3c06aSMatthew 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);
25696ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25706ce3c06aSMatthew 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);
25716ce3c06aSMatthew G. Knepley       }
25726ce3c06aSMatthew G. Knepley #endif
25736ce3c06aSMatthew G. Knepley       /* D triangle */
25746ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
25756ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
25766ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
25776ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
25786ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
25796ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
25806ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
25816ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
25826ce3c06aSMatthew G. Knepley #if 1
25836ce3c06aSMatthew 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);
25846ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
25856ce3c06aSMatthew 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);
25866ce3c06aSMatthew G. Knepley       }
25876ce3c06aSMatthew G. Knepley #endif
25886ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
25896ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
25906ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
25916ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
25929ddff745SMatthew G. Knepley           PetscInt subf;
25936ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
25946ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
25956ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
25966ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
25976ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
25986ce3c06aSMatthew G. Knepley           }
25999ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
26006ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
26019ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
26026ce3c06aSMatthew G. Knepley           } else {
26039ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
26046ce3c06aSMatthew G. Knepley           }
26056ce3c06aSMatthew G. Knepley         }
26066ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
26076ce3c06aSMatthew G. Knepley #if 1
26089ddff745SMatthew 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);
26096ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
26106ce3c06aSMatthew 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);
26116ce3c06aSMatthew G. Knepley         }
26126ce3c06aSMatthew G. Knepley #endif
26136ce3c06aSMatthew G. Knepley       }
26146ce3c06aSMatthew G. Knepley     }
26156ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
26166ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
26176ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
26186ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
26196ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
26206ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
26216ce3c06aSMatthew G. Knepley 
26226ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
26236ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
26246ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
26259ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
26266ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
26279ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
26286ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
26299ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
26306ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
26316ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
26326ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
26336ce3c06aSMatthew G. Knepley #if 1
26346ce3c06aSMatthew 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);
26356ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26366ce3c06aSMatthew 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);
26376ce3c06aSMatthew G. Knepley       }
26386ce3c06aSMatthew G. Knepley #endif
26396ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
26406ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
26416ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
26426ce3c06aSMatthew G. Knepley #if 1
26436ce3c06aSMatthew 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);
26446ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
26456ce3c06aSMatthew 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);
26466ce3c06aSMatthew G. Knepley       }
26476ce3c06aSMatthew G. Knepley #endif
26486ce3c06aSMatthew G. Knepley       ++newp;
26496ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
26509ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
26516ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
26529ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
26536ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
26549ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
26556ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
26566ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
26576ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
26586ce3c06aSMatthew G. Knepley #if 1
26596ce3c06aSMatthew 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);
26606ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26616ce3c06aSMatthew 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);
26626ce3c06aSMatthew G. Knepley       }
26636ce3c06aSMatthew G. Knepley #endif
26646ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
26656ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
26666ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
26676ce3c06aSMatthew G. Knepley #if 1
26686ce3c06aSMatthew 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);
26696ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
26706ce3c06aSMatthew 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);
26716ce3c06aSMatthew G. Knepley       }
26726ce3c06aSMatthew G. Knepley #endif
26736ce3c06aSMatthew G. Knepley       ++newp;
26746ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
26759ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
26766ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
26779ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
26786ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
26799ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
26806ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
26816ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
26826ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
26836ce3c06aSMatthew G. Knepley #if 1
26846ce3c06aSMatthew 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);
26856ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
26866ce3c06aSMatthew 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);
26876ce3c06aSMatthew G. Knepley       }
26886ce3c06aSMatthew G. Knepley #endif
26896ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
26906ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
26916ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
26926ce3c06aSMatthew G. Knepley #if 1
26936ce3c06aSMatthew 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);
26946ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
26956ce3c06aSMatthew 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);
26966ce3c06aSMatthew G. Knepley       }
26976ce3c06aSMatthew G. Knepley #endif
26986ce3c06aSMatthew G. Knepley       ++newp;
26996ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
27009ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
27016ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
27029ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
27036ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
27049ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
27056ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
27066ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27076ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
27086ce3c06aSMatthew G. Knepley #if 1
27096ce3c06aSMatthew 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);
27106ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
27116ce3c06aSMatthew 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);
27126ce3c06aSMatthew G. Knepley       }
27136ce3c06aSMatthew G. Knepley #endif
27146ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
27156ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
27166ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
27176ce3c06aSMatthew G. Knepley #if 1
27186ce3c06aSMatthew 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);
27196ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
27206ce3c06aSMatthew 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);
27216ce3c06aSMatthew G. Knepley       }
27226ce3c06aSMatthew G. Knepley #endif
27236ce3c06aSMatthew G. Knepley       ++newp;
27246ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
27259ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
27266ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
27276ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
27289ddff745SMatthew G. Knepley       orntNew[1] = -2;
27299ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
27306ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
27316ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27326ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
27336ce3c06aSMatthew G. Knepley #if 1
27346ce3c06aSMatthew 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);
27356ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
27366ce3c06aSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
27376ce3c06aSMatthew G. Knepley       }
27386ce3c06aSMatthew G. Knepley #endif
27396ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
27406ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
27416ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
27426ce3c06aSMatthew G. Knepley #if 1
27436ce3c06aSMatthew 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);
27446ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
27456ce3c06aSMatthew 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);
27466ce3c06aSMatthew G. Knepley       }
27476ce3c06aSMatthew G. Knepley #endif
27486ce3c06aSMatthew G. Knepley       ++newp;
27496ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
27509ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
27516ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
27526ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
27539ddff745SMatthew G. Knepley       orntNew[1] = 0;
27549ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
27559ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
27566ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27576ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
27586ce3c06aSMatthew G. Knepley #if 1
27596ce3c06aSMatthew 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);
27606ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
27616ce3c06aSMatthew 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);
27626ce3c06aSMatthew G. Knepley       }
27636ce3c06aSMatthew G. Knepley #endif
27646ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
27656ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
27666ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
27676ce3c06aSMatthew G. Knepley #if 1
27686ce3c06aSMatthew 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);
27696ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
27706ce3c06aSMatthew 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);
27716ce3c06aSMatthew G. Knepley       }
27726ce3c06aSMatthew G. Knepley #endif
27736ce3c06aSMatthew G. Knepley       ++newp;
27746ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
27759ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
27766ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
27776ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
27789ddff745SMatthew G. Knepley       orntNew[1] = 0;
27799ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
27806ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
27816ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
27826ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
27836ce3c06aSMatthew G. Knepley #if 1
27846ce3c06aSMatthew 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);
27856ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
27866ce3c06aSMatthew 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);
27876ce3c06aSMatthew G. Knepley       }
27886ce3c06aSMatthew G. Knepley #endif
27896ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
27906ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
27916ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
27926ce3c06aSMatthew G. Knepley #if 1
27936ce3c06aSMatthew 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);
27946ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
27956ce3c06aSMatthew 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);
27966ce3c06aSMatthew G. Knepley       }
27976ce3c06aSMatthew G. Knepley #endif
27986ce3c06aSMatthew G. Knepley       ++newp;
27996ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
28009ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
28016ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
28029ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
28036ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
28046ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
28059ddff745SMatthew G. Knepley       orntNew[2] = -2;
28066ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
28076ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
28086ce3c06aSMatthew G. Knepley #if 1
28096ce3c06aSMatthew 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);
28106ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
28116ce3c06aSMatthew 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);
28126ce3c06aSMatthew G. Knepley       }
28136ce3c06aSMatthew G. Knepley #endif
28146ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
28156ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
28166ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
28176ce3c06aSMatthew G. Knepley #if 1
28186ce3c06aSMatthew 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);
28196ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
28206ce3c06aSMatthew 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);
28216ce3c06aSMatthew G. Knepley       }
28226ce3c06aSMatthew G. Knepley #endif
28236ce3c06aSMatthew G. Knepley       ++newp;
28246ce3c06aSMatthew G. Knepley     }
28256ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
28266ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
28276ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
28286ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
28296ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
28306ce3c06aSMatthew G. Knepley 
28316ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
28326ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
28336ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
28346ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
28356ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
28366ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
28376ce3c06aSMatthew G. Knepley 
28386ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
28396ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
28406ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
28416ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
28426ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
28436ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
28446ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
28456ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
28466ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
28476ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
28486ce3c06aSMatthew G. Knepley #if 1
28496ce3c06aSMatthew 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);
28506ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
28516ce3c06aSMatthew 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);
28526ce3c06aSMatthew G. Knepley         }
28536ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
28546ce3c06aSMatthew 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);
28556ce3c06aSMatthew G. Knepley         }
28566ce3c06aSMatthew G. Knepley #endif
28576ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
2858d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
28596ce3c06aSMatthew G. Knepley 
28606ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
28616ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
28626ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
28636ce3c06aSMatthew 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]);
2864d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
2865d3a1cc75SMatthew G. Knepley           supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%3;
28666ce3c06aSMatthew G. Knepley         }
28676ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
28686ce3c06aSMatthew G. Knepley #if 1
28696ce3c06aSMatthew 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);
28706ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
28716ce3c06aSMatthew 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);
28726ce3c06aSMatthew G. Knepley         }
28736ce3c06aSMatthew G. Knepley #endif
28746ce3c06aSMatthew G. Knepley       }
28756ce3c06aSMatthew G. Knepley     }
28766ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
28776ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
28786ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
28796ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
28806ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
28816ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
28826ce3c06aSMatthew G. Knepley 
28836ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
28846ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
28856ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
28866ce3c06aSMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], (r+2)%3);
28876ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
28886ce3c06aSMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], (r+2)%3);
28896ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
28906ce3c06aSMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], (r+2)%3)] - fMax);
28916ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
28926ce3c06aSMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], r)]       - fMax);
28936ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
28946ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
28956ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
28966ce3c06aSMatthew G. Knepley #if 1
28976ce3c06aSMatthew 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);
28986ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
28996ce3c06aSMatthew 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);
29006ce3c06aSMatthew G. Knepley         }
29016ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
29026ce3c06aSMatthew 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);
29036ce3c06aSMatthew G. Knepley         }
29046ce3c06aSMatthew G. Knepley #endif
29056ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
29066ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
29076ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
29086ce3c06aSMatthew G. Knepley #if 1
29096ce3c06aSMatthew 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);
29106ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
29116ce3c06aSMatthew 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);
29126ce3c06aSMatthew G. Knepley         }
29136ce3c06aSMatthew G. Knepley #endif
29146ce3c06aSMatthew G. Knepley       }
29156ce3c06aSMatthew G. Knepley     }
29166ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
29176ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
29186ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
29196ce3c06aSMatthew G. Knepley 
29206ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
29216ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
29226ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
29236ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
29246ce3c06aSMatthew G. Knepley 
29256ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
29266ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
29276ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
29286ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
29296ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
29306ce3c06aSMatthew G. Knepley #if 1
29316ce3c06aSMatthew 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);
29326ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
29336ce3c06aSMatthew 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);
29346ce3c06aSMatthew G. Knepley         }
29356ce3c06aSMatthew G. Knepley #endif
29366ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
29376ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
29386ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
29396ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
29406ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
29416ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
29426ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
29436ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
29446ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
29456ce3c06aSMatthew G. Knepley           } else {
29466ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
29476ce3c06aSMatthew G. Knepley           }
29486ce3c06aSMatthew G. Knepley         }
29496ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
29506ce3c06aSMatthew G. Knepley #if 1
29516ce3c06aSMatthew 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);
29526ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
29536ce3c06aSMatthew 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);
29546ce3c06aSMatthew G. Knepley         }
29556ce3c06aSMatthew G. Knepley #endif
29566ce3c06aSMatthew G. Knepley       }
29576ce3c06aSMatthew G. Knepley     }
29586ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
29596ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
29606ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
29616ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
29626ce3c06aSMatthew G. Knepley 
29636ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
29646ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
29656ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
29666ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
29676ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
29686ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
29696ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
29706ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
29716ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
29726ce3c06aSMatthew G. Knepley 
29736ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
29746ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
29756ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
29766ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
29776ce3c06aSMatthew G. Knepley #if 1
29786ce3c06aSMatthew 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);
29796ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
29806ce3c06aSMatthew 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);
29816ce3c06aSMatthew G. Knepley         }
29826ce3c06aSMatthew G. Knepley #endif
29836ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
29846ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
29856ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
29866ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
29876ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
29886ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
29896ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
29906ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
29916ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
29929ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
29936ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
29946ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
29956ce3c06aSMatthew G. Knepley             } else {
29966ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
29976ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
29986ce3c06aSMatthew G. Knepley             }
29996ce3c06aSMatthew G. Knepley           } else {
3000e515e2ddSMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(ornt[c], r) + 1)%3;
30016ce3c06aSMatthew G. Knepley           }
30026ce3c06aSMatthew G. Knepley         }
30036ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
30046ce3c06aSMatthew G. Knepley #if 1
30056ce3c06aSMatthew 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);
30066ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
30076ce3c06aSMatthew 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);
30086ce3c06aSMatthew G. Knepley         }
30096ce3c06aSMatthew G. Knepley #endif
30106ce3c06aSMatthew G. Knepley       }
30116ce3c06aSMatthew G. Knepley     }
30126ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
30136ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
30146ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
30156ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
30166ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
30176ce3c06aSMatthew G. Knepley 
30186ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
30196ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
30206ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
30216ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
30226ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
30236ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
30246ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
30256ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
30266ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
30276ce3c06aSMatthew G. Knepley #if 1
30286ce3c06aSMatthew 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);
30296ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
30306ce3c06aSMatthew 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);
30316ce3c06aSMatthew G. Knepley       }
30326ce3c06aSMatthew G. Knepley #endif
30336ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
30346ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
30356ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
30366ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
30376ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
30386ce3c06aSMatthew G. Knepley #if 1
30396ce3c06aSMatthew 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);
30406ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30416ce3c06aSMatthew 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);
30426ce3c06aSMatthew G. Knepley       }
30436ce3c06aSMatthew G. Knepley #endif
30446ce3c06aSMatthew G. Knepley     }
30456ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
30466ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
30476ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
30486ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
30496ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
30506ce3c06aSMatthew G. Knepley 
30516ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
30526ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
30536ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
30546ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
30556ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
30566ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
30576ce3c06aSMatthew G. Knepley #if 1
30586ce3c06aSMatthew 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);
30596ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
30606ce3c06aSMatthew 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);
30616ce3c06aSMatthew G. Knepley       }
30626ce3c06aSMatthew G. Knepley #endif
30636ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
30646ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
30656ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
30666ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
30676ce3c06aSMatthew 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]);
30686ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
30696ce3c06aSMatthew G. Knepley       }
30706ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
30716ce3c06aSMatthew G. Knepley #if 1
30726ce3c06aSMatthew 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);
30736ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
30746ce3c06aSMatthew 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);
30756ce3c06aSMatthew G. Knepley       }
30766ce3c06aSMatthew G. Knepley #endif
30776ce3c06aSMatthew G. Knepley     }
30786ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
30796ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
30806ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
3081623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
30826ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
30836ce3c06aSMatthew G. Knepley 
30846ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
30856ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
30866ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
30876ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
30886ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
30896ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
30906ce3c06aSMatthew G. Knepley #if 1
30916ce3c06aSMatthew 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);
30926ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
30936ce3c06aSMatthew 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);
30946ce3c06aSMatthew G. Knepley       }
30956ce3c06aSMatthew G. Knepley #endif
30966ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
30976ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
30986ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
30996ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
31006ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
3101623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
31026ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
31036ce3c06aSMatthew 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]);
3104623f4348SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + GetTriSubfaceInverse_Static(cornt[0], c-2);
3105623f4348SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(cornt[0], c-2) + 1)%3;
31066ce3c06aSMatthew G. Knepley       }
31076ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
31086ce3c06aSMatthew G. Knepley #if 1
31096ce3c06aSMatthew 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);
31106ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
31116ce3c06aSMatthew 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);
31126ce3c06aSMatthew G. Knepley       }
31136ce3c06aSMatthew G. Knepley #endif
31146ce3c06aSMatthew G. Knepley     }
31156ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
31166ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
31176ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
31186ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
31196ce3c06aSMatthew G. Knepley       PetscInt        size, s;
31206ce3c06aSMatthew G. Knepley 
31216ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
31226ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
31236ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
31246ce3c06aSMatthew G. Knepley         PetscInt r = 0;
31256ce3c06aSMatthew G. Knepley 
31266ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
31276ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
31286ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
31296ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
31306ce3c06aSMatthew G. Knepley       }
31316ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
31326ce3c06aSMatthew G. Knepley #if 1
31336ce3c06aSMatthew 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);
31346ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
31356ce3c06aSMatthew 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);
31366ce3c06aSMatthew G. Knepley       }
31376ce3c06aSMatthew G. Knepley #endif
31386ce3c06aSMatthew G. Knepley     }
31396ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
31406ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
31416ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
31426ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
31436ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
31446ce3c06aSMatthew G. Knepley 
31456ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
31466ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
31476ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
31486ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
31496ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
31506ce3c06aSMatthew G. Knepley         PetscInt r = 0;
31516ce3c06aSMatthew G. Knepley 
31526ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
31536ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
31546ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
31556ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
31566ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
31576ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
31586ce3c06aSMatthew G. Knepley           faceSize += 2;
31596ce3c06aSMatthew G. Knepley         } else {
31606ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
31616ce3c06aSMatthew G. Knepley           ++faceSize;
31626ce3c06aSMatthew G. Knepley         }
31636ce3c06aSMatthew G. Knepley       }
31646ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
31656ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
31666ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
31676ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
31686ce3c06aSMatthew G. Knepley 
31696ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
31706ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
31716ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
31726ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
31736ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
31746ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
31756ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
31766ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
31776ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
31786ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
31796ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
31806ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
31816ce3c06aSMatthew G. Knepley         }
31826ce3c06aSMatthew G. Knepley       }
31836ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
31846ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
31856ce3c06aSMatthew G. Knepley #if 1
31866ce3c06aSMatthew 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);
31876ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
31886ce3c06aSMatthew 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);
31896ce3c06aSMatthew G. Knepley       }
31906ce3c06aSMatthew G. Knepley #endif
31916ce3c06aSMatthew G. Knepley     }
31926ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
31936ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
31946ce3c06aSMatthew G. Knepley     break;
31952eabf88fSMatthew G. Knepley   case 6:
31962eabf88fSMatthew G. Knepley     /* Hex 3D */
31972eabf88fSMatthew G. Knepley     /*
31982eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
31992eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
32002eabf88fSMatthew G. Knepley      |         |         |       |         |         |
32012eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
32022eabf88fSMatthew G. Knepley      |         |         |       |         |         |
32032eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
32042eabf88fSMatthew G. Knepley      |         |         |       |         |         |
32052eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
32062eabf88fSMatthew G. Knepley      |         |         |       |         |         |
32072eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
32082eabf88fSMatthew G. Knepley      */
32092eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
32102eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
32112eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
32122eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
32132eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
32142eabf88fSMatthew G. Knepley 
32152eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
32162eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
32172eabf88fSMatthew G. Knepley       /* A hex */
3218e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
32192eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
32202eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
32212eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3222e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
32232eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
32242eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
32252eabf88fSMatthew G. Knepley       orntNew[3] = 0;
32262eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
32272eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3228e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
32292eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
32302eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
32312eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
32322eabf88fSMatthew G. Knepley #if 1
32332eabf88fSMatthew 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);
32342eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
32352eabf88fSMatthew 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);
32362eabf88fSMatthew G. Knepley       }
32372eabf88fSMatthew G. Knepley #endif
32382eabf88fSMatthew G. Knepley       /* B hex */
3239e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
32402eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
32412eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
32422eabf88fSMatthew G. Knepley       orntNew[1] = 0;
32432eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
3244a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3245e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
32462eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
32472eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
32482eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3249e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
32502eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
32512eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
32522eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
32532eabf88fSMatthew G. Knepley #if 1
32542eabf88fSMatthew 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);
32552eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
32562eabf88fSMatthew 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);
32572eabf88fSMatthew G. Knepley       }
32582eabf88fSMatthew G. Knepley #endif
32592eabf88fSMatthew G. Knepley       /* C hex */
3260e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
32612eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
32622eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
32632eabf88fSMatthew G. Knepley       orntNew[1] = 0;
32642eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3265a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3266e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
32672eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3268e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
32692eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
32702eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
3271a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
32722eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
32732eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
32742eabf88fSMatthew G. Knepley #if 1
32752eabf88fSMatthew 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);
32762eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
32772eabf88fSMatthew 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);
32782eabf88fSMatthew G. Knepley       }
32792eabf88fSMatthew G. Knepley #endif
32802eabf88fSMatthew G. Knepley       /* D hex */
3281e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
32822eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
32832eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
32842eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3285e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
32862eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
32872eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3288a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3289e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
32902eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
32912eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
3292a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
32932eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
32942eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
32952eabf88fSMatthew G. Knepley #if 1
32962eabf88fSMatthew 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);
32972eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
32982eabf88fSMatthew 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);
32992eabf88fSMatthew G. Knepley       }
33002eabf88fSMatthew G. Knepley #endif
33012eabf88fSMatthew G. Knepley       /* E hex */
33022eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
3303a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3304e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
33052eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3306e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
33072eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
33082eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
33092eabf88fSMatthew G. Knepley       orntNew[3] = 0;
33102eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3311a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
3312e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
33132eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3314b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
3315b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
33162eabf88fSMatthew G. Knepley #if 1
3317b164cbf2SMatthew 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);
33182eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33192eabf88fSMatthew 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);
33202eabf88fSMatthew G. Knepley       }
33212eabf88fSMatthew G. Knepley #endif
33222eabf88fSMatthew G. Knepley       /* F hex */
33232eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
3324a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3325e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
33262eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3327e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
33282eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
33292eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3330a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
3331e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
33322eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
33332eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3334a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
3335b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
3336b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
33372eabf88fSMatthew G. Knepley #if 1
3338b164cbf2SMatthew 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);
33392eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33402eabf88fSMatthew 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);
33412eabf88fSMatthew G. Knepley       }
33422eabf88fSMatthew G. Knepley #endif
33432eabf88fSMatthew G. Knepley       /* G hex */
33442eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
3345a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3346e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
33472eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
33482eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3349a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
3350e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
33512eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3352e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
33532eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
33542eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3355a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
3356b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
3357b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
33582eabf88fSMatthew G. Knepley #if 1
3359b164cbf2SMatthew 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);
33602eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33612eabf88fSMatthew 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);
33622eabf88fSMatthew G. Knepley       }
33632eabf88fSMatthew G. Knepley #endif
33642eabf88fSMatthew G. Knepley       /* H hex */
33652eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
3366a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3367e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
33682eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
33692eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
3370a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3371e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
33722eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
33732eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3374a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
3375e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
33762eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3377b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
3378b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
33792eabf88fSMatthew G. Knepley #if 1
3380b164cbf2SMatthew 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);
33812eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
33822eabf88fSMatthew 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);
33832eabf88fSMatthew G. Knepley       }
33842eabf88fSMatthew G. Knepley #endif
33852eabf88fSMatthew G. Knepley     }
33862eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
33872eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3388785e854fSJed Brown     ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
33892eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
33902eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
3391aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
33922eabf88fSMatthew 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};
33932eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
33942eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3395aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
33962eabf88fSMatthew G. Knepley 
33972eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3398aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
3399a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
3400a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
3401a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
3402a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
3403a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
3404a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
3405a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
3406a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
34072eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3408aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
34092eabf88fSMatthew G. Knepley #if 1
34102eabf88fSMatthew 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);
34112eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
34122eabf88fSMatthew 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);
34132eabf88fSMatthew G. Knepley         }
34142eabf88fSMatthew G. Knepley #endif
34152eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
34162eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
34172eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
34182eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
34192eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
34202eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
34212eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
34222eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
34232eabf88fSMatthew G. Knepley           }
3424a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
34252eabf88fSMatthew G. Knepley         }
34262eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
34272eabf88fSMatthew G. Knepley #if 1
34282eabf88fSMatthew 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);
34292eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
34302eabf88fSMatthew 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);
34312eabf88fSMatthew G. Knepley         }
34322eabf88fSMatthew G. Knepley #endif
34332eabf88fSMatthew G. Knepley       }
34342eabf88fSMatthew G. Knepley     }
34352eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
34362eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
34372eabf88fSMatthew 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};
3438afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
3439afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
34402eabf88fSMatthew G. Knepley 
34412eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3442afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3443afb2665bSMatthew G. Knepley       /* A-D face */
3444afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
3445a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
3446a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3447a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3448afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3449a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3450a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3451a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
3452afb2665bSMatthew G. Knepley       orntNew[3] = -2;
34532eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3454afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
34552eabf88fSMatthew G. Knepley #if 1
34562eabf88fSMatthew 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);
34572eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
34582eabf88fSMatthew 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);
34592eabf88fSMatthew G. Knepley       }
34602eabf88fSMatthew G. Knepley #endif
3461afb2665bSMatthew G. Knepley       /* C-D face */
3462afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
3463a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
3464a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3465a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3466afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3467a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3468a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3469a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
3470afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3471afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3472afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3473afb2665bSMatthew G. Knepley #if 1
3474afb2665bSMatthew 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);
3475afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3476afb2665bSMatthew 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);
3477afb2665bSMatthew G. Knepley       }
3478afb2665bSMatthew G. Knepley #endif
3479afb2665bSMatthew G. Knepley       /* B-C face */
3480afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
3481afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
3482afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3483afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
3484afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3485afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3486afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3487afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3488afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3489afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3490afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3491afb2665bSMatthew G. Knepley #if 1
3492afb2665bSMatthew 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);
3493afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3494afb2665bSMatthew 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);
3495afb2665bSMatthew G. Knepley       }
3496afb2665bSMatthew G. Knepley #endif
3497afb2665bSMatthew G. Knepley       /* A-B face */
3498afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
3499afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
3500afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3501afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
3502afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3503afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3504afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3505afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
3506afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3507afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3508afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3509afb2665bSMatthew G. Knepley #if 1
3510afb2665bSMatthew 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);
3511afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3512afb2665bSMatthew 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);
3513afb2665bSMatthew G. Knepley       }
3514afb2665bSMatthew G. Knepley #endif
3515afb2665bSMatthew G. Knepley       /* E-F face */
3516afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
3517a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3518afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3519a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
3520a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3521a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
3522afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3523a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3524a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3525afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3526afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3527afb2665bSMatthew G. Knepley #if 1
3528afb2665bSMatthew 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);
3529afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3530afb2665bSMatthew 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);
3531afb2665bSMatthew G. Knepley       }
3532afb2665bSMatthew G. Knepley #endif
3533afb2665bSMatthew G. Knepley       /* F-G face */
3534afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
3535a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3536afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3537a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
3538a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3539a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
3540afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3541a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3542a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3543afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3544afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3545afb2665bSMatthew G. Knepley #if 1
3546afb2665bSMatthew 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);
3547afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3548afb2665bSMatthew 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);
3549afb2665bSMatthew G. Knepley       }
3550afb2665bSMatthew G. Knepley #endif
3551afb2665bSMatthew G. Knepley       /* G-H face */
3552afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
3553afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
3554afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3555afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
3556afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3557afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3558afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3559afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3560afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3561afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3562afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3563afb2665bSMatthew G. Knepley #if 1
3564afb2665bSMatthew 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);
3565afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3566afb2665bSMatthew 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);
3567afb2665bSMatthew G. Knepley       }
3568afb2665bSMatthew G. Knepley #endif
3569afb2665bSMatthew G. Knepley       /* E-H face */
3570afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
3571a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3572afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3573a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
3574a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3575a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
3576afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3577a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
3578a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3579afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3580afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3581afb2665bSMatthew G. Knepley #if 1
3582afb2665bSMatthew 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);
3583afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3584afb2665bSMatthew 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);
3585afb2665bSMatthew G. Knepley       }
3586afb2665bSMatthew G. Knepley #endif
3587afb2665bSMatthew G. Knepley       /* A-E face */
3588afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
3589a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
3590a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3591a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3592afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3593a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3594a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3595a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
3596afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3597afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3598afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3599afb2665bSMatthew G. Knepley #if 1
3600afb2665bSMatthew 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);
3601afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3602afb2665bSMatthew 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);
3603afb2665bSMatthew G. Knepley       }
3604afb2665bSMatthew G. Knepley #endif
3605afb2665bSMatthew G. Knepley       /* D-F face */
3606afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
3607afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
3608afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3609afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
3610afb2665bSMatthew G. Knepley       orntNew[1] = 0;
3611afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3612afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3613afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
3614afb2665bSMatthew G. Knepley       orntNew[3] = -2;
3615afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3616afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3617afb2665bSMatthew G. Knepley #if 1
3618afb2665bSMatthew 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);
3619afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3620afb2665bSMatthew 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);
3621afb2665bSMatthew G. Knepley       }
3622afb2665bSMatthew G. Knepley #endif
3623afb2665bSMatthew G. Knepley       /* C-G face */
3624afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
3625a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
3626afb2665bSMatthew G. Knepley       orntNew[0] = -2;
3627a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
3628a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3629a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
3630afb2665bSMatthew G. Knepley       orntNew[2] = 0;
3631a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3632a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3633afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3634afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3635afb2665bSMatthew G. Knepley #if 1
3636afb2665bSMatthew 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);
3637afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3638afb2665bSMatthew 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);
3639afb2665bSMatthew G. Knepley       }
3640afb2665bSMatthew G. Knepley #endif
3641afb2665bSMatthew G. Knepley       /* B-H face */
3642afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
3643a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
3644a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
3645a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
3646a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
3647a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
3648a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
3649a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
3650a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3651afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3652afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
3653afb2665bSMatthew G. Knepley #if 1
3654afb2665bSMatthew 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);
3655afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
3656afb2665bSMatthew 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);
3657afb2665bSMatthew G. Knepley       }
3658afb2665bSMatthew G. Knepley #endif
3659afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
3660afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
36612eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
36622eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
36632eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36642eabf88fSMatthew G. Knepley #if 1
36652eabf88fSMatthew 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);
36662eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
36672eabf88fSMatthew 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);
36682eabf88fSMatthew G. Knepley         }
36692eabf88fSMatthew G. Knepley #endif
36702eabf88fSMatthew G. Knepley       }
36712eabf88fSMatthew G. Knepley     }
36722eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
36732eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
36742eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
36752eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
36762eabf88fSMatthew G. Knepley 
36772eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
36782eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
36792eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
36802eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
36812eabf88fSMatthew G. Knepley 
36822eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
36832eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
36842eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
36852eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
36862eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36872eabf88fSMatthew G. Knepley #if 1
36882eabf88fSMatthew 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);
36892eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
36902eabf88fSMatthew 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);
36912eabf88fSMatthew G. Knepley         }
36922eabf88fSMatthew G. Knepley #endif
36932eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
36942eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
36952eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
36962eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
36972eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36982eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
36992eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
37002eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
37012eabf88fSMatthew G. Knepley           }
37022eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
37032eabf88fSMatthew G. Knepley         }
37042eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37052eabf88fSMatthew G. Knepley #if 1
37062eabf88fSMatthew 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);
37072eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
37082eabf88fSMatthew 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);
37092eabf88fSMatthew G. Knepley         }
37102eabf88fSMatthew G. Knepley #endif
37112eabf88fSMatthew G. Knepley       }
37122eabf88fSMatthew G. Knepley     }
37132eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
37142eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
37156b852384SMatthew 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};
37162eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
37176b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
37182eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
37192eabf88fSMatthew G. Knepley 
37202eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
37212eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
37222eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
37232eabf88fSMatthew G. Knepley 
37242eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
37252eabf88fSMatthew G. Knepley         coneNew[1] = newv;
37262eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37272eabf88fSMatthew G. Knepley #if 1
37282eabf88fSMatthew 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);
37292eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
37302eabf88fSMatthew 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);
37312eabf88fSMatthew G. Knepley         }
37322eabf88fSMatthew G. Knepley #endif
37332eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
37342eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
37352eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
37362eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
37372eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
37386b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
37396b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
37406b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
37412eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
3742a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
37432eabf88fSMatthew G. Knepley         }
37442eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37452eabf88fSMatthew G. Knepley #if 1
37462eabf88fSMatthew 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);
37472eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
37482eabf88fSMatthew 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);
37492eabf88fSMatthew G. Knepley         }
37502eabf88fSMatthew G. Knepley #endif
37512eabf88fSMatthew G. Knepley       }
37522eabf88fSMatthew G. Knepley     }
37532eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
37542eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
37552eabf88fSMatthew 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};
37562eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
37572eabf88fSMatthew G. Knepley       const PetscInt *cone;
37582eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
37592eabf88fSMatthew G. Knepley 
37602eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
37612eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
37622eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
37632eabf88fSMatthew G. Knepley 
37642eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
37652eabf88fSMatthew G. Knepley         coneNew[1] = newv;
37662eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37672eabf88fSMatthew G. Knepley #if 1
37682eabf88fSMatthew 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);
37692eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
37702eabf88fSMatthew 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);
37712eabf88fSMatthew G. Knepley         }
37722eabf88fSMatthew G. Knepley #endif
37732eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
37742eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
37752eabf88fSMatthew G. Knepley #if 1
37762eabf88fSMatthew G. Knepley         if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew);
37772eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
37782eabf88fSMatthew 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);
37792eabf88fSMatthew G. Knepley         }
37802eabf88fSMatthew G. Knepley #endif
37812eabf88fSMatthew G. Knepley       }
37822eabf88fSMatthew G. Knepley     }
37832eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
37842eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
37852eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
37862eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
37872eabf88fSMatthew G. Knepley       PetscInt        size, s;
37882eabf88fSMatthew G. Knepley 
37892eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
37902eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
37912eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
37922eabf88fSMatthew G. Knepley         PetscInt r = 0;
37932eabf88fSMatthew G. Knepley 
37942eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
37952eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
37962eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
37972eabf88fSMatthew G. Knepley       }
37982eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37992eabf88fSMatthew G. Knepley #if 1
38002eabf88fSMatthew 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);
38012eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
38022eabf88fSMatthew 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);
38032eabf88fSMatthew G. Knepley       }
38042eabf88fSMatthew G. Knepley #endif
38052eabf88fSMatthew G. Knepley     }
38062eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
38072eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
38082eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
38092eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
38102eabf88fSMatthew G. Knepley       PetscInt        size, s;
38112eabf88fSMatthew G. Knepley 
38122eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
38132eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
38142eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
38152eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
38162eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
38172eabf88fSMatthew G. Knepley         PetscInt r;
38182eabf88fSMatthew G. Knepley 
38192eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
3820a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
38212eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
38222eabf88fSMatthew G. Knepley       }
38232eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
38242eabf88fSMatthew G. Knepley #if 1
38252eabf88fSMatthew 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);
38262eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
38272eabf88fSMatthew 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);
38282eabf88fSMatthew G. Knepley       }
38292eabf88fSMatthew G. Knepley #endif
38302eabf88fSMatthew G. Knepley     }
38312eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
38322eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
38332eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
38342eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
38352eabf88fSMatthew G. Knepley       PetscInt        size, s;
38362eabf88fSMatthew G. Knepley 
38372eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
38382eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
38390793999aSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 +  (f - fStart)*4 + r;
38402eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
38412eabf88fSMatthew G. Knepley         PetscInt r;
38422eabf88fSMatthew G. Knepley 
38432eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
38442eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
38452eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
38462eabf88fSMatthew G. Knepley       }
38472eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
38482eabf88fSMatthew G. Knepley #if 1
38492eabf88fSMatthew 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);
38502eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
38512eabf88fSMatthew 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);
38522eabf88fSMatthew G. Knepley       }
38532eabf88fSMatthew G. Knepley #endif
38542eabf88fSMatthew G. Knepley     }
38552eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
38562eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
38572eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
38582eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
38592eabf88fSMatthew G. Knepley 
38602eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
38612eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
38622eabf88fSMatthew G. Knepley       }
38632eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
38642eabf88fSMatthew G. Knepley     }
3865da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
38662eabf88fSMatthew G. Knepley     break;
3867*27fcede3SMatthew G. Knepley   case 8:
3868*27fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
3869*27fcede3SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
3870*27fcede3SMatthew G. Knepley     /*
3871*27fcede3SMatthew G. Knepley      Bottom (viewed from top)    Top
3872*27fcede3SMatthew G. Knepley      1---------2---------2       7---------2---------6
3873*27fcede3SMatthew G. Knepley      |         |         |       |         |         |
3874*27fcede3SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
3875*27fcede3SMatthew G. Knepley      |         |         |       |         |         |
3876*27fcede3SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
3877*27fcede3SMatthew G. Knepley      |         |         |       |         |         |
3878*27fcede3SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
3879*27fcede3SMatthew G. Knepley      |         |         |       |         |         |
3880*27fcede3SMatthew G. Knepley      0---------0---------3       4---------0---------5
3881*27fcede3SMatthew G. Knepley      */
3882*27fcede3SMatthew G. Knepley     /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
3883*27fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
3884*27fcede3SMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
3885*27fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
3886*27fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
3887*27fcede3SMatthew G. Knepley 
3888*27fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
3889*27fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3890*27fcede3SMatthew G. Knepley       /* A hex */
3891*27fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
3892*27fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
3893*27fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
3894*27fcede3SMatthew G. Knepley       orntNew[1] = 0;
3895*27fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
3896*27fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
3897*27fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
3898*27fcede3SMatthew G. Knepley       orntNew[3] = 0;
3899*27fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
3900*27fcede3SMatthew G. Knepley       orntNew[4] = 0;
3901*27fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
3902*27fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
3903*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
3904*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
3905*27fcede3SMatthew G. Knepley #if 1
3906*27fcede3SMatthew 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);
3907*27fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
3908*27fcede3SMatthew 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);
3909*27fcede3SMatthew G. Knepley       }
3910*27fcede3SMatthew G. Knepley #endif
3911*27fcede3SMatthew G. Knepley       /* B hex */
3912*27fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
3913*27fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
3914*27fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
3915*27fcede3SMatthew G. Knepley       orntNew[1] = 0;
3916*27fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
3917*27fcede3SMatthew G. Knepley       orntNew[2] = -1;
3918*27fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
3919*27fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
3920*27fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
3921*27fcede3SMatthew G. Knepley       orntNew[4] = 0;
3922*27fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
3923*27fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
3924*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
3925*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
3926*27fcede3SMatthew G. Knepley #if 1
3927*27fcede3SMatthew 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);
3928*27fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
3929*27fcede3SMatthew 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);
3930*27fcede3SMatthew G. Knepley       }
3931*27fcede3SMatthew G. Knepley #endif
3932*27fcede3SMatthew G. Knepley       /* C hex */
3933*27fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
3934*27fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
3935*27fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
3936*27fcede3SMatthew G. Knepley       orntNew[1] = 0;
3937*27fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3938*27fcede3SMatthew G. Knepley       orntNew[2] = -1;
3939*27fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
3940*27fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
3941*27fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
3942*27fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
3943*27fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
3944*27fcede3SMatthew G. Knepley       orntNew[5] = -4;
3945*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
3946*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
3947*27fcede3SMatthew G. Knepley #if 1
3948*27fcede3SMatthew 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);
3949*27fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
3950*27fcede3SMatthew 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);
3951*27fcede3SMatthew G. Knepley       }
3952*27fcede3SMatthew G. Knepley #endif
3953*27fcede3SMatthew G. Knepley       /* D hex */
3954*27fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
3955*27fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
3956*27fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
3957*27fcede3SMatthew G. Knepley       orntNew[1] = 0;
3958*27fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
3959*27fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
3960*27fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3961*27fcede3SMatthew G. Knepley       orntNew[3] = 0;
3962*27fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
3963*27fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
3964*27fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
3965*27fcede3SMatthew G. Knepley       orntNew[5] = -4;
3966*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
3967*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
3968*27fcede3SMatthew G. Knepley #if 1
3969*27fcede3SMatthew 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);
3970*27fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
3971*27fcede3SMatthew 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);
3972*27fcede3SMatthew G. Knepley       }
3973*27fcede3SMatthew G. Knepley #endif
3974*27fcede3SMatthew G. Knepley       /* E hex */
3975*27fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
3976*27fcede3SMatthew G. Knepley       orntNew[0] = -4;
3977*27fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
3978*27fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
3979*27fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
3980*27fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
3981*27fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
3982*27fcede3SMatthew G. Knepley       orntNew[3] = 0;
3983*27fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3984*27fcede3SMatthew G. Knepley       orntNew[4] = -1;
3985*27fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
3986*27fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
3987*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
3988*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
3989*27fcede3SMatthew G. Knepley #if 1
3990*27fcede3SMatthew 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);
3991*27fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
3992*27fcede3SMatthew 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);
3993*27fcede3SMatthew G. Knepley       }
3994*27fcede3SMatthew G. Knepley #endif
3995*27fcede3SMatthew G. Knepley       /* F hex */
3996*27fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
3997*27fcede3SMatthew G. Knepley       orntNew[0] = -4;
3998*27fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
3999*27fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
4000*27fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
4001*27fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
4002*27fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
4003*27fcede3SMatthew G. Knepley       orntNew[3] = -1;
4004*27fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
4005*27fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
4006*27fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
4007*27fcede3SMatthew G. Knepley       orntNew[5] = 1;
4008*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
4009*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
4010*27fcede3SMatthew G. Knepley #if 1
4011*27fcede3SMatthew 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);
4012*27fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
4013*27fcede3SMatthew 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);
4014*27fcede3SMatthew G. Knepley       }
4015*27fcede3SMatthew G. Knepley #endif
4016*27fcede3SMatthew G. Knepley       /* G hex */
4017*27fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
4018*27fcede3SMatthew G. Knepley       orntNew[0] = -4;
4019*27fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
4020*27fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
4021*27fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
4022*27fcede3SMatthew G. Knepley       orntNew[2] = 0;
4023*27fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
4024*27fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
4025*27fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
4026*27fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
4027*27fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
4028*27fcede3SMatthew G. Knepley       orntNew[5] = -3;
4029*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
4030*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
4031*27fcede3SMatthew G. Knepley #if 1
4032*27fcede3SMatthew 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);
4033*27fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
4034*27fcede3SMatthew 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);
4035*27fcede3SMatthew G. Knepley       }
4036*27fcede3SMatthew G. Knepley #endif
4037*27fcede3SMatthew G. Knepley       /* H hex */
4038*27fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
4039*27fcede3SMatthew G. Knepley       orntNew[0] = -4;
4040*27fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
4041*27fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
4042*27fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
4043*27fcede3SMatthew G. Knepley       orntNew[2] = -1;
4044*27fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
4045*27fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
4046*27fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
4047*27fcede3SMatthew G. Knepley       orntNew[4] = 3;
4048*27fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
4049*27fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
4050*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
4051*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
4052*27fcede3SMatthew G. Knepley #if 1
4053*27fcede3SMatthew 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);
4054*27fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
4055*27fcede3SMatthew 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);
4056*27fcede3SMatthew G. Knepley       }
4057*27fcede3SMatthew G. Knepley #endif
4058*27fcede3SMatthew G. Knepley     }
4059*27fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces: Front, Back, Sides */
4060*27fcede3SMatthew G. Knepley     /*
4061*27fcede3SMatthew G. Knepley      3---------2---------2
4062*27fcede3SMatthew G. Knepley      |         |         |
4063*27fcede3SMatthew G. Knepley      |    D    2    C    |
4064*27fcede3SMatthew G. Knepley      |         |         |
4065*27fcede3SMatthew G. Knepley      3----3----0----1----1
4066*27fcede3SMatthew G. Knepley      |         |         |
4067*27fcede3SMatthew G. Knepley      |    A    0    B    |
4068*27fcede3SMatthew G. Knepley      |         |         |
4069*27fcede3SMatthew G. Knepley      0---------0---------1
4070*27fcede3SMatthew G. Knepley      */
4071*27fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
4072*27fcede3SMatthew G. Knepley       const PetscInt  newp = (cMax - cStart)*8 + (c - cMax)*4;
4073*27fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
4074*27fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
4075*27fcede3SMatthew G. Knepley 
4076*27fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4077*27fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4078*27fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
4079*27fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
4080*27fcede3SMatthew G. Knepley         PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
4081*27fcede3SMatthew G. Knepley         PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
4082*27fcede3SMatthew G. Knepley         PetscInt edgeB = (edgeA+3)%4;
4083*27fcede3SMatthew 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]);
4084*27fcede3SMatthew G. Knepley         coneNew[0]         = fStartNew + (cone[0] - fStart)*4 + subfA;
4085*27fcede3SMatthew G. Knepley         orntNew[0]         = ornt[0];
4086*27fcede3SMatthew G. Knepley         coneNew[1]         = fStartNew + (cone[1] - fStart)*4 + subfA;
4087*27fcede3SMatthew G. Knepley         orntNew[1]         = ornt[0];
4088*27fcede3SMatthew G. Knepley         coneNew[(r+0)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeA+2] - fMax)*2 + (fornt[edgeA] < 0 ? 1 : 0);
4089*27fcede3SMatthew G. Knepley         orntNew[(r+0)%4+2] = ornt[edgeA];
4090*27fcede3SMatthew G. Knepley         coneNew[(r+1)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeA;
4091*27fcede3SMatthew G. Knepley         orntNew[(r+1)%4+2] = 0;
4092*27fcede3SMatthew G. Knepley         coneNew[(r+2)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeB;
4093*27fcede3SMatthew G. Knepley         orntNew[(r+2)%4+2] = -2;
4094*27fcede3SMatthew G. Knepley         coneNew[(r+3)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeB+2] - fMax)*2 + (fornt[edgeB] < 0 ? 0 : 1);
4095*27fcede3SMatthew G. Knepley         orntNew[(r+3)%4+2] = ornt[edgeB];
4096*27fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
4097*27fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
4098*27fcede3SMatthew G. Knepley #if 1
4099*27fcede3SMatthew 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);
4100*27fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
4101*27fcede3SMatthew 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);
4102*27fcede3SMatthew G. Knepley         }
4103*27fcede3SMatthew G. Knepley         for (p = 2; p < 6; ++p) {
4104*27fcede3SMatthew 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);
4105*27fcede3SMatthew G. Knepley         }
4106*27fcede3SMatthew G. Knepley #endif
4107*27fcede3SMatthew G. Knepley       }
4108*27fcede3SMatthew G. Knepley     }
4109*27fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
4110*27fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4111*27fcede3SMatthew G. Knepley     ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
4112*27fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
4113*27fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
4114*27fcede3SMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
4115*27fcede3SMatthew 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};
4116*27fcede3SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
4117*27fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
4118*27fcede3SMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
4119*27fcede3SMatthew G. Knepley 
4120*27fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4121*27fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
4122*27fcede3SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
4123*27fcede3SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
4124*27fcede3SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
4125*27fcede3SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
4126*27fcede3SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
4127*27fcede3SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
4128*27fcede3SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
4129*27fcede3SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
4130*27fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4131*27fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4132*27fcede3SMatthew G. Knepley #if 1
4133*27fcede3SMatthew 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);
4134*27fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
4135*27fcede3SMatthew 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);
4136*27fcede3SMatthew G. Knepley         }
4137*27fcede3SMatthew G. Knepley #endif
4138*27fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
4139*27fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4140*27fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
4141*27fcede3SMatthew G. Knepley           PetscInt subf;
4142*27fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4143*27fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4144*27fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4145*27fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
4146*27fcede3SMatthew G. Knepley             if (cone[c] == f) break;
4147*27fcede3SMatthew G. Knepley           }
4148*27fcede3SMatthew G. Knepley           subf = GetQuadSubfaceInverse_Static(ornt[c], r);
4149*27fcede3SMatthew G. Knepley           if (support[s] < cMax) {
4150*27fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
4151*27fcede3SMatthew G. Knepley           } else {
4152*27fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax       - cStart)*8 + (support[s] - cMax)*4 + subf;
4153*27fcede3SMatthew G. Knepley           }
4154*27fcede3SMatthew G. Knepley         }
4155*27fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4156*27fcede3SMatthew G. Knepley #if 1
4157*27fcede3SMatthew 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);
4158*27fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
4159*27fcede3SMatthew 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);
4160*27fcede3SMatthew G. Knepley         }
4161*27fcede3SMatthew G. Knepley #endif
4162*27fcede3SMatthew G. Knepley       }
4163*27fcede3SMatthew G. Knepley     }
4164*27fcede3SMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
4165*27fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
4166*27fcede3SMatthew 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};
4167*27fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
4168*27fcede3SMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
4169*27fcede3SMatthew G. Knepley 
4170*27fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4171*27fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4172*27fcede3SMatthew G. Knepley       /* A-D face */
4173*27fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
4174*27fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
4175*27fcede3SMatthew G. Knepley       orntNew[0] = 0;
4176*27fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
4177*27fcede3SMatthew G. Knepley       orntNew[1] = 0;
4178*27fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
4179*27fcede3SMatthew G. Knepley       orntNew[2] = -2;
4180*27fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
4181*27fcede3SMatthew G. Knepley       orntNew[3] = -2;
4182*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4183*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4184*27fcede3SMatthew G. Knepley #if 1
4185*27fcede3SMatthew 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);
4186*27fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4187*27fcede3SMatthew 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);
4188*27fcede3SMatthew G. Knepley       }
4189*27fcede3SMatthew G. Knepley #endif
4190*27fcede3SMatthew G. Knepley       /* C-D face */
4191*27fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
4192*27fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
4193*27fcede3SMatthew G. Knepley       orntNew[0] = 0;
4194*27fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
4195*27fcede3SMatthew G. Knepley       orntNew[1] = 0;
4196*27fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
4197*27fcede3SMatthew G. Knepley       orntNew[2] = -2;
4198*27fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
4199*27fcede3SMatthew G. Knepley       orntNew[3] = -2;
4200*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4201*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4202*27fcede3SMatthew G. Knepley #if 1
4203*27fcede3SMatthew 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);
4204*27fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4205*27fcede3SMatthew 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);
4206*27fcede3SMatthew G. Knepley       }
4207*27fcede3SMatthew G. Knepley #endif
4208*27fcede3SMatthew G. Knepley       /* B-C face */
4209*27fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
4210*27fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
4211*27fcede3SMatthew G. Knepley       orntNew[0] = -2;
4212*27fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
4213*27fcede3SMatthew G. Knepley       orntNew[1] = 0;
4214*27fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
4215*27fcede3SMatthew G. Knepley       orntNew[2] = 0;
4216*27fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
4217*27fcede3SMatthew G. Knepley       orntNew[3] = -2;
4218*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4219*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4220*27fcede3SMatthew G. Knepley #if 1
4221*27fcede3SMatthew 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);
4222*27fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4223*27fcede3SMatthew 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);
4224*27fcede3SMatthew G. Knepley       }
4225*27fcede3SMatthew G. Knepley #endif
4226*27fcede3SMatthew G. Knepley       /* A-B face */
4227*27fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
4228*27fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
4229*27fcede3SMatthew G. Knepley       orntNew[0] = -2;
4230*27fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
4231*27fcede3SMatthew G. Knepley       orntNew[1] = 0;
4232*27fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
4233*27fcede3SMatthew G. Knepley       orntNew[2] = 0;
4234*27fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
4235*27fcede3SMatthew G. Knepley       orntNew[3] = -2;
4236*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4237*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4238*27fcede3SMatthew G. Knepley #if 1
4239*27fcede3SMatthew 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);
4240*27fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4241*27fcede3SMatthew 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);
4242*27fcede3SMatthew G. Knepley       }
4243*27fcede3SMatthew G. Knepley #endif
4244*27fcede3SMatthew G. Knepley       /* E-F face */
4245*27fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
4246*27fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
4247*27fcede3SMatthew G. Knepley       orntNew[0] = -2;
4248*27fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
4249*27fcede3SMatthew G. Knepley       orntNew[1] = -2;
4250*27fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
4251*27fcede3SMatthew G. Knepley       orntNew[2] = 0;
4252*27fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
4253*27fcede3SMatthew G. Knepley       orntNew[3] = 0;
4254*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4255*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4256*27fcede3SMatthew G. Knepley #if 1
4257*27fcede3SMatthew 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);
4258*27fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4259*27fcede3SMatthew 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);
4260*27fcede3SMatthew G. Knepley       }
4261*27fcede3SMatthew G. Knepley #endif
4262*27fcede3SMatthew G. Knepley       /* F-G face */
4263*27fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
4264*27fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
4265*27fcede3SMatthew G. Knepley       orntNew[0] = -2;
4266*27fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
4267*27fcede3SMatthew G. Knepley       orntNew[1] = -2;
4268*27fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
4269*27fcede3SMatthew G. Knepley       orntNew[2] = 0;
4270*27fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
4271*27fcede3SMatthew G. Knepley       orntNew[3] = 0;
4272*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4273*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4274*27fcede3SMatthew G. Knepley #if 1
4275*27fcede3SMatthew 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);
4276*27fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4277*27fcede3SMatthew 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);
4278*27fcede3SMatthew G. Knepley       }
4279*27fcede3SMatthew G. Knepley #endif
4280*27fcede3SMatthew G. Knepley       /* G-H face */
4281*27fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
4282*27fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
4283*27fcede3SMatthew G. Knepley       orntNew[0] = -2;
4284*27fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
4285*27fcede3SMatthew G. Knepley       orntNew[1] = 0;
4286*27fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
4287*27fcede3SMatthew G. Knepley       orntNew[2] = 0;
4288*27fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
4289*27fcede3SMatthew G. Knepley       orntNew[3] = -2;
4290*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4291*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4292*27fcede3SMatthew G. Knepley #if 1
4293*27fcede3SMatthew 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);
4294*27fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4295*27fcede3SMatthew 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);
4296*27fcede3SMatthew G. Knepley       }
4297*27fcede3SMatthew G. Knepley #endif
4298*27fcede3SMatthew G. Knepley       /* E-H face */
4299*27fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
4300*27fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
4301*27fcede3SMatthew G. Knepley       orntNew[0] = -2;
4302*27fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
4303*27fcede3SMatthew G. Knepley       orntNew[1] = -2;
4304*27fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
4305*27fcede3SMatthew G. Knepley       orntNew[2] = 0;
4306*27fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
4307*27fcede3SMatthew G. Knepley       orntNew[3] = 0;
4308*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4309*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4310*27fcede3SMatthew G. Knepley #if 1
4311*27fcede3SMatthew 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);
4312*27fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4313*27fcede3SMatthew 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);
4314*27fcede3SMatthew G. Knepley       }
4315*27fcede3SMatthew G. Knepley #endif
4316*27fcede3SMatthew G. Knepley       /* A-E face */
4317*27fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
4318*27fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
4319*27fcede3SMatthew G. Knepley       orntNew[0] = 0;
4320*27fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
4321*27fcede3SMatthew G. Knepley       orntNew[1] = 0;
4322*27fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
4323*27fcede3SMatthew G. Knepley       orntNew[2] = -2;
4324*27fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
4325*27fcede3SMatthew G. Knepley       orntNew[3] = -2;
4326*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4327*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4328*27fcede3SMatthew G. Knepley #if 1
4329*27fcede3SMatthew 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);
4330*27fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4331*27fcede3SMatthew 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);
4332*27fcede3SMatthew G. Knepley       }
4333*27fcede3SMatthew G. Knepley #endif
4334*27fcede3SMatthew G. Knepley       /* D-F face */
4335*27fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
4336*27fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
4337*27fcede3SMatthew G. Knepley       orntNew[0] = -2;
4338*27fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
4339*27fcede3SMatthew G. Knepley       orntNew[1] = 0;
4340*27fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
4341*27fcede3SMatthew G. Knepley       orntNew[2] = 0;
4342*27fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
4343*27fcede3SMatthew G. Knepley       orntNew[3] = -2;
4344*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4345*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4346*27fcede3SMatthew G. Knepley #if 1
4347*27fcede3SMatthew 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);
4348*27fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4349*27fcede3SMatthew 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);
4350*27fcede3SMatthew G. Knepley       }
4351*27fcede3SMatthew G. Knepley #endif
4352*27fcede3SMatthew G. Knepley       /* C-G face */
4353*27fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
4354*27fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
4355*27fcede3SMatthew G. Knepley       orntNew[0] = -2;
4356*27fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
4357*27fcede3SMatthew G. Knepley       orntNew[1] = -2;
4358*27fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
4359*27fcede3SMatthew G. Knepley       orntNew[2] = 0;
4360*27fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
4361*27fcede3SMatthew G. Knepley       orntNew[3] = 0;
4362*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4363*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4364*27fcede3SMatthew G. Knepley #if 1
4365*27fcede3SMatthew 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);
4366*27fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4367*27fcede3SMatthew 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);
4368*27fcede3SMatthew G. Knepley       }
4369*27fcede3SMatthew G. Knepley #endif
4370*27fcede3SMatthew G. Knepley       /* B-H face */
4371*27fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
4372*27fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
4373*27fcede3SMatthew G. Knepley       orntNew[0] = 0;
4374*27fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
4375*27fcede3SMatthew G. Knepley       orntNew[1] = -2;
4376*27fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
4377*27fcede3SMatthew G. Knepley       orntNew[2] = -2;
4378*27fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
4379*27fcede3SMatthew G. Knepley       orntNew[3] = 0;
4380*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4381*27fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4382*27fcede3SMatthew G. Knepley #if 1
4383*27fcede3SMatthew 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);
4384*27fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4385*27fcede3SMatthew 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);
4386*27fcede3SMatthew G. Knepley       }
4387*27fcede3SMatthew G. Knepley #endif
4388*27fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
4389*27fcede3SMatthew G. Knepley         newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
4390*27fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
4391*27fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
4392*27fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4393*27fcede3SMatthew G. Knepley #if 1
4394*27fcede3SMatthew 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);
4395*27fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
4396*27fcede3SMatthew 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);
4397*27fcede3SMatthew G. Knepley         }
4398*27fcede3SMatthew G. Knepley #endif
4399*27fcede3SMatthew G. Knepley       }
4400*27fcede3SMatthew G. Knepley     }
4401*27fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
4402*27fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
4403*27fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
4404*27fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
4405*27fcede3SMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
4406*27fcede3SMatthew G. Knepley 
4407*27fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4408*27fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
4409*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
4410*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4411*27fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
4412*27fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
4413*27fcede3SMatthew G. Knepley 
4414*27fcede3SMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
4415*27fcede3SMatthew G. Knepley         orntNew[0]   = ornt[0];
4416*27fcede3SMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
4417*27fcede3SMatthew G. Knepley         orntNew[1]   = ornt[1];
4418*27fcede3SMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
4419*27fcede3SMatthew G. Knepley         orntNew[2+r] = 0;
4420*27fcede3SMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd      - eMax) + (f - fMax);
4421*27fcede3SMatthew G. Knepley         orntNew[3-r] = 0;
4422*27fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4423*27fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4424*27fcede3SMatthew G. Knepley #if 1
4425*27fcede3SMatthew 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);
4426*27fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
4427*27fcede3SMatthew 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);
4428*27fcede3SMatthew G. Knepley         }
4429*27fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
4430*27fcede3SMatthew 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);
4431*27fcede3SMatthew G. Knepley         }
4432*27fcede3SMatthew G. Knepley #endif
4433*27fcede3SMatthew G. Knepley         for (s = 0; s < size; ++s) {
4434*27fcede3SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
4435*27fcede3SMatthew G. Knepley 
4436*27fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
4437*27fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
4438*27fcede3SMatthew G. Knepley           for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
4439*27fcede3SMatthew 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]);
4440*27fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
4441*27fcede3SMatthew 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;
4442*27fcede3SMatthew G. Knepley         }
4443*27fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4444*27fcede3SMatthew G. Knepley #if 1
4445*27fcede3SMatthew 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);
4446*27fcede3SMatthew G. Knepley         for (p = 0; p < size; ++p) {
4447*27fcede3SMatthew 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);
4448*27fcede3SMatthew G. Knepley         }
4449*27fcede3SMatthew G. Knepley #endif
4450*27fcede3SMatthew G. Knepley       }
4451*27fcede3SMatthew G. Knepley     }
4452*27fcede3SMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
4453*27fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
4454*27fcede3SMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
4455*27fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
4456*27fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
4457*27fcede3SMatthew G. Knepley       PetscInt        supportNew[2];
4458*27fcede3SMatthew G. Knepley 
4459*27fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4460*27fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4461*27fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
4462*27fcede3SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
4463*27fcede3SMatthew G. Knepley         orntNew[0] = 0;
4464*27fcede3SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
4465*27fcede3SMatthew G. Knepley         orntNew[1] = 0;
4466*27fcede3SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
4467*27fcede3SMatthew G. Knepley         orntNew[2] = 0;
4468*27fcede3SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd                                   - fMax) + (c - cMax);
4469*27fcede3SMatthew G. Knepley         orntNew[3] = 0;
4470*27fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
4471*27fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
4472*27fcede3SMatthew G. Knepley #if 1
4473*27fcede3SMatthew 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);
4474*27fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
4475*27fcede3SMatthew 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);
4476*27fcede3SMatthew G. Knepley         }
4477*27fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
4478*27fcede3SMatthew 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);
4479*27fcede3SMatthew G. Knepley         }
4480*27fcede3SMatthew G. Knepley #endif
4481*27fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
4482*27fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
4483*27fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
4484*27fcede3SMatthew G. Knepley #if 1
4485*27fcede3SMatthew 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);
4486*27fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
4487*27fcede3SMatthew 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);
4488*27fcede3SMatthew G. Knepley         }
4489*27fcede3SMatthew G. Knepley #endif
4490*27fcede3SMatthew G. Knepley       }
4491*27fcede3SMatthew G. Knepley     }
4492*27fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
4493*27fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4494*27fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
4495*27fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
4496*27fcede3SMatthew G. Knepley 
4497*27fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
4498*27fcede3SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
4499*27fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
4500*27fcede3SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
4501*27fcede3SMatthew G. Knepley 
4502*27fcede3SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
4503*27fcede3SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
4504*27fcede3SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
4505*27fcede3SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
4506*27fcede3SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4507*27fcede3SMatthew G. Knepley #if 1
4508*27fcede3SMatthew 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);
4509*27fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
4510*27fcede3SMatthew 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);
4511*27fcede3SMatthew G. Knepley         }
4512*27fcede3SMatthew G. Knepley #endif
4513*27fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
4514*27fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
4515*27fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
4516*27fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4517*27fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4518*27fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
4519*27fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
4520*27fcede3SMatthew G. Knepley             if (cone[c] == e) break;
4521*27fcede3SMatthew G. Knepley           }
4522*27fcede3SMatthew G. Knepley           if (support[s] < fMax) {
4523*27fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
4524*27fcede3SMatthew G. Knepley           } else {
4525*27fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
4526*27fcede3SMatthew G. Knepley           }
4527*27fcede3SMatthew G. Knepley         }
4528*27fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4529*27fcede3SMatthew G. Knepley #if 1
4530*27fcede3SMatthew 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);
4531*27fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
4532*27fcede3SMatthew 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);
4533*27fcede3SMatthew G. Knepley         }
4534*27fcede3SMatthew G. Knepley #endif
4535*27fcede3SMatthew G. Knepley       }
4536*27fcede3SMatthew G. Knepley     }
4537*27fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
4538*27fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
4539*27fcede3SMatthew 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};
4540*27fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
4541*27fcede3SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
4542*27fcede3SMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
4543*27fcede3SMatthew G. Knepley 
4544*27fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4545*27fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
4546*27fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
4547*27fcede3SMatthew G. Knepley 
4548*27fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
4549*27fcede3SMatthew G. Knepley         coneNew[1] = newv;
4550*27fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4551*27fcede3SMatthew G. Knepley #if 1
4552*27fcede3SMatthew 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);
4553*27fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
4554*27fcede3SMatthew 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);
4555*27fcede3SMatthew G. Knepley         }
4556*27fcede3SMatthew G. Knepley #endif
4557*27fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
4558*27fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4559*27fcede3SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
4560*27fcede3SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
4561*27fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
4562*27fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
4563*27fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
4564*27fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
4565*27fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
4566*27fcede3SMatthew G. Knepley           if (support[s] < cMax) {
4567*27fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
4568*27fcede3SMatthew G. Knepley           } else {
4569*27fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadEdgeInverse_Static(orntCell[c], r);
4570*27fcede3SMatthew G. Knepley           }
4571*27fcede3SMatthew G. Knepley         }
4572*27fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4573*27fcede3SMatthew G. Knepley #if 1
4574*27fcede3SMatthew 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);
4575*27fcede3SMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
4576*27fcede3SMatthew 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);
4577*27fcede3SMatthew G. Knepley         }
4578*27fcede3SMatthew G. Knepley #endif
4579*27fcede3SMatthew G. Knepley       }
4580*27fcede3SMatthew G. Knepley     }
4581*27fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
4582*27fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
4583*27fcede3SMatthew 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};
4584*27fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
4585*27fcede3SMatthew G. Knepley       const PetscInt *cone;
4586*27fcede3SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
4587*27fcede3SMatthew G. Knepley 
4588*27fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4589*27fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
4590*27fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
4591*27fcede3SMatthew G. Knepley 
4592*27fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
4593*27fcede3SMatthew G. Knepley         coneNew[1] = newv;
4594*27fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4595*27fcede3SMatthew G. Knepley #if 1
4596*27fcede3SMatthew 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);
4597*27fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
4598*27fcede3SMatthew 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);
4599*27fcede3SMatthew G. Knepley         }
4600*27fcede3SMatthew G. Knepley #endif
4601*27fcede3SMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
4602*27fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4603*27fcede3SMatthew G. Knepley #if 1
4604*27fcede3SMatthew 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);
4605*27fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
4606*27fcede3SMatthew 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);
4607*27fcede3SMatthew G. Knepley         }
4608*27fcede3SMatthew G. Knepley #endif
4609*27fcede3SMatthew G. Knepley       }
4610*27fcede3SMatthew G. Knepley     }
4611*27fcede3SMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
4612*27fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
4613*27fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
4614*27fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
4615*27fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
4616*27fcede3SMatthew G. Knepley 
4617*27fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
4618*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
4619*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
4620*27fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
4621*27fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
4622*27fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4623*27fcede3SMatthew G. Knepley #if 1
4624*27fcede3SMatthew 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);
4625*27fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
4626*27fcede3SMatthew 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);
4627*27fcede3SMatthew G. Knepley       }
4628*27fcede3SMatthew G. Knepley #endif
4629*27fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
4630*27fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
4631*27fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
4632*27fcede3SMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
4633*27fcede3SMatthew 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]);
4634*27fcede3SMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
4635*27fcede3SMatthew G. Knepley       }
4636*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4637*27fcede3SMatthew G. Knepley #if 1
4638*27fcede3SMatthew 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);
4639*27fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
4640*27fcede3SMatthew 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);
4641*27fcede3SMatthew G. Knepley       }
4642*27fcede3SMatthew G. Knepley #endif
4643*27fcede3SMatthew G. Knepley     }
4644*27fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
4645*27fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
4646*27fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
4647*27fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
4648*27fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
4649*27fcede3SMatthew G. Knepley 
4650*27fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4651*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
4652*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4653*27fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
4654*27fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
4655*27fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4656*27fcede3SMatthew G. Knepley #if 1
4657*27fcede3SMatthew 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);
4658*27fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
4659*27fcede3SMatthew 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);
4660*27fcede3SMatthew G. Knepley       }
4661*27fcede3SMatthew G. Knepley #endif
4662*27fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
4663*27fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
4664*27fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
4665*27fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
4666*27fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
4667*27fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
4668*27fcede3SMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
4669*27fcede3SMatthew 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]);
4670*27fcede3SMatthew 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);
4671*27fcede3SMatthew G. Knepley       }
4672*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4673*27fcede3SMatthew G. Knepley #if 1
4674*27fcede3SMatthew 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);
4675*27fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
4676*27fcede3SMatthew 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);
4677*27fcede3SMatthew G. Knepley       }
4678*27fcede3SMatthew G. Knepley #endif
4679*27fcede3SMatthew G. Knepley     }
4680*27fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
4681*27fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
4682*27fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
4683*27fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
4684*27fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size;
4685*27fcede3SMatthew G. Knepley 
4686*27fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4687*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr);
4688*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr);
4689*27fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
4690*27fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
4691*27fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4692*27fcede3SMatthew G. Knepley #if 1
4693*27fcede3SMatthew 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);
4694*27fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
4695*27fcede3SMatthew 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);
4696*27fcede3SMatthew G. Knepley       }
4697*27fcede3SMatthew G. Knepley #endif
4698*27fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
4699*27fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
4700*27fcede3SMatthew G. Knepley       supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
4701*27fcede3SMatthew G. Knepley       supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
4702*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4703*27fcede3SMatthew G. Knepley #if 1
4704*27fcede3SMatthew 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);
4705*27fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4706*27fcede3SMatthew 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);
4707*27fcede3SMatthew G. Knepley       }
4708*27fcede3SMatthew G. Knepley #endif
4709*27fcede3SMatthew G. Knepley     }
4710*27fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
4711*27fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
4712*27fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
4713*27fcede3SMatthew G. Knepley       const PetscInt *support, *cone;
4714*27fcede3SMatthew G. Knepley       PetscInt        size, s;
4715*27fcede3SMatthew G. Knepley 
4716*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
4717*27fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
4718*27fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
4719*27fcede3SMatthew G. Knepley         PetscInt r = 0;
4720*27fcede3SMatthew G. Knepley 
4721*27fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4722*27fcede3SMatthew G. Knepley         if (cone[1] == v) r = 1;
4723*27fcede3SMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
4724*27fcede3SMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
4725*27fcede3SMatthew G. Knepley       }
4726*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4727*27fcede3SMatthew G. Knepley #if 1
4728*27fcede3SMatthew 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);
4729*27fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
4730*27fcede3SMatthew 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);
4731*27fcede3SMatthew G. Knepley       }
4732*27fcede3SMatthew G. Knepley #endif
4733*27fcede3SMatthew G. Knepley     }
4734*27fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
4735*27fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
4736*27fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
4737*27fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
4738*27fcede3SMatthew G. Knepley       PetscInt        size, s;
4739*27fcede3SMatthew G. Knepley 
4740*27fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
4741*27fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
4742*27fcede3SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
4743*27fcede3SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
4744*27fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
4745*27fcede3SMatthew G. Knepley         PetscInt r;
4746*27fcede3SMatthew G. Knepley 
4747*27fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4748*27fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
4749*27fcede3SMatthew G. Knepley         if (support[s] < fMax) {
4750*27fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
4751*27fcede3SMatthew G. Knepley         } else {
4752*27fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
4753*27fcede3SMatthew G. Knepley         }
4754*27fcede3SMatthew G. Knepley       }
4755*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4756*27fcede3SMatthew G. Knepley #if 1
4757*27fcede3SMatthew 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);
4758*27fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
4759*27fcede3SMatthew 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);
4760*27fcede3SMatthew G. Knepley       }
4761*27fcede3SMatthew G. Knepley #endif
4762*27fcede3SMatthew G. Knepley     }
4763*27fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
4764*27fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
4765*27fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
4766*27fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
4767*27fcede3SMatthew G. Knepley       PetscInt        size, s;
4768*27fcede3SMatthew G. Knepley 
4769*27fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
4770*27fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
4771*27fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 +  (f - fStart)*4 + r;
4772*27fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
4773*27fcede3SMatthew G. Knepley         PetscInt r;
4774*27fcede3SMatthew G. Knepley 
4775*27fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4776*27fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
4777*27fcede3SMatthew G. Knepley         if (support[s] < cMax) {
4778*27fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
4779*27fcede3SMatthew G. Knepley         } else {
4780*27fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax       - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
4781*27fcede3SMatthew G. Knepley         }
4782*27fcede3SMatthew G. Knepley       }
4783*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
4784*27fcede3SMatthew G. Knepley #if 1
4785*27fcede3SMatthew 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);
4786*27fcede3SMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
4787*27fcede3SMatthew 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);
4788*27fcede3SMatthew G. Knepley       }
4789*27fcede3SMatthew G. Knepley #endif
4790*27fcede3SMatthew G. Knepley     }
4791*27fcede3SMatthew G. Knepley     /* Cell vertices have 6 supports */
4792*27fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
4793*27fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
4794*27fcede3SMatthew G. Knepley       PetscInt       supportNew[6];
4795*27fcede3SMatthew G. Knepley 
4796*27fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
4797*27fcede3SMatthew G. Knepley         supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
4798*27fcede3SMatthew G. Knepley       }
4799*27fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
4800*27fcede3SMatthew G. Knepley     }
4801*27fcede3SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
4802*27fcede3SMatthew G. Knepley     break;
480375d3a19aSMatthew G. Knepley   default:
480475d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
480575d3a19aSMatthew G. Knepley   }
480675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
480775d3a19aSMatthew G. Knepley }
480875d3a19aSMatthew G. Knepley 
480975d3a19aSMatthew G. Knepley #undef __FUNCT__
481075d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates"
481186150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
481275d3a19aSMatthew G. Knepley {
481375d3a19aSMatthew G. Knepley   PetscSection   coordSection, coordSectionNew;
481475d3a19aSMatthew G. Knepley   Vec            coordinates, coordinatesNew;
481575d3a19aSMatthew G. Knepley   PetscScalar   *coords, *coordsNew;
48163478d7aaSMatthew G. Knepley   const PetscInt numVertices = depthSize ? depthSize[0] : 0;
4817*27fcede3SMatthew G. Knepley   PetscInt       dim, depth, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
481875d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
481975d3a19aSMatthew G. Knepley 
482075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
482175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
482275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
482375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
4824b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
482575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
482675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
4827*27fcede3SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr);
48283478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);}
482975d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);
483075d3a19aSMatthew G. Knepley   ierr = DMPlexGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
483175d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
483275d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
483375d3a19aSMatthew G. Knepley   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr);
48343478d7aaSMatthew G. Knepley   ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
4835*27fcede3SMatthew G. Knepley   if (cMax < 0) cMax = cEnd;
483675d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
4837b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
483875d3a19aSMatthew G. Knepley   /* All vertices have the dim coordinates */
48393478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
484075d3a19aSMatthew G. Knepley     ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr);
484175d3a19aSMatthew G. Knepley     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr);
484275d3a19aSMatthew G. Knepley   }
484375d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
484475d3a19aSMatthew G. Knepley   ierr = DMPlexSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr);
484575d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
484675d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
484775d3a19aSMatthew G. Knepley   ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr);
484875d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
484975d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
485075d3a19aSMatthew G. Knepley   ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr);
485175d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
485275d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
4853b5da9499SMatthew G. Knepley   switch (refiner) {
48543478d7aaSMatthew G. Knepley   case 0: break;
4855b5da9499SMatthew G. Knepley   case 6: /* Hex 3D */
4856d856d60fSMatthew G. Knepley   case 8: /* Hybrid Hex 3D */
4857b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
4858d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
4859*27fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
4860b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
4861b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
4862b5da9499SMatthew G. Knepley 
4863b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
4864b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
4865b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
4866b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
4867b5da9499SMatthew G. Knepley       }
4868b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
4869b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
4870b5da9499SMatthew G. Knepley       }
4871b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
4872b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
4873b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
4874b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
4875b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
4876b5da9499SMatthew G. Knepley       }
4877b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
4878b5da9499SMatthew G. Knepley     }
4879b5da9499SMatthew G. Knepley   case 2: /* Hex 2D */
4880b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
4881*27fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
4882*27fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
4883b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
4884b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
4885b5da9499SMatthew G. Knepley 
4886b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
4887b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
4888b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
4889b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
4890b5da9499SMatthew G. Knepley       }
4891b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
4892b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
4893b5da9499SMatthew G. Knepley       }
4894b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
4895b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
4896b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.0;
4897b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d];
4898b5da9499SMatthew G. Knepley         coordsNew[offnew+d] /= coneSize;
4899b5da9499SMatthew G. Knepley       }
4900b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
4901b5da9499SMatthew G. Knepley     }
4902b5da9499SMatthew G. Knepley   case 1: /* Simplicial 2D */
4903b5da9499SMatthew G. Knepley   case 3: /* Hybrid Simplicial 2D */
4904b5da9499SMatthew G. Knepley   case 5: /* Simplicial 3D */
49056ce3c06aSMatthew G. Knepley   case 7: /* Hybrid Simplicial 3D */
4906b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
4907b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
4908b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
4909b5da9499SMatthew G. Knepley       const PetscInt *cone;
4910b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
4911b5da9499SMatthew G. Knepley 
4912b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
4913b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
4914b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
4915b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
4916b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
4917b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
4918b5da9499SMatthew G. Knepley       for (d = 0; d < dim; ++d) {
4919b5da9499SMatthew G. Knepley         coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]);
4920b5da9499SMatthew G. Knepley       }
4921b5da9499SMatthew G. Knepley     }
492275d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
492375d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
492475d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
492575d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
492675d3a19aSMatthew G. Knepley 
492775d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
492875d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
492975d3a19aSMatthew G. Knepley       for (d = 0; d < dim; ++d) {
493075d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
493175d3a19aSMatthew G. Knepley       }
493275d3a19aSMatthew G. Knepley     }
4933b5da9499SMatthew G. Knepley     break;
4934b5da9499SMatthew G. Knepley   default:
4935b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
493675d3a19aSMatthew G. Knepley   }
493775d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
493875d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
493975d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
494075d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
494175d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
494275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
494375d3a19aSMatthew G. Knepley }
494475d3a19aSMatthew G. Knepley 
494575d3a19aSMatthew G. Knepley #undef __FUNCT__
494675d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF"
494786150812SJed Brown static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
494875d3a19aSMatthew G. Knepley {
494975d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
495075d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
495175d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
495275d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
495375d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
495475d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
495575d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
495675d3a19aSMatthew G. Knepley 
495775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
495875d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
4959785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
496075d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
496175d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
496275d3a19aSMatthew G. Knepley   }
496375d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
4964785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &ranksNew);CHKERRQ(ierr);
4965785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &localPointsNew);CHKERRQ(ierr);
4966785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
496775d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
496875d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
496975d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
497075d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
497175d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
497275d3a19aSMatthew G. Knepley   }
497375d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
497475d3a19aSMatthew G. Knepley   ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);
497575d3a19aSMatthew G. Knepley   ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
497675d3a19aSMatthew G. Knepley   ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
497775d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
497875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
497975d3a19aSMatthew G. Knepley }
498075d3a19aSMatthew G. Knepley 
498175d3a19aSMatthew G. Knepley #undef __FUNCT__
498275d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF"
498386150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
498475d3a19aSMatthew G. Knepley {
498575d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
498675d3a19aSMatthew G. Knepley   IS                 processRanks;
498775d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
498875d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
498975d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
499075d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
499175d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
499275d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
499375d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
49947ba685a0SMatthew G. Knepley   PetscInt           depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
49957ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
499675d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
499775d3a19aSMatthew G. Knepley 
499875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
499975d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
500075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
500175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
500275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
500375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
500475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
500575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
50063478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
500775d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
500875d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
500975d3a19aSMatthew G. Knepley   /* Caculate size of new SF */
501075d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
501175d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
501275d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
501375d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
501475d3a19aSMatthew G. Knepley 
501575d3a19aSMatthew G. Knepley     switch (refiner) {
501675d3a19aSMatthew G. Knepley     case 1:
501775d3a19aSMatthew G. Knepley       /* Simplicial 2D */
501875d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
501975d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
502075d3a19aSMatthew G. Knepley         ++numLeavesNew;
502175d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
502275d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
5023d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
502475d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
502575d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
502675d3a19aSMatthew G. Knepley         numLeavesNew += 4 + 3;
502775d3a19aSMatthew G. Knepley       }
502875d3a19aSMatthew G. Knepley       break;
502975d3a19aSMatthew G. Knepley     case 2:
503075d3a19aSMatthew G. Knepley       /* Hex 2D */
503175d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
503275d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
503375d3a19aSMatthew G. Knepley         ++numLeavesNew;
503475d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
503575d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
5036d963de37SMatthew G. Knepley         numLeavesNew += 2 + 1;
503775d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5038455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
5039455d6cd4SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
504075d3a19aSMatthew G. Knepley       }
504175d3a19aSMatthew G. Knepley       break;
5042b5da9499SMatthew G. Knepley     case 5:
5043b5da9499SMatthew G. Knepley       /* Simplicial 3D */
5044b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5045b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
5046b5da9499SMatthew G. Knepley         ++numLeavesNew;
5047b5da9499SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
5048b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
5049b5da9499SMatthew G. Knepley         numLeavesNew += 2 + 1;
5050b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
5051b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
5052b5da9499SMatthew G. Knepley         numLeavesNew += 4 + 3;
5053b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5054b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
5055b5da9499SMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
5056b5da9499SMatthew G. Knepley       }
5057b5da9499SMatthew G. Knepley       break;
50586ce3c06aSMatthew G. Knepley     case 7:
50596ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
50606ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
50616ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
50626ce3c06aSMatthew G. Knepley         ++numLeavesNew;
50636ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
50646ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
50656ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
50666ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
50676ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
50686ce3c06aSMatthew G. Knepley         ++numLeavesNew;
50696ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
50706ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
50716ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
50726ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
50736ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
50746ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
50756ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
50766ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
50776ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
50786ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
50796ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
50806ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
50816ce3c06aSMatthew G. Knepley       }
50826ce3c06aSMatthew G. Knepley       break;
50832eabf88fSMatthew G. Knepley     case 6:
50842eabf88fSMatthew G. Knepley       /* Hex 3D */
50852eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
50862eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
50872eabf88fSMatthew G. Knepley         ++numLeavesNew;
50882eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
50892eabf88fSMatthew G. Knepley         /* Old edges add new edges, and vertex */
50902eabf88fSMatthew G. Knepley         numLeavesNew += 2 + 1;
50912eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
50922eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
50932eabf88fSMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
50942eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
50952eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
50962eabf88fSMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
50972eabf88fSMatthew G. Knepley       }
50982eabf88fSMatthew G. Knepley       break;
5099*27fcede3SMatthew G. Knepley     case 8:
5100*27fcede3SMatthew G. Knepley       /* Hybrid Hex 3D */
5101*27fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5102*27fcede3SMatthew G. Knepley         /* Old vertices stay the same */
5103*27fcede3SMatthew G. Knepley         ++numLeavesNew;
5104*27fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
5105*27fcede3SMatthew G. Knepley         /* Interior edges add new edges, and vertex */
5106*27fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
5107*27fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
5108*27fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
5109*27fcede3SMatthew G. Knepley         ++numLeavesNew;
5110*27fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5111*27fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
5112*27fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
5113*27fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5114*27fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
5115*27fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
5116*27fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5117*27fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
5118*27fcede3SMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
5119*27fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5120*27fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
5121*27fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
5122*27fcede3SMatthew G. Knepley       }
5123*27fcede3SMatthew G. Knepley       break;
512475d3a19aSMatthew G. Knepley     default:
512575d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
512675d3a19aSMatthew G. Knepley     }
512775d3a19aSMatthew G. Knepley   }
512875d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
512975d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
513075d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
5131dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
5132dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
513375d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
513475d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
513575d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
513675d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
513775d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
513875d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
513975d3a19aSMatthew G. Knepley   }
514075d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
514175d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
514275d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
514375d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
514475d3a19aSMatthew G. Knepley 
514575d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
514675d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
514775d3a19aSMatthew G. Knepley 
514875d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
514975d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
515075d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
515175d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
515275d3a19aSMatthew G. Knepley 
515375d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
515475d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
515575d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
515675d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
515775d3a19aSMatthew G. Knepley   }
515875d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
515975d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
516075d3a19aSMatthew G. Knepley   /* Calculate new point SF */
5161785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew,    &localPointsNew);CHKERRQ(ierr);
5162785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
516375d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
516475d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
516575d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
516675d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
516775d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
516875d3a19aSMatthew G. Knepley 
516975d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
517075d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
517175d3a19aSMatthew G. Knepley     switch (refiner) {
517275d3a19aSMatthew G. Knepley     case 1:
517375d3a19aSMatthew G. Knepley       /* Simplicial 2D */
517475d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
517575d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
517675d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
517775d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
517875d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
517975d3a19aSMatthew G. Knepley         ++m;
518075d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
518175d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
518275d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
518375d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
518475d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
518575d3a19aSMatthew G. Knepley         ++m;
518675d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
518775d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
518875d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
518975d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
519075d3a19aSMatthew G. Knepley         }
519175d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
519275d3a19aSMatthew G. Knepley         /* Old cells add new cells and interior faces */
519375d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
519475d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
519575d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
519675d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
519775d3a19aSMatthew G. Knepley         }
519875d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
519975d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*3     + r;
520075d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r;
520175d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
520275d3a19aSMatthew G. Knepley         }
520375d3a19aSMatthew G. Knepley       }
520475d3a19aSMatthew G. Knepley       break;
520575d3a19aSMatthew G. Knepley     case 2:
520675d3a19aSMatthew G. Knepley       /* Hex 2D */
520775d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
520875d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
520975d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
521075d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
521175d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
521275d3a19aSMatthew G. Knepley         ++m;
521375d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
521475d3a19aSMatthew G. Knepley         /* Old faces add new faces and vertex */
521575d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
521675d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
521775d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
521875d3a19aSMatthew G. Knepley         ++m;
521975d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
522075d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
522175d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
522275d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
522375d3a19aSMatthew G. Knepley         }
522475d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5225455d6cd4SMatthew G. Knepley         /* Old cells add new cells, interior faces, and vertex */
522675d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
522775d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
522875d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
522975d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
523075d3a19aSMatthew G. Knepley         }
523175d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
523275d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*2                    + (p  - cStart)*4     + r;
523375d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r;
523475d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
523575d3a19aSMatthew G. Knepley         }
5236455d6cd4SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
5237455d6cd4SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (fEnd - fStart)                    + (p  - cStart)     + r;
5238455d6cd4SMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
5239455d6cd4SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5240455d6cd4SMatthew G. Knepley         }
524175d3a19aSMatthew G. Knepley       }
524275d3a19aSMatthew G. Knepley       break;
524375d3a19aSMatthew G. Knepley     case 3:
524475d3a19aSMatthew G. Knepley       /* Hybrid simplicial 2D */
524575d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
524675d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
524775d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
524875d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
524975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
525075d3a19aSMatthew G. Knepley         ++m;
525175d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
525275d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
525375d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
525475d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
525575d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
525675d3a19aSMatthew G. Knepley         ++m;
525775d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
525875d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
525975d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
526075d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
526175d3a19aSMatthew G. Knepley         }
526275d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
526375d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
526475d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
526575d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
526675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
526775d3a19aSMatthew G. Knepley         ++m;
526875d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
526975d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
527075d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
527175d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
527275d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
527375d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
527475d3a19aSMatthew G. Knepley         }
527575d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
527675d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
527775d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
527875d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
527975d3a19aSMatthew G. Knepley         }
528075d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
528175d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
528275d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
528375d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
528475d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
528575d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
528675d3a19aSMatthew G. Knepley         }
528775d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
528875d3a19aSMatthew 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]);
528975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
529075d3a19aSMatthew G. Knepley         ++m;
529175d3a19aSMatthew G. Knepley       }
529275d3a19aSMatthew G. Knepley       break;
5293b5da9499SMatthew G. Knepley     case 5:
5294b5da9499SMatthew G. Knepley       /* Simplicial 3D */
5295b5da9499SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5296b5da9499SMatthew G. Knepley         /* Old vertices stay the same */
5297b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
5298b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5299b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5300b5da9499SMatthew G. Knepley         ++m;
530187fe6628SMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
5302b5da9499SMatthew G. Knepley         /* Old edges add new edges and vertex */
5303b5da9499SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5304b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
5305b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
5306b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5307b5da9499SMatthew G. Knepley         }
5308b5da9499SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
5309b5da9499SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
5310b5da9499SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5311b5da9499SMatthew G. Knepley         ++m;
5312b5da9499SMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
5313b5da9499SMatthew G. Knepley         /* Old faces add new faces and face edges */
5314b5da9499SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5315b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
5316b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
5317b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5318b5da9499SMatthew G. Knepley         }
5319b5da9499SMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
5320b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*3     + r;
5321b5da9499SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r;
5322b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5323b5da9499SMatthew G. Knepley         }
5324b5da9499SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
5325b5da9499SMatthew G. Knepley         /* Old cells add new cells and interior faces and edges */
5326b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
5327b5da9499SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
5328b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
5329b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5330b5da9499SMatthew G. Knepley         }
5331b5da9499SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
5332b5da9499SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*8     + r;
5333b5da9499SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r;
5334b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5335b5da9499SMatthew G. Knepley         }
5336b5da9499SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
5337b5da9499SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*3                    + (p  - cStart)*1     + r;
5338b5da9499SMatthew 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;
5339b5da9499SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5340b5da9499SMatthew G. Knepley         }
5341b5da9499SMatthew G. Knepley       }
5342b5da9499SMatthew G. Knepley       break;
53436ce3c06aSMatthew G. Knepley     case 7:
53446ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
53456ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
53466ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
53476ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
53486ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
53496ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
53506ce3c06aSMatthew G. Knepley         ++m;
53516ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
53526ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
53536ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
53546ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
53556ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
53566ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
53576ce3c06aSMatthew G. Knepley         }
53586ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
53596ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
53606ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
53616ce3c06aSMatthew G. Knepley         ++m;
53626ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
53636ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
53646ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
53656ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rp - rdepthMaxOld[n*(depth+1)+1]);
53666ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
53676ce3c06aSMatthew G. Knepley         ++m;
53686ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
53696ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
53706ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
53716ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
53726ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
53736ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
53746ce3c06aSMatthew G. Knepley         }
53756ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
53766ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
53776ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
53786ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
53796ce3c06aSMatthew G. Knepley         }
53806ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
53816ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
53826ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5383899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
5384899f98d0SMatthew 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;
53856ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
53866ce3c06aSMatthew G. Knepley         }
5387899f98d0SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - fMax);
5388899f98d0SMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
53896ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
539009b1338fSMatthew G. Knepley         ++m;
53916ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
53926ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
53936ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
53946ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
53956ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
53966ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
53976ce3c06aSMatthew G. Knepley         }
53986ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
53996ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
54006ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
54016ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54026ce3c06aSMatthew G. Knepley         }
54036ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + r;
54046ce3c06aSMatthew 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;
54056ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
540609b1338fSMatthew G. Knepley         ++m;
54076ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
54086ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
54096ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
54106ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
54116ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
54126ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54136ce3c06aSMatthew G. Knepley         }
54146ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
5415899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*3                            + r;
5416899f98d0SMatthew 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;
54176ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54186ce3c06aSMatthew G. Knepley         }
54196ce3c06aSMatthew G. Knepley       }
54206ce3c06aSMatthew G. Knepley       break;
54212eabf88fSMatthew G. Knepley     case 6:
54222eabf88fSMatthew G. Knepley       /* Hex 3D */
54232eabf88fSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
54242eabf88fSMatthew G. Knepley         /* Old vertices stay the same */
54252eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
54262eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
54272eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
54282eabf88fSMatthew G. Knepley         ++m;
54292eabf88fSMatthew G. Knepley       } else if ((p >= eStart) && (p < eEnd)) {
54302eabf88fSMatthew G. Knepley         /* Old edges add new edges and vertex */
54312eabf88fSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
54322eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
54332eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
54342eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54352eabf88fSMatthew G. Knepley         }
54362eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
54372eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
54382eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
54392eabf88fSMatthew G. Knepley         ++m;
54402eabf88fSMatthew G. Knepley       } else if ((p >= fStart) && (p < fEnd)) {
54412eabf88fSMatthew G. Knepley         /* Old faces add new faces, edges, and vertex */
54422eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
54432eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
54442eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
54452eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54462eabf88fSMatthew G. Knepley         }
54472eabf88fSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
54482eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (p  - fStart)*4     + r;
54492eabf88fSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r;
54502eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54512eabf88fSMatthew G. Knepley         }
54522eabf88fSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eEnd - eStart)              + (p  - fStart);
54532eabf88fSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]);
54542eabf88fSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
54552eabf88fSMatthew G. Knepley         ++m;
54562eabf88fSMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
54572eabf88fSMatthew G. Knepley         /* Old cells add new cells, faces, edges, and vertex */
54582eabf88fSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
54592eabf88fSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
54602eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
54612eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54622eabf88fSMatthew G. Knepley         }
54632eabf88fSMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
54642eabf88fSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fEnd - fStart)*4                    + (p  - cStart)*12     + r;
54652eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r;
54662eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54672eabf88fSMatthew G. Knepley         }
54682eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
54692eabf88fSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eEnd - eStart)*2              + (fEnd - fStart)*4                    + (p  - cStart)*6     + r;
54702eabf88fSMatthew 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;
54712eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54722eabf88fSMatthew G. Knepley         }
54732eabf88fSMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
54742eabf88fSMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eEnd - eStart)              + (fEnd - fStart)                    + (p  - cStart)     + r;
54752eabf88fSMatthew G. Knepley           remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r;
54762eabf88fSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
54772eabf88fSMatthew G. Knepley         }
54782eabf88fSMatthew G. Knepley       }
54792eabf88fSMatthew G. Knepley       break;
5480*27fcede3SMatthew G. Knepley     case 8:
5481*27fcede3SMatthew G. Knepley       /* Hybrid Hex 3D */
5482*27fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5483*27fcede3SMatthew G. Knepley         /* Interior vertices stay the same */
5484*27fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
5485*27fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5486*27fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5487*27fcede3SMatthew G. Knepley         ++m;
5488*27fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
5489*27fcede3SMatthew G. Knepley         /* Interior edges add new edges and vertex */
5490*27fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5491*27fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
5492*27fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
5493*27fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5494*27fcede3SMatthew G. Knepley         }
5495*27fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
5496*27fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
5497*27fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5498*27fcede3SMatthew G. Knepley         ++m;
5499*27fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
5500*27fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
5501*27fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (p  - eMax);
5502*27fcede3SMatthew 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]);
5503*27fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5504*27fcede3SMatthew G. Knepley         ++m;
5505*27fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5506*27fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
5507*27fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5508*27fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
5509*27fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
5510*27fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5511*27fcede3SMatthew G. Knepley         }
5512*27fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5513*27fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*4     + r;
5514*27fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
5515*27fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5516*27fcede3SMatthew G. Knepley         }
5517*27fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eMax                        - eStart)     + (p  - fStart);
5518*27fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
5519*27fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5520*27fcede3SMatthew G. Knepley         ++m;
5521*27fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5522*27fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
5523*27fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5524*27fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
5525*27fcede3SMatthew 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;
5526*27fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5527*27fcede3SMatthew G. Knepley         }
5528*27fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (fEnd                                          - fMax);
5529*27fcede3SMatthew 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]);
5530*27fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5531*27fcede3SMatthew G. Knepley         ++m;
5532*27fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5533*27fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
5534*27fcede3SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
5535*27fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
5536*27fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
5537*27fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5538*27fcede3SMatthew G. Knepley         }
5539*27fcede3SMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
5540*27fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*12     + r;
5541*27fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
5542*27fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5543*27fcede3SMatthew G. Knepley         }
5544*27fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
5545*27fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (p  - cStart)*6     + r;
5546*27fcede3SMatthew 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;
5547*27fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5548*27fcede3SMatthew G. Knepley         }
5549*27fcede3SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
5550*27fcede3SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eMax                        - eStart)     + (fMax                              - fStart)     + (p  - cStart)     + r;
5551*27fcede3SMatthew 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;
5552*27fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5553*27fcede3SMatthew G. Knepley         }
5554*27fcede3SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
5555*27fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
5556*27fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5557*27fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
5558*27fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
5559*27fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5560*27fcede3SMatthew G. Knepley         }
5561*27fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5562*27fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*4                            + r;
5563*27fcede3SMatthew 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;
5564*27fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5565*27fcede3SMatthew G. Knepley         }
5566*27fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (fEnd                                          - fMax)                              + (p  - cMax);
5567*27fcede3SMatthew 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]);
5568*27fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5569*27fcede3SMatthew G. Knepley         ++m;
5570*27fcede3SMatthew G. Knepley       }
5571*27fcede3SMatthew G. Knepley       break;
557275d3a19aSMatthew G. Knepley     default:
557375d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
557475d3a19aSMatthew G. Knepley     }
557575d3a19aSMatthew G. Knepley   }
557609b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
557775d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
557875d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
557975d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
558075d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
558106a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
558275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
558375d3a19aSMatthew G. Knepley }
558475d3a19aSMatthew G. Knepley 
558575d3a19aSMatthew G. Knepley #undef __FUNCT__
558675d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels"
558786150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
558875d3a19aSMatthew G. Knepley {
558975d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
55907ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
55917ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
559275d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
559375d3a19aSMatthew G. Knepley 
559475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
559575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
559675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
559775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
559875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
5599d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
56003478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
560175d3a19aSMatthew G. Knepley   ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
560275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
560375d3a19aSMatthew G. Knepley   switch (refiner) {
56043478d7aaSMatthew G. Knepley   case 0: break;
560558b8852aSMatthew G. Knepley   case 7:
560658b8852aSMatthew G. Knepley   case 8:
560758b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
560875d3a19aSMatthew G. Knepley   case 3:
560958b8852aSMatthew G. Knepley   case 4:
561075d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
561175d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
561275d3a19aSMatthew G. Knepley   }
561375d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
561475d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
561575d3a19aSMatthew G. Knepley     const char     *lname;
561675d3a19aSMatthew G. Knepley     PetscBool       isDepth;
561775d3a19aSMatthew G. Knepley     IS              valueIS;
561875d3a19aSMatthew G. Knepley     const PetscInt *values;
561975d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
562075d3a19aSMatthew G. Knepley 
562175d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr);
562275d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
562375d3a19aSMatthew G. Knepley     if (isDepth) continue;
562475d3a19aSMatthew G. Knepley     ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr);
562575d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr);
562675d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
562775d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
562875d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
562975d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
563075d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
563175d3a19aSMatthew G. Knepley       IS              pointIS;
563275d3a19aSMatthew G. Knepley       const PetscInt *points;
563375d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
563475d3a19aSMatthew G. Knepley 
563575d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
563675d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
563775d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
563875d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
563975d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
564075d3a19aSMatthew G. Knepley         switch (refiner) {
564175d3a19aSMatthew G. Knepley         case 1:
564275d3a19aSMatthew G. Knepley           /* Simplicial 2D */
564375d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
564475d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
564575d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
564675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
564775d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
564875d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
564975d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
565075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
565175d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
565275d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
565375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
565475d3a19aSMatthew G. Knepley             }
565575d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
565675d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
565775d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
565875d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
565975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
566075d3a19aSMatthew G. Knepley             }
566175d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
566275d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
566375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
566475d3a19aSMatthew G. Knepley             }
566575d3a19aSMatthew G. Knepley           }
566675d3a19aSMatthew G. Knepley           break;
566775d3a19aSMatthew G. Knepley         case 2:
566875d3a19aSMatthew G. Knepley           /* Hex 2D */
566975d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
567075d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
567175d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
567275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
567375d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
567475d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
567575d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
567675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
567775d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
567875d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
567975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
568075d3a19aSMatthew G. Knepley             }
568175d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
568275d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
568375d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
568475d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
568575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
568675d3a19aSMatthew G. Knepley             }
568775d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
568875d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
568975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
569075d3a19aSMatthew G. Knepley             }
569175d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
569275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
569375d3a19aSMatthew G. Knepley           }
569475d3a19aSMatthew G. Knepley           break;
569575d3a19aSMatthew G. Knepley         case 3:
569675d3a19aSMatthew G. Knepley           /* Hybrid simplicial 2D */
569775d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
569875d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
569975d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
570075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
570175d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
570275d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
570375d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
570475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
570575d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
570675d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
570775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
570875d3a19aSMatthew G. Knepley             }
570975d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
571075d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
571175d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
571275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
571375d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
571475d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
571575d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
571675d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
571775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
571875d3a19aSMatthew G. Knepley             }
571975d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
572075d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
572175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
572275d3a19aSMatthew G. Knepley             }
572375d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
572475d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
572575d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
572675d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
572775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
572875d3a19aSMatthew G. Knepley             }
572975d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
573075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
573175d3a19aSMatthew G. Knepley           }
573275d3a19aSMatthew G. Knepley           break;
5733b5da9499SMatthew G. Knepley         case 5:
5734b5da9499SMatthew G. Knepley           /* Simplicial 3D */
5735b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
5736b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
5737b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
5738b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5739b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
5740b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
5741b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
5742b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
5743b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5744b5da9499SMatthew G. Knepley             }
5745b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
5746b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5747b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
5748b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
5749b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
5750b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
5751b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5752b5da9499SMatthew G. Knepley             }
5753b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
5754b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
5755b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5756b5da9499SMatthew G. Knepley             }
5757b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
5758b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
5759b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
5760b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
5761b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5762b5da9499SMatthew G. Knepley             }
5763b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
5764b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
5765b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5766b5da9499SMatthew G. Knepley             }
5767b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
5768b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
5769b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5770b5da9499SMatthew G. Knepley             }
5771b5da9499SMatthew G. Knepley           }
5772b5da9499SMatthew G. Knepley           break;
57736ce3c06aSMatthew G. Knepley         case 7:
57746ce3c06aSMatthew G. Knepley           /* Hybrid Simplicial 3D */
57756ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
57766ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
57776ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
57786ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
57796ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
57806ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
57816ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
57826ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
57836ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
57846ce3c06aSMatthew G. Knepley             }
57856ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
57866ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
57876ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
57886ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
57896ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
57906ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
57916ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
57926ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
57936ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
57946ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
57956ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
57966ce3c06aSMatthew G. Knepley             }
57976ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
57986ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
57996ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58006ce3c06aSMatthew G. Knepley             }
58016ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
58026ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
58036ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
58046ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
58056ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58066ce3c06aSMatthew G. Knepley             }
58076ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
58086ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58096ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
58106ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
58116ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
58126ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
58136ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58146ce3c06aSMatthew G. Knepley             }
58156ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
58166ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
58176ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58186ce3c06aSMatthew G. Knepley             }
58196ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
58206ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
582158b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
58226ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
58236ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
58246ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
58256ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58266ce3c06aSMatthew G. Knepley             }
58276ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
58286ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
58296ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58306ce3c06aSMatthew G. Knepley             }
58316ce3c06aSMatthew G. Knepley           }
58326ce3c06aSMatthew G. Knepley           break;
58332eabf88fSMatthew G. Knepley         case 6:
58342eabf88fSMatthew G. Knepley           /* Hex 3D */
58352eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
58362eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
58372eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
58382eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
583919d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
58402eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
58412eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
58422eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
58432eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58442eabf88fSMatthew G. Knepley             }
58452eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
58462eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58472eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
58482eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
58492eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
58502eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
58512eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58522eabf88fSMatthew G. Knepley             }
58532eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
58542eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
58552eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58562eabf88fSMatthew G. Knepley             }
58572eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
58582eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58592eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
58602eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
58612eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
58622eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
58632eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58642eabf88fSMatthew G. Knepley             }
58652eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
58662eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
58672eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58682eabf88fSMatthew G. Knepley             }
58692eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
58702eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
58712eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58722eabf88fSMatthew G. Knepley             }
58732eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
58742eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
58752eabf88fSMatthew G. Knepley           }
58762eabf88fSMatthew G. Knepley           break;
5877*27fcede3SMatthew G. Knepley         case 8:
5878*27fcede3SMatthew G. Knepley           /* Hybrid Hex 3D */
5879*27fcede3SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
5880*27fcede3SMatthew G. Knepley             /* Interior vertices stay the same */
5881*27fcede3SMatthew G. Knepley             newp = vStartNew + (p - vStart);
5882*27fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5883*27fcede3SMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
5884*27fcede3SMatthew G. Knepley             /* Interior edges add new edges and vertex */
5885*27fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
5886*27fcede3SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
5887*27fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5888*27fcede3SMatthew G. Knepley             }
5889*27fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
5890*27fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5891*27fcede3SMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
5892*27fcede3SMatthew G. Knepley             /* Hybrid edges stay the same */
5893*27fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
5894*27fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5895*27fcede3SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
5896*27fcede3SMatthew G. Knepley             /* Interior faces add new faces, edges, and vertex */
5897*27fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
5898*27fcede3SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
5899*27fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5900*27fcede3SMatthew G. Knepley             }
5901*27fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
5902*27fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
5903*27fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5904*27fcede3SMatthew G. Knepley             }
5905*27fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
5906*27fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5907*27fcede3SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
5908*27fcede3SMatthew G. Knepley             /* Hybrid faces add new faces and edges */
5909*27fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
5910*27fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
5911*27fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5912*27fcede3SMatthew G. Knepley             }
5913*27fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
5914*27fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5915*27fcede3SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
5916*27fcede3SMatthew G. Knepley             /* Interior cells add new cells, faces, edges, and vertex */
5917*27fcede3SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
5918*27fcede3SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
5919*27fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5920*27fcede3SMatthew G. Knepley             }
5921*27fcede3SMatthew G. Knepley             for (r = 0; r < 12; ++r) {
5922*27fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
5923*27fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5924*27fcede3SMatthew G. Knepley             }
5925*27fcede3SMatthew G. Knepley             for (r = 0; r < 6; ++r) {
5926*27fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
5927*27fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5928*27fcede3SMatthew G. Knepley             }
5929*27fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
5930*27fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5931*27fcede3SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
5932*27fcede3SMatthew G. Knepley             /* Hybrid cells add new cells, faces, and edges */
5933*27fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
5934*27fcede3SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
5935*27fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5936*27fcede3SMatthew G. Knepley             }
5937*27fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
5938*27fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
5939*27fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5940*27fcede3SMatthew G. Knepley             }
5941*27fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
5942*27fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
5943*27fcede3SMatthew G. Knepley           }
5944*27fcede3SMatthew G. Knepley           break;
594575d3a19aSMatthew G. Knepley         default:
594675d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
594775d3a19aSMatthew G. Knepley         }
594875d3a19aSMatthew G. Knepley       }
594975d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
595075d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
595175d3a19aSMatthew G. Knepley     }
595275d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
595375d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
595475d3a19aSMatthew G. Knepley     if (0) {
595575d3a19aSMatthew G. Knepley       ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr);
595675d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
595775d3a19aSMatthew G. Knepley       ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
595875d3a19aSMatthew G. Knepley     }
595975d3a19aSMatthew G. Knepley   }
596075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
596175d3a19aSMatthew G. Knepley }
596275d3a19aSMatthew G. Knepley 
596375d3a19aSMatthew G. Knepley #undef __FUNCT__
5964509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexRefineUniform_Internal"
596575d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
5966509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
596775d3a19aSMatthew G. Knepley {
596875d3a19aSMatthew G. Knepley   DM             rdm;
596975d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
597075d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
597175d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
597275d3a19aSMatthew G. Knepley 
597375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
597475d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
597575d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
597675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
597775d3a19aSMatthew G. Knepley   ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr);
597875d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
597975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
5980785e854fSJed Brown   ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr);
598175d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
598275d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
598375d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
598475d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
598575d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
598675d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
598775d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
598875d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
598975d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
599075d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
599175d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
599275d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
599375d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
599475d3a19aSMatthew G. Knepley   /* Step 6: Set coordinates for vertices */
599575d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
599675d3a19aSMatthew G. Knepley   /* Step 7: Create pointSF */
599775d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
599875d3a19aSMatthew G. Knepley   /* Step 8: Create labels */
599975d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
600075d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
600175d3a19aSMatthew G. Knepley 
600275d3a19aSMatthew G. Knepley   *dmRefined = rdm;
600375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
600475d3a19aSMatthew G. Knepley }
600575d3a19aSMatthew G. Knepley 
600675d3a19aSMatthew G. Knepley #undef __FUNCT__
600775d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform"
600875d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
600975d3a19aSMatthew G. Knepley {
601075d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
601175d3a19aSMatthew G. Knepley 
601275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
601375d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
601475d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
601575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
601675d3a19aSMatthew G. Knepley }
601775d3a19aSMatthew G. Knepley 
601875d3a19aSMatthew G. Knepley #undef __FUNCT__
601975d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform"
602075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
602175d3a19aSMatthew G. Knepley {
602275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
602375d3a19aSMatthew G. Knepley 
602475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
602575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
602675d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
602775d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
602875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
602975d3a19aSMatthew G. Knepley }
603075d3a19aSMatthew G. Knepley 
603175d3a19aSMatthew G. Knepley #undef __FUNCT__
603275d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit"
603375d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
603475d3a19aSMatthew G. Knepley {
603575d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
603675d3a19aSMatthew G. Knepley 
603775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
603875d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
603975d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
604075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
604175d3a19aSMatthew G. Knepley }
604275d3a19aSMatthew G. Knepley 
604375d3a19aSMatthew G. Knepley #undef __FUNCT__
604475d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit"
604575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
604675d3a19aSMatthew G. Knepley {
604775d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
604875d3a19aSMatthew G. Knepley 
604975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
605075d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
605175d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
605275d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
605375d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
605475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
605575d3a19aSMatthew G. Knepley }
605675d3a19aSMatthew G. Knepley 
605775d3a19aSMatthew G. Knepley #undef __FUNCT__
6058509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Internal"
6059509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
606075d3a19aSMatthew G. Knepley {
60613478d7aaSMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax;
606275d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
606375d3a19aSMatthew G. Knepley 
606475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
606575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
60663478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
60673478d7aaSMatthew G. Knepley   if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);}
606875d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
606975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr);
607075d3a19aSMatthew G. Knepley   switch (dim) {
607175d3a19aSMatthew G. Knepley   case 2:
607275d3a19aSMatthew G. Knepley     switch (coneSize) {
607375d3a19aSMatthew G. Knepley     case 3:
607475d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 3; /* Hybrid */
607575d3a19aSMatthew G. Knepley       else *cellRefiner = 1; /* Triangular */
607675d3a19aSMatthew G. Knepley       break;
607775d3a19aSMatthew G. Knepley     case 4:
607875d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 4; /* Hybrid */
607975d3a19aSMatthew G. Knepley       else *cellRefiner = 2; /* Quadrilateral */
608075d3a19aSMatthew G. Knepley       break;
608175d3a19aSMatthew G. Knepley     default:
608275d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
608375d3a19aSMatthew G. Knepley     }
608475d3a19aSMatthew G. Knepley     break;
6085b5da9499SMatthew G. Knepley   case 3:
6086b5da9499SMatthew G. Knepley     switch (coneSize) {
6087b5da9499SMatthew G. Knepley     case 4:
6088b5da9499SMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 7; /* Hybrid */
6089b5da9499SMatthew G. Knepley       else *cellRefiner = 5; /* Tetrahedral */
6090b5da9499SMatthew G. Knepley       break;
60912eabf88fSMatthew G. Knepley     case 6:
60922eabf88fSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 8; /* Hybrid */
60932eabf88fSMatthew G. Knepley       else *cellRefiner = 6; /* hexahedral */
60942eabf88fSMatthew G. Knepley       break;
6095b5da9499SMatthew G. Knepley     default:
6096b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
6097b5da9499SMatthew G. Knepley     }
6098b5da9499SMatthew G. Knepley     break;
609975d3a19aSMatthew G. Knepley   default:
610075d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
610175d3a19aSMatthew G. Knepley   }
610275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
610375d3a19aSMatthew G. Knepley }
6104