xref: /petsc/src/dm/impls/plex/plexrefine.c (revision 0fadad52afc28ff01a9cf0e073dcec024eff2f85)
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__
29bed052eaSMatthew G. Knepley #define __FUNCT__ "CellRefinerGetAffineTransforms_Internal"
30bed052eaSMatthew G. Knepley /* Gets the affine map from the original cell to each subcell */
31bed052eaSMatthew G. Knepley PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
32bed052eaSMatthew G. Knepley {
33bed052eaSMatthew G. Knepley   PetscReal     *v = NULL, *j = NULL, *invj = NULL, detJ;
34bed052eaSMatthew G. Knepley   PetscInt       dim, s;
35bed052eaSMatthew G. Knepley   PetscErrorCode ierr;
36bed052eaSMatthew G. Knepley 
37bed052eaSMatthew G. Knepley   PetscFunctionBegin;
38bed052eaSMatthew G. Knepley   switch (refiner) {
39bed052eaSMatthew G. Knepley   case 0: break;
40bed052eaSMatthew G. Knepley   case 1:
41260b6d3fSMatthew G. Knepley     /*
42260b6d3fSMatthew G. Knepley      2
43260b6d3fSMatthew G. Knepley      |\
44260b6d3fSMatthew G. Knepley      | \
45260b6d3fSMatthew G. Knepley      |  \
46260b6d3fSMatthew G. Knepley      |   \
47260b6d3fSMatthew G. Knepley      | C  \
48260b6d3fSMatthew G. Knepley      |     \
49260b6d3fSMatthew G. Knepley      |      \
50260b6d3fSMatthew G. Knepley      2---1---1
51260b6d3fSMatthew G. Knepley      |\  D  / \
52260b6d3fSMatthew G. Knepley      | 2   0   \
53260b6d3fSMatthew G. Knepley      |A \ /  B  \
54260b6d3fSMatthew G. Knepley      0---0-------1
55260b6d3fSMatthew G. Knepley      */
56bed052eaSMatthew G. Knepley     dim = 2;
57bed052eaSMatthew G. Knepley     if (numSubcells) *numSubcells = 4;
58bed052eaSMatthew G. Knepley     if (v0) {
59bed052eaSMatthew G. Knepley       ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr);
60bed052eaSMatthew G. Knepley       /* A */
61bed052eaSMatthew G. Knepley       v[0+0] = -1.0; v[0+1] = -1.0;
62bed052eaSMatthew G. Knepley       j[0+0] =  0.5; j[0+1] =  0.0;
63bed052eaSMatthew G. Knepley       j[0+2] =  0.0; j[0+3] =  0.5;
64bed052eaSMatthew G. Knepley       /* B */
65bed052eaSMatthew G. Knepley       v[2+0] =  0.0; v[2+1] = -1.0;
66bed052eaSMatthew G. Knepley       j[4+0] =  0.5; j[4+1] =  0.0;
67bed052eaSMatthew G. Knepley       j[4+2] =  0.0; j[4+3] =  0.5;
68bed052eaSMatthew G. Knepley       /* C */
69bed052eaSMatthew G. Knepley       v[4+0] = -1.0; v[4+1] =  0.0;
70bed052eaSMatthew G. Knepley       j[8+0] =  0.5; j[8+1] =  0.0;
71bed052eaSMatthew G. Knepley       j[8+2] =  0.0; j[8+3] =  0.5;
72bed052eaSMatthew G. Knepley       /* D */
73bed052eaSMatthew G. Knepley       v[6+0]  =  0.0; v[6+1]  = -1.0;
74bed052eaSMatthew G. Knepley       j[12+0] =  0.0; j[12+1] = -0.5;
75bed052eaSMatthew G. Knepley       j[12+2] =  0.5; j[12+3] =  0.5;
76bed052eaSMatthew G. Knepley       for (s = 0; s < 4; ++s) {
77bed052eaSMatthew G. Knepley         DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
78bed052eaSMatthew G. Knepley         DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
79bed052eaSMatthew G. Knepley       }
80bed052eaSMatthew G. Knepley     }
81bed052eaSMatthew G. Knepley     break;
82260b6d3fSMatthew G. Knepley   case 2:
83260b6d3fSMatthew G. Knepley     /*
84260b6d3fSMatthew G. Knepley      3---------2---------2
85260b6d3fSMatthew G. Knepley      |         |         |
86260b6d3fSMatthew G. Knepley      |    D    2    C    |
87260b6d3fSMatthew G. Knepley      |         |         |
88260b6d3fSMatthew G. Knepley      3----3----0----1----1
89260b6d3fSMatthew G. Knepley      |         |         |
90260b6d3fSMatthew G. Knepley      |    A    0    B    |
91260b6d3fSMatthew G. Knepley      |         |         |
92260b6d3fSMatthew G. Knepley      0---------0---------1
93260b6d3fSMatthew G. Knepley      */
94260b6d3fSMatthew G. Knepley     dim = 2;
95260b6d3fSMatthew G. Knepley     if (numSubcells) *numSubcells = 4;
96260b6d3fSMatthew G. Knepley     if (v0) {
97260b6d3fSMatthew G. Knepley       ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr);
98260b6d3fSMatthew G. Knepley       /* A */
99260b6d3fSMatthew G. Knepley       v[0+0] = -1.0; v[0+1] = -1.0;
100260b6d3fSMatthew G. Knepley       j[0+0] =  0.5; j[0+1] =  0.0;
101260b6d3fSMatthew G. Knepley       j[0+2] =  0.0; j[0+3] =  0.5;
102260b6d3fSMatthew G. Knepley       /* B */
103260b6d3fSMatthew G. Knepley       v[2+0] =  0.0; v[2+1] = -1.0;
104260b6d3fSMatthew G. Knepley       j[4+0] =  0.5; j[4+1] =  0.0;
105260b6d3fSMatthew G. Knepley       j[4+2] =  0.0; j[4+3] =  0.5;
106260b6d3fSMatthew G. Knepley       /* C */
107260b6d3fSMatthew G. Knepley       v[4+0] =  0.0; v[4+1] =  0.0;
108260b6d3fSMatthew G. Knepley       j[8+0] =  0.5; j[8+1] =  0.0;
109260b6d3fSMatthew G. Knepley       j[8+2] =  0.0; j[8+3] =  0.5;
110260b6d3fSMatthew G. Knepley       /* D */
111260b6d3fSMatthew G. Knepley       v[6+0]  = -1.0; v[6+1]  =  0.0;
112260b6d3fSMatthew G. Knepley       j[12+0] =  0.5; j[12+1] =  0.0;
113260b6d3fSMatthew G. Knepley       j[12+2] =  0.0; j[12+3] =  0.5;
114260b6d3fSMatthew G. Knepley       for (s = 0; s < 4; ++s) {
115260b6d3fSMatthew G. Knepley         DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
116260b6d3fSMatthew G. Knepley         DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
117260b6d3fSMatthew G. Knepley       }
118260b6d3fSMatthew G. Knepley     }
119260b6d3fSMatthew G. Knepley     break;
120bed052eaSMatthew G. Knepley   default:
121bed052eaSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
122bed052eaSMatthew G. Knepley   }
123bed052eaSMatthew G. Knepley   if (v0) {*v0 = v; *jac = j; *invjac = invj;}
124bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
125bed052eaSMatthew G. Knepley }
126bed052eaSMatthew G. Knepley 
127bed052eaSMatthew G. Knepley #undef __FUNCT__
128bed052eaSMatthew G. Knepley #define __FUNCT__ "CellRefinerRestoreAffineTransforms_Internal"
129bed052eaSMatthew G. Knepley PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
130bed052eaSMatthew G. Knepley {
131bed052eaSMatthew G. Knepley   PetscErrorCode ierr;
132bed052eaSMatthew G. Knepley 
133bed052eaSMatthew G. Knepley   PetscFunctionBegin;
134bed052eaSMatthew G. Knepley   ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr);
135bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
136bed052eaSMatthew G. Knepley }
137bed052eaSMatthew G. Knepley 
138bed052eaSMatthew G. Knepley #undef __FUNCT__
13980389061SMatthew G. Knepley #define __FUNCT__ "CellRefinerInCellTest_Internal"
14080389061SMatthew G. Knepley /* Should this be here or in the DualSpace somehow? */
14180389061SMatthew G. Knepley PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside)
14280389061SMatthew G. Knepley {
14380389061SMatthew G. Knepley   PetscReal sum = 0.0;
14480389061SMatthew G. Knepley   PetscInt  d;
14580389061SMatthew G. Knepley 
14680389061SMatthew G. Knepley   PetscFunctionBegin;
14780389061SMatthew G. Knepley   *inside = PETSC_TRUE;
14880389061SMatthew G. Knepley   switch (refiner) {
14980389061SMatthew G. Knepley   case 0: break;
15080389061SMatthew G. Knepley   case 1:
15180389061SMatthew G. Knepley     for (d = 0; d < 2; ++d) {
15280389061SMatthew G. Knepley       if (point[d] < -1.0) {*inside = PETSC_FALSE; break;}
15380389061SMatthew G. Knepley       sum += point[d];
15480389061SMatthew G. Knepley     }
15580389061SMatthew G. Knepley     if (sum > 0.0) {*inside = PETSC_FALSE; break;}
15680389061SMatthew G. Knepley     break;
15780389061SMatthew G. Knepley   case 2:
15880389061SMatthew G. Knepley     for (d = 0; d < 2; ++d) if ((point[d] < -1.0) || (point[d] > 1.0)) {*inside = PETSC_FALSE; break;}
15980389061SMatthew G. Knepley     break;
16080389061SMatthew G. Knepley   default:
16180389061SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
16280389061SMatthew G. Knepley   }
16380389061SMatthew G. Knepley   PetscFunctionReturn(0);
16480389061SMatthew G. Knepley }
16580389061SMatthew G. Knepley 
16680389061SMatthew G. Knepley #undef __FUNCT__
16775d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerGetSizes"
16886150812SJed Brown static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[])
16975d3a19aSMatthew G. Knepley {
1706ce3c06aSMatthew G. Knepley   PetscInt       cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
17175d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
17275d3a19aSMatthew G. Knepley 
17375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
17475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
17575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
17675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
17775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
17875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
17975d3a19aSMatthew G. Knepley   switch (refiner) {
1803478d7aaSMatthew G. Knepley   case 0:
1813478d7aaSMatthew G. Knepley     break;
18275d3a19aSMatthew G. Knepley   case 1:
18375d3a19aSMatthew G. Knepley     /* Simplicial 2D */
18475d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart;         /* Add a vertex on every face */
18575d3a19aSMatthew 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 */
18675d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                     /* Every cell split into 4 cells */
18775d3a19aSMatthew G. Knepley     break;
18875d3a19aSMatthew G. Knepley   case 3:
189d963de37SMatthew G. Knepley     /* Hybrid Simplicial 2D */
19075d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
19175d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
19275d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart;                                         /* Add a vertex on every face, but not hybrid faces */
19375d3a19aSMatthew 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 */
19475d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax);                                   /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */
19575d3a19aSMatthew G. Knepley     break;
19675d3a19aSMatthew G. Knepley   case 2:
19775d3a19aSMatthew G. Knepley     /* Hex 2D */
198149f48fdSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
19975d3a19aSMatthew 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 */
20075d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                             /* Every cell split into 4 cells */
20175d3a19aSMatthew G. Knepley     break;
202a97b51b8SMatthew G. Knepley   case 4:
203a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
204a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
205a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
206a97b51b8SMatthew G. Knepley     /* Quadrilateral */
207a97b51b8SMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart;                 /* Add a vertex on every face and cell */
208a97b51b8SMatthew G. Knepley     depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart);                         /* Every face is split into 2 faces, and 4 faces are added for each cell */
209a97b51b8SMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart);                                             /* Every cell split into 4 cells */
210a97b51b8SMatthew G. Knepley     /* Segment Prisms */
211a97b51b8SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
212a97b51b8SMatthew G. Knepley     depthSize[1] +=   (fEnd - fMax)  +   (cEnd - cMax);                           /* Every hybrid face remains and 1 faces is added for each hybrid cell */
213a97b51b8SMatthew G. Knepley     depthSize[2] += 2*(cEnd - cMax);                                              /* Every hybrid cell split into 2 cells */
214a97b51b8SMatthew G. Knepley     break;
215b5da9499SMatthew G. Knepley   case 5:
216b5da9499SMatthew G. Knepley     /* Simplicial 3D */
217b5da9499SMatthew G. Knepley     depthSize[0] =    vEnd - vStart  +    eEnd - eStart;                    /* Add a vertex on every edge */
218b5da9499SMatthew 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 */
219b5da9499SMatthew G. Knepley     depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart);                   /* Every face split into 4 faces and 8 faces are added for each cell */
220b5da9499SMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                       /* Every cell split into 8 cells */
221b5da9499SMatthew G. Knepley     break;
222b5da9499SMatthew G. Knepley   case 7:
223b5da9499SMatthew G. Knepley     /* Hybrid Simplicial 3D */
224b5da9499SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2256ce3c06aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
226b5da9499SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
227dae4404aSMatthew G. Knepley     /* Tetrahedra */
228dae4404aSMatthew G. Knepley     depthSize[0]  =    vEnd - vStart  +    eMax - eStart;                    /* Add a vertex on every interior edge */
229dae4404aSMatthew 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 */
230dae4404aSMatthew G. Knepley     depthSize[2]  = 4*(fMax - fStart) + 8*(cMax - cStart);                   /* Every interior face split into 4 faces, 8 faces added for each interior cell */
231dae4404aSMatthew G. Knepley     depthSize[3]  = 8*(cMax - cStart);                                       /* Every interior cell split into 8 cells */
232dae4404aSMatthew G. Knepley     /* Triangular Prisms */
233dae4404aSMatthew G. Knepley     depthSize[0] += 0;                                                       /* No hybrid vertices */
234dae4404aSMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax);                     /* Every hybrid edge remains, 1 edge for every hybrid face */
2356ce3c06aSMatthew 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 */
236dae4404aSMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                         /* Every hybrid cell split into 4 cells */
237b5da9499SMatthew G. Knepley     break;
2386ce3c06aSMatthew G. Knepley   case 6:
2396ce3c06aSMatthew G. Knepley     /* Hex 3D */
2406ce3c06aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
2416ce3c06aSMatthew 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 */
2426ce3c06aSMatthew 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 */
2436ce3c06aSMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                             /* Every cell split into 8 cells */
2446ce3c06aSMatthew G. Knepley     break;
24527fcede3SMatthew G. Knepley   case 8:
24627fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
24727fcede3SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
24827fcede3SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
24927fcede3SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
25027fcede3SMatthew G. Knepley     /* Hexahedra */
25127fcede3SMatthew G. Knepley     depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
25227fcede3SMatthew 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 */
25327fcede3SMatthew 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 */
25427fcede3SMatthew G. Knepley     depthSize[3] = 8*(cMax - cStart);                                             /* Every cell split into 8 cells */
25527fcede3SMatthew G. Knepley     /* Quadrilateral Prisms */
25627fcede3SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
25727fcede3SMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax)   +   (cEnd - cMax);      /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
25827fcede3SMatthew 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 */
25927fcede3SMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                              /* Every hybrid cell split into 4 cells */
26027fcede3SMatthew G. Knepley     break;
26175d3a19aSMatthew G. Knepley   default:
26275d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
26375d3a19aSMatthew G. Knepley   }
26475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
26575d3a19aSMatthew G. Knepley }
26675d3a19aSMatthew G. Knepley 
26742525629SMatthew G. Knepley /* Return triangle edge for orientation o, if it is r for o == 0 */
26842525629SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
269518a8359SMatthew G. Knepley   return (o < 0 ? 2-(o+r) : o+r)%3;
270518a8359SMatthew G. Knepley }
271de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
272de65f515SMatthew G. Knepley   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
273de65f515SMatthew G. Knepley }
274518a8359SMatthew G. Knepley 
275518a8359SMatthew G. Knepley /* Return triangle subface for orientation o, if it is r for o == 0 */
276518a8359SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
2774bae88c7SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%3;
27842525629SMatthew G. Knepley }
279de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
280de65f515SMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 3+s-o)%3;
281de65f515SMatthew G. Knepley }
28242525629SMatthew G. Knepley 
283431647a4SMatthew G. Knepley /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */
284431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) {
285431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+r) : o+r)%3;
286431647a4SMatthew G. Knepley }
287431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) {
288431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+s) : 3+s-o)%3;
289431647a4SMatthew G. Knepley }
290431647a4SMatthew G. Knepley 
29142525629SMatthew G. Knepley 
292e3f8b1d6SMatthew G. Knepley /* Return quad edge for orientation o, if it is r for o == 0 */
293e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
294e3f8b1d6SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%4;
295e3f8b1d6SMatthew G. Knepley }
296d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
297d6d937efSMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 4+s-o)%4;
298d6d937efSMatthew G. Knepley }
299e3f8b1d6SMatthew G. Knepley 
300e3f8b1d6SMatthew G. Knepley /* Return quad subface for orientation o, if it is r for o == 0 */
301e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
3024bae88c7SMatthew G. Knepley   return (o < 0 ? 4-(o+r) : o+r)%4;
30342525629SMatthew G. Knepley }
304d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
305d6d937efSMatthew G. Knepley   return (o < 0 ? 4-(o+s) : 4+s-o)%4;
306d6d937efSMatthew G. Knepley }
30742525629SMatthew G. Knepley 
30875d3a19aSMatthew G. Knepley #undef __FUNCT__
30975d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetConeSizes"
31086150812SJed Brown static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
31175d3a19aSMatthew G. Knepley {
312b5da9499SMatthew 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;
31375d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
31475d3a19aSMatthew G. Knepley 
31575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
3162a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
31775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
31875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
31975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
32075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
32175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
32275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
3232a5d0125SJed Brown   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
32475d3a19aSMatthew G. Knepley   switch (refiner) {
32575d3a19aSMatthew G. Knepley   case 1:
32675d3a19aSMatthew G. Knepley     /* Simplicial 2D */
32775d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
32875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
32975d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
33075d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
33175d3a19aSMatthew G. Knepley 
33275d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
33375d3a19aSMatthew G. Knepley       }
33475d3a19aSMatthew G. Knepley     }
33575d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
33675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
33775d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
33875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
33975d3a19aSMatthew G. Knepley         PetscInt       size;
34075d3a19aSMatthew G. Knepley 
34175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
34275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
34375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
34475d3a19aSMatthew G. Knepley       }
34575d3a19aSMatthew G. Knepley     }
34675d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
34775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
34875d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
34975d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
35075d3a19aSMatthew G. Knepley 
35175d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
35275d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
35375d3a19aSMatthew G. Knepley       }
35475d3a19aSMatthew G. Knepley     }
35575d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
35675d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
35775d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
35875d3a19aSMatthew G. Knepley       PetscInt       size;
35975d3a19aSMatthew G. Knepley 
36075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
36175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
36275d3a19aSMatthew G. Knepley     }
36375d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
36475d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
36575d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
36675d3a19aSMatthew G. Knepley       PetscInt       size;
36775d3a19aSMatthew G. Knepley 
36875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
36975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
37075d3a19aSMatthew G. Knepley     }
37175d3a19aSMatthew G. Knepley     break;
37275d3a19aSMatthew G. Knepley   case 2:
37375d3a19aSMatthew G. Knepley     /* Hex 2D */
37475d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
37575d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
37675d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
377149f48fdSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
37875d3a19aSMatthew G. Knepley 
37975d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
38075d3a19aSMatthew G. Knepley       }
38175d3a19aSMatthew G. Knepley     }
38275d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
38375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
38475d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
38575d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
38675d3a19aSMatthew G. Knepley         PetscInt       size;
38775d3a19aSMatthew G. Knepley 
38875d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
38975d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
39075d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
39175d3a19aSMatthew G. Knepley       }
39275d3a19aSMatthew G. Knepley     }
39375d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
39475d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
39575d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
39675d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
39775d3a19aSMatthew G. Knepley 
39875d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
39975d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
40075d3a19aSMatthew G. Knepley       }
40175d3a19aSMatthew G. Knepley     }
40275d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
40375d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
40475d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
40575d3a19aSMatthew G. Knepley       PetscInt       size;
40675d3a19aSMatthew G. Knepley 
40775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
40875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
40975d3a19aSMatthew G. Knepley     }
41075d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
41175d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
41275d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
41375d3a19aSMatthew G. Knepley       PetscInt       size;
41475d3a19aSMatthew G. Knepley 
41575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
41675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
41775d3a19aSMatthew G. Knepley     }
41875d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
41975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
42075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
42175d3a19aSMatthew G. Knepley 
42275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
42375d3a19aSMatthew G. Knepley     }
42475d3a19aSMatthew G. Knepley     break;
42575d3a19aSMatthew G. Knepley   case 3:
426d963de37SMatthew G. Knepley     /* Hybrid Simplicial 2D */
42775d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
42875d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
42975d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
43075d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
43175d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
43275d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
43375d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
43475d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
43575d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
43675d3a19aSMatthew G. Knepley 
43775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
43875d3a19aSMatthew G. Knepley       }
43975d3a19aSMatthew G. Knepley     }
44075d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
44175d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
44275d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
44375d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
44475d3a19aSMatthew G. Knepley 
44575d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
44675d3a19aSMatthew G. Knepley       }
44775d3a19aSMatthew G. Knepley     }
44875d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
44975d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
45075d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
45175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
45275d3a19aSMatthew G. Knepley         PetscInt       size;
45375d3a19aSMatthew G. Knepley 
45475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
45575d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
45675d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
45775d3a19aSMatthew G. Knepley       }
45875d3a19aSMatthew G. Knepley     }
45975d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
46075d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
46175d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
46275d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
46375d3a19aSMatthew G. Knepley 
46475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
46575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
46675d3a19aSMatthew G. Knepley       }
46775d3a19aSMatthew G. Knepley     }
46875d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
46975d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
47075d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
47175d3a19aSMatthew G. Knepley       PetscInt       size;
47275d3a19aSMatthew G. Knepley 
47375d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
47475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
47575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
47675d3a19aSMatthew G. Knepley     }
47775d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
47875d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
47975d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
48075d3a19aSMatthew G. Knepley 
48175d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
48275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
48375d3a19aSMatthew G. Knepley     }
48475d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
48575d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
48675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
48775d3a19aSMatthew G. Knepley       PetscInt       size;
48875d3a19aSMatthew G. Knepley 
48975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
49075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
49175d3a19aSMatthew G. Knepley     }
49275d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
49375d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
49475d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
49575d3a19aSMatthew G. Knepley       const PetscInt *support;
49675d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
49775d3a19aSMatthew G. Knepley 
49875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
49975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
50075d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
50175d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
50275d3a19aSMatthew G. Knepley         else newSize += 2;
50375d3a19aSMatthew G. Knepley       }
50475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
50575d3a19aSMatthew G. Knepley     }
50675d3a19aSMatthew G. Knepley     break;
507a97b51b8SMatthew G. Knepley   case 4:
508a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
509a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
510a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
511a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
512a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
513a97b51b8SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
514a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
515a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
516a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
517a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
518a97b51b8SMatthew G. Knepley 
519a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
520a97b51b8SMatthew G. Knepley       }
521a97b51b8SMatthew G. Knepley     }
522a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
523a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
524a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
525a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
526a97b51b8SMatthew G. Knepley 
527a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
528a97b51b8SMatthew G. Knepley       }
529a97b51b8SMatthew G. Knepley     }
530a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
531a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
532a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
533a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
534a97b51b8SMatthew G. Knepley         PetscInt       size;
535a97b51b8SMatthew G. Knepley 
536a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
537a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
538a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
539a97b51b8SMatthew G. Knepley       }
540a97b51b8SMatthew G. Knepley     }
541a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
542a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
543a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
544a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
545a97b51b8SMatthew G. Knepley 
546a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
547a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
548a97b51b8SMatthew G. Knepley       }
549a97b51b8SMatthew G. Knepley     }
550a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
551a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
552a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
553a97b51b8SMatthew G. Knepley       PetscInt       size;
554a97b51b8SMatthew G. Knepley 
555a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
556a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
557a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
558a97b51b8SMatthew G. Knepley     }
559a97b51b8SMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
560a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
561a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
562a97b51b8SMatthew G. Knepley 
563a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
564a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
565a97b51b8SMatthew G. Knepley     }
566a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
567a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
568a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
569a97b51b8SMatthew G. Knepley       PetscInt       size;
570a97b51b8SMatthew G. Knepley 
571a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
572a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
573a97b51b8SMatthew G. Knepley     }
574a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
575a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
576a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
577a97b51b8SMatthew G. Knepley       PetscInt       size;
578a97b51b8SMatthew G. Knepley 
579a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
580a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
581a97b51b8SMatthew G. Knepley     }
582a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
583a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
584a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
585a97b51b8SMatthew G. Knepley 
586a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
587a97b51b8SMatthew G. Knepley     }
588a97b51b8SMatthew G. Knepley     break;
589b5da9499SMatthew G. Knepley   case 5:
590b5da9499SMatthew G. Knepley     /* Simplicial 3D */
591b5da9499SMatthew G. Knepley     /* All cells have 4 faces */
592b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
593b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
594dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
595b5da9499SMatthew G. Knepley 
596b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
597b5da9499SMatthew G. Knepley       }
598b5da9499SMatthew G. Knepley     }
599b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
600b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
601b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
602b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
603b5da9499SMatthew G. Knepley         PetscInt       size;
604b5da9499SMatthew G. Knepley 
605b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
606b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
607b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
608b5da9499SMatthew G. Knepley       }
609b5da9499SMatthew G. Knepley     }
6109ddff745SMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
611b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
612b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
613b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
614b5da9499SMatthew G. Knepley 
615b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
616b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
617b5da9499SMatthew G. Knepley       }
618b5da9499SMatthew G. Knepley     }
619b5da9499SMatthew G. Knepley     /* Split edges have 2 vertices and the same faces */
620b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
621b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
622b5da9499SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
623b5da9499SMatthew G. Knepley         PetscInt       size;
624b5da9499SMatthew G. Knepley 
625b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
626b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
627b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
628b5da9499SMatthew G. Knepley       }
629b5da9499SMatthew G. Knepley     }
630b5da9499SMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
631b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
632b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
633b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
634b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
635b5da9499SMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
636b5da9499SMatthew G. Knepley 
637b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
638b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
639b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
640b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
641b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
642b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
643b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
644b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
64586f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
6469ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
647b5da9499SMatthew G. Knepley           if (er == eint[c]) {
648b5da9499SMatthew G. Knepley             intFaces += 1;
649b5da9499SMatthew G. Knepley           } else {
650b5da9499SMatthew G. Knepley             intFaces += 2;
651b5da9499SMatthew G. Knepley           }
652b5da9499SMatthew G. Knepley         }
653b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
654b5da9499SMatthew G. Knepley       }
655b5da9499SMatthew G. Knepley     }
6569ddff745SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
657b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
658b5da9499SMatthew G. Knepley       const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
659b5da9499SMatthew G. Knepley 
660b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
661b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
662b5da9499SMatthew G. Knepley     }
663b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
664b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
665b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
666b5da9499SMatthew G. Knepley       PetscInt       size;
667b5da9499SMatthew G. Knepley 
668b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
669b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
670b5da9499SMatthew G. Knepley     }
671b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
672b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
673b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
674b5da9499SMatthew G. Knepley       PetscInt       size, *star = NULL, starSize, s, cellSize = 0;
675b5da9499SMatthew G. Knepley 
676b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
677b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
678b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
679b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
680b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
681b5da9499SMatthew G. Knepley 
682b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
683b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
684b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
685b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
686b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
68742525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
688b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
689b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
690b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
69142525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
69242525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
693b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
694b5da9499SMatthew G. Knepley         }
695b5da9499SMatthew G. Knepley       }
696b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
697b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr);
698b5da9499SMatthew G. Knepley     }
699b5da9499SMatthew G. Knepley     break;
700dae4404aSMatthew G. Knepley   case 7:
7016ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
7026ce3c06aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
7036ce3c06aSMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
704dae4404aSMatthew G. Knepley     /* Interior cells have 4 faces */
705dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
706dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
707dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
708dae4404aSMatthew G. Knepley 
709dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
710dae4404aSMatthew G. Knepley       }
711dae4404aSMatthew G. Knepley     }
712dae4404aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
713dae4404aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
714dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
715dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
716dae4404aSMatthew G. Knepley 
717dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr);
718dae4404aSMatthew G. Knepley       }
719dae4404aSMatthew G. Knepley     }
7206ce3c06aSMatthew G. Knepley     /* Interior split faces have 3 edges and the same cells as the parent */
721dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
722dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
723dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
724dae4404aSMatthew G. Knepley         PetscInt       size;
725dae4404aSMatthew G. Knepley 
726dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
727dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
728dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
729dae4404aSMatthew G. Knepley       }
730dae4404aSMatthew G. Knepley     }
731dae4404aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
732dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
733dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
734dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
735dae4404aSMatthew G. Knepley 
736dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
737dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
738dae4404aSMatthew G. Knepley       }
739dae4404aSMatthew G. Knepley     }
7406ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
7416ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
7426ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
7436ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
7446ce3c06aSMatthew G. Knepley         PetscInt       size;
7456ce3c06aSMatthew G. Knepley 
7466ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
7476ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
7486ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
7496ce3c06aSMatthew G. Knepley       }
7506ce3c06aSMatthew G. Knepley     }
7516ce3c06aSMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
7526ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
7536ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
7546ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
7556ce3c06aSMatthew G. Knepley 
7566ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
7576ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
7586ce3c06aSMatthew G. Knepley       }
7596ce3c06aSMatthew G. Knepley     }
7606ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces */
761dae4404aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
762dae4404aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
763dae4404aSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
764dae4404aSMatthew G. Knepley         PetscInt       size;
765dae4404aSMatthew G. Knepley 
766dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
767dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
768dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
769dae4404aSMatthew G. Knepley       }
770dae4404aSMatthew G. Knepley     }
7716ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
772dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
773dae4404aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
774dae4404aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
775dae4404aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
776dae4404aSMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
777dae4404aSMatthew G. Knepley 
778dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
779dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
780dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
781dae4404aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
782dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
783dae4404aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
784dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
785dae4404aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
7866ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
787dae4404aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
7889ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
789dae4404aSMatthew G. Knepley             if (er == eint[c]) {
790dae4404aSMatthew G. Knepley               intFaces += 1;
791dae4404aSMatthew G. Knepley             } else {
792dae4404aSMatthew G. Knepley               intFaces += 2;
793dae4404aSMatthew G. Knepley             }
7946ce3c06aSMatthew G. Knepley           } else {
7956ce3c06aSMatthew G. Knepley             intFaces += 1;
7966ce3c06aSMatthew G. Knepley           }
797dae4404aSMatthew G. Knepley         }
798dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
799dae4404aSMatthew G. Knepley       }
800dae4404aSMatthew G. Knepley     }
8016ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
802dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
803dae4404aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
804dae4404aSMatthew G. Knepley 
805dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
806dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
807dae4404aSMatthew G. Knepley     }
8086ce3c06aSMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
809dae4404aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
8106ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
8116ce3c06aSMatthew G. Knepley       PetscInt       size;
8126ce3c06aSMatthew G. Knepley 
8136ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
8146ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
8156ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
8166ce3c06aSMatthew G. Knepley     }
8176ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
8186ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
8196ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
820dae4404aSMatthew G. Knepley       PetscInt       size;
821dae4404aSMatthew G. Knepley 
822dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
823dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
8246ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr);
825dae4404aSMatthew G. Knepley     }
8266ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
827dae4404aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
828dae4404aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
829dae4404aSMatthew G. Knepley       PetscInt       size;
830dae4404aSMatthew G. Knepley 
831dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
832dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
833dae4404aSMatthew G. Knepley     }
8346ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
8356ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
8366ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
837dae4404aSMatthew G. Knepley       const PetscInt *support;
8386ce3c06aSMatthew G. Knepley       PetscInt        size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
839dae4404aSMatthew G. Knepley 
8406ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
8416ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
842dae4404aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
8436ce3c06aSMatthew G. Knepley         if (support[s] < fMax) faceSize += 2;
8446ce3c06aSMatthew G. Knepley         else                   faceSize += 1;
845dae4404aSMatthew G. Knepley       }
8466ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
8476ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
8486ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
8496ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
8506ce3c06aSMatthew G. Knepley 
8516ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
8526ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
8536ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
8546ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
8556ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
8566ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
8576ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
8586ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
8596ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
8606ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
8616ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
8626ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
8636ce3c06aSMatthew G. Knepley         }
8646ce3c06aSMatthew G. Knepley       }
8656ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
8666ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr);
867dae4404aSMatthew G. Knepley     }
868dae4404aSMatthew G. Knepley     break;
8692eabf88fSMatthew G. Knepley   case 6:
8702eabf88fSMatthew G. Knepley     /* Hex 3D */
8712eabf88fSMatthew G. Knepley     /* All cells have 6 faces */
8722eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
8732eabf88fSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
8742eabf88fSMatthew G. Knepley         const PetscInt newp = (c - cStart)*8 + r;
8752eabf88fSMatthew G. Knepley 
8762eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
8772eabf88fSMatthew G. Knepley       }
8782eabf88fSMatthew G. Knepley     }
8792eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
8802eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
8812eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
8822eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
8832eabf88fSMatthew G. Knepley         PetscInt       size;
8842eabf88fSMatthew G. Knepley 
8852eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
8862eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
8872eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
8882eabf88fSMatthew G. Knepley       }
8892eabf88fSMatthew G. Knepley     }
8902eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
8912eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
8922eabf88fSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
8932eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
8942eabf88fSMatthew G. Knepley 
8952eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
8962eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
8972eabf88fSMatthew G. Knepley       }
8982eabf88fSMatthew G. Knepley     }
8992eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
9002eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
9012eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
9022eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
9032eabf88fSMatthew G. Knepley         PetscInt       size;
9042eabf88fSMatthew G. Knepley 
9052eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
9062eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
9072eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
9082eabf88fSMatthew G. Knepley       }
9092eabf88fSMatthew G. Knepley     }
9102eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
9112eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
9122eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
9132eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
9142eabf88fSMatthew G. Knepley         PetscInt       size;
9152eabf88fSMatthew G. Knepley 
9162eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
9172eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
9182eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
9192eabf88fSMatthew G. Knepley       }
9202eabf88fSMatthew G. Knepley     }
9212eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
9222eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
9232eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
9242eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
9252eabf88fSMatthew G. Knepley 
9262eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
9272eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
9282eabf88fSMatthew G. Knepley       }
9292eabf88fSMatthew G. Knepley     }
9302eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
9312eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
9322eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
9332eabf88fSMatthew G. Knepley       PetscInt       size;
9342eabf88fSMatthew G. Knepley 
9352eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
9362eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
9372eabf88fSMatthew G. Knepley     }
9382eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
9392eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
9402eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
9412eabf88fSMatthew G. Knepley       PetscInt       size;
9422eabf88fSMatthew G. Knepley 
9432eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
9442eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
9452eabf88fSMatthew G. Knepley     }
9462eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
9472eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
9482eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
9492eabf88fSMatthew G. Knepley       PetscInt       size;
9502eabf88fSMatthew G. Knepley 
9512eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
9522eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
9532eabf88fSMatthew G. Knepley     }
9542eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
9552eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
9562eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
9572eabf88fSMatthew G. Knepley 
9582eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
9592eabf88fSMatthew G. Knepley     }
9602eabf88fSMatthew G. Knepley     break;
96127fcede3SMatthew G. Knepley   case 8:
96227fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
96327fcede3SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
96427fcede3SMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
96527fcede3SMatthew G. Knepley     /* Interior cells have 6 faces */
96627fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
96727fcede3SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
96827fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
96927fcede3SMatthew G. Knepley 
97027fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
97127fcede3SMatthew G. Knepley       }
97227fcede3SMatthew G. Knepley     }
97327fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces */
97427fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
97527fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
97627fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
97727fcede3SMatthew G. Knepley 
97827fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
97927fcede3SMatthew G. Knepley       }
98027fcede3SMatthew G. Knepley     }
98127fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
98227fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
98327fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
98427fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
98527fcede3SMatthew G. Knepley         PetscInt       size;
98627fcede3SMatthew G. Knepley 
98727fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
98827fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
98927fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
99027fcede3SMatthew G. Knepley       }
99127fcede3SMatthew G. Knepley     }
99227fcede3SMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
99327fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
99427fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
99527fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
99627fcede3SMatthew G. Knepley 
99727fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
99827fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
99927fcede3SMatthew G. Knepley       }
100027fcede3SMatthew G. Knepley     }
100127fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
100227fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
100327fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
100427fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
100527fcede3SMatthew G. Knepley         PetscInt       size;
100627fcede3SMatthew G. Knepley 
100727fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
100827fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
100927fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
101027fcede3SMatthew G. Knepley       }
101127fcede3SMatthew G. Knepley     }
101227fcede3SMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
101327fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
101427fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
101527fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
101627fcede3SMatthew G. Knepley 
101727fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
101827fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
101927fcede3SMatthew G. Knepley       }
102027fcede3SMatthew G. Knepley     }
102127fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
102227fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
102327fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
102427fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
102527fcede3SMatthew G. Knepley         PetscInt       size;
102627fcede3SMatthew G. Knepley 
102727fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
102827fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
102927fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
103027fcede3SMatthew G. Knepley       }
103127fcede3SMatthew G. Knepley     }
103227fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
103327fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
103427fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
103527fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
103627fcede3SMatthew G. Knepley         PetscInt       size;
103727fcede3SMatthew G. Knepley 
103827fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
103927fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
104027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
104127fcede3SMatthew G. Knepley       }
104227fcede3SMatthew G. Knepley     }
104327fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
104427fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
104527fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
104627fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
104727fcede3SMatthew G. Knepley 
104827fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
104927fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
105027fcede3SMatthew G. Knepley       }
105127fcede3SMatthew G. Knepley     }
105227fcede3SMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
105327fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
105427fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
105527fcede3SMatthew G. Knepley       PetscInt       size;
105627fcede3SMatthew G. Knepley 
105727fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
105827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
105927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
106027fcede3SMatthew G. Knepley     }
106127fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
106227fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
106327fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
106427fcede3SMatthew G. Knepley       PetscInt       size;
106527fcede3SMatthew G. Knepley 
106627fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
106727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
106827fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
106927fcede3SMatthew G. Knepley     }
107027fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
107127fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
107227fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
107327fcede3SMatthew G. Knepley 
107427fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
107527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
107627fcede3SMatthew G. Knepley     }
107727fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
107827fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
107927fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
108027fcede3SMatthew G. Knepley       PetscInt       size;
108127fcede3SMatthew G. Knepley 
108227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
108327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
108427fcede3SMatthew G. Knepley     }
108527fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
108627fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
108727fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
108827fcede3SMatthew G. Knepley       PetscInt       size;
108927fcede3SMatthew G. Knepley 
109027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
109127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
109227fcede3SMatthew G. Knepley     }
109327fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
109427fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
109527fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
109627fcede3SMatthew G. Knepley       PetscInt       size;
109727fcede3SMatthew G. Knepley 
109827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
109927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
110027fcede3SMatthew G. Knepley     }
110127fcede3SMatthew G. Knepley     /* Interior cell vertices have 6 supports */
110227fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
110327fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
110427fcede3SMatthew G. Knepley 
110527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
110627fcede3SMatthew G. Knepley     }
110727fcede3SMatthew G. Knepley     break;
110875d3a19aSMatthew G. Knepley   default:
110975d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
111075d3a19aSMatthew G. Knepley   }
111175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
111275d3a19aSMatthew G. Knepley }
111375d3a19aSMatthew G. Knepley 
111475d3a19aSMatthew G. Knepley #undef __FUNCT__
111575d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCones"
111686150812SJed Brown static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
111775d3a19aSMatthew G. Knepley {
1118b5da9499SMatthew G. Knepley   const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
11196ce3c06aSMatthew G. Knepley   PetscInt        cStart,    cEnd,    cMax,    vStart,    vEnd, vMax, fStart,    fEnd,    fMax,    eStart,    eEnd,    eMax;
11206ce3c06aSMatthew G. Knepley   PetscInt        cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew,    fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
11216ce3c06aSMatthew G. Knepley   PetscInt        depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
112275d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
112375d3a19aSMatthew G. Knepley 
112475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
11252a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
112675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
112775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
112875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
112975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
113075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
113175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
113275d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
113375d3a19aSMatthew G. Knepley   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
113475d3a19aSMatthew G. Knepley   switch (refiner) {
113575d3a19aSMatthew G. Knepley   case 1:
113675d3a19aSMatthew G. Knepley     /* Simplicial 2D */
113775d3a19aSMatthew G. Knepley     /*
113875d3a19aSMatthew G. Knepley      2
113975d3a19aSMatthew G. Knepley      |\
114075d3a19aSMatthew G. Knepley      | \
114175d3a19aSMatthew G. Knepley      |  \
114275d3a19aSMatthew G. Knepley      |   \
114375d3a19aSMatthew G. Knepley      | C  \
114475d3a19aSMatthew G. Knepley      |     \
114575d3a19aSMatthew G. Knepley      |      \
114675d3a19aSMatthew G. Knepley      2---1---1
114775d3a19aSMatthew G. Knepley      |\  D  / \
114875d3a19aSMatthew G. Knepley      | 2   0   \
114975d3a19aSMatthew G. Knepley      |A \ /  B  \
115075d3a19aSMatthew G. Knepley      0---0-------1
115175d3a19aSMatthew G. Knepley      */
115275d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
115375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
115475d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
115575d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
115675d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
115775d3a19aSMatthew G. Knepley 
115875d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
115975d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
116075d3a19aSMatthew G. Knepley       /* A triangle */
116175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
116275d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
116375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
116475d3a19aSMatthew G. Knepley       orntNew[1] = -2;
116575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
116675d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
116775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
116875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
116975d3a19aSMatthew G. Knepley #if 1
117075d3a19aSMatthew 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);
117175d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
117275d3a19aSMatthew 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);
117375d3a19aSMatthew G. Knepley       }
117475d3a19aSMatthew G. Knepley #endif
117575d3a19aSMatthew G. Knepley       /* B triangle */
117675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
117775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
117875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
117975d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
118075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
118175d3a19aSMatthew G. Knepley       orntNew[2] = -2;
118275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
118375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
118475d3a19aSMatthew G. Knepley #if 1
118575d3a19aSMatthew 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);
118675d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
118775d3a19aSMatthew 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);
118875d3a19aSMatthew G. Knepley       }
118975d3a19aSMatthew G. Knepley #endif
119075d3a19aSMatthew G. Knepley       /* C triangle */
119175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
119275d3a19aSMatthew G. Knepley       orntNew[0] = -2;
119375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
119475d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
119575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
119675d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
119775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
119875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
119975d3a19aSMatthew G. Knepley #if 1
120075d3a19aSMatthew 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);
120175d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
120275d3a19aSMatthew 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);
120375d3a19aSMatthew G. Knepley       }
120475d3a19aSMatthew G. Knepley #endif
120575d3a19aSMatthew G. Knepley       /* D triangle */
120675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
120775d3a19aSMatthew G. Knepley       orntNew[0] = 0;
120875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
120975d3a19aSMatthew G. Knepley       orntNew[1] = 0;
121075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
121175d3a19aSMatthew G. Knepley       orntNew[2] = 0;
121275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
121375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
121475d3a19aSMatthew G. Knepley #if 1
121575d3a19aSMatthew 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);
121675d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
121775d3a19aSMatthew 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);
121875d3a19aSMatthew G. Knepley       }
121975d3a19aSMatthew G. Knepley #endif
122075d3a19aSMatthew G. Knepley     }
122175d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
122275d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1223785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
122475d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
122575d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
122675d3a19aSMatthew G. Knepley 
122775d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
122875d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1229297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
123075d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
123175d3a19aSMatthew G. Knepley 
123275d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
123375d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
123475d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
123575d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
123675d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
123775d3a19aSMatthew G. Knepley #if 1
123875d3a19aSMatthew 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);
123975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
124075d3a19aSMatthew 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);
124175d3a19aSMatthew G. Knepley         }
124275d3a19aSMatthew G. Knepley #endif
124375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
124475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
124575d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
124675d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
124775d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1248297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
124975d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
125075d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
125175d3a19aSMatthew G. Knepley           }
1252297d2bf4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
125375d3a19aSMatthew G. Knepley         }
125475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
125575d3a19aSMatthew G. Knepley #if 1
125675d3a19aSMatthew 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);
125775d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
125875d3a19aSMatthew 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);
125975d3a19aSMatthew G. Knepley         }
126075d3a19aSMatthew G. Knepley #endif
126175d3a19aSMatthew G. Knepley       }
126275d3a19aSMatthew G. Knepley     }
126375d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
126475d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
126575d3a19aSMatthew G. Knepley       const PetscInt *cone;
126675d3a19aSMatthew G. Knepley 
126775d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
126875d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
126975d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
127075d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
127175d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
127275d3a19aSMatthew G. Knepley 
127375d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
127475d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
127575d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
127675d3a19aSMatthew G. Knepley #if 1
127775d3a19aSMatthew 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);
127875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
127975d3a19aSMatthew 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);
128075d3a19aSMatthew G. Knepley         }
128175d3a19aSMatthew G. Knepley #endif
128275d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
128375d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
128475d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
128575d3a19aSMatthew G. Knepley #if 1
128675d3a19aSMatthew 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);
128775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
128875d3a19aSMatthew 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);
128975d3a19aSMatthew G. Knepley         }
129075d3a19aSMatthew G. Knepley #endif
129175d3a19aSMatthew G. Knepley       }
129275d3a19aSMatthew G. Knepley     }
129375d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
129475d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
129575d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
129675d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
129775d3a19aSMatthew G. Knepley       PetscInt        size, s;
129875d3a19aSMatthew G. Knepley 
129975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
130075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
130175d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
130275d3a19aSMatthew G. Knepley         PetscInt r = 0;
130375d3a19aSMatthew G. Knepley 
130475d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
130575d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
130675d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
130775d3a19aSMatthew G. Knepley       }
130875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
130975d3a19aSMatthew G. Knepley #if 1
131075d3a19aSMatthew 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);
131175d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
131275d3a19aSMatthew 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);
131375d3a19aSMatthew G. Knepley       }
131475d3a19aSMatthew G. Knepley #endif
131575d3a19aSMatthew G. Knepley     }
131675d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
131775d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
131875d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
131975d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
132075d3a19aSMatthew G. Knepley       PetscInt        size, s;
132175d3a19aSMatthew G. Knepley 
132275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
132375d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
132475d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
132575d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
132675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
132775d3a19aSMatthew G. Knepley         PetscInt r = 0;
132875d3a19aSMatthew G. Knepley 
132975d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
133075d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
133175d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
133275d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
133375d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
133475d3a19aSMatthew G. Knepley       }
133575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
133675d3a19aSMatthew G. Knepley #if 1
133775d3a19aSMatthew 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);
133875d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
133975d3a19aSMatthew 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);
134075d3a19aSMatthew G. Knepley       }
134175d3a19aSMatthew G. Knepley #endif
134275d3a19aSMatthew G. Knepley     }
134375d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
134475d3a19aSMatthew G. Knepley     break;
134575d3a19aSMatthew G. Knepley   case 2:
134675d3a19aSMatthew G. Knepley     /* Hex 2D */
134775d3a19aSMatthew G. Knepley     /*
134875d3a19aSMatthew G. Knepley      3---------2---------2
134975d3a19aSMatthew G. Knepley      |         |         |
135075d3a19aSMatthew G. Knepley      |    D    2    C    |
135175d3a19aSMatthew G. Knepley      |         |         |
135275d3a19aSMatthew G. Knepley      3----3----0----1----1
135375d3a19aSMatthew G. Knepley      |         |         |
135475d3a19aSMatthew G. Knepley      |    A    0    B    |
135575d3a19aSMatthew G. Knepley      |         |         |
135675d3a19aSMatthew G. Knepley      0---------0---------1
135775d3a19aSMatthew G. Knepley      */
135875d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
135975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
136075d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
136175d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
136275d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
136375d3a19aSMatthew G. Knepley 
136475d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
136575d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
136675d3a19aSMatthew G. Knepley       /* A quad */
136775d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
136875d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
136975d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
137075d3a19aSMatthew G. Knepley       orntNew[1] = 0;
137175d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
137275d3a19aSMatthew G. Knepley       orntNew[2] = -2;
137375d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
137475d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
137575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
137675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
137775d3a19aSMatthew G. Knepley #if 1
137875d3a19aSMatthew 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);
137975d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
138075d3a19aSMatthew 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);
138175d3a19aSMatthew G. Knepley       }
138275d3a19aSMatthew G. Knepley #endif
138375d3a19aSMatthew G. Knepley       /* B quad */
138475d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
138575d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
138675d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
138775d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
138875d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
138975d3a19aSMatthew G. Knepley       orntNew[2] = 0;
139075d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
139175d3a19aSMatthew G. Knepley       orntNew[3] = -2;
139275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
139375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
139475d3a19aSMatthew G. Knepley #if 1
139575d3a19aSMatthew 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);
139675d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
139775d3a19aSMatthew 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);
139875d3a19aSMatthew G. Knepley       }
139975d3a19aSMatthew G. Knepley #endif
140075d3a19aSMatthew G. Knepley       /* C quad */
140175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
140275d3a19aSMatthew G. Knepley       orntNew[0] = -2;
140375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
140475d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
140575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
140675d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
140775d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
140875d3a19aSMatthew G. Knepley       orntNew[3] = 0;
140975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
141075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
141175d3a19aSMatthew G. Knepley #if 1
141275d3a19aSMatthew 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);
141375d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
141475d3a19aSMatthew 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);
141575d3a19aSMatthew G. Knepley       }
141675d3a19aSMatthew G. Knepley #endif
141775d3a19aSMatthew G. Knepley       /* D quad */
141875d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
141975d3a19aSMatthew G. Knepley       orntNew[0] = 0;
142075d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
142175d3a19aSMatthew G. Knepley       orntNew[1] = -2;
142275d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
142375d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
142475d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
142575d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
142675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
142775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
142875d3a19aSMatthew G. Knepley #if 1
142975d3a19aSMatthew 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);
143075d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
143175d3a19aSMatthew 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);
143275d3a19aSMatthew G. Knepley       }
143375d3a19aSMatthew G. Knepley #endif
143475d3a19aSMatthew G. Knepley     }
143575d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
143675d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1437785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
143875d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
143975d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
144075d3a19aSMatthew G. Knepley 
144175d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
144275d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1443455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
144475d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
144575d3a19aSMatthew G. Knepley 
144675d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
144775d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
144875d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
144975d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
145075d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
145175d3a19aSMatthew G. Knepley #if 1
145275d3a19aSMatthew 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);
145375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
145475d3a19aSMatthew 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);
145575d3a19aSMatthew G. Knepley         }
145675d3a19aSMatthew G. Knepley #endif
145775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
145875d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
145975d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
146075d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
146175d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1462455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
146375d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
146475d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
146575d3a19aSMatthew G. Knepley           }
1466455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
146775d3a19aSMatthew G. Knepley         }
146875d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
146975d3a19aSMatthew G. Knepley #if 1
147075d3a19aSMatthew 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);
147175d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
147275d3a19aSMatthew 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);
147375d3a19aSMatthew G. Knepley         }
147475d3a19aSMatthew G. Knepley #endif
147575d3a19aSMatthew G. Knepley       }
147675d3a19aSMatthew G. Knepley     }
147775d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
147875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
147975d3a19aSMatthew G. Knepley       const PetscInt *cone;
148075d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
148175d3a19aSMatthew G. Knepley 
148275d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
148375d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
148475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
148575d3a19aSMatthew G. Knepley 
148675d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
148775d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
148875d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
148975d3a19aSMatthew G. Knepley #if 1
149075d3a19aSMatthew 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);
149175d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
149275d3a19aSMatthew 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);
149375d3a19aSMatthew G. Knepley         }
149475d3a19aSMatthew G. Knepley #endif
149575d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
149675d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
149775d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
149875d3a19aSMatthew G. Knepley #if 1
149975d3a19aSMatthew 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);
150075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
150175d3a19aSMatthew 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);
150275d3a19aSMatthew G. Knepley         }
150375d3a19aSMatthew G. Knepley #endif
150475d3a19aSMatthew G. Knepley       }
150575d3a19aSMatthew G. Knepley     }
150675d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
150775d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
150875d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
150975d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
151075d3a19aSMatthew G. Knepley       PetscInt        size, s;
151175d3a19aSMatthew G. Knepley 
151275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
151375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
151475d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
151575d3a19aSMatthew G. Knepley         PetscInt r = 0;
151675d3a19aSMatthew G. Knepley 
151775d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
151875d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
151975d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
152075d3a19aSMatthew G. Knepley       }
152175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
152275d3a19aSMatthew G. Knepley #if 1
152375d3a19aSMatthew 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);
152475d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
152575d3a19aSMatthew 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);
152675d3a19aSMatthew G. Knepley       }
152775d3a19aSMatthew G. Knepley #endif
152875d3a19aSMatthew G. Knepley     }
152975d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
153075d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
153175d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
153275d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
153375d3a19aSMatthew G. Knepley       PetscInt        size, s;
153475d3a19aSMatthew G. Knepley 
153575d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
153675d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
153775d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
153875d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
153975d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
154075d3a19aSMatthew G. Knepley         PetscInt r = 0;
154175d3a19aSMatthew G. Knepley 
154275d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
154375d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
154475d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
154575d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
154675d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
154775d3a19aSMatthew G. Knepley       }
154875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
154975d3a19aSMatthew G. Knepley #if 1
155075d3a19aSMatthew 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);
155175d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
155275d3a19aSMatthew 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);
155375d3a19aSMatthew G. Knepley       }
155475d3a19aSMatthew G. Knepley #endif
155575d3a19aSMatthew G. Knepley     }
155675d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
155775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
155875d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
155975d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
156075d3a19aSMatthew G. Knepley 
156175d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
156275d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
156375d3a19aSMatthew G. Knepley       }
156475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
156575d3a19aSMatthew G. Knepley     }
1566da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
156775d3a19aSMatthew G. Knepley     break;
156875d3a19aSMatthew G. Knepley   case 3:
1569149f48fdSMatthew G. Knepley     /* Hybrid Simplicial 2D */
157075d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
157175d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
157275d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
157375d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
1574149f48fdSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
157575d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
157675d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
157775d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
157875d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
157975d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
158075d3a19aSMatthew G. Knepley 
158175d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
158275d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
158375d3a19aSMatthew G. Knepley       /* A triangle */
158475d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
158575d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
158675d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
158775d3a19aSMatthew G. Knepley       orntNew[1] = -2;
158875d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
158975d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
159075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
159175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
159275d3a19aSMatthew G. Knepley #if 1
1593149f48fdSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+0, cStartNew, cMaxNew);
159475d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1595149f48fdSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
159675d3a19aSMatthew G. Knepley       }
159775d3a19aSMatthew G. Knepley #endif
159875d3a19aSMatthew G. Knepley       /* B triangle */
159975d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
160075d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
160175d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
160275d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
160375d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
160475d3a19aSMatthew G. Knepley       orntNew[2] = -2;
160575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
160675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
160775d3a19aSMatthew G. Knepley #if 1
1608a97b51b8SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew);
160975d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1610a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
161175d3a19aSMatthew G. Knepley       }
161275d3a19aSMatthew G. Knepley #endif
161375d3a19aSMatthew G. Knepley       /* C triangle */
161475d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
161575d3a19aSMatthew G. Knepley       orntNew[0] = -2;
161675d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
161775d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
161875d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
161975d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
162075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
162175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
162275d3a19aSMatthew G. Knepley #if 1
1623a97b51b8SMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew);
162475d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1625a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
162675d3a19aSMatthew G. Knepley       }
162775d3a19aSMatthew G. Knepley #endif
162875d3a19aSMatthew G. Knepley       /* D triangle */
162975d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
163075d3a19aSMatthew G. Knepley       orntNew[0] = 0;
163175d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
163275d3a19aSMatthew G. Knepley       orntNew[1] = 0;
163375d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
163475d3a19aSMatthew G. Knepley       orntNew[2] = 0;
163575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
163675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
163775d3a19aSMatthew G. Knepley #if 1
1638a97b51b8SMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew);
163975d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1640a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
164175d3a19aSMatthew G. Knepley       }
164275d3a19aSMatthew G. Knepley #endif
164375d3a19aSMatthew G. Knepley     }
164475d3a19aSMatthew G. Knepley     /*
164575d3a19aSMatthew G. Knepley      2----3----3
164675d3a19aSMatthew G. Knepley      |         |
164775d3a19aSMatthew G. Knepley      |    B    |
164875d3a19aSMatthew G. Knepley      |         |
164975d3a19aSMatthew G. Knepley      0----4--- 1
165075d3a19aSMatthew G. Knepley      |         |
165175d3a19aSMatthew G. Knepley      |    A    |
165275d3a19aSMatthew G. Knepley      |         |
165375d3a19aSMatthew G. Knepley      0----2----1
165475d3a19aSMatthew G. Knepley      */
165575d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
165675d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
165775d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
165875d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
1659ea00e70eSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4], r;
166075d3a19aSMatthew G. Knepley 
166175d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
166275d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1663ea00e70eSMatthew G. Knepley       r    = (ornt[0] < 0 ? 1 : 0);
166475d3a19aSMatthew G. Knepley       /* A quad */
1665ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + r;
166675d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
1667ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + r;
166875d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
1669ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax);
1670ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
1671ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
1672ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
167375d3a19aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
167475d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
167575d3a19aSMatthew G. Knepley #if 1
167675d3a19aSMatthew 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);
167775d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
167875d3a19aSMatthew 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);
167975d3a19aSMatthew G. Knepley       }
168075d3a19aSMatthew G. Knepley #endif
168175d3a19aSMatthew G. Knepley       /* B quad */
1682ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + 1-r;
168375d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
1684ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + 1-r;
168575d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
1686ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
1687ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
1688ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax);
1689ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
169075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
169175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
169275d3a19aSMatthew G. Knepley #if 1
169375d3a19aSMatthew 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);
169475d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
169575d3a19aSMatthew 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);
169675d3a19aSMatthew G. Knepley       }
169775d3a19aSMatthew G. Knepley #endif
169875d3a19aSMatthew G. Knepley     }
169975d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
170075d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1701785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
170275d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
170375d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
170475d3a19aSMatthew G. Knepley 
170575d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
170675d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1707297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
170875d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
170975d3a19aSMatthew G. Knepley 
171075d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
171175d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
171275d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
171375d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
171475d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
171575d3a19aSMatthew G. Knepley #if 1
171675d3a19aSMatthew 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);
171775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
171875d3a19aSMatthew 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);
171975d3a19aSMatthew G. Knepley         }
172075d3a19aSMatthew G. Knepley #endif
172175d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
172275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
172375d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
172475d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
172575d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1726297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1727ea00e70eSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == f) break;
1728ea00e70eSMatthew G. Knepley           if (support[s] >= cMax) {
1729ea00e70eSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r);
1730ea00e70eSMatthew G. Knepley           } else {
1731297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
173275d3a19aSMatthew G. Knepley           }
173375d3a19aSMatthew G. Knepley         }
173475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
173575d3a19aSMatthew G. Knepley #if 1
173675d3a19aSMatthew 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);
173775d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
173875d3a19aSMatthew 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);
173975d3a19aSMatthew G. Knepley         }
174075d3a19aSMatthew G. Knepley #endif
174175d3a19aSMatthew G. Knepley       }
174275d3a19aSMatthew G. Knepley     }
174375d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
174475d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
174575d3a19aSMatthew G. Knepley       const PetscInt *cone;
174675d3a19aSMatthew G. Knepley 
174775d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
174875d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
174975d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
175075d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
175175d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
175275d3a19aSMatthew G. Knepley 
175375d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
175475d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
175575d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
175675d3a19aSMatthew G. Knepley #if 1
175775d3a19aSMatthew 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);
175875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
175975d3a19aSMatthew 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);
176075d3a19aSMatthew G. Knepley         }
176175d3a19aSMatthew G. Knepley #endif
176275d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
176375d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
176475d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
176575d3a19aSMatthew G. Knepley #if 1
176675d3a19aSMatthew 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);
176775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
176875d3a19aSMatthew 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);
176975d3a19aSMatthew G. Knepley         }
177075d3a19aSMatthew G. Knepley #endif
177175d3a19aSMatthew G. Knepley       }
177275d3a19aSMatthew G. Knepley     }
177375d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
177475d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
177575d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
1776ea00e70eSMatthew G. Knepley       const PetscInt *cone, *ornt;
177775d3a19aSMatthew G. Knepley       const PetscInt *support;
177875d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
177975d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
178075d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
178175d3a19aSMatthew G. Knepley 
178275d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
178375d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
178475d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
178575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
178675d3a19aSMatthew G. Knepley #if 1
178775d3a19aSMatthew 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);
178875d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
178975d3a19aSMatthew 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);
179075d3a19aSMatthew G. Knepley       }
179175d3a19aSMatthew G. Knepley #endif
179275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
179375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
179475d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
179575d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1796ea00e70eSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
179775d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
179875d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
179975d3a19aSMatthew G. Knepley         }
1800ea00e70eSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r);
180175d3a19aSMatthew G. Knepley       }
180275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
180375d3a19aSMatthew G. Knepley #if 1
180475d3a19aSMatthew 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);
180575d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
180675d3a19aSMatthew 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);
180775d3a19aSMatthew G. Knepley       }
180875d3a19aSMatthew G. Knepley #endif
180975d3a19aSMatthew G. Knepley     }
181075d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
181175d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
181275d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
181375d3a19aSMatthew G. Knepley       const PetscInt *cone;
181475d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
181575d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
181675d3a19aSMatthew G. Knepley 
181775d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
181875d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
181975d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
182075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
182175d3a19aSMatthew G. Knepley #if 1
182275d3a19aSMatthew 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);
182375d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
182475d3a19aSMatthew 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);
182575d3a19aSMatthew G. Knepley       }
182675d3a19aSMatthew G. Knepley #endif
182775d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
182875d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
182975d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
183075d3a19aSMatthew G. Knepley #if 1
183175d3a19aSMatthew 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);
183275d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
183375d3a19aSMatthew 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);
183475d3a19aSMatthew G. Knepley       }
183575d3a19aSMatthew G. Knepley #endif
183675d3a19aSMatthew G. Knepley     }
183775d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
183875d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
183975d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
184075d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
184175d3a19aSMatthew G. Knepley       PetscInt        size, s;
184275d3a19aSMatthew G. Knepley 
184375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
184475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
184575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
184675d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
184775d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
184875d3a19aSMatthew G. Knepley         } else {
184975d3a19aSMatthew G. Knepley           PetscInt r = 0;
185075d3a19aSMatthew G. Knepley 
185175d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
185275d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
185375d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
185475d3a19aSMatthew G. Knepley         }
185575d3a19aSMatthew G. Knepley       }
185675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
185775d3a19aSMatthew G. Knepley #if 1
185875d3a19aSMatthew 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);
185975d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
186075d3a19aSMatthew 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);
186175d3a19aSMatthew G. Knepley       }
186275d3a19aSMatthew G. Knepley #endif
186375d3a19aSMatthew G. Knepley     }
186475d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
186575d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
186675d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
186775d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
186875d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
186975d3a19aSMatthew G. Knepley 
187075d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
187175d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
187275d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
187375d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
187475d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
187575d3a19aSMatthew G. Knepley         PetscInt r = 0;
187675d3a19aSMatthew G. Knepley 
187775d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
187875d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
187975d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
188075d3a19aSMatthew G. Knepley 
188175d3a19aSMatthew G. Knepley           newSize += 1;
188275d3a19aSMatthew G. Knepley         } else {
188375d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
188475d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
188575d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
188675d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
188775d3a19aSMatthew G. Knepley 
188875d3a19aSMatthew G. Knepley           newSize += 2;
188975d3a19aSMatthew G. Knepley         }
189075d3a19aSMatthew G. Knepley       }
189175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
189275d3a19aSMatthew G. Knepley #if 1
189375d3a19aSMatthew 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);
189475d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
189575d3a19aSMatthew 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);
189675d3a19aSMatthew G. Knepley       }
189775d3a19aSMatthew G. Knepley #endif
189875d3a19aSMatthew G. Knepley     }
189975d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
190075d3a19aSMatthew G. Knepley     break;
1901a97b51b8SMatthew G. Knepley   case 4:
1902a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
1903a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
1904a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
1905a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
1906a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
1907a97b51b8SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
1908a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
1909a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
1910a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
1911a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
1912a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1913a97b51b8SMatthew G. Knepley 
1914a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1915a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1916a97b51b8SMatthew G. Knepley       /* A quad */
1917a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1918a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1919a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
1920a97b51b8SMatthew G. Knepley       orntNew[1] = 0;
1921a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
1922a97b51b8SMatthew G. Knepley       orntNew[2] = -2;
1923a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
1924a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
1925a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1926a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1927a97b51b8SMatthew G. Knepley #if 1
1928a97b51b8SMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+0, cStartNew, cMaxNew);
1929a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1930a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
1931a97b51b8SMatthew G. Knepley       }
1932a97b51b8SMatthew G. Knepley #endif
1933a97b51b8SMatthew G. Knepley       /* B quad */
1934a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1935a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1936a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1937a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1938a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
1939a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
1940a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
1941a97b51b8SMatthew G. Knepley       orntNew[3] = -2;
1942a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1943a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1944a97b51b8SMatthew G. Knepley #if 1
1945a97b51b8SMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew);
1946a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1947a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
1948a97b51b8SMatthew G. Knepley       }
1949a97b51b8SMatthew G. Knepley #endif
1950a97b51b8SMatthew G. Knepley       /* C quad */
1951a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
1952a97b51b8SMatthew G. Knepley       orntNew[0] = -2;
1953a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1954a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1955a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
1956a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
1957a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
1958a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
1959a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1960a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1961a97b51b8SMatthew G. Knepley #if 1
1962a97b51b8SMatthew G. Knepley       if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew);
1963a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1964a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
1965a97b51b8SMatthew G. Knepley       }
1966a97b51b8SMatthew G. Knepley #endif
1967a97b51b8SMatthew G. Knepley       /* D quad */
1968a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
1969a97b51b8SMatthew G. Knepley       orntNew[0] = 0;
1970a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
1971a97b51b8SMatthew G. Knepley       orntNew[1] = -2;
1972a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
1973a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
1974a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
1975a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
1976a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1977a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1978a97b51b8SMatthew G. Knepley #if 1
1979a97b51b8SMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew);
1980a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1981a97b51b8SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
1982a97b51b8SMatthew G. Knepley       }
1983a97b51b8SMatthew G. Knepley #endif
1984a97b51b8SMatthew G. Knepley     }
1985a97b51b8SMatthew G. Knepley     /*
1986a97b51b8SMatthew G. Knepley      2----3----3
1987a97b51b8SMatthew G. Knepley      |         |
1988a97b51b8SMatthew G. Knepley      |    B    |
1989a97b51b8SMatthew G. Knepley      |         |
1990a97b51b8SMatthew G. Knepley      0----4--- 1
1991a97b51b8SMatthew G. Knepley      |         |
1992a97b51b8SMatthew G. Knepley      |    A    |
1993a97b51b8SMatthew G. Knepley      |         |
1994a97b51b8SMatthew G. Knepley      0----2----1
1995a97b51b8SMatthew G. Knepley      */
1996a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
1997a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
1998a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
1999a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
2000a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2001a97b51b8SMatthew G. Knepley 
2002a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2003a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2004a97b51b8SMatthew G. Knepley       /* A quad */
2005a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2006a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2007a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2008a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2009a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax);
2010a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2011a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2012a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2013a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2014a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2015a97b51b8SMatthew G. Knepley #if 1
2016a97b51b8SMatthew 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);
2017a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2018a97b51b8SMatthew 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);
2019a97b51b8SMatthew G. Knepley       }
2020a97b51b8SMatthew G. Knepley #endif
2021a97b51b8SMatthew G. Knepley       /* B quad */
2022a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2023a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2024a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2025a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2026a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2027a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2028a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax);
2029a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2030a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2031a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2032a97b51b8SMatthew G. Knepley #if 1
2033a97b51b8SMatthew 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);
2034a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2035a97b51b8SMatthew 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);
2036a97b51b8SMatthew G. Knepley       }
2037a97b51b8SMatthew G. Knepley #endif
2038a97b51b8SMatthew G. Knepley     }
2039a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
2040a97b51b8SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2041a97b51b8SMatthew G. Knepley     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
2042a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2043a97b51b8SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2044a97b51b8SMatthew G. Knepley 
2045a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2046a97b51b8SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
2047a97b51b8SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2048a97b51b8SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2049a97b51b8SMatthew G. Knepley 
2050a97b51b8SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2051a97b51b8SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2052a97b51b8SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2053a97b51b8SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2054a97b51b8SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2055a97b51b8SMatthew G. Knepley #if 1
2056a97b51b8SMatthew 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);
2057a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2058a97b51b8SMatthew 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);
2059a97b51b8SMatthew G. Knepley         }
2060a97b51b8SMatthew G. Knepley #endif
2061a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2062a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2063a97b51b8SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2064a97b51b8SMatthew G. Knepley           if (support[s] >= cMax) {
2065a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2066a97b51b8SMatthew G. Knepley           } else {
2067a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2068a97b51b8SMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2069a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2070a97b51b8SMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
2071a97b51b8SMatthew G. Knepley               if (cone[c] == f) break;
2072a97b51b8SMatthew G. Knepley             }
2073a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
2074a97b51b8SMatthew G. Knepley           }
2075a97b51b8SMatthew G. Knepley         }
2076a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2077a97b51b8SMatthew G. Knepley #if 1
2078a97b51b8SMatthew 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);
2079a97b51b8SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2080a97b51b8SMatthew 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);
2081a97b51b8SMatthew G. Knepley         }
2082a97b51b8SMatthew G. Knepley #endif
2083a97b51b8SMatthew G. Knepley       }
2084a97b51b8SMatthew G. Knepley     }
2085a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
2086a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2087a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2088a97b51b8SMatthew G. Knepley 
2089a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2090a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2091a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2092a97b51b8SMatthew G. Knepley         PetscInt       coneNew[2], supportNew[2];
2093a97b51b8SMatthew G. Knepley 
2094a97b51b8SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2095a97b51b8SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fMax    - fStart) + (c - cStart);
2096a97b51b8SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2097a97b51b8SMatthew G. Knepley #if 1
2098a97b51b8SMatthew 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);
2099a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2100a97b51b8SMatthew 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);
2101a97b51b8SMatthew G. Knepley         }
2102a97b51b8SMatthew G. Knepley #endif
2103a97b51b8SMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
2104a97b51b8SMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
2105a97b51b8SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2106a97b51b8SMatthew G. Knepley #if 1
2107a97b51b8SMatthew 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);
2108a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2109a97b51b8SMatthew 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);
2110a97b51b8SMatthew G. Knepley         }
2111a97b51b8SMatthew G. Knepley #endif
2112a97b51b8SMatthew G. Knepley       }
2113a97b51b8SMatthew G. Knepley     }
2114a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
2115a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
2116a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
2117a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2118a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2119a97b51b8SMatthew G. Knepley       PetscInt        size, s, r;
2120a97b51b8SMatthew G. Knepley 
2121a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2122a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
2123a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
2124a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2125a97b51b8SMatthew G. Knepley #if 1
2126a97b51b8SMatthew 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);
2127a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2128a97b51b8SMatthew 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);
2129a97b51b8SMatthew G. Knepley       }
2130a97b51b8SMatthew G. Knepley #endif
2131a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2132a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2133a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2134a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2135a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r) {
2136a97b51b8SMatthew G. Knepley           if (cone[r+2] == f) break;
2137a97b51b8SMatthew G. Knepley         }
2138a97b51b8SMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2139a97b51b8SMatthew G. Knepley       }
2140a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2141a97b51b8SMatthew G. Knepley #if 1
2142a97b51b8SMatthew 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);
2143a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2144a97b51b8SMatthew 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);
2145a97b51b8SMatthew G. Knepley       }
2146a97b51b8SMatthew G. Knepley #endif
2147a97b51b8SMatthew G. Knepley     }
2148a97b51b8SMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
2149a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2150a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
2151a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2152a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2153a97b51b8SMatthew G. Knepley 
2154a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2155a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
2156a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
2157a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2158a97b51b8SMatthew G. Knepley #if 1
2159a97b51b8SMatthew 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);
2160a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2161a97b51b8SMatthew 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);
2162a97b51b8SMatthew G. Knepley       }
2163a97b51b8SMatthew G. Knepley #endif
2164a97b51b8SMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
2165a97b51b8SMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
2166a97b51b8SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2167a97b51b8SMatthew G. Knepley #if 1
2168a97b51b8SMatthew 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);
2169a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2170a97b51b8SMatthew 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);
2171a97b51b8SMatthew G. Knepley       }
2172a97b51b8SMatthew G. Knepley #endif
2173a97b51b8SMatthew G. Knepley     }
2174a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
2175a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2176a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2177a97b51b8SMatthew G. Knepley       const PetscInt *support, *cone;
2178a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2179a97b51b8SMatthew G. Knepley 
2180a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2181a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2182a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2183a97b51b8SMatthew G. Knepley         if (support[s] >= fMax) {
2184a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax);
2185a97b51b8SMatthew G. Knepley         } else {
2186a97b51b8SMatthew G. Knepley           PetscInt r = 0;
2187a97b51b8SMatthew G. Knepley 
2188a97b51b8SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2189a97b51b8SMatthew G. Knepley           if (cone[1] == v) r = 1;
2190a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2191a97b51b8SMatthew G. Knepley         }
2192a97b51b8SMatthew G. Knepley       }
2193a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2194a97b51b8SMatthew G. Knepley #if 1
2195a97b51b8SMatthew 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);
2196a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2197a97b51b8SMatthew 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);
2198a97b51b8SMatthew G. Knepley       }
2199a97b51b8SMatthew G. Knepley #endif
2200a97b51b8SMatthew G. Knepley     }
2201a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
2202a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2203a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
2204a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2205a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2206a97b51b8SMatthew G. Knepley 
2207a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2208a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2209a97b51b8SMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2210a97b51b8SMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2211a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2212a97b51b8SMatthew G. Knepley         PetscInt r = 0;
2213a97b51b8SMatthew G. Knepley 
2214a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2215a97b51b8SMatthew G. Knepley         if (support[s] >= cMax) {
2216a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax);
2217a97b51b8SMatthew G. Knepley         } else {
2218a97b51b8SMatthew G. Knepley           if      (cone[1] == f) r = 1;
2219a97b51b8SMatthew G. Knepley           else if (cone[2] == f) r = 2;
2220a97b51b8SMatthew G. Knepley           else if (cone[3] == f) r = 3;
2221a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r;
2222a97b51b8SMatthew G. Knepley         }
2223a97b51b8SMatthew G. Knepley       }
2224a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2225a97b51b8SMatthew G. Knepley #if 1
2226a97b51b8SMatthew 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);
2227a97b51b8SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
2228a97b51b8SMatthew 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);
2229a97b51b8SMatthew G. Knepley       }
2230a97b51b8SMatthew G. Knepley #endif
2231a97b51b8SMatthew G. Knepley     }
2232a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
2233a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2234a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
2235a97b51b8SMatthew G. Knepley       PetscInt       supportNew[4];
2236a97b51b8SMatthew G. Knepley 
2237a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2238a97b51b8SMatthew G. Knepley         supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2239a97b51b8SMatthew G. Knepley       }
2240a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2241a97b51b8SMatthew G. Knepley     }
2242a97b51b8SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2243a97b51b8SMatthew G. Knepley     break;
2244b5da9499SMatthew G. Knepley   case 5:
2245b5da9499SMatthew G. Knepley     /* Simplicial 3D */
2246b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
2247b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
2248b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2249b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
2250b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2251b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2252b5da9499SMatthew G. Knepley 
2253b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2254b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2255b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
2256518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
2257b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2258518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
2259b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2260518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
2261b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2262b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2263b5da9499SMatthew G. Knepley       orntNew[3] = 0;
2264b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2265b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2266b5da9499SMatthew G. Knepley #if 1
2267b5da9499SMatthew 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);
2268b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2269b5da9499SMatthew 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);
2270b5da9499SMatthew G. Knepley       }
2271b5da9499SMatthew G. Knepley #endif
2272b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
2273518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
2274b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2275518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
2276b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2277b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2278b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2279518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
2280b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2281b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2282b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2283b5da9499SMatthew G. Knepley #if 1
2284b5da9499SMatthew 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);
2285b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2286b5da9499SMatthew 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);
2287b5da9499SMatthew G. Knepley       }
2288b5da9499SMatthew G. Knepley #endif
2289b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
2290518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
2291b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2292b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2293b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2294518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
2295b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2296518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
2297b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2298b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2299b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2300b5da9499SMatthew G. Knepley #if 1
2301b5da9499SMatthew 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);
2302b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2303b5da9499SMatthew 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);
2304b5da9499SMatthew G. Knepley       }
2305b5da9499SMatthew G. Knepley #endif
2306b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
2307b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2308b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2309518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
2310b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2311518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
2312b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2313518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
2314b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2315b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2316b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2317b5da9499SMatthew G. Knepley #if 1
2318b5da9499SMatthew 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);
2319b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2320b5da9499SMatthew 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);
2321b5da9499SMatthew G. Knepley       }
2322b5da9499SMatthew G. Knepley #endif
2323b5da9499SMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
2324b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2325b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2326fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
2327db2c6090SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
2328fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2329fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
2330fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2331fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
2332b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
2333b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
2334b5da9499SMatthew G. Knepley #if 1
2335b5da9499SMatthew 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);
2336b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2337b5da9499SMatthew 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);
2338b5da9499SMatthew G. Knepley       }
2339b5da9499SMatthew G. Knepley #endif
2340b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
2341b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2342b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2343fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2344fac4ab25SMatthew G. Knepley       orntNew[1] = 1;
2345fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
2346b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2347fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
2348db2c6090SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
2349b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
2350b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
2351b5da9499SMatthew G. Knepley #if 1
2352b5da9499SMatthew 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);
2353b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2354b5da9499SMatthew 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);
2355b5da9499SMatthew G. Knepley       }
2356b5da9499SMatthew G. Knepley #endif
2357b5da9499SMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
2358b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2359b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2360fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
2361db2c6090SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
2362fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2363fac4ab25SMatthew G. Knepley       orntNew[2] = -3;
2364fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
2365fac4ab25SMatthew G. Knepley       orntNew[3] = -2;
2366b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
2367b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
2368b5da9499SMatthew G. Knepley #if 1
2369b5da9499SMatthew 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);
2370b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2371b5da9499SMatthew 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);
2372b5da9499SMatthew G. Knepley       }
2373b5da9499SMatthew G. Knepley #endif
2374b5da9499SMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
2375b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2376b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2377fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2378b5da9499SMatthew G. Knepley       orntNew[1] = -3;
2379fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
2380db2c6090SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
2381fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2382fac4ab25SMatthew G. Knepley       orntNew[3] = -3;
2383b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
2384b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
2385b5da9499SMatthew G. Knepley #if 1
2386b5da9499SMatthew 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);
2387b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2388b5da9499SMatthew 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);
2389b5da9499SMatthew G. Knepley       }
2390b5da9499SMatthew G. Knepley #endif
2391b5da9499SMatthew G. Knepley     }
2392b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
2393b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2394785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
2395b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2396b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
2397b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2398b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
2399b5da9499SMatthew G. Knepley 
2400b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2401b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
2402b5da9499SMatthew G. Knepley       /* A triangle */
2403b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
2404b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2405b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2406b5da9499SMatthew G. Knepley       orntNew[1] = -2;
2407b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
2408b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2409b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2410b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2411b5da9499SMatthew G. Knepley #if 1
2412b5da9499SMatthew 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);
2413b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2414b5da9499SMatthew 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);
2415b5da9499SMatthew G. Knepley       }
2416b5da9499SMatthew G. Knepley #endif
2417b5da9499SMatthew G. Knepley       /* B triangle */
2418b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
2419b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2420b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
2421b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2422b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2423b5da9499SMatthew G. Knepley       orntNew[2] = -2;
2424b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2425b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2426b5da9499SMatthew G. Knepley #if 1
2427b5da9499SMatthew 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);
2428b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2429b5da9499SMatthew 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);
2430b5da9499SMatthew G. Knepley       }
2431b5da9499SMatthew G. Knepley #endif
2432b5da9499SMatthew G. Knepley       /* C triangle */
2433b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2434b5da9499SMatthew G. Knepley       orntNew[0] = -2;
2435b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
2436b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2437b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
2438b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2439b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2440b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2441b5da9499SMatthew G. Knepley #if 1
2442b5da9499SMatthew 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);
2443b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2444b5da9499SMatthew 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);
2445b5da9499SMatthew G. Knepley       }
2446b5da9499SMatthew G. Knepley #endif
2447b5da9499SMatthew G. Knepley       /* D triangle */
2448b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2449b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2450b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2451b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2452b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2453b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2454b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2455b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2456b5da9499SMatthew G. Knepley #if 1
2457b5da9499SMatthew 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);
2458b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2459b5da9499SMatthew 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);
2460b5da9499SMatthew G. Knepley       }
2461b5da9499SMatthew G. Knepley #endif
2462b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2463b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2464b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2465b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2466219f7b90SMatthew G. Knepley           PetscInt subf;
2467b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2468b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2469b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2470b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2471b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
2472b5da9499SMatthew G. Knepley           }
2473219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
2474219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
2475b5da9499SMatthew G. Knepley         }
2476b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
2477b5da9499SMatthew G. Knepley #if 1
24789ddff745SMatthew 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);
2479b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2480b5da9499SMatthew 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);
2481b5da9499SMatthew G. Knepley         }
2482b5da9499SMatthew G. Knepley #endif
2483b5da9499SMatthew G. Knepley       }
2484b5da9499SMatthew G. Knepley     }
2485b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
2486b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2487b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
2488b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2489b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
2490b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
2491b5da9499SMatthew G. Knepley 
2492b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2493b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2494b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
24954bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2496b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
24974bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2498b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
24994bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
2500b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2501b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2502b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2503b5da9499SMatthew G. Knepley #if 1
2504b5da9499SMatthew 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);
2505b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2506b5da9499SMatthew 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);
2507b5da9499SMatthew G. Knepley       }
2508b5da9499SMatthew G. Knepley #endif
2509b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
2510b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
2511b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2512b5da9499SMatthew G. Knepley #if 1
2513b5da9499SMatthew 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);
2514b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2515b5da9499SMatthew 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);
2516b5da9499SMatthew G. Knepley       }
2517b5da9499SMatthew G. Knepley #endif
2518b5da9499SMatthew G. Knepley       ++newp;
2519b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
25204bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2521b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
25224bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
2523b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
25244bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2525b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2526b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2527b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2528b5da9499SMatthew G. Knepley #if 1
25294bb260e2SMatthew 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);
2530b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2531b5da9499SMatthew 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);
2532b5da9499SMatthew G. Knepley       }
2533b5da9499SMatthew G. Knepley #endif
2534b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
2535b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
2536b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2537b5da9499SMatthew G. Knepley #if 1
2538b5da9499SMatthew 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);
2539b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2540b5da9499SMatthew 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);
2541b5da9499SMatthew G. Knepley       }
2542b5da9499SMatthew G. Knepley #endif
2543b5da9499SMatthew G. Knepley       ++newp;
2544b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
25454bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
2546b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
25474bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2548b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
25494bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
2550b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
2551b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2552b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2553b5da9499SMatthew G. Knepley #if 1
2554b5da9499SMatthew 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);
2555b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2556b5da9499SMatthew 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);
2557b5da9499SMatthew G. Knepley       }
2558b5da9499SMatthew G. Knepley #endif
2559b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
2560b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2561b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2562b5da9499SMatthew G. Knepley #if 1
2563b5da9499SMatthew 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);
2564b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2565b5da9499SMatthew 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);
2566b5da9499SMatthew G. Knepley       }
2567b5da9499SMatthew G. Knepley #endif
2568b5da9499SMatthew G. Knepley       ++newp;
2569b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
25704bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
2571b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
25724bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2573b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
25744bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2575b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2576b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2577b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2578b5da9499SMatthew G. Knepley #if 1
2579b5da9499SMatthew 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);
2580b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2581b5da9499SMatthew 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);
2582b5da9499SMatthew G. Knepley       }
2583b5da9499SMatthew G. Knepley #endif
2584b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
2585b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2586b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2587b5da9499SMatthew G. Knepley #if 1
2588b5da9499SMatthew 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);
2589b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2590b5da9499SMatthew 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);
2591b5da9499SMatthew G. Knepley       }
2592b5da9499SMatthew G. Knepley #endif
2593b5da9499SMatthew G. Knepley       ++newp;
2594b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
25954bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2596b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
2597b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
25984bb260e2SMatthew G. Knepley       orntNew[1] = -2;
25994bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2600b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2601b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2602b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2603b5da9499SMatthew G. Knepley #if 1
2604b5da9499SMatthew 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);
2605b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2606b5da9499SMatthew 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);
2607b5da9499SMatthew G. Knepley       }
2608b5da9499SMatthew G. Knepley #endif
2609b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2610b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2611b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2612b5da9499SMatthew G. Knepley #if 1
2613b5da9499SMatthew 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);
2614b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2615b5da9499SMatthew 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);
2616b5da9499SMatthew G. Knepley       }
2617b5da9499SMatthew G. Knepley #endif
2618b5da9499SMatthew G. Knepley       ++newp;
2619b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
26204bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2621b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2622b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
26234bb260e2SMatthew G. Knepley       orntNew[1] = 0;
26244bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
26252baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
2626b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2627b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2628b5da9499SMatthew G. Knepley #if 1
2629b5da9499SMatthew 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);
2630b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2631b5da9499SMatthew 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);
2632b5da9499SMatthew G. Knepley       }
2633b5da9499SMatthew G. Knepley #endif
2634b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2635b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2636b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2637b5da9499SMatthew G. Knepley #if 1
2638b5da9499SMatthew 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);
2639b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2640b5da9499SMatthew 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);
2641b5da9499SMatthew G. Knepley       }
2642b5da9499SMatthew G. Knepley #endif
2643b5da9499SMatthew G. Knepley       ++newp;
2644b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
26454bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2646b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
2647b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2648fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
26494bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2650b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
2651b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2652b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2653b5da9499SMatthew G. Knepley #if 1
2654b5da9499SMatthew 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);
2655b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2656b5da9499SMatthew 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);
2657b5da9499SMatthew G. Knepley       }
2658b5da9499SMatthew G. Knepley #endif
2659b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2660b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2661b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2662b5da9499SMatthew G. Knepley #if 1
2663b5da9499SMatthew 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);
2664b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2665b5da9499SMatthew 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);
2666b5da9499SMatthew G. Knepley       }
2667b5da9499SMatthew G. Knepley #endif
2668b5da9499SMatthew G. Knepley       ++newp;
2669b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
26704bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2671b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
26724bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2673b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
2674b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
26754bb260e2SMatthew G. Knepley       orntNew[2] = -2;
2676b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2677b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2678b5da9499SMatthew G. Knepley #if 1
2679b5da9499SMatthew 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);
2680b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2681b5da9499SMatthew 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);
2682b5da9499SMatthew G. Knepley       }
2683b5da9499SMatthew G. Knepley #endif
2684b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2685b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2686b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2687b5da9499SMatthew G. Knepley #if 1
2688b5da9499SMatthew 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);
2689b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2690b5da9499SMatthew 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);
2691b5da9499SMatthew G. Knepley       }
2692b5da9499SMatthew G. Knepley #endif
2693b5da9499SMatthew G. Knepley       ++newp;
2694b5da9499SMatthew G. Knepley     }
2695b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
2696b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2697b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
2698b5da9499SMatthew G. Knepley 
2699b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2700b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
2701b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2702b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2703b5da9499SMatthew G. Knepley 
2704b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
2705b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2706b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2707b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2708b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2709b5da9499SMatthew G. Knepley #if 1
2710b5da9499SMatthew 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);
2711b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2712b5da9499SMatthew 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);
2713b5da9499SMatthew G. Knepley         }
2714b5da9499SMatthew G. Knepley #endif
2715b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
2716b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2717b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2718b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2719b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2720b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2721b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2722b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
2723b5da9499SMatthew G. Knepley           }
2724b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
2725b5da9499SMatthew G. Knepley         }
2726b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2727b5da9499SMatthew G. Knepley #if 1
2728b5da9499SMatthew 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);
2729b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2730b5da9499SMatthew 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);
2731b5da9499SMatthew G. Knepley         }
2732b5da9499SMatthew G. Knepley #endif
2733b5da9499SMatthew G. Knepley       }
2734b5da9499SMatthew G. Knepley     }
273586f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
2736b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2737b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2738b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
2739b5da9499SMatthew G. Knepley 
2740b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2741b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2742b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
2743b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
2744b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
2745b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
2746b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
2747b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
2748b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
2749b5da9499SMatthew G. Knepley 
2750b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2751b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
2752b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
2753b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2754b5da9499SMatthew G. Knepley #if 1
2755b5da9499SMatthew 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);
2756b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2757b5da9499SMatthew 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);
2758b5da9499SMatthew G. Knepley         }
2759b5da9499SMatthew G. Knepley #endif
2760b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
2761b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
2762b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2763b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2764b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2765b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2766b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
276786f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
27689ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
2769b5da9499SMatthew G. Knepley           if (er == eint[c]) {
2770b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
2771b5da9499SMatthew G. Knepley           } else {
2772b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
2773b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
2774b5da9499SMatthew G. Knepley           }
2775b5da9499SMatthew G. Knepley         }
2776b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2777b5da9499SMatthew G. Knepley #if 1
2778b5da9499SMatthew 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);
2779b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
2780b5da9499SMatthew 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);
2781b5da9499SMatthew G. Knepley         }
2782b5da9499SMatthew G. Knepley #endif
2783b5da9499SMatthew G. Knepley       }
2784b5da9499SMatthew G. Knepley     }
2785b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
2786b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2787b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2788b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
27894a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
2790b5da9499SMatthew G. Knepley 
2791b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2792b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2793b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
279442525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
2795b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2796b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
279742525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
2798b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2799b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2800b5da9499SMatthew G. Knepley #if 1
2801b5da9499SMatthew 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);
2802b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2803b5da9499SMatthew 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);
2804b5da9499SMatthew G. Knepley       }
2805b5da9499SMatthew G. Knepley #endif
2806b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
2807b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
2808b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
2809b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
2810b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2811b5da9499SMatthew G. Knepley #if 1
2812b5da9499SMatthew 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);
2813b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2814b5da9499SMatthew 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);
2815b5da9499SMatthew G. Knepley       }
2816b5da9499SMatthew G. Knepley #endif
2817b5da9499SMatthew G. Knepley     }
2818b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
2819b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2820b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2821b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
2822b5da9499SMatthew G. Knepley       PetscInt        size, s;
2823b5da9499SMatthew G. Knepley 
2824b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2825b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2826b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2827b5da9499SMatthew G. Knepley         PetscInt r = 0;
2828b5da9499SMatthew G. Knepley 
2829b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2830b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
2831b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
2832b5da9499SMatthew G. Knepley       }
2833b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2834b5da9499SMatthew G. Knepley #if 1
2835b5da9499SMatthew 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);
2836b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2837b5da9499SMatthew 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);
2838b5da9499SMatthew G. Knepley       }
2839b5da9499SMatthew G. Knepley #endif
2840b5da9499SMatthew G. Knepley     }
2841b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
2842b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2843b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
2844b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
2845b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
2846b5da9499SMatthew G. Knepley 
2847b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
2848b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2849b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
2850b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
2851b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2852b5da9499SMatthew G. Knepley         PetscInt r = 0;
2853b5da9499SMatthew G. Knepley 
2854b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2855b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2856b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
2857b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
2858b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
2859b5da9499SMatthew G. Knepley       }
2860b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2861b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
2862b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
2863b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
2864b5da9499SMatthew G. Knepley 
2865b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
2866b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
2867b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2868b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
2869b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
287042525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
2871b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
2872b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2873b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
287442525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
287542525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
2876b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
2877b5da9499SMatthew G. Knepley         }
2878b5da9499SMatthew G. Knepley       }
2879b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2880b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2881b5da9499SMatthew G. Knepley #if 1
2882b5da9499SMatthew 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);
2883b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
2884b5da9499SMatthew 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);
2885b5da9499SMatthew G. Knepley       }
2886b5da9499SMatthew G. Knepley #endif
2887b5da9499SMatthew G. Knepley     }
2888b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2889b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
2890b5da9499SMatthew G. Knepley     break;
28916ce3c06aSMatthew G. Knepley   case 7:
28926ce3c06aSMatthew G. Knepley     /* Hybrid Simplicial 3D */
28936ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
28946ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
28956ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
28966ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
28976ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
28986ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
28996ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
29006ce3c06aSMatthew G. Knepley 
29016ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
29026ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
29036ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
29046ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
29056ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
29066ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
29076ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
29086ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
29096ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
29106ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
29116ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
29126ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
29136ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
29146ce3c06aSMatthew G. Knepley #if 1
29156ce3c06aSMatthew 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);
29166ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29176ce3c06aSMatthew 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);
29186ce3c06aSMatthew G. Knepley       }
29196ce3c06aSMatthew G. Knepley #endif
29206ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
29216ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
29226ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
29236ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
29246ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
29256ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
29266ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
29276ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
29286ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
29296ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
29306ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
29316ce3c06aSMatthew G. Knepley #if 1
29326ce3c06aSMatthew 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);
29336ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29346ce3c06aSMatthew 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);
29356ce3c06aSMatthew G. Knepley       }
29366ce3c06aSMatthew G. Knepley #endif
29376ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
29386ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
29396ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
29406ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
29416ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
29426ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
29436ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
29446ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
29456ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
29466ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
29476ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
29486ce3c06aSMatthew G. Knepley #if 1
29496ce3c06aSMatthew 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);
29506ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29516ce3c06aSMatthew 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);
29526ce3c06aSMatthew G. Knepley       }
29536ce3c06aSMatthew G. Knepley #endif
29546ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
29556ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
29566ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
29576ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
29586ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
29596ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
29606ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
29616ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
29626ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
29636ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
29646ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
29656ce3c06aSMatthew G. Knepley #if 1
29666ce3c06aSMatthew 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);
29676ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29686ce3c06aSMatthew 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);
29696ce3c06aSMatthew G. Knepley       }
29706ce3c06aSMatthew G. Knepley #endif
29716ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
29726ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
29736ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
29749ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
29759ddff745SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
29769ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
29779ddff745SMatthew G. Knepley       orntNew[2] = 0;
29789ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
29799ddff745SMatthew G. Knepley       orntNew[3] = 2;
29806ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
29816ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
29826ce3c06aSMatthew G. Knepley #if 1
29836ce3c06aSMatthew 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);
29846ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29856ce3c06aSMatthew 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);
29866ce3c06aSMatthew G. Knepley       }
29876ce3c06aSMatthew G. Knepley #endif
29886ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
29896ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
29906ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
29919ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
29929ddff745SMatthew G. Knepley       orntNew[1] = 1;
29939ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
29946ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
29959ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
29969ddff745SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
29976ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
29986ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
29996ce3c06aSMatthew G. Knepley #if 1
30006ce3c06aSMatthew 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);
30016ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30026ce3c06aSMatthew 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);
30036ce3c06aSMatthew G. Knepley       }
30046ce3c06aSMatthew G. Knepley #endif
30056ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
30066ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
30076ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
30089ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
30099ddff745SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
30109ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
30119ddff745SMatthew G. Knepley       orntNew[2] = -3;
30129ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
30139ddff745SMatthew G. Knepley       orntNew[3] = -2;
30146ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
30156ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
30166ce3c06aSMatthew G. Knepley #if 1
30176ce3c06aSMatthew 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);
30186ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30196ce3c06aSMatthew 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);
30206ce3c06aSMatthew G. Knepley       }
30216ce3c06aSMatthew G. Knepley #endif
30226ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
30236ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
30246ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
30259ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
30266ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
30279ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
30289ddff745SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
30299ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
30309ddff745SMatthew G. Knepley       orntNew[3] = -3;
30316ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
30326ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
30336ce3c06aSMatthew G. Knepley #if 1
30346ce3c06aSMatthew 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);
30356ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30366ce3c06aSMatthew 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);
30376ce3c06aSMatthew G. Knepley       }
30386ce3c06aSMatthew G. Knepley #endif
30396ce3c06aSMatthew G. Knepley     }
30406ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
30416ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
30426ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
3043d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
30443b61eb6dSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5], o, of, i;
30456ce3c06aSMatthew G. Knepley 
30466ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
30476ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3048d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
3049084f9c62SMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
30506ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
30516ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
30526ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
30536ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
30546ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
3055084f9c62SMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? -1 : 1;
30563b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], r)       + 2;
30573b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)]       - fMax)*2 + (o*of < 0 ? 1 : 0);
30583b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
30593b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2;
30603b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
30613b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
30623b61eb6dSMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
30633b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2;
30643b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (o*of < 0 ? 0 : 1);
30653b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
30666ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
30676ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
30686ce3c06aSMatthew G. Knepley #if 1
30696ce3c06aSMatthew 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);
30706ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
30716ce3c06aSMatthew 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);
30726ce3c06aSMatthew G. Knepley         }
30736ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
30746ce3c06aSMatthew 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);
30756ce3c06aSMatthew G. Knepley         }
30766ce3c06aSMatthew G. Knepley #endif
30776ce3c06aSMatthew G. Knepley       }
30786ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
30796ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
30806ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
30816ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
30823b61eb6dSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
30836ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
30843b61eb6dSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
30856ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
30863b61eb6dSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
30876ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
30886ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
30896ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
30906ce3c06aSMatthew G. Knepley #if 1
30916ce3c06aSMatthew 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);
30926ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
30936ce3c06aSMatthew 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);
30946ce3c06aSMatthew G. Knepley       }
30956ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
30966ce3c06aSMatthew 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);
30976ce3c06aSMatthew G. Knepley       }
30986ce3c06aSMatthew G. Knepley #endif
30996ce3c06aSMatthew G. Knepley     }
31006ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
31016ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3102785e854fSJed Brown     ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
31036ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
31046ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
31056ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
31066ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
31076ce3c06aSMatthew G. Knepley 
31086ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
31096ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
31106ce3c06aSMatthew G. Knepley       /* A triangle */
31116ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
31126ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
31136ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
31146ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
31156ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
31166ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
31176ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
31186ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
31196ce3c06aSMatthew G. Knepley #if 1
31206ce3c06aSMatthew 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);
31216ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31226ce3c06aSMatthew 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);
31236ce3c06aSMatthew G. Knepley       }
31246ce3c06aSMatthew G. Knepley #endif
31256ce3c06aSMatthew G. Knepley       /* B triangle */
31266ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
31276ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
31286ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
31296ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
31306ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
31316ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
31326ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
31336ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
31346ce3c06aSMatthew G. Knepley #if 1
31356ce3c06aSMatthew 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);
31366ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31376ce3c06aSMatthew 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);
31386ce3c06aSMatthew G. Knepley       }
31396ce3c06aSMatthew G. Knepley #endif
31406ce3c06aSMatthew G. Knepley       /* C triangle */
31416ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
31426ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
31436ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
31446ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
31456ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
31466ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
31476ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
31486ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
31496ce3c06aSMatthew G. Knepley #if 1
31506ce3c06aSMatthew 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);
31516ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31526ce3c06aSMatthew 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);
31536ce3c06aSMatthew G. Knepley       }
31546ce3c06aSMatthew G. Knepley #endif
31556ce3c06aSMatthew G. Knepley       /* D triangle */
31566ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
31576ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
31586ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
31596ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
31606ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
31616ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
31626ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
31636ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
31646ce3c06aSMatthew G. Knepley #if 1
31656ce3c06aSMatthew 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);
31666ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31676ce3c06aSMatthew 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);
31686ce3c06aSMatthew G. Knepley       }
31696ce3c06aSMatthew G. Knepley #endif
31706ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
31716ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
31726ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
31736ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
31749ddff745SMatthew G. Knepley           PetscInt subf;
31756ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
31766ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
31776ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
31786ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
31796ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
31806ce3c06aSMatthew G. Knepley           }
31819ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
31826ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
31839ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
31846ce3c06aSMatthew G. Knepley           } else {
31859ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
31866ce3c06aSMatthew G. Knepley           }
31876ce3c06aSMatthew G. Knepley         }
31886ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
31896ce3c06aSMatthew G. Knepley #if 1
31909ddff745SMatthew 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);
31916ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
31926ce3c06aSMatthew 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);
31936ce3c06aSMatthew G. Knepley         }
31946ce3c06aSMatthew G. Knepley #endif
31956ce3c06aSMatthew G. Knepley       }
31966ce3c06aSMatthew G. Knepley     }
31976ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
31986ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
31996ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
32006ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
32016ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
32026ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
32036ce3c06aSMatthew G. Knepley 
32046ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
32056ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
32066ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
32079ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
32086ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
32099ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
32106ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
32119ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
32126ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
32136ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32146ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32156ce3c06aSMatthew G. Knepley #if 1
32166ce3c06aSMatthew 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);
32176ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32186ce3c06aSMatthew 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);
32196ce3c06aSMatthew G. Knepley       }
32206ce3c06aSMatthew G. Knepley #endif
32216ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
32226ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
32236ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32246ce3c06aSMatthew G. Knepley #if 1
32256ce3c06aSMatthew 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);
32266ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32276ce3c06aSMatthew 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);
32286ce3c06aSMatthew G. Knepley       }
32296ce3c06aSMatthew G. Knepley #endif
32306ce3c06aSMatthew G. Knepley       ++newp;
32316ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
32329ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
32336ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
32349ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
32356ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
32369ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
32376ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
32386ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32396ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32406ce3c06aSMatthew G. Knepley #if 1
32416ce3c06aSMatthew 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);
32426ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32436ce3c06aSMatthew 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);
32446ce3c06aSMatthew G. Knepley       }
32456ce3c06aSMatthew G. Knepley #endif
32466ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
32476ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
32486ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32496ce3c06aSMatthew G. Knepley #if 1
32506ce3c06aSMatthew 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);
32516ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32526ce3c06aSMatthew 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);
32536ce3c06aSMatthew G. Knepley       }
32546ce3c06aSMatthew G. Knepley #endif
32556ce3c06aSMatthew G. Knepley       ++newp;
32566ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
32579ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
32586ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
32599ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
32606ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
32619ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
32626ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
32636ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32646ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32656ce3c06aSMatthew G. Knepley #if 1
32666ce3c06aSMatthew 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);
32676ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32686ce3c06aSMatthew 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);
32696ce3c06aSMatthew G. Knepley       }
32706ce3c06aSMatthew G. Knepley #endif
32716ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
32726ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
32736ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32746ce3c06aSMatthew G. Knepley #if 1
32756ce3c06aSMatthew 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);
32766ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32776ce3c06aSMatthew 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);
32786ce3c06aSMatthew G. Knepley       }
32796ce3c06aSMatthew G. Knepley #endif
32806ce3c06aSMatthew G. Knepley       ++newp;
32816ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
32829ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
32836ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
32849ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
32856ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
32869ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
32876ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
32886ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32896ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32906ce3c06aSMatthew G. Knepley #if 1
32916ce3c06aSMatthew 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);
32926ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32936ce3c06aSMatthew 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);
32946ce3c06aSMatthew G. Knepley       }
32956ce3c06aSMatthew G. Knepley #endif
32966ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
32976ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
32986ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32996ce3c06aSMatthew G. Knepley #if 1
33006ce3c06aSMatthew 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);
33016ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
33026ce3c06aSMatthew 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);
33036ce3c06aSMatthew G. Knepley       }
33046ce3c06aSMatthew G. Knepley #endif
33056ce3c06aSMatthew G. Knepley       ++newp;
33066ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
33079ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
33086ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
33096ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
33109ddff745SMatthew G. Knepley       orntNew[1] = -2;
33119ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
33126ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
33136ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33146ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33156ce3c06aSMatthew G. Knepley #if 1
33166ce3c06aSMatthew 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);
33176ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33186ce3c06aSMatthew 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);
33196ce3c06aSMatthew G. Knepley       }
33206ce3c06aSMatthew G. Knepley #endif
33216ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
33226ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
33236ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33246ce3c06aSMatthew G. Knepley #if 1
33256ce3c06aSMatthew 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);
33266ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
33276ce3c06aSMatthew 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);
33286ce3c06aSMatthew G. Knepley       }
33296ce3c06aSMatthew G. Knepley #endif
33306ce3c06aSMatthew G. Knepley       ++newp;
33316ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
33329ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
33336ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
33346ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
33359ddff745SMatthew G. Knepley       orntNew[1] = 0;
33369ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
33379ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
33386ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33396ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33406ce3c06aSMatthew G. Knepley #if 1
33416ce3c06aSMatthew 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);
33426ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33436ce3c06aSMatthew 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);
33446ce3c06aSMatthew G. Knepley       }
33456ce3c06aSMatthew G. Knepley #endif
33466ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
33476ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
33486ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33496ce3c06aSMatthew G. Knepley #if 1
33506ce3c06aSMatthew 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);
33516ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
33526ce3c06aSMatthew 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);
33536ce3c06aSMatthew G. Knepley       }
33546ce3c06aSMatthew G. Knepley #endif
33556ce3c06aSMatthew G. Knepley       ++newp;
33566ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
33579ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
33586ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
33596ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
33609ddff745SMatthew G. Knepley       orntNew[1] = 0;
33619ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
33626ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
33636ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33646ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33656ce3c06aSMatthew G. Knepley #if 1
33666ce3c06aSMatthew 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);
33676ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33686ce3c06aSMatthew 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);
33696ce3c06aSMatthew G. Knepley       }
33706ce3c06aSMatthew G. Knepley #endif
33716ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
33726ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
33736ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33746ce3c06aSMatthew G. Knepley #if 1
33756ce3c06aSMatthew 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);
33766ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
33776ce3c06aSMatthew 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);
33786ce3c06aSMatthew G. Knepley       }
33796ce3c06aSMatthew G. Knepley #endif
33806ce3c06aSMatthew G. Knepley       ++newp;
33816ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
33829ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
33836ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
33849ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
33856ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
33866ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
33879ddff745SMatthew G. Knepley       orntNew[2] = -2;
33886ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33896ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33906ce3c06aSMatthew G. Knepley #if 1
33916ce3c06aSMatthew 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);
33926ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33936ce3c06aSMatthew 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);
33946ce3c06aSMatthew G. Knepley       }
33956ce3c06aSMatthew G. Knepley #endif
33966ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
33976ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
33986ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33996ce3c06aSMatthew G. Knepley #if 1
34006ce3c06aSMatthew 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);
34016ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
34026ce3c06aSMatthew 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);
34036ce3c06aSMatthew G. Knepley       }
34046ce3c06aSMatthew G. Knepley #endif
34056ce3c06aSMatthew G. Knepley       ++newp;
34066ce3c06aSMatthew G. Knepley     }
34076ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
34086ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
34096ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
34106ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
34116ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
34126ce3c06aSMatthew G. Knepley 
34136ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
34146ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
34156ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
34166ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
34176ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
34186ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
34196ce3c06aSMatthew G. Knepley 
34206ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
34216ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
34226ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
34236ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
34246ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
34256ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
34266ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
34276ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
34286ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34296ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
34306ce3c06aSMatthew G. Knepley #if 1
34316ce3c06aSMatthew 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);
34326ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34336ce3c06aSMatthew 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);
34346ce3c06aSMatthew G. Knepley         }
34356ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
34366ce3c06aSMatthew 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);
34376ce3c06aSMatthew G. Knepley         }
34386ce3c06aSMatthew G. Knepley #endif
34396ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
3440d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
3441084f9c62SMatthew G. Knepley           PetscInt        o, of;
34426ce3c06aSMatthew G. Knepley 
34436ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
34446ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
3445084f9c62SMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
34466ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
34476ce3c06aSMatthew 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]);
3448d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
3449084f9c62SMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
3450084f9c62SMatthew G. Knepley           supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3;
34516ce3c06aSMatthew G. Knepley         }
34526ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
34536ce3c06aSMatthew G. Knepley #if 1
34546ce3c06aSMatthew 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);
34556ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
34566ce3c06aSMatthew 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);
34576ce3c06aSMatthew G. Knepley         }
34586ce3c06aSMatthew G. Knepley #endif
34596ce3c06aSMatthew G. Knepley       }
34606ce3c06aSMatthew G. Knepley     }
34616ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
34626ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
34636ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
34646ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
34656ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
34666ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
34676ce3c06aSMatthew G. Knepley 
34686ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
34696ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
34706ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3471b598a9d5SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
34726ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
3473b598a9d5SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
34746ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
3475b598a9d5SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
34766ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
3477b598a9d5SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r]       - fMax);
34786ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
34796ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
34806ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
34816ce3c06aSMatthew G. Knepley #if 1
34826ce3c06aSMatthew 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);
34836ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34846ce3c06aSMatthew 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);
34856ce3c06aSMatthew G. Knepley         }
34866ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
34876ce3c06aSMatthew 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);
34886ce3c06aSMatthew G. Knepley         }
34896ce3c06aSMatthew G. Knepley #endif
34906ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
34916ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
34926ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
34936ce3c06aSMatthew G. Knepley #if 1
34946ce3c06aSMatthew 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);
34956ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34966ce3c06aSMatthew 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);
34976ce3c06aSMatthew G. Knepley         }
34986ce3c06aSMatthew G. Knepley #endif
34996ce3c06aSMatthew G. Knepley       }
35006ce3c06aSMatthew G. Knepley     }
35016ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
35026ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
35036ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
35046ce3c06aSMatthew G. Knepley 
35056ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
35066ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
35076ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
35086ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
35096ce3c06aSMatthew G. Knepley 
35106ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
35116ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
35126ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
35136ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
35146ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35156ce3c06aSMatthew G. Knepley #if 1
35166ce3c06aSMatthew 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);
35176ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35186ce3c06aSMatthew 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);
35196ce3c06aSMatthew G. Knepley         }
35206ce3c06aSMatthew G. Knepley #endif
35216ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
35226ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
35236ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
35246ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
35256ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
35266ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
35276ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
35286ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
35296ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
35306ce3c06aSMatthew G. Knepley           } else {
35316ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
35326ce3c06aSMatthew G. Knepley           }
35336ce3c06aSMatthew G. Knepley         }
35346ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35356ce3c06aSMatthew G. Knepley #if 1
35366ce3c06aSMatthew 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);
35376ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
35386ce3c06aSMatthew 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);
35396ce3c06aSMatthew G. Knepley         }
35406ce3c06aSMatthew G. Knepley #endif
35416ce3c06aSMatthew G. Knepley       }
35426ce3c06aSMatthew G. Knepley     }
35436ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
35446ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
35456ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
35466ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
35476ce3c06aSMatthew G. Knepley 
35486ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
35496ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
35506ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
35516ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
35526ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
35536ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
35546ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
35556ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
35566ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
35576ce3c06aSMatthew G. Knepley 
35586ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
35596ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
35606ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
35616ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35626ce3c06aSMatthew G. Knepley #if 1
35636ce3c06aSMatthew 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);
35646ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35656ce3c06aSMatthew 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);
35666ce3c06aSMatthew G. Knepley         }
35676ce3c06aSMatthew G. Knepley #endif
35686ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
35696ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
35706ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
35716ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
35726ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
35736ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
35746ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
35756ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
35766ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
35779ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
35786ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
35796ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
35806ce3c06aSMatthew G. Knepley             } else {
35816ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
35826ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
35836ce3c06aSMatthew G. Knepley             }
35846ce3c06aSMatthew G. Knepley           } else {
3585b598a9d5SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
35866ce3c06aSMatthew G. Knepley           }
35876ce3c06aSMatthew G. Knepley         }
35886ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35896ce3c06aSMatthew G. Knepley #if 1
35906ce3c06aSMatthew 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);
35916ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
35926ce3c06aSMatthew 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);
35936ce3c06aSMatthew G. Knepley         }
35946ce3c06aSMatthew G. Knepley #endif
35956ce3c06aSMatthew G. Knepley       }
35966ce3c06aSMatthew G. Knepley     }
35976ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
35986ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
35996ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
36006ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
36016ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
36026ce3c06aSMatthew G. Knepley 
36036ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
36046ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
36056ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
36066ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
36076ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
36086ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
36096ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
36106ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
36116ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36126ce3c06aSMatthew G. Knepley #if 1
36136ce3c06aSMatthew 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);
36146ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36156ce3c06aSMatthew 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);
36166ce3c06aSMatthew G. Knepley       }
36176ce3c06aSMatthew G. Knepley #endif
36186ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
36196ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
36206ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
36216ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
36226ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36236ce3c06aSMatthew G. Knepley #if 1
36246ce3c06aSMatthew 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);
36256ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
36266ce3c06aSMatthew 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);
36276ce3c06aSMatthew G. Knepley       }
36286ce3c06aSMatthew G. Knepley #endif
36296ce3c06aSMatthew G. Knepley     }
36306ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
36316ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
36326ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
36336ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
36346ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
36356ce3c06aSMatthew G. Knepley 
36366ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
36376ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
36386ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
36396ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
36406ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
36416ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36426ce3c06aSMatthew G. Knepley #if 1
36436ce3c06aSMatthew 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);
36446ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36456ce3c06aSMatthew 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);
36466ce3c06aSMatthew G. Knepley       }
36476ce3c06aSMatthew G. Knepley #endif
36486ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36496ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
36506ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
36516ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
36526ce3c06aSMatthew 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]);
36536ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
36546ce3c06aSMatthew G. Knepley       }
36556ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36566ce3c06aSMatthew G. Knepley #if 1
36576ce3c06aSMatthew 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);
36586ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
36596ce3c06aSMatthew 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);
36606ce3c06aSMatthew G. Knepley       }
36616ce3c06aSMatthew G. Knepley #endif
36626ce3c06aSMatthew G. Knepley     }
36636ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
36646ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
36656ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
3666623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
36676ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
36686ce3c06aSMatthew G. Knepley 
36696ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
36706ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
36716ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
36726ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
36736ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
36746ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36756ce3c06aSMatthew G. Knepley #if 1
36766ce3c06aSMatthew 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);
36776ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36786ce3c06aSMatthew 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);
36796ce3c06aSMatthew G. Knepley       }
36806ce3c06aSMatthew G. Knepley #endif
36816ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
36826ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
36836ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36846ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
36856ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
3686623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
36876ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
36886ce3c06aSMatthew 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]);
3689b598a9d5SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
3690b598a9d5SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
36916ce3c06aSMatthew G. Knepley       }
36926ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36936ce3c06aSMatthew G. Knepley #if 1
36946ce3c06aSMatthew 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);
36956ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
36966ce3c06aSMatthew 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);
36976ce3c06aSMatthew G. Knepley       }
36986ce3c06aSMatthew G. Knepley #endif
36996ce3c06aSMatthew G. Knepley     }
37006ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
37016ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
37026ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
37036ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
37046ce3c06aSMatthew G. Knepley       PetscInt        size, s;
37056ce3c06aSMatthew G. Knepley 
37066ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
37076ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
37086ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
37096ce3c06aSMatthew G. Knepley         PetscInt r = 0;
37106ce3c06aSMatthew G. Knepley 
37116ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
37126ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
37136ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
37146ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
37156ce3c06aSMatthew G. Knepley       }
37166ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37176ce3c06aSMatthew G. Knepley #if 1
37186ce3c06aSMatthew 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);
37196ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
37206ce3c06aSMatthew 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);
37216ce3c06aSMatthew G. Knepley       }
37226ce3c06aSMatthew G. Knepley #endif
37236ce3c06aSMatthew G. Knepley     }
37246ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
37256ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
37266ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
37276ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
37286ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
37296ce3c06aSMatthew G. Knepley 
37306ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
37316ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
37326ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
37336ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
37346ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
37356ce3c06aSMatthew G. Knepley         PetscInt r = 0;
37366ce3c06aSMatthew G. Knepley 
37376ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
37386ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
37396ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
37406ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
37416ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
37426ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
37436ce3c06aSMatthew G. Knepley           faceSize += 2;
37446ce3c06aSMatthew G. Knepley         } else {
37456ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
37466ce3c06aSMatthew G. Knepley           ++faceSize;
37476ce3c06aSMatthew G. Knepley         }
37486ce3c06aSMatthew G. Knepley       }
37496ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
37506ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
37516ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
37526ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
37536ce3c06aSMatthew G. Knepley 
37546ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
37556ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
37566ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
37576ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
37586ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
37596ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
37606ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
37616ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
37626ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
37636ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
37646ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
37656ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
37666ce3c06aSMatthew G. Knepley         }
37676ce3c06aSMatthew G. Knepley       }
37686ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
37696ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37706ce3c06aSMatthew G. Knepley #if 1
37716ce3c06aSMatthew 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);
37726ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
37736ce3c06aSMatthew 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);
37746ce3c06aSMatthew G. Knepley       }
37756ce3c06aSMatthew G. Knepley #endif
37766ce3c06aSMatthew G. Knepley     }
37776ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
37786ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
37796ce3c06aSMatthew G. Knepley     break;
37802eabf88fSMatthew G. Knepley   case 6:
37812eabf88fSMatthew G. Knepley     /* Hex 3D */
37822eabf88fSMatthew G. Knepley     /*
37832eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
37842eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
37852eabf88fSMatthew G. Knepley      |         |         |       |         |         |
37862eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
37872eabf88fSMatthew G. Knepley      |         |         |       |         |         |
37882eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
37892eabf88fSMatthew G. Knepley      |         |         |       |         |         |
37902eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
37912eabf88fSMatthew G. Knepley      |         |         |       |         |         |
37922eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
37932eabf88fSMatthew G. Knepley      */
37942eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
37952eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
37962eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
37972eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
37982eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
37992eabf88fSMatthew G. Knepley 
38002eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
38012eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
38022eabf88fSMatthew G. Knepley       /* A hex */
3803e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
38042eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
38052eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
38062eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3807e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
38082eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
38092eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
38102eabf88fSMatthew G. Knepley       orntNew[3] = 0;
38112eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
38122eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3813e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
38142eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
38152eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
38162eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
38172eabf88fSMatthew G. Knepley #if 1
38182eabf88fSMatthew 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);
38192eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38202eabf88fSMatthew 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);
38212eabf88fSMatthew G. Knepley       }
38222eabf88fSMatthew G. Knepley #endif
38232eabf88fSMatthew G. Knepley       /* B hex */
3824e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
38252eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
38262eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
38272eabf88fSMatthew G. Knepley       orntNew[1] = 0;
38282eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
3829a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3830e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
38312eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
38322eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
38332eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3834e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
38352eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
38362eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
38372eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
38382eabf88fSMatthew G. Knepley #if 1
38392eabf88fSMatthew 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);
38402eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38412eabf88fSMatthew 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);
38422eabf88fSMatthew G. Knepley       }
38432eabf88fSMatthew G. Knepley #endif
38442eabf88fSMatthew G. Knepley       /* C hex */
3845e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
38462eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
38472eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
38482eabf88fSMatthew G. Knepley       orntNew[1] = 0;
38492eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3850a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3851e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
38522eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3853e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
38542eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
38552eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
3856a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
38572eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
38582eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
38592eabf88fSMatthew G. Knepley #if 1
38602eabf88fSMatthew 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);
38612eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38622eabf88fSMatthew 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);
38632eabf88fSMatthew G. Knepley       }
38642eabf88fSMatthew G. Knepley #endif
38652eabf88fSMatthew G. Knepley       /* D hex */
3866e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
38672eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
38682eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
38692eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3870e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
38712eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
38722eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3873a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3874e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
38752eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
38762eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
3877a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
38782eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
38792eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
38802eabf88fSMatthew G. Knepley #if 1
38812eabf88fSMatthew 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);
38822eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38832eabf88fSMatthew 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);
38842eabf88fSMatthew G. Knepley       }
38852eabf88fSMatthew G. Knepley #endif
38862eabf88fSMatthew G. Knepley       /* E hex */
38872eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
3888a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3889e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
38902eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3891e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
38922eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
38932eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
38942eabf88fSMatthew G. Knepley       orntNew[3] = 0;
38952eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3896a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
3897e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
38982eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3899b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
3900b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
39012eabf88fSMatthew G. Knepley #if 1
3902b164cbf2SMatthew 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);
39032eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39042eabf88fSMatthew 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);
39052eabf88fSMatthew G. Knepley       }
39062eabf88fSMatthew G. Knepley #endif
39072eabf88fSMatthew G. Knepley       /* F hex */
39082eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
3909a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3910e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
39112eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3912e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
39132eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
39142eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3915a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
3916e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
39172eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
39182eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3919a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
3920b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
3921b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
39222eabf88fSMatthew G. Knepley #if 1
3923b164cbf2SMatthew 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);
39242eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39252eabf88fSMatthew 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);
39262eabf88fSMatthew G. Knepley       }
39272eabf88fSMatthew G. Knepley #endif
39282eabf88fSMatthew G. Knepley       /* G hex */
39292eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
3930a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3931e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
39322eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
39332eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3934a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
3935e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
39362eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3937e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
39382eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
39392eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3940a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
3941b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
3942b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
39432eabf88fSMatthew G. Knepley #if 1
3944b164cbf2SMatthew 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);
39452eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39462eabf88fSMatthew 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);
39472eabf88fSMatthew G. Knepley       }
39482eabf88fSMatthew G. Knepley #endif
39492eabf88fSMatthew G. Knepley       /* H hex */
39502eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
3951a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3952e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
39532eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
39542eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
3955a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3956e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
39572eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
39582eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3959a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
3960e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
39612eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3962b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
3963b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
39642eabf88fSMatthew G. Knepley #if 1
3965b164cbf2SMatthew 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);
39662eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39672eabf88fSMatthew 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);
39682eabf88fSMatthew G. Knepley       }
39692eabf88fSMatthew G. Knepley #endif
39702eabf88fSMatthew G. Knepley     }
39712eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
39722eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3973785e854fSJed Brown     ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
39742eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
39752eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
3976aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
39772eabf88fSMatthew 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};
39782eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
39792eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3980aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
39812eabf88fSMatthew G. Knepley 
39822eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3983aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
3984a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
3985a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
3986a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
3987a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
3988a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
3989a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
3990a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
3991a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
39922eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3993aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
39942eabf88fSMatthew G. Knepley #if 1
39952eabf88fSMatthew 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);
39962eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
39972eabf88fSMatthew 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);
39982eabf88fSMatthew G. Knepley         }
39992eabf88fSMatthew G. Knepley #endif
40002eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
40012eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
40022eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
40032eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
40042eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
40052eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
40062eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
40072eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
40082eabf88fSMatthew G. Knepley           }
4009a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
40102eabf88fSMatthew G. Knepley         }
40112eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
40122eabf88fSMatthew G. Knepley #if 1
40132eabf88fSMatthew 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);
40142eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
40152eabf88fSMatthew 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);
40162eabf88fSMatthew G. Knepley         }
40172eabf88fSMatthew G. Knepley #endif
40182eabf88fSMatthew G. Knepley       }
40192eabf88fSMatthew G. Knepley     }
40202eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
40212eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
40222eabf88fSMatthew 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};
4023afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
4024afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
40252eabf88fSMatthew G. Knepley 
40262eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4027afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4028afb2665bSMatthew G. Knepley       /* A-D face */
4029afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
4030a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
4031a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4032a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4033afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4034a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4035a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4036a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
4037afb2665bSMatthew G. Knepley       orntNew[3] = -2;
40382eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4039afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
40402eabf88fSMatthew G. Knepley #if 1
40412eabf88fSMatthew 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);
40422eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
40432eabf88fSMatthew 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);
40442eabf88fSMatthew G. Knepley       }
40452eabf88fSMatthew G. Knepley #endif
4046afb2665bSMatthew G. Knepley       /* C-D face */
4047afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
4048a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
4049a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4050a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4051afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4052a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4053a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4054a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
4055afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4056afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4057afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4058afb2665bSMatthew G. Knepley #if 1
4059afb2665bSMatthew 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);
4060afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4061afb2665bSMatthew 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);
4062afb2665bSMatthew G. Knepley       }
4063afb2665bSMatthew G. Knepley #endif
4064afb2665bSMatthew G. Knepley       /* B-C face */
4065afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
4066afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
4067afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4068afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
4069afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4070afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4071afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4072afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4073afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4074afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4075afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4076afb2665bSMatthew G. Knepley #if 1
4077afb2665bSMatthew 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);
4078afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4079afb2665bSMatthew 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);
4080afb2665bSMatthew G. Knepley       }
4081afb2665bSMatthew G. Knepley #endif
4082afb2665bSMatthew G. Knepley       /* A-B face */
4083afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
4084afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
4085afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4086afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
4087afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4088afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4089afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4090afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4091afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4092afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4093afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4094afb2665bSMatthew G. Knepley #if 1
4095afb2665bSMatthew 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);
4096afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4097afb2665bSMatthew 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);
4098afb2665bSMatthew G. Knepley       }
4099afb2665bSMatthew G. Knepley #endif
4100afb2665bSMatthew G. Knepley       /* E-F face */
4101afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
4102a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4103afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4104a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
4105a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4106a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
4107afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4108a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4109a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4110afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4111afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4112afb2665bSMatthew G. Knepley #if 1
4113afb2665bSMatthew 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);
4114afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4115afb2665bSMatthew 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);
4116afb2665bSMatthew G. Knepley       }
4117afb2665bSMatthew G. Knepley #endif
4118afb2665bSMatthew G. Knepley       /* F-G face */
4119afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
4120a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4121afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4122a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
4123a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4124a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
4125afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4126a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4127a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4128afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4129afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4130afb2665bSMatthew G. Knepley #if 1
4131afb2665bSMatthew 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);
4132afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4133afb2665bSMatthew 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);
4134afb2665bSMatthew G. Knepley       }
4135afb2665bSMatthew G. Knepley #endif
4136afb2665bSMatthew G. Knepley       /* G-H face */
4137afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
4138afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
4139afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4140afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
4141afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4142afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4143afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4144afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4145afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4146afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4147afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4148afb2665bSMatthew G. Knepley #if 1
4149afb2665bSMatthew 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);
4150afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4151afb2665bSMatthew 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);
4152afb2665bSMatthew G. Knepley       }
4153afb2665bSMatthew G. Knepley #endif
4154afb2665bSMatthew G. Knepley       /* E-H face */
4155afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
4156a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4157afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4158a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
4159a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4160a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
4161afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4162a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4163a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4164afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4165afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4166afb2665bSMatthew G. Knepley #if 1
4167afb2665bSMatthew 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);
4168afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4169afb2665bSMatthew 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);
4170afb2665bSMatthew G. Knepley       }
4171afb2665bSMatthew G. Knepley #endif
4172afb2665bSMatthew G. Knepley       /* A-E face */
4173afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
4174a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
4175a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4176a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4177afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4178a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4179a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4180a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
4181afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4182afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4183afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4184afb2665bSMatthew G. Knepley #if 1
4185afb2665bSMatthew 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);
4186afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4187afb2665bSMatthew 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);
4188afb2665bSMatthew G. Knepley       }
4189afb2665bSMatthew G. Knepley #endif
4190afb2665bSMatthew G. Knepley       /* D-F face */
4191afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
4192afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
4193afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4194afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
4195afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4196afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4197afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4198afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4199afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4200afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4201afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4202afb2665bSMatthew G. Knepley #if 1
4203afb2665bSMatthew 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);
4204afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4205afb2665bSMatthew 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);
4206afb2665bSMatthew G. Knepley       }
4207afb2665bSMatthew G. Knepley #endif
4208afb2665bSMatthew G. Knepley       /* C-G face */
4209afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
4210a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4211afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4212a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
4213a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4214a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
4215afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4216a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4217a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4218afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4219afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4220afb2665bSMatthew G. Knepley #if 1
4221afb2665bSMatthew 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);
4222afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4223afb2665bSMatthew 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);
4224afb2665bSMatthew G. Knepley       }
4225afb2665bSMatthew G. Knepley #endif
4226afb2665bSMatthew G. Knepley       /* B-H face */
4227afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
4228a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4229a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4230a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4231a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4232a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
4233a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4234a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
4235a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4236afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4237afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4238afb2665bSMatthew G. Knepley #if 1
4239afb2665bSMatthew 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);
4240afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4241afb2665bSMatthew 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);
4242afb2665bSMatthew G. Knepley       }
4243afb2665bSMatthew G. Knepley #endif
4244afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
4245afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
42462eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
42472eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
42482eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
42492eabf88fSMatthew G. Knepley #if 1
42502eabf88fSMatthew 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);
42512eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
42522eabf88fSMatthew 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);
42532eabf88fSMatthew G. Knepley         }
42542eabf88fSMatthew G. Knepley #endif
42552eabf88fSMatthew G. Knepley       }
42562eabf88fSMatthew G. Knepley     }
42572eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
42582eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
42592eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
42602eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
42612eabf88fSMatthew G. Knepley 
42622eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
42632eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
42642eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
42652eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
42662eabf88fSMatthew G. Knepley 
42672eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
42682eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
42692eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
42702eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
42712eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
42722eabf88fSMatthew G. Knepley #if 1
42732eabf88fSMatthew 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);
42742eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
42752eabf88fSMatthew 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);
42762eabf88fSMatthew G. Knepley         }
42772eabf88fSMatthew G. Knepley #endif
42782eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
42792eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
42802eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
42812eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
42822eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
42832eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
42842eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
42852eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
42862eabf88fSMatthew G. Knepley           }
42872eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
42882eabf88fSMatthew G. Knepley         }
42892eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
42902eabf88fSMatthew G. Knepley #if 1
42912eabf88fSMatthew 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);
42922eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
42932eabf88fSMatthew 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);
42942eabf88fSMatthew G. Knepley         }
42952eabf88fSMatthew G. Knepley #endif
42962eabf88fSMatthew G. Knepley       }
42972eabf88fSMatthew G. Knepley     }
42982eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
42992eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
43006b852384SMatthew 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};
43012eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
43026b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
43032eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
43042eabf88fSMatthew G. Knepley 
43052eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
43062eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
43072eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
43082eabf88fSMatthew G. Knepley 
43092eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
43102eabf88fSMatthew G. Knepley         coneNew[1] = newv;
43112eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
43122eabf88fSMatthew G. Knepley #if 1
43132eabf88fSMatthew 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);
43142eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
43152eabf88fSMatthew 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);
43162eabf88fSMatthew G. Knepley         }
43172eabf88fSMatthew G. Knepley #endif
43182eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
43192eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
43202eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
43212eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
43222eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
43236b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
43246b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
43256b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
43262eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
4327a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
43282eabf88fSMatthew G. Knepley         }
43292eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
43302eabf88fSMatthew G. Knepley #if 1
43312eabf88fSMatthew 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);
43322eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
43332eabf88fSMatthew 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);
43342eabf88fSMatthew G. Knepley         }
43352eabf88fSMatthew G. Knepley #endif
43362eabf88fSMatthew G. Knepley       }
43372eabf88fSMatthew G. Knepley     }
43382eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
43392eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
43402eabf88fSMatthew 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};
43412eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
43422eabf88fSMatthew G. Knepley       const PetscInt *cone;
43432eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
43442eabf88fSMatthew G. Knepley 
43452eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
43462eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
43472eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
43482eabf88fSMatthew G. Knepley 
43492eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
43502eabf88fSMatthew G. Knepley         coneNew[1] = newv;
43512eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
43522eabf88fSMatthew G. Knepley #if 1
43532eabf88fSMatthew 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);
43542eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
43552eabf88fSMatthew 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);
43562eabf88fSMatthew G. Knepley         }
43572eabf88fSMatthew G. Knepley #endif
43582eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
43592eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
43602eabf88fSMatthew G. Knepley #if 1
43612eabf88fSMatthew 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);
43622eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
43632eabf88fSMatthew 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);
43642eabf88fSMatthew G. Knepley         }
43652eabf88fSMatthew G. Knepley #endif
43662eabf88fSMatthew G. Knepley       }
43672eabf88fSMatthew G. Knepley     }
43682eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
43692eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
43702eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
43712eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
43722eabf88fSMatthew G. Knepley       PetscInt        size, s;
43732eabf88fSMatthew G. Knepley 
43742eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
43752eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
43762eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
43772eabf88fSMatthew G. Knepley         PetscInt r = 0;
43782eabf88fSMatthew G. Knepley 
43792eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
43802eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
43812eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
43822eabf88fSMatthew G. Knepley       }
43832eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
43842eabf88fSMatthew G. Knepley #if 1
43852eabf88fSMatthew 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);
43862eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
43872eabf88fSMatthew 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);
43882eabf88fSMatthew G. Knepley       }
43892eabf88fSMatthew G. Knepley #endif
43902eabf88fSMatthew G. Knepley     }
43912eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
43922eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
43932eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
43942eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
43952eabf88fSMatthew G. Knepley       PetscInt        size, s;
43962eabf88fSMatthew G. Knepley 
43972eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
43982eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
43992eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
44002eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
44012eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
44022eabf88fSMatthew G. Knepley         PetscInt r;
44032eabf88fSMatthew G. Knepley 
44042eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4405a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
44062eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
44072eabf88fSMatthew G. Knepley       }
44082eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
44092eabf88fSMatthew G. Knepley #if 1
44102eabf88fSMatthew 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);
44112eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
44122eabf88fSMatthew 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);
44132eabf88fSMatthew G. Knepley       }
44142eabf88fSMatthew G. Knepley #endif
44152eabf88fSMatthew G. Knepley     }
44162eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
44172eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
44182eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
44192eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
44202eabf88fSMatthew G. Knepley       PetscInt        size, s;
44212eabf88fSMatthew G. Knepley 
44222eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
44232eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
44240793999aSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 +  (f - fStart)*4 + r;
44252eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
44262eabf88fSMatthew G. Knepley         PetscInt r;
44272eabf88fSMatthew G. Knepley 
44282eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
44292eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
44302eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
44312eabf88fSMatthew G. Knepley       }
44322eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
44332eabf88fSMatthew G. Knepley #if 1
44342eabf88fSMatthew 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);
44352eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
44362eabf88fSMatthew 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);
44372eabf88fSMatthew G. Knepley       }
44382eabf88fSMatthew G. Knepley #endif
44392eabf88fSMatthew G. Knepley     }
44402eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
44412eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
44422eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
44432eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
44442eabf88fSMatthew G. Knepley 
44452eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
44462eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
44472eabf88fSMatthew G. Knepley       }
44482eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
44492eabf88fSMatthew G. Knepley     }
4450da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
44512eabf88fSMatthew G. Knepley     break;
445227fcede3SMatthew G. Knepley   case 8:
445327fcede3SMatthew G. Knepley     /* Hybrid Hex 3D */
445427fcede3SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
445527fcede3SMatthew G. Knepley     /*
445627fcede3SMatthew G. Knepley      Bottom (viewed from top)    Top
445727fcede3SMatthew G. Knepley      1---------2---------2       7---------2---------6
445827fcede3SMatthew G. Knepley      |         |         |       |         |         |
445927fcede3SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
446027fcede3SMatthew G. Knepley      |         |         |       |         |         |
446127fcede3SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
446227fcede3SMatthew G. Knepley      |         |         |       |         |         |
446327fcede3SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
446427fcede3SMatthew G. Knepley      |         |         |       |         |         |
446527fcede3SMatthew G. Knepley      0---------0---------3       4---------0---------5
446627fcede3SMatthew G. Knepley      */
446727fcede3SMatthew G. Knepley     /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
446827fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
446927fcede3SMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
447027fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
447127fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
447227fcede3SMatthew G. Knepley 
447327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
447427fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
447527fcede3SMatthew G. Knepley       /* A hex */
447627fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
447727fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
447827fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
447927fcede3SMatthew G. Knepley       orntNew[1] = 0;
448027fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
448127fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
448227fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
448327fcede3SMatthew G. Knepley       orntNew[3] = 0;
448427fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
448527fcede3SMatthew G. Knepley       orntNew[4] = 0;
448627fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
448727fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
448827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
448927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
449027fcede3SMatthew G. Knepley #if 1
449127fcede3SMatthew 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);
449227fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
449327fcede3SMatthew 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);
449427fcede3SMatthew G. Knepley       }
449527fcede3SMatthew G. Knepley #endif
449627fcede3SMatthew G. Knepley       /* B hex */
449727fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
449827fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
449927fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
450027fcede3SMatthew G. Knepley       orntNew[1] = 0;
450127fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
450227fcede3SMatthew G. Knepley       orntNew[2] = -1;
450327fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
450427fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
450527fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
450627fcede3SMatthew G. Knepley       orntNew[4] = 0;
450727fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
450827fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
450927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
451027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
451127fcede3SMatthew G. Knepley #if 1
451227fcede3SMatthew 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);
451327fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
451427fcede3SMatthew 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);
451527fcede3SMatthew G. Knepley       }
451627fcede3SMatthew G. Knepley #endif
451727fcede3SMatthew G. Knepley       /* C hex */
451827fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
451927fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
452027fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
452127fcede3SMatthew G. Knepley       orntNew[1] = 0;
452227fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
452327fcede3SMatthew G. Knepley       orntNew[2] = -1;
452427fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
452527fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
452627fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
452727fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
452827fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
452927fcede3SMatthew G. Knepley       orntNew[5] = -4;
453027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
453127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
453227fcede3SMatthew G. Knepley #if 1
453327fcede3SMatthew 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);
453427fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
453527fcede3SMatthew 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);
453627fcede3SMatthew G. Knepley       }
453727fcede3SMatthew G. Knepley #endif
453827fcede3SMatthew G. Knepley       /* D hex */
453927fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
454027fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
454127fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
454227fcede3SMatthew G. Knepley       orntNew[1] = 0;
454327fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
454427fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
454527fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
454627fcede3SMatthew G. Knepley       orntNew[3] = 0;
454727fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
454827fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
454927fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
455027fcede3SMatthew G. Knepley       orntNew[5] = -4;
455127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
455227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
455327fcede3SMatthew G. Knepley #if 1
455427fcede3SMatthew 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);
455527fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
455627fcede3SMatthew 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);
455727fcede3SMatthew G. Knepley       }
455827fcede3SMatthew G. Knepley #endif
455927fcede3SMatthew G. Knepley       /* E hex */
456027fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
456127fcede3SMatthew G. Knepley       orntNew[0] = -4;
456227fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
456327fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
456427fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
456527fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
456627fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
456727fcede3SMatthew G. Knepley       orntNew[3] = 0;
456827fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
456927fcede3SMatthew G. Knepley       orntNew[4] = -1;
457027fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
457127fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
457227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
457327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
457427fcede3SMatthew G. Knepley #if 1
457527fcede3SMatthew 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);
457627fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
457727fcede3SMatthew 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);
457827fcede3SMatthew G. Knepley       }
457927fcede3SMatthew G. Knepley #endif
458027fcede3SMatthew G. Knepley       /* F hex */
458127fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
458227fcede3SMatthew G. Knepley       orntNew[0] = -4;
458327fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
458427fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
458527fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
458627fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
458727fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
458827fcede3SMatthew G. Knepley       orntNew[3] = -1;
458927fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
459027fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
459127fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
459227fcede3SMatthew G. Knepley       orntNew[5] = 1;
459327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
459427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
459527fcede3SMatthew G. Knepley #if 1
459627fcede3SMatthew 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);
459727fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
459827fcede3SMatthew 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);
459927fcede3SMatthew G. Knepley       }
460027fcede3SMatthew G. Knepley #endif
460127fcede3SMatthew G. Knepley       /* G hex */
460227fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
460327fcede3SMatthew G. Knepley       orntNew[0] = -4;
460427fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
460527fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
460627fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
460727fcede3SMatthew G. Knepley       orntNew[2] = 0;
460827fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
460927fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
461027fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
461127fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
461227fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
461327fcede3SMatthew G. Knepley       orntNew[5] = -3;
461427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
461527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
461627fcede3SMatthew G. Knepley #if 1
461727fcede3SMatthew 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);
461827fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
461927fcede3SMatthew 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);
462027fcede3SMatthew G. Knepley       }
462127fcede3SMatthew G. Knepley #endif
462227fcede3SMatthew G. Knepley       /* H hex */
462327fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
462427fcede3SMatthew G. Knepley       orntNew[0] = -4;
462527fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
462627fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
462727fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
462827fcede3SMatthew G. Knepley       orntNew[2] = -1;
462927fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
463027fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
463127fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
463227fcede3SMatthew G. Knepley       orntNew[4] = 3;
463327fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
463427fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
463527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
463627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
463727fcede3SMatthew G. Knepley #if 1
463827fcede3SMatthew 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);
463927fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
464027fcede3SMatthew 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);
464127fcede3SMatthew G. Knepley       }
464227fcede3SMatthew G. Knepley #endif
464327fcede3SMatthew G. Knepley     }
464427fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces: Front, Back, Sides */
464527fcede3SMatthew G. Knepley     /*
464627fcede3SMatthew G. Knepley      3---------2---------2
464727fcede3SMatthew G. Knepley      |         |         |
464827fcede3SMatthew G. Knepley      |    D    2    C    |
464927fcede3SMatthew G. Knepley      |         |         |
465027fcede3SMatthew G. Knepley      3----3----0----1----1
465127fcede3SMatthew G. Knepley      |         |         |
465227fcede3SMatthew G. Knepley      |    A    0    B    |
465327fcede3SMatthew G. Knepley      |         |         |
465427fcede3SMatthew G. Knepley      0---------0---------1
465527fcede3SMatthew G. Knepley      */
465627fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
465727fcede3SMatthew G. Knepley       const PetscInt  newp = (cMax - cStart)*8 + (c - cMax)*4;
465827fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
4659d273725eSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6], o, of, i;
466027fcede3SMatthew G. Knepley 
466127fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
466227fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
466327fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
4664d273725eSMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
466527fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
466627fcede3SMatthew G. Knepley         PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
466727fcede3SMatthew G. Knepley         PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
4668d273725eSMatthew G. Knepley         PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4);
466927fcede3SMatthew 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]);
467027fcede3SMatthew G. Knepley         coneNew[0]         = fStartNew + (cone[0] - fStart)*4 + subfA;
467127fcede3SMatthew G. Knepley         orntNew[0]         = ornt[0];
467227fcede3SMatthew G. Knepley         coneNew[1]         = fStartNew + (cone[1] - fStart)*4 + subfA;
467327fcede3SMatthew G. Knepley         orntNew[1]         = ornt[0];
4674d273725eSMatthew G. Knepley         of = fornt[edgeA] < 0 ? -1 : 1;
4675d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], r) + 2;
4676d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0);
4677d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeA];
4678d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2;
4679d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeA;
4680d273725eSMatthew G. Knepley         orntNew[i] = 0;
4681d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2;
4682d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeB;
4683d273725eSMatthew G. Knepley         orntNew[i] = -2;
4684d273725eSMatthew G. Knepley         of = fornt[edgeB] < 0 ? -1 : 1;
4685d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2;
4686d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1);
4687d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeB];
468827fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
468927fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
469027fcede3SMatthew G. Knepley #if 1
469127fcede3SMatthew 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);
469227fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
469327fcede3SMatthew 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);
469427fcede3SMatthew G. Knepley         }
469527fcede3SMatthew G. Knepley         for (p = 2; p < 6; ++p) {
469627fcede3SMatthew 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);
469727fcede3SMatthew G. Knepley         }
469827fcede3SMatthew G. Knepley #endif
469927fcede3SMatthew G. Knepley       }
470027fcede3SMatthew G. Knepley     }
470127fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
470227fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
470327fcede3SMatthew G. Knepley     ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr);
470427fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
470527fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
470627fcede3SMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
470727fcede3SMatthew 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};
470827fcede3SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
470927fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
471027fcede3SMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
471127fcede3SMatthew G. Knepley 
471227fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
471327fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
471427fcede3SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
471527fcede3SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
471627fcede3SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
471727fcede3SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
471827fcede3SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
471927fcede3SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
472027fcede3SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
472127fcede3SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
472227fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
472327fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
472427fcede3SMatthew G. Knepley #if 1
472527fcede3SMatthew 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);
472627fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
472727fcede3SMatthew 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);
472827fcede3SMatthew G. Knepley         }
472927fcede3SMatthew G. Knepley #endif
473027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
473127fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
473227fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
473327fcede3SMatthew G. Knepley           PetscInt subf;
473427fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
473527fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
473627fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
473727fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
473827fcede3SMatthew G. Knepley             if (cone[c] == f) break;
473927fcede3SMatthew G. Knepley           }
474027fcede3SMatthew G. Knepley           subf = GetQuadSubfaceInverse_Static(ornt[c], r);
474127fcede3SMatthew G. Knepley           if (support[s] < cMax) {
474227fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
474327fcede3SMatthew G. Knepley           } else {
474427fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax       - cStart)*8 + (support[s] - cMax)*4 + subf;
474527fcede3SMatthew G. Knepley           }
474627fcede3SMatthew G. Knepley         }
474727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
474827fcede3SMatthew G. Knepley #if 1
474927fcede3SMatthew 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);
475027fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
475127fcede3SMatthew 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);
475227fcede3SMatthew G. Knepley         }
475327fcede3SMatthew G. Knepley #endif
475427fcede3SMatthew G. Knepley       }
475527fcede3SMatthew G. Knepley     }
4756d273725eSMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
475727fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
475827fcede3SMatthew 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};
475927fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
476027fcede3SMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
476127fcede3SMatthew G. Knepley 
476227fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
476327fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
476427fcede3SMatthew G. Knepley       /* A-D face */
476527fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
476627fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
476727fcede3SMatthew G. Knepley       orntNew[0] = 0;
476827fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
476927fcede3SMatthew G. Knepley       orntNew[1] = 0;
477027fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
477127fcede3SMatthew G. Knepley       orntNew[2] = -2;
477227fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
477327fcede3SMatthew G. Knepley       orntNew[3] = -2;
477427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
477527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
477627fcede3SMatthew G. Knepley #if 1
477727fcede3SMatthew 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);
477827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
477927fcede3SMatthew 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);
478027fcede3SMatthew G. Knepley       }
478127fcede3SMatthew G. Knepley #endif
478227fcede3SMatthew G. Knepley       /* C-D face */
478327fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
478427fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
478527fcede3SMatthew G. Knepley       orntNew[0] = 0;
478627fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
478727fcede3SMatthew G. Knepley       orntNew[1] = 0;
478827fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
478927fcede3SMatthew G. Knepley       orntNew[2] = -2;
479027fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
479127fcede3SMatthew G. Knepley       orntNew[3] = -2;
479227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
479327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
479427fcede3SMatthew G. Knepley #if 1
479527fcede3SMatthew 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);
479627fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
479727fcede3SMatthew 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);
479827fcede3SMatthew G. Knepley       }
479927fcede3SMatthew G. Knepley #endif
480027fcede3SMatthew G. Knepley       /* B-C face */
480127fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
480227fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
480327fcede3SMatthew G. Knepley       orntNew[0] = -2;
480427fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
480527fcede3SMatthew G. Knepley       orntNew[1] = 0;
480627fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
480727fcede3SMatthew G. Knepley       orntNew[2] = 0;
480827fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
480927fcede3SMatthew G. Knepley       orntNew[3] = -2;
481027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
481127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
481227fcede3SMatthew G. Knepley #if 1
481327fcede3SMatthew 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);
481427fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
481527fcede3SMatthew 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);
481627fcede3SMatthew G. Knepley       }
481727fcede3SMatthew G. Knepley #endif
481827fcede3SMatthew G. Knepley       /* A-B face */
481927fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
482027fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
482127fcede3SMatthew G. Knepley       orntNew[0] = -2;
482227fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
482327fcede3SMatthew G. Knepley       orntNew[1] = 0;
482427fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
482527fcede3SMatthew G. Knepley       orntNew[2] = 0;
482627fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
482727fcede3SMatthew G. Knepley       orntNew[3] = -2;
482827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
482927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
483027fcede3SMatthew G. Knepley #if 1
483127fcede3SMatthew 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);
483227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
483327fcede3SMatthew 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);
483427fcede3SMatthew G. Knepley       }
483527fcede3SMatthew G. Knepley #endif
483627fcede3SMatthew G. Knepley       /* E-F face */
483727fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
483827fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
483927fcede3SMatthew G. Knepley       orntNew[0] = -2;
484027fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
484127fcede3SMatthew G. Knepley       orntNew[1] = -2;
484227fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
484327fcede3SMatthew G. Knepley       orntNew[2] = 0;
484427fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
484527fcede3SMatthew G. Knepley       orntNew[3] = 0;
484627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
484727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
484827fcede3SMatthew G. Knepley #if 1
484927fcede3SMatthew 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);
485027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
485127fcede3SMatthew 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);
485227fcede3SMatthew G. Knepley       }
485327fcede3SMatthew G. Knepley #endif
485427fcede3SMatthew G. Knepley       /* F-G face */
485527fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
485627fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
485727fcede3SMatthew G. Knepley       orntNew[0] = -2;
485827fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
485927fcede3SMatthew G. Knepley       orntNew[1] = -2;
486027fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
486127fcede3SMatthew G. Knepley       orntNew[2] = 0;
486227fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
486327fcede3SMatthew G. Knepley       orntNew[3] = 0;
486427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
486527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
486627fcede3SMatthew G. Knepley #if 1
486727fcede3SMatthew 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);
486827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
486927fcede3SMatthew 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);
487027fcede3SMatthew G. Knepley       }
487127fcede3SMatthew G. Knepley #endif
487227fcede3SMatthew G. Knepley       /* G-H face */
487327fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
487427fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
487527fcede3SMatthew G. Knepley       orntNew[0] = -2;
487627fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
487727fcede3SMatthew G. Knepley       orntNew[1] = 0;
487827fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
487927fcede3SMatthew G. Knepley       orntNew[2] = 0;
488027fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
488127fcede3SMatthew G. Knepley       orntNew[3] = -2;
488227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
488327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
488427fcede3SMatthew G. Knepley #if 1
488527fcede3SMatthew 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);
488627fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
488727fcede3SMatthew 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);
488827fcede3SMatthew G. Knepley       }
488927fcede3SMatthew G. Knepley #endif
489027fcede3SMatthew G. Knepley       /* E-H face */
489127fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
489227fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
489327fcede3SMatthew G. Knepley       orntNew[0] = -2;
489427fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
489527fcede3SMatthew G. Knepley       orntNew[1] = -2;
489627fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
489727fcede3SMatthew G. Knepley       orntNew[2] = 0;
489827fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
489927fcede3SMatthew G. Knepley       orntNew[3] = 0;
490027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
490127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
490227fcede3SMatthew G. Knepley #if 1
490327fcede3SMatthew 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);
490427fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
490527fcede3SMatthew 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);
490627fcede3SMatthew G. Knepley       }
490727fcede3SMatthew G. Knepley #endif
490827fcede3SMatthew G. Knepley       /* A-E face */
490927fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
491027fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
491127fcede3SMatthew G. Knepley       orntNew[0] = 0;
491227fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
491327fcede3SMatthew G. Knepley       orntNew[1] = 0;
491427fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
491527fcede3SMatthew G. Knepley       orntNew[2] = -2;
491627fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
491727fcede3SMatthew G. Knepley       orntNew[3] = -2;
491827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
491927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
492027fcede3SMatthew G. Knepley #if 1
492127fcede3SMatthew 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);
492227fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
492327fcede3SMatthew 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);
492427fcede3SMatthew G. Knepley       }
492527fcede3SMatthew G. Knepley #endif
492627fcede3SMatthew G. Knepley       /* D-F face */
492727fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
492827fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
492927fcede3SMatthew G. Knepley       orntNew[0] = -2;
493027fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
493127fcede3SMatthew G. Knepley       orntNew[1] = 0;
493227fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
493327fcede3SMatthew G. Knepley       orntNew[2] = 0;
493427fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
493527fcede3SMatthew G. Knepley       orntNew[3] = -2;
493627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
493727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
493827fcede3SMatthew G. Knepley #if 1
493927fcede3SMatthew 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);
494027fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
494127fcede3SMatthew 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);
494227fcede3SMatthew G. Knepley       }
494327fcede3SMatthew G. Knepley #endif
494427fcede3SMatthew G. Knepley       /* C-G face */
494527fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
494627fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
494727fcede3SMatthew G. Knepley       orntNew[0] = -2;
494827fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
494927fcede3SMatthew G. Knepley       orntNew[1] = -2;
495027fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
495127fcede3SMatthew G. Knepley       orntNew[2] = 0;
495227fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
495327fcede3SMatthew G. Knepley       orntNew[3] = 0;
495427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
495527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
495627fcede3SMatthew G. Knepley #if 1
495727fcede3SMatthew 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);
495827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
495927fcede3SMatthew 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);
496027fcede3SMatthew G. Knepley       }
496127fcede3SMatthew G. Knepley #endif
496227fcede3SMatthew G. Knepley       /* B-H face */
496327fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
496427fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
496527fcede3SMatthew G. Knepley       orntNew[0] = 0;
496627fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
496727fcede3SMatthew G. Knepley       orntNew[1] = -2;
496827fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
496927fcede3SMatthew G. Knepley       orntNew[2] = -2;
497027fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
497127fcede3SMatthew G. Knepley       orntNew[3] = 0;
497227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
497327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
497427fcede3SMatthew G. Knepley #if 1
497527fcede3SMatthew 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);
497627fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
497727fcede3SMatthew 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);
497827fcede3SMatthew G. Knepley       }
497927fcede3SMatthew G. Knepley #endif
498027fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
498127fcede3SMatthew G. Knepley         newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
498227fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
498327fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
498427fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
498527fcede3SMatthew G. Knepley #if 1
498627fcede3SMatthew 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);
498727fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
498827fcede3SMatthew 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);
498927fcede3SMatthew G. Knepley         }
499027fcede3SMatthew G. Knepley #endif
499127fcede3SMatthew G. Knepley       }
499227fcede3SMatthew G. Knepley     }
499327fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
499427fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
499527fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
499627fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
499727fcede3SMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
499827fcede3SMatthew G. Knepley 
499927fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
500027fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
500127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
500227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
500327fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
500427fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
500527fcede3SMatthew G. Knepley 
500627fcede3SMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
500727fcede3SMatthew G. Knepley         orntNew[0]   = ornt[0];
500827fcede3SMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
500927fcede3SMatthew G. Knepley         orntNew[1]   = ornt[1];
501027fcede3SMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
501127fcede3SMatthew G. Knepley         orntNew[2+r] = 0;
501227fcede3SMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd      - eMax) + (f - fMax);
501327fcede3SMatthew G. Knepley         orntNew[3-r] = 0;
501427fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
501527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
501627fcede3SMatthew G. Knepley #if 1
501727fcede3SMatthew 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);
501827fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
501927fcede3SMatthew 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);
502027fcede3SMatthew G. Knepley         }
502127fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
502227fcede3SMatthew 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);
502327fcede3SMatthew G. Knepley         }
502427fcede3SMatthew G. Knepley #endif
502527fcede3SMatthew G. Knepley         for (s = 0; s < size; ++s) {
502627fcede3SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
5027d273725eSMatthew G. Knepley           PetscInt        o, of;
502827fcede3SMatthew G. Knepley 
502927fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
503027fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
5031d273725eSMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
503227fcede3SMatthew G. Knepley           for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
503327fcede3SMatthew 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]);
503427fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
5035d273725eSMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
5036d273725eSMatthew G. Knepley           supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4;
503727fcede3SMatthew G. Knepley         }
503827fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
503927fcede3SMatthew G. Knepley #if 1
504027fcede3SMatthew 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);
504127fcede3SMatthew G. Knepley         for (p = 0; p < size; ++p) {
504227fcede3SMatthew 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);
504327fcede3SMatthew G. Knepley         }
504427fcede3SMatthew G. Knepley #endif
504527fcede3SMatthew G. Knepley       }
504627fcede3SMatthew G. Knepley     }
504727fcede3SMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
504827fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
504927fcede3SMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
505027fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
505127fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
505227fcede3SMatthew G. Knepley       PetscInt        supportNew[2];
505327fcede3SMatthew G. Knepley 
505427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
505527fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
505627fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
5057d273725eSMatthew G. Knepley #if 0
505827fcede3SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
505927fcede3SMatthew G. Knepley         orntNew[0] = 0;
506027fcede3SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
506127fcede3SMatthew G. Knepley         orntNew[1] = 0;
506227fcede3SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
506327fcede3SMatthew G. Knepley         orntNew[2] = 0;
506427fcede3SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd                                   - fMax) + (c - cMax);
506527fcede3SMatthew G. Knepley         orntNew[3] = 0;
5066d273725eSMatthew G. Knepley #else
5067d273725eSMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r;
5068d273725eSMatthew G. Knepley         orntNew[0] = 0;
5069d273725eSMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r;
5070d273725eSMatthew G. Knepley         orntNew[1] = 0;
5071d273725eSMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax);
5072d273725eSMatthew G. Knepley         orntNew[2] = 0;
5073d273725eSMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd      - fMax) + (c - cMax);
5074d273725eSMatthew G. Knepley         orntNew[3] = 0;
5075d273725eSMatthew G. Knepley #endif
507627fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
507727fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
507827fcede3SMatthew G. Knepley #if 1
507927fcede3SMatthew 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);
508027fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
508127fcede3SMatthew 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);
508227fcede3SMatthew G. Knepley         }
508327fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
508427fcede3SMatthew 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);
508527fcede3SMatthew G. Knepley         }
508627fcede3SMatthew G. Knepley #endif
508727fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
508827fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
508927fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
509027fcede3SMatthew G. Knepley #if 1
509127fcede3SMatthew 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);
509227fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
509327fcede3SMatthew 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);
509427fcede3SMatthew G. Knepley         }
509527fcede3SMatthew G. Knepley #endif
509627fcede3SMatthew G. Knepley       }
509727fcede3SMatthew G. Knepley     }
509827fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
509927fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
510027fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
510127fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
510227fcede3SMatthew G. Knepley 
510327fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
510427fcede3SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
510527fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
510627fcede3SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
510727fcede3SMatthew G. Knepley 
510827fcede3SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
510927fcede3SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
511027fcede3SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
511127fcede3SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
511227fcede3SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
511327fcede3SMatthew G. Knepley #if 1
511427fcede3SMatthew 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);
511527fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
511627fcede3SMatthew 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);
511727fcede3SMatthew G. Knepley         }
511827fcede3SMatthew G. Knepley #endif
511927fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
512027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
512127fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
512227fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
512327fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
512427fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
512527fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
512627fcede3SMatthew G. Knepley             if (cone[c] == e) break;
512727fcede3SMatthew G. Knepley           }
512827fcede3SMatthew G. Knepley           if (support[s] < fMax) {
512927fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
513027fcede3SMatthew G. Knepley           } else {
513127fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
513227fcede3SMatthew G. Knepley           }
513327fcede3SMatthew G. Knepley         }
513427fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
513527fcede3SMatthew G. Knepley #if 1
513627fcede3SMatthew 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);
513727fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
513827fcede3SMatthew 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);
513927fcede3SMatthew G. Knepley         }
514027fcede3SMatthew G. Knepley #endif
514127fcede3SMatthew G. Knepley       }
514227fcede3SMatthew G. Knepley     }
514327fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
514427fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
514527fcede3SMatthew 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};
514627fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
514727fcede3SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
514827fcede3SMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
514927fcede3SMatthew G. Knepley 
515027fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
515127fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
515227fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
515327fcede3SMatthew G. Knepley 
515427fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
515527fcede3SMatthew G. Knepley         coneNew[1] = newv;
515627fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
515727fcede3SMatthew G. Knepley #if 1
515827fcede3SMatthew 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);
515927fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
516027fcede3SMatthew 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);
516127fcede3SMatthew G. Knepley         }
516227fcede3SMatthew G. Knepley #endif
516327fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
516427fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
516527fcede3SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
516627fcede3SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
516727fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
516827fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
516927fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
517027fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
517127fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
517227fcede3SMatthew G. Knepley           if (support[s] < cMax) {
517327fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
517427fcede3SMatthew G. Knepley           } else {
5175d273725eSMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r;
517627fcede3SMatthew G. Knepley           }
517727fcede3SMatthew G. Knepley         }
517827fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
517927fcede3SMatthew G. Knepley #if 1
518027fcede3SMatthew 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);
518127fcede3SMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
518227fcede3SMatthew 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);
518327fcede3SMatthew G. Knepley         }
518427fcede3SMatthew G. Knepley #endif
518527fcede3SMatthew G. Knepley       }
518627fcede3SMatthew G. Knepley     }
518727fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
518827fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
518927fcede3SMatthew 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};
519027fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
519127fcede3SMatthew G. Knepley       const PetscInt *cone;
519227fcede3SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
519327fcede3SMatthew G. Knepley 
519427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
519527fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
519627fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
519727fcede3SMatthew G. Knepley 
519827fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
519927fcede3SMatthew G. Knepley         coneNew[1] = newv;
520027fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
520127fcede3SMatthew G. Knepley #if 1
520227fcede3SMatthew 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);
520327fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
520427fcede3SMatthew 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);
520527fcede3SMatthew G. Knepley         }
520627fcede3SMatthew G. Knepley #endif
520727fcede3SMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
520827fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
520927fcede3SMatthew G. Knepley #if 1
521027fcede3SMatthew 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);
521127fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
521227fcede3SMatthew 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);
521327fcede3SMatthew G. Knepley         }
521427fcede3SMatthew G. Knepley #endif
521527fcede3SMatthew G. Knepley       }
521627fcede3SMatthew G. Knepley     }
521727fcede3SMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
521827fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
521927fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
522027fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
522127fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
522227fcede3SMatthew G. Knepley 
522327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
522427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
522527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
522627fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
522727fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
522827fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
522927fcede3SMatthew G. Knepley #if 1
523027fcede3SMatthew 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);
523127fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
523227fcede3SMatthew 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);
523327fcede3SMatthew G. Knepley       }
523427fcede3SMatthew G. Knepley #endif
523527fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
523627fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
523727fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
523827fcede3SMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
523927fcede3SMatthew 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]);
524027fcede3SMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
524127fcede3SMatthew G. Knepley       }
524227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
524327fcede3SMatthew G. Knepley #if 1
524427fcede3SMatthew 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);
524527fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
524627fcede3SMatthew 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);
524727fcede3SMatthew G. Knepley       }
524827fcede3SMatthew G. Knepley #endif
524927fcede3SMatthew G. Knepley     }
525027fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
525127fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
525227fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
525327fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
525427fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
525527fcede3SMatthew G. Knepley 
525627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
525727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
525827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
525927fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
526027fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
526127fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
526227fcede3SMatthew G. Knepley #if 1
526327fcede3SMatthew 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);
526427fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
526527fcede3SMatthew 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);
526627fcede3SMatthew G. Knepley       }
526727fcede3SMatthew G. Knepley #endif
526827fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
526927fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
527027fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
527127fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
527227fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
527327fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
527427fcede3SMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
527527fcede3SMatthew 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]);
5276d273725eSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2;
527727fcede3SMatthew G. Knepley       }
527827fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
527927fcede3SMatthew G. Knepley #if 1
528027fcede3SMatthew 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);
528127fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
528227fcede3SMatthew 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);
528327fcede3SMatthew G. Knepley       }
528427fcede3SMatthew G. Knepley #endif
528527fcede3SMatthew G. Knepley     }
528627fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
528727fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
528827fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
528927fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
529027fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size;
529127fcede3SMatthew G. Knepley 
529227fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
529327fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr);
529427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr);
529527fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
529627fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
529727fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
529827fcede3SMatthew G. Knepley #if 1
529927fcede3SMatthew 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);
530027fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
530127fcede3SMatthew 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);
530227fcede3SMatthew G. Knepley       }
530327fcede3SMatthew G. Knepley #endif
530427fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
530527fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
530627fcede3SMatthew G. Knepley       supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
530727fcede3SMatthew G. Knepley       supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
530827fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
530927fcede3SMatthew G. Knepley #if 1
531027fcede3SMatthew 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);
531127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
531227fcede3SMatthew 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);
531327fcede3SMatthew G. Knepley       }
531427fcede3SMatthew G. Knepley #endif
531527fcede3SMatthew G. Knepley     }
531627fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
531727fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
531827fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
531927fcede3SMatthew G. Knepley       const PetscInt *support, *cone;
532027fcede3SMatthew G. Knepley       PetscInt        size, s;
532127fcede3SMatthew G. Knepley 
532227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
532327fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
532427fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
532527fcede3SMatthew G. Knepley         PetscInt r = 0;
532627fcede3SMatthew G. Knepley 
532727fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
532827fcede3SMatthew G. Knepley         if (cone[1] == v) r = 1;
532927fcede3SMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
533027fcede3SMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
533127fcede3SMatthew G. Knepley       }
533227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
533327fcede3SMatthew G. Knepley #if 1
533427fcede3SMatthew 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);
533527fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
533627fcede3SMatthew 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);
533727fcede3SMatthew G. Knepley       }
533827fcede3SMatthew G. Knepley #endif
533927fcede3SMatthew G. Knepley     }
534027fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
534127fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
534227fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
534327fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
534427fcede3SMatthew G. Knepley       PetscInt        size, s;
534527fcede3SMatthew G. Knepley 
534627fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
534727fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
534827fcede3SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
534927fcede3SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
535027fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
535127fcede3SMatthew G. Knepley         PetscInt r;
535227fcede3SMatthew G. Knepley 
535327fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
535427fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
535527fcede3SMatthew G. Knepley         if (support[s] < fMax) {
535627fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
535727fcede3SMatthew G. Knepley         } else {
535827fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
535927fcede3SMatthew G. Knepley         }
536027fcede3SMatthew G. Knepley       }
536127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
536227fcede3SMatthew G. Knepley #if 1
536327fcede3SMatthew 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);
536427fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
536527fcede3SMatthew 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);
536627fcede3SMatthew G. Knepley       }
536727fcede3SMatthew G. Knepley #endif
536827fcede3SMatthew G. Knepley     }
536927fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
537027fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
537127fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
537227fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
537327fcede3SMatthew G. Knepley       PetscInt        size, s;
537427fcede3SMatthew G. Knepley 
537527fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
537627fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
537727fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 +  (f - fStart)*4 + r;
537827fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
537927fcede3SMatthew G. Knepley         PetscInt r;
538027fcede3SMatthew G. Knepley 
538127fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
538227fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
538327fcede3SMatthew G. Knepley         if (support[s] < cMax) {
538427fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
538527fcede3SMatthew G. Knepley         } else {
538627fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax       - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
538727fcede3SMatthew G. Knepley         }
538827fcede3SMatthew G. Knepley       }
538927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
539027fcede3SMatthew G. Knepley #if 1
539127fcede3SMatthew 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);
539227fcede3SMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
539327fcede3SMatthew 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);
539427fcede3SMatthew G. Knepley       }
539527fcede3SMatthew G. Knepley #endif
539627fcede3SMatthew G. Knepley     }
539727fcede3SMatthew G. Knepley     /* Cell vertices have 6 supports */
539827fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
539927fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
540027fcede3SMatthew G. Knepley       PetscInt       supportNew[6];
540127fcede3SMatthew G. Knepley 
540227fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
540327fcede3SMatthew G. Knepley         supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
540427fcede3SMatthew G. Knepley       }
540527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
540627fcede3SMatthew G. Knepley     }
540727fcede3SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
540827fcede3SMatthew G. Knepley     break;
540975d3a19aSMatthew G. Knepley   default:
541075d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
541175d3a19aSMatthew G. Knepley   }
541275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
541375d3a19aSMatthew G. Knepley }
541475d3a19aSMatthew G. Knepley 
541575d3a19aSMatthew G. Knepley #undef __FUNCT__
541675d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates"
541786150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
541875d3a19aSMatthew G. Knepley {
541975d3a19aSMatthew G. Knepley   PetscSection     coordSection, coordSectionNew;
542075d3a19aSMatthew G. Knepley   Vec              coordinates, coordinatesNew;
542175d3a19aSMatthew G. Knepley   PetscScalar     *coords, *coordsNew;
5422*0fadad52SMatthew G. Knepley   const PetscReal *maxCell, *L;
54233478d7aaSMatthew G. Knepley   const PetscInt   numVertices = depthSize ? depthSize[0] : 0;
5424f1d7821bSLawrence Mitchell   PetscInt         spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
542575d3a19aSMatthew G. Knepley   PetscErrorCode   ierr;
542675d3a19aSMatthew G. Knepley 
542775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
542875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
542975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
5430b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
543175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
543275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
543327fcede3SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr);
54343478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);}
543575d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);
5436f719d809SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
5437f1d7821bSLawrence Mitchell   ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr);
543875d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
543975d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
5440f1d7821bSLawrence Mitchell   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr);
54413478d7aaSMatthew G. Knepley   ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
544227fcede3SMatthew G. Knepley   if (cMax < 0) cMax = cEnd;
544375d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
5444b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
5445f1d7821bSLawrence Mitchell   /* All vertices have the spaceDim coordinates */
54463478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
5447f1d7821bSLawrence Mitchell     ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr);
5448f1d7821bSLawrence Mitchell     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr);
544975d3a19aSMatthew G. Knepley   }
545075d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
5451f719d809SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr);
5452*0fadad52SMatthew G. Knepley   ierr = DMGetPeriodicity(dm, &maxCell, &L);CHKERRQ(ierr);
5453*0fadad52SMatthew G. Knepley   if (L) {ierr = DMSetPeriodicity(rdm, maxCell, L);CHKERRQ(ierr);}
545475d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
545575d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
545675d3a19aSMatthew G. Knepley   ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr);
545775d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
545875d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
545960b9e8a1SMatthew G. Knepley   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
546060b9e8a1SMatthew G. Knepley   ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr);
546175d3a19aSMatthew G. Knepley   ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr);
546275d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
546375d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
5464b5da9499SMatthew G. Knepley   switch (refiner) {
54653478d7aaSMatthew G. Knepley   case 0: break;
5466b5da9499SMatthew G. Knepley   case 6: /* Hex 3D */
5467d856d60fSMatthew G. Knepley   case 8: /* Hybrid Hex 3D */
5468b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
5469d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
547027fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
5471b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
5472b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
5473b5da9499SMatthew G. Knepley 
5474b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5475b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
5476b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
5477b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
5478b5da9499SMatthew G. Knepley       }
5479b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
5480b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
5481b5da9499SMatthew G. Knepley       }
5482b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5483f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
5484f1d7821bSLawrence Mitchell       for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
5485f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
5486b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5487b5da9499SMatthew G. Knepley     }
5488b5da9499SMatthew G. Knepley   case 2: /* Hex 2D */
5489a97b51b8SMatthew G. Knepley   case 4: /* Hybrid Hex 2D */
5490b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
549127fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
5492f1d7821bSLawrence Mitchell       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (spaceDim > 2 ? (fMax - fStart) : 0);
5493b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
5494b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
5495b5da9499SMatthew G. Knepley 
5496b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5497b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
5498b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
5499b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
5500b5da9499SMatthew G. Knepley       }
5501b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
5502b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
5503b5da9499SMatthew G. Knepley       }
5504b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5505f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
5506f1d7821bSLawrence Mitchell       for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
5507f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
5508b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5509b5da9499SMatthew G. Knepley     }
5510b5da9499SMatthew G. Knepley   case 1: /* Simplicial 2D */
5511b5da9499SMatthew G. Knepley   case 3: /* Hybrid Simplicial 2D */
5512b5da9499SMatthew G. Knepley   case 5: /* Simplicial 3D */
55136ce3c06aSMatthew G. Knepley   case 7: /* Hybrid Simplicial 3D */
5514b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
5515b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
5516b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
5517b5da9499SMatthew G. Knepley       const PetscInt *cone;
5518b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
5519b5da9499SMatthew G. Knepley 
5520b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
5521b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
5522b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
5523b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
5524b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
5525b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5526f1d7821bSLawrence Mitchell       ierr = DMPlexLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr);
5527f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
5528a96104c9SMatthew G. Knepley         coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]);
5529b5da9499SMatthew G. Knepley       }
5530b5da9499SMatthew G. Knepley     }
553175d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
553275d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
553375d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
553475d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
553575d3a19aSMatthew G. Knepley 
553675d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
553775d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5538f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
553975d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
554075d3a19aSMatthew G. Knepley       }
554175d3a19aSMatthew G. Knepley     }
5542b5da9499SMatthew G. Knepley     break;
5543b5da9499SMatthew G. Knepley   default:
5544b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
554575d3a19aSMatthew G. Knepley   }
554675d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
554775d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
554875d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
554975d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
555075d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
5551a96104c9SMatthew G. Knepley   if (dm->maxCell) {
5552a96104c9SMatthew G. Knepley     const PetscReal *maxCell, *L;
5553a96104c9SMatthew G. Knepley     ierr = DMGetPeriodicity(dm,  &maxCell, &L);CHKERRQ(ierr);
5554a96104c9SMatthew G. Knepley     ierr = DMSetPeriodicity(rdm,  maxCell,  L);CHKERRQ(ierr);
5555a96104c9SMatthew G. Knepley   }
555675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
555775d3a19aSMatthew G. Knepley }
555875d3a19aSMatthew G. Knepley 
555975d3a19aSMatthew G. Knepley #undef __FUNCT__
556075d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF"
556186150812SJed Brown static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
556275d3a19aSMatthew G. Knepley {
556375d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
556475d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
556575d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
556675d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
556775d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
556875d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
556975d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
557075d3a19aSMatthew G. Knepley 
557175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
557275d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
5573785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
557475d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
557575d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
557675d3a19aSMatthew G. Knepley   }
557775d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
5578785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &ranksNew);CHKERRQ(ierr);
5579785e854fSJed Brown   ierr = PetscMalloc1(numLeaves,    &localPointsNew);CHKERRQ(ierr);
5580785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
558175d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
558275d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
558375d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
558475d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
558575d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
558675d3a19aSMatthew G. Knepley   }
558775d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
558875d3a19aSMatthew G. Knepley   ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);
558975d3a19aSMatthew G. Knepley   ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
559075d3a19aSMatthew G. Knepley   ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
559175d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
559275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
559375d3a19aSMatthew G. Knepley }
559475d3a19aSMatthew G. Knepley 
559575d3a19aSMatthew G. Knepley #undef __FUNCT__
559675d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF"
559786150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
559875d3a19aSMatthew G. Knepley {
559975d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
560075d3a19aSMatthew G. Knepley   IS                 processRanks;
560175d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
560275d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
560375d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
560475d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
560575d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
560675d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
560775d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
56087ba685a0SMatthew G. Knepley   PetscInt           depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
56097ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
561075d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
561175d3a19aSMatthew G. Knepley 
561275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
561375d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
561475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
561575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
561675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
561775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
561875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
561975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
5620add09238SMatthew G. Knepley   cMax = cMax < 0 ? cEnd : cMax;
5621add09238SMatthew G. Knepley   fMax = fMax < 0 ? fEnd : fMax;
5622add09238SMatthew G. Knepley   eMax = eMax < 0 ? eEnd : eMax;
56233478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
562475d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
562575d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
5626add09238SMatthew G. Knepley   /* Calculate size of new SF */
562775d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
562875d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
562975d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
563075d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
563175d3a19aSMatthew G. Knepley 
563275d3a19aSMatthew G. Knepley     switch (refiner) {
563375d3a19aSMatthew G. Knepley     case 1:
5634a97b51b8SMatthew G. Knepley     case 3:
5635a97b51b8SMatthew G. Knepley       /* Hybrid Simplicial 2D */
5636a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5637a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
5638a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5639a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5640a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
5641a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5642a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5643a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
5644a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5645a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5646a97b51b8SMatthew G. Knepley         /* Interior cells add new cells and interior faces */
5647a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 3;
5648a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
5649a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
5650a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5651a97b51b8SMatthew G. Knepley       }
5652a97b51b8SMatthew G. Knepley       break;
565375d3a19aSMatthew G. Knepley     case 2:
5654a97b51b8SMatthew G. Knepley     case 4:
5655a97b51b8SMatthew G. Knepley       /* Hybrid Hex 2D */
5656a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5657a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
5658a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5659a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5660a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
5661a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5662a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5663a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
5664a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5665a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5666a97b51b8SMatthew G. Knepley         /* Interior cells add new cells, interior faces, and vertex */
5667a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
5668a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
5669a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
5670a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5671a97b51b8SMatthew G. Knepley       }
5672a97b51b8SMatthew G. Knepley       break;
5673b5da9499SMatthew G. Knepley     case 5:
56746ce3c06aSMatthew G. Knepley     case 7:
56756ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
56766ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
56776ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
56786ce3c06aSMatthew G. Knepley         ++numLeavesNew;
56796ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
56806ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
56816ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
56826ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
56836ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
56846ce3c06aSMatthew G. Knepley         ++numLeavesNew;
56856ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
56866ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
56876ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
56886ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
56896ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
56906ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
56916ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
56926ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
56936ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
56946ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
56956ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
56966ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
56976ce3c06aSMatthew G. Knepley       }
56986ce3c06aSMatthew G. Knepley       break;
56992eabf88fSMatthew G. Knepley     case 6:
570027fcede3SMatthew G. Knepley     case 8:
570127fcede3SMatthew G. Knepley       /* Hybrid Hex 3D */
570227fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
570327fcede3SMatthew G. Knepley         /* Old vertices stay the same */
570427fcede3SMatthew G. Knepley         ++numLeavesNew;
570527fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
570627fcede3SMatthew G. Knepley         /* Interior edges add new edges, and vertex */
570727fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
570827fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
570927fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
571027fcede3SMatthew G. Knepley         ++numLeavesNew;
571127fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
571227fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
571327fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
571427fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
571527fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
571627fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
571727fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
571827fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
571927fcede3SMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
572027fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
572127fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
572227fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
572327fcede3SMatthew G. Knepley       }
572427fcede3SMatthew G. Knepley       break;
572575d3a19aSMatthew G. Knepley     default:
572675d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
572775d3a19aSMatthew G. Knepley     }
572875d3a19aSMatthew G. Knepley   }
572975d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
573075d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
573175d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
5732dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
5733dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
573475d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
573575d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
573675d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
573775d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
573875d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
573975d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
574075d3a19aSMatthew G. Knepley   }
574175d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
574275d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
574375d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
574475d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
574575d3a19aSMatthew G. Knepley 
574675d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
574775d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
574875d3a19aSMatthew G. Knepley 
574975d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
575075d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
575175d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
575275d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
575375d3a19aSMatthew G. Knepley 
575475d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
575575d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
575675d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
575775d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
57580252e7f5SMatthew G. Knepley     rdepthMaxOld[n*(depth+1)+depth]   = rdepthMaxOld[n*(depth+1)+depth]   < 0 ? rdepthSizeOld[n*(depth+1)+depth]  +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth];
57590252e7f5SMatthew G. Knepley     rdepthMaxOld[n*(depth+1)+depth-1] = rdepthMaxOld[n*(depth+1)+depth-1] < 0 ? rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n]: rdepthMaxOld[n*(depth+1)+depth-1];
57600252e7f5SMatthew G. Knepley     rdepthMaxOld[n*(depth+1)+1]       = rdepthMaxOld[n*(depth+1)+1]       < 0 ? rdepthSizeOld[n*(depth+1)+1]      +reStart[n]: rdepthMaxOld[n*(depth+1)+1];
576175d3a19aSMatthew G. Knepley   }
576275d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
576375d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
576475d3a19aSMatthew G. Knepley   /* Calculate new point SF */
5765785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew,    &localPointsNew);CHKERRQ(ierr);
5766785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
576775d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
576875d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
576975d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
577075d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
577175d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
577275d3a19aSMatthew G. Knepley 
577375d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
577475d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
577575d3a19aSMatthew G. Knepley     switch (refiner) {
577675d3a19aSMatthew G. Knepley     case 1:
577775d3a19aSMatthew G. Knepley     case 3:
577875d3a19aSMatthew G. Knepley       /* Hybrid simplicial 2D */
577975d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
578075d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
578175d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
578275d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
578375d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
578475d3a19aSMatthew G. Knepley         ++m;
578575d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
578675d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
578775d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
578875d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
578975d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
579075d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
579175d3a19aSMatthew G. Knepley         }
5792add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
5793add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
5794add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5795add09238SMatthew G. Knepley         ++m;
579675d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
579775d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
579875d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
579975d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
580075d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
580175d3a19aSMatthew G. Knepley         ++m;
580275d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
580375d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
580475d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
580575d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
580675d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
580775d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
580875d3a19aSMatthew G. Knepley         }
580975d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
581075d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
581175d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
581275d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
581375d3a19aSMatthew G. Knepley         }
5814add09238SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
581575d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
581675d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
581775d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
581875d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
581975d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
582075d3a19aSMatthew G. Knepley         }
582175d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
582275d3a19aSMatthew 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]);
582375d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
582475d3a19aSMatthew G. Knepley         ++m;
582575d3a19aSMatthew G. Knepley       }
582675d3a19aSMatthew G. Knepley       break;
5827add09238SMatthew G. Knepley     case 2:
5828a97b51b8SMatthew G. Knepley     case 4:
5829a97b51b8SMatthew G. Knepley       /* Hybrid Hex 2D */
5830a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5831a97b51b8SMatthew G. Knepley         /* Old vertices stay the same */
5832a97b51b8SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
5833a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5834a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5835a97b51b8SMatthew G. Knepley         ++m;
5836a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5837a97b51b8SMatthew G. Knepley         /* Old interior faces add new faces and vertex */
5838a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5839a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
5840a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
5841a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5842a97b51b8SMatthew G. Knepley         }
5843add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
5844add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
5845add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5846add09238SMatthew G. Knepley         ++m;
5847a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5848a97b51b8SMatthew G. Knepley         /* Old hybrid faces stay the same */
5849a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
5850a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
5851a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5852a97b51b8SMatthew G. Knepley         ++m;
5853a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5854a97b51b8SMatthew G. Knepley         /* Old interior cells add new cells, interior faces, and vertex */
5855a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5856a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
5857a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5858a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5859a97b51b8SMatthew G. Knepley         }
5860a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5861a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*4     + r;
5862a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r;
5863a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5864a97b51b8SMatthew G. Knepley         }
5865add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)               + (fMax                              - fStart)     + (p  - cStart);
5866add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0]  + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]);
5867add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5868add09238SMatthew G. Knepley         ++m;
5869a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5870a97b51b8SMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
5871a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5872a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
5873a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5874a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5875a97b51b8SMatthew G. Knepley         }
5876a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*4     + (p  - cMax);
5877a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth]);
5878a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5879a97b51b8SMatthew G. Knepley         ++m;
5880a97b51b8SMatthew G. Knepley       }
5881a97b51b8SMatthew G. Knepley       break;
5882b5da9499SMatthew G. Knepley     case 5:
58836ce3c06aSMatthew G. Knepley     case 7:
58846ce3c06aSMatthew G. Knepley       /* Hybrid Simplicial 3D */
58856ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
58866ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
58876ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
58886ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
58896ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
58906ce3c06aSMatthew G. Knepley         ++m;
58916ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
58926ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
58936ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
58946ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
58956ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
58966ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
58976ce3c06aSMatthew G. Knepley         }
58986ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
58996ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
59006ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
59016ce3c06aSMatthew G. Knepley         ++m;
59026ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
59036ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
59046ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
59057d5cd7d5SMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rp - rdepthMaxOld[n*(depth+1)+1]);
59066ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
59076ce3c06aSMatthew G. Knepley         ++m;
59086ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
59096ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
59106ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
59116ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
59126ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
59136ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59146ce3c06aSMatthew G. Knepley         }
59156ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
59166ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
59176ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
59186ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59196ce3c06aSMatthew G. Knepley         }
59206ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
59216ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
59226ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5923899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
5924899f98d0SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r;
59256ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59266ce3c06aSMatthew G. Knepley         }
59277d5cd7d5SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (eEnd                                    - eMax)                        + (p  - fMax);
59287d5cd7d5SMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
59296ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
593009b1338fSMatthew G. Knepley         ++m;
59316ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
59326ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
59336ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
59346ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
59356ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
59366ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59376ce3c06aSMatthew G. Knepley         }
59386ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
59396ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
59406ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
59416ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59426ce3c06aSMatthew G. Knepley         }
59436ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + r;
59446ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rp - rcStart[n])*1 + r;
59456ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
594609b1338fSMatthew G. Knepley         ++m;
59476ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
59486ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
59496ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
59506ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
59516ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
59526ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59536ce3c06aSMatthew G. Knepley         }
59546ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
5955899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*3                            + r;
5956899f98d0SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r;
59576ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59586ce3c06aSMatthew G. Knepley         }
59596ce3c06aSMatthew G. Knepley       }
59606ce3c06aSMatthew G. Knepley       break;
59612eabf88fSMatthew G. Knepley     case 6:
596227fcede3SMatthew G. Knepley     case 8:
596327fcede3SMatthew G. Knepley       /* Hybrid Hex 3D */
596427fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
596527fcede3SMatthew G. Knepley         /* Interior vertices stay the same */
596627fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
596727fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
596827fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
596927fcede3SMatthew G. Knepley         ++m;
597027fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
597127fcede3SMatthew G. Knepley         /* Interior edges add new edges and vertex */
597227fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
597327fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
597427fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
597527fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
597627fcede3SMatthew G. Knepley         }
597727fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
597827fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
597927fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
598027fcede3SMatthew G. Knepley         ++m;
598127fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
598227fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
598327fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (p  - eMax);
5984d2701f60SMatthew 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 + (rp - rdepthMaxOld[n*(depth+1)+1]);
598527fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
598627fcede3SMatthew G. Knepley         ++m;
598727fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
598827fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
598927fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
599027fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
599127fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
599227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
599327fcede3SMatthew G. Knepley         }
599427fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
599527fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*4     + r;
599627fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
599727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
599827fcede3SMatthew G. Knepley         }
599927fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eMax                        - eStart)     + (p  - fStart);
600027fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
600127fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
600227fcede3SMatthew G. Knepley         ++m;
600327fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
600427fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
600527fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
6006d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (p  - fMax)*2                              + r;
6007d2701f60SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*12 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r;
600827fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
600927fcede3SMatthew G. Knepley         }
6010d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (p  - fMax);
6011d2701f60SMatthew 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)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
601227fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
601327fcede3SMatthew G. Knepley         ++m;
601427fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
601527fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
601627fcede3SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
601727fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
601827fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
601927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
602027fcede3SMatthew G. Knepley         }
602127fcede3SMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
602227fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*12     + r;
602327fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
602427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
602527fcede3SMatthew G. Knepley         }
602627fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
602727fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (p  - cStart)*6     + r;
602827fcede3SMatthew 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;
602927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
603027fcede3SMatthew G. Knepley         }
603127fcede3SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
603227fcede3SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eMax                        - eStart)     + (fMax                              - fStart)     + (p  - cStart)     + r;
603327fcede3SMatthew 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;
603427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
603527fcede3SMatthew G. Knepley         }
603627fcede3SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
603727fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
603827fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
603927fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
604027fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
604127fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
604227fcede3SMatthew G. Knepley         }
604327fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
6044d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (fEnd                                          - fMax)*2                              + (p  - cMax)*4                            + r;
6045d2701f60SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*12 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
604627fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
604727fcede3SMatthew G. Knepley         }
6048d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (fEnd                                          - fMax)                              + (p  - cMax);
6049d2701f60SMatthew 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)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]);
605027fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
605127fcede3SMatthew G. Knepley         ++m;
605227fcede3SMatthew G. Knepley       }
605327fcede3SMatthew G. Knepley       break;
605475d3a19aSMatthew G. Knepley     default:
605575d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
605675d3a19aSMatthew G. Knepley     }
605775d3a19aSMatthew G. Knepley   }
605809b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
605975d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
606075d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
6061ba3c3d50SMatthew G. Knepley   {
6062ba3c3d50SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
6063ba3c3d50SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
6064ba3c3d50SMatthew G. Knepley 
6065ba3c3d50SMatthew G. Knepley     /* SF needs sorted leaves to correct calculate Gather */
6066ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr);
6067ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr);
6068ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr);
6069ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) idx[i] = i;
6070ba3c3d50SMatthew G. Knepley     ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr);
6071ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
6072ba3c3d50SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
6073ba3c3d50SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
6074ba3c3d50SMatthew G. Knepley     }
6075ba3c3d50SMatthew G. Knepley     ltmp            = localPointsNew;
6076ba3c3d50SMatthew G. Knepley     localPointsNew  = lp;
6077ba3c3d50SMatthew G. Knepley     rtmp            = remotePointsNew;
6078ba3c3d50SMatthew G. Knepley     remotePointsNew = rp;
6079ba3c3d50SMatthew G. Knepley     ierr = PetscFree(idx);CHKERRQ(ierr);
6080ba3c3d50SMatthew G. Knepley     ierr = PetscFree(ltmp);CHKERRQ(ierr);
6081ba3c3d50SMatthew G. Knepley     ierr = PetscFree(rtmp);CHKERRQ(ierr);
6082ba3c3d50SMatthew G. Knepley   }
608375d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
608475d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
608506a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
608675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
608775d3a19aSMatthew G. Knepley }
608875d3a19aSMatthew G. Knepley 
608975d3a19aSMatthew G. Knepley #undef __FUNCT__
609075d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels"
609186150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
609275d3a19aSMatthew G. Knepley {
609375d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
60947ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
60957ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
609675d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
609775d3a19aSMatthew G. Knepley 
609875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
609975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
610075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
610175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
610275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
6103d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
61043478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
610575d3a19aSMatthew G. Knepley   ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
610675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
610775d3a19aSMatthew G. Knepley   switch (refiner) {
61083478d7aaSMatthew G. Knepley   case 0: break;
610958b8852aSMatthew G. Knepley   case 7:
611058b8852aSMatthew G. Knepley   case 8:
611158b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
611275d3a19aSMatthew G. Knepley   case 3:
611358b8852aSMatthew G. Knepley   case 4:
611475d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
611575d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
611675d3a19aSMatthew G. Knepley   }
611775d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
611875d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
611975d3a19aSMatthew G. Knepley     const char     *lname;
612075d3a19aSMatthew G. Knepley     PetscBool       isDepth;
612175d3a19aSMatthew G. Knepley     IS              valueIS;
612275d3a19aSMatthew G. Knepley     const PetscInt *values;
612375d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
612475d3a19aSMatthew G. Knepley 
612575d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr);
612675d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
612775d3a19aSMatthew G. Knepley     if (isDepth) continue;
612875d3a19aSMatthew G. Knepley     ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr);
612975d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr);
613075d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
613175d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
613275d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
613375d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
613475d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
613575d3a19aSMatthew G. Knepley       IS              pointIS;
613675d3a19aSMatthew G. Knepley       const PetscInt *points;
613775d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
613875d3a19aSMatthew G. Knepley 
613975d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
614075d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
614175d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
614275d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
614375d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
614475d3a19aSMatthew G. Knepley         switch (refiner) {
614575d3a19aSMatthew G. Knepley         case 1:
614675d3a19aSMatthew G. Knepley           /* Simplicial 2D */
614775d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
614875d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
614975d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
615075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
615175d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
615275d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
615375d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
615475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
615575d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
615675d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
615775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
615875d3a19aSMatthew G. Knepley             }
615975d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
616075d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
616175d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
616275d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
616375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
616475d3a19aSMatthew G. Knepley             }
616575d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
616675d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
616775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
616875d3a19aSMatthew G. Knepley             }
616975d3a19aSMatthew G. Knepley           }
617075d3a19aSMatthew G. Knepley           break;
617175d3a19aSMatthew G. Knepley         case 2:
617275d3a19aSMatthew G. Knepley           /* Hex 2D */
617375d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
617475d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
617575d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
617675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
617775d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
617875d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
617975d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
618075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
618175d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
618275d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
618375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
618475d3a19aSMatthew G. Knepley             }
618575d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
618675d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
618775d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
618875d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
618975d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
619075d3a19aSMatthew G. Knepley             }
619175d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
619275d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
619375d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
619475d3a19aSMatthew G. Knepley             }
619575d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
619675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
619775d3a19aSMatthew G. Knepley           }
619875d3a19aSMatthew G. Knepley           break;
619975d3a19aSMatthew G. Knepley         case 3:
620075d3a19aSMatthew G. Knepley           /* Hybrid simplicial 2D */
620175d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
620275d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
620375d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
620475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
620575d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
620675d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
620775d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
620875d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
620975d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
621075d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
621175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
621275d3a19aSMatthew G. Knepley             }
621375d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
621475d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
621575d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
621675d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
621775d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
621875d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
621975d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
622075d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
622175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
622275d3a19aSMatthew G. Knepley             }
622375d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
622475d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
622575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
622675d3a19aSMatthew G. Knepley             }
622775d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
622875d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
622975d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
623075d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
623175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
623275d3a19aSMatthew G. Knepley             }
623375d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
623475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
623575d3a19aSMatthew G. Knepley           }
623675d3a19aSMatthew G. Knepley           break;
6237a97b51b8SMatthew G. Knepley         case 4:
6238a97b51b8SMatthew G. Knepley           /* Hybrid Hex 2D */
6239a97b51b8SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
6240a97b51b8SMatthew G. Knepley             /* Old vertices stay the same */
6241a97b51b8SMatthew G. Knepley             newp = vStartNew + (p - vStart);
6242a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6243a97b51b8SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
6244a97b51b8SMatthew G. Knepley             /* Old interior faces add new faces and vertex */
6245a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
6246a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6247a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6248a97b51b8SMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
6249a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6250a97b51b8SMatthew G. Knepley             }
6251a97b51b8SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
6252a97b51b8SMatthew G. Knepley             /* Old hybrid faces stay the same */
6253a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
6254a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6255a97b51b8SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
6256a97b51b8SMatthew G. Knepley             /* Old interior cells add new cells, interior faces, and vertex */
6257a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6258a97b51b8SMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
6259a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6260a97b51b8SMatthew G. Knepley             }
6261a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6262a97b51b8SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
6263a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6264a97b51b8SMatthew G. Knepley             }
6265a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
6266a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6267a97b51b8SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
6268a97b51b8SMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
6269a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6270a97b51b8SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
6271a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6272a97b51b8SMatthew G. Knepley             }
6273a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
6274a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6275a97b51b8SMatthew G. Knepley           }
6276a97b51b8SMatthew G. Knepley           break;
6277b5da9499SMatthew G. Knepley         case 5:
6278b5da9499SMatthew G. Knepley           /* Simplicial 3D */
6279b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
6280b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
6281b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
6282b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6283b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
6284b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
6285b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6286b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
6287b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6288b5da9499SMatthew G. Knepley             }
6289b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
6290b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6291b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
6292b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
6293b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6294b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
6295b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6296b5da9499SMatthew G. Knepley             }
6297b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
6298b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
6299b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6300b5da9499SMatthew G. Knepley             }
6301b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
6302b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
6303b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
6304b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
6305b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6306b5da9499SMatthew G. Knepley             }
6307b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
6308b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
6309b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6310b5da9499SMatthew G. Knepley             }
6311b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
6312b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
6313b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6314b5da9499SMatthew G. Knepley             }
6315b5da9499SMatthew G. Knepley           }
6316b5da9499SMatthew G. Knepley           break;
63176ce3c06aSMatthew G. Knepley         case 7:
63186ce3c06aSMatthew G. Knepley           /* Hybrid Simplicial 3D */
63196ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
63206ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
63216ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
63226ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63236ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
63246ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
63256ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
63266ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
63276ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63286ce3c06aSMatthew G. Knepley             }
63296ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
63306ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63316ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
63326ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
63336ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
63346ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63356ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
63366ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
63376ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
63386ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
63396ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63406ce3c06aSMatthew G. Knepley             }
63416ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
63426ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
63436ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63446ce3c06aSMatthew G. Knepley             }
63456ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
63466ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
63476ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
63486ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
63496ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63506ce3c06aSMatthew G. Knepley             }
63516ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
63526ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63536ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
63546ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
63556ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
63566ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
63576ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63586ce3c06aSMatthew G. Knepley             }
63596ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
63606ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
63616ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63626ce3c06aSMatthew G. Knepley             }
63636ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
63646ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
636558b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
63666ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
63676ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
63686ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
63696ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63706ce3c06aSMatthew G. Knepley             }
63716ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
63726ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
63736ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63746ce3c06aSMatthew G. Knepley             }
63756ce3c06aSMatthew G. Knepley           }
63766ce3c06aSMatthew G. Knepley           break;
63772eabf88fSMatthew G. Knepley         case 6:
63782eabf88fSMatthew G. Knepley           /* Hex 3D */
63792eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
63802eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
63812eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
63822eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
638319d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
63842eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
63852eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
63862eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
63872eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63882eabf88fSMatthew G. Knepley             }
63892eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
63902eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63912eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
63922eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
63932eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
63942eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
63952eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63962eabf88fSMatthew G. Knepley             }
63972eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
63982eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
63992eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64002eabf88fSMatthew G. Knepley             }
64012eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
64022eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64032eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
64042eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
64052eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
64062eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
64072eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64082eabf88fSMatthew G. Knepley             }
64092eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
64102eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
64112eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64122eabf88fSMatthew G. Knepley             }
64132eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
64142eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
64152eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64162eabf88fSMatthew G. Knepley             }
64172eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
64182eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64192eabf88fSMatthew G. Knepley           }
64202eabf88fSMatthew G. Knepley           break;
642127fcede3SMatthew G. Knepley         case 8:
642227fcede3SMatthew G. Knepley           /* Hybrid Hex 3D */
642327fcede3SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
642427fcede3SMatthew G. Knepley             /* Interior vertices stay the same */
642527fcede3SMatthew G. Knepley             newp = vStartNew + (p - vStart);
642627fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
642727fcede3SMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
642827fcede3SMatthew G. Knepley             /* Interior edges add new edges and vertex */
642927fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
643027fcede3SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
643127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
643227fcede3SMatthew G. Knepley             }
643327fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
643427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
643527fcede3SMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
643627fcede3SMatthew G. Knepley             /* Hybrid edges stay the same */
643727fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
643827fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
643927fcede3SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
644027fcede3SMatthew G. Knepley             /* Interior faces add new faces, edges, and vertex */
644127fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
644227fcede3SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
644327fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
644427fcede3SMatthew G. Knepley             }
644527fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
644627fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
644727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
644827fcede3SMatthew G. Knepley             }
644927fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
645027fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
645127fcede3SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
645227fcede3SMatthew G. Knepley             /* Hybrid faces add new faces and edges */
645327fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
645427fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
645527fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
645627fcede3SMatthew G. Knepley             }
645727fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
645827fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
645927fcede3SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
646027fcede3SMatthew G. Knepley             /* Interior cells add new cells, faces, edges, and vertex */
646127fcede3SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
646227fcede3SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
646327fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
646427fcede3SMatthew G. Knepley             }
646527fcede3SMatthew G. Knepley             for (r = 0; r < 12; ++r) {
646627fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
646727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
646827fcede3SMatthew G. Knepley             }
646927fcede3SMatthew G. Knepley             for (r = 0; r < 6; ++r) {
647027fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
647127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
647227fcede3SMatthew G. Knepley             }
647327fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
647427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
647527fcede3SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
647627fcede3SMatthew G. Knepley             /* Hybrid cells add new cells, faces, and edges */
647727fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
647827fcede3SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
647927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
648027fcede3SMatthew G. Knepley             }
648127fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
648227fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
648327fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
648427fcede3SMatthew G. Knepley             }
648527fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
648627fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
648727fcede3SMatthew G. Knepley           }
648827fcede3SMatthew G. Knepley           break;
648975d3a19aSMatthew G. Knepley         default:
649075d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
649175d3a19aSMatthew G. Knepley         }
649275d3a19aSMatthew G. Knepley       }
649375d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
649475d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
649575d3a19aSMatthew G. Knepley     }
649675d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
649775d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
649875d3a19aSMatthew G. Knepley     if (0) {
649975d3a19aSMatthew G. Knepley       ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr);
650075d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
650175d3a19aSMatthew G. Knepley       ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
650275d3a19aSMatthew G. Knepley     }
650375d3a19aSMatthew G. Knepley   }
650475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
650575d3a19aSMatthew G. Knepley }
650675d3a19aSMatthew G. Knepley 
650775d3a19aSMatthew G. Knepley #undef __FUNCT__
6508509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexRefineUniform_Internal"
650975d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
6510509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
651175d3a19aSMatthew G. Knepley {
651275d3a19aSMatthew G. Knepley   DM             rdm;
651375d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
651475d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
651575d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
651675d3a19aSMatthew G. Knepley 
651775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
651875d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
651975d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
652075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
652175d3a19aSMatthew G. Knepley   ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr);
652275d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
652375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
6524785e854fSJed Brown   ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr);
652575d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
652675d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
652775d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
652875d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
652975d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
653075d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
653175d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
653275d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
653375d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
653475d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
653575d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
653675d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
653775d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
6538*0fadad52SMatthew G. Knepley   /* Step 6: Create pointSF */
653975d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
6540*0fadad52SMatthew G. Knepley   /* Step 7: Set coordinates for vertices */
6541*0fadad52SMatthew G. Knepley   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
654275d3a19aSMatthew G. Knepley   /* Step 8: Create labels */
654375d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
654475d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
654575d3a19aSMatthew G. Knepley 
654675d3a19aSMatthew G. Knepley   *dmRefined = rdm;
654775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
654875d3a19aSMatthew G. Knepley }
654975d3a19aSMatthew G. Knepley 
655075d3a19aSMatthew G. Knepley #undef __FUNCT__
65512389894bSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateCoarsePointIS"
65522389894bSMatthew G. Knepley /*@
65532389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
65542389894bSMatthew G. Knepley 
65552389894bSMatthew G. Knepley   Input Parameter:
65562389894bSMatthew G. Knepley . dm - The coarse DM
65572389894bSMatthew G. Knepley 
65582389894bSMatthew G. Knepley   Output Parameter:
65592389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
65602389894bSMatthew G. Knepley 
65612389894bSMatthew G. Knepley   Level: developer
65622389894bSMatthew G. Knepley 
65632389894bSMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS()
65642389894bSMatthew G. Knepley @*/
65652389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
65662389894bSMatthew G. Knepley {
65672389894bSMatthew G. Knepley   CellRefiner    cellRefiner;
65682389894bSMatthew G. Knepley   PetscInt      *depthSize, *fpoints;
65692389894bSMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
65702389894bSMatthew G. Knepley   PetscInt       depth, pStart, pEnd, p, vStart, vEnd, v;
65712389894bSMatthew G. Knepley   PetscErrorCode ierr;
65722389894bSMatthew G. Knepley 
65732389894bSMatthew G. Knepley   PetscFunctionBegin;
65742389894bSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
65752389894bSMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
65762389894bSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
65772389894bSMatthew G. Knepley   ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr);
65782389894bSMatthew G. Knepley   ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr);
65792389894bSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
65802389894bSMatthew G. Knepley   if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
65812389894bSMatthew G. Knepley   ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr);
65822389894bSMatthew G. Knepley   for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
65832389894bSMatthew G. Knepley   switch (cellRefiner) {
65842389894bSMatthew G. Knepley   case 1: /* Simplicial 2D */
65852389894bSMatthew G. Knepley   case 3: /* Hybrid simplicial 2D */
65862389894bSMatthew G. Knepley   case 2: /* Hex 2D */
65872389894bSMatthew G. Knepley   case 4: /* Hybrid Hex 2D */
65882389894bSMatthew G. Knepley   case 5: /* Simplicial 3D */
65892389894bSMatthew G. Knepley   case 7: /* Hybrid Simplicial 3D */
65902389894bSMatthew G. Knepley   case 6: /* Hex 3D */
65912389894bSMatthew G. Knepley   case 8: /* Hybrid Hex 3D */
65922389894bSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart);
65932389894bSMatthew G. Knepley     break;
65942389894bSMatthew G. Knepley   default:
65952389894bSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner);
65962389894bSMatthew G. Knepley   }
65972389894bSMatthew G. Knepley   ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr);
65982389894bSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
65992389894bSMatthew G. Knepley   PetscFunctionReturn(0);
66002389894bSMatthew G. Knepley }
66012389894bSMatthew G. Knepley 
66022389894bSMatthew G. Knepley #undef __FUNCT__
660375d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform"
66040e2b6761SMatthew G. Knepley /*@
66050e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
66060e2b6761SMatthew G. Knepley 
66070e2b6761SMatthew G. Knepley   Input Parameters:
66080e2b6761SMatthew G. Knepley + dm - The DM
66090e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
66100e2b6761SMatthew G. Knepley 
66110e2b6761SMatthew G. Knepley   Level: developer
66120e2b6761SMatthew G. Knepley 
66130e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
66140e2b6761SMatthew G. Knepley @*/
661575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
661675d3a19aSMatthew G. Knepley {
661775d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
661875d3a19aSMatthew G. Knepley 
661975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
662075d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
662175d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
662275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
662375d3a19aSMatthew G. Knepley }
662475d3a19aSMatthew G. Knepley 
662575d3a19aSMatthew G. Knepley #undef __FUNCT__
662675d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform"
66270e2b6761SMatthew G. Knepley /*@
66280e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
66290e2b6761SMatthew G. Knepley 
66300e2b6761SMatthew G. Knepley   Input Parameter:
66310e2b6761SMatthew G. Knepley . dm - The DM
66320e2b6761SMatthew G. Knepley 
66330e2b6761SMatthew G. Knepley   Output Parameter:
66340e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
66350e2b6761SMatthew G. Knepley 
66360e2b6761SMatthew G. Knepley   Level: developer
66370e2b6761SMatthew G. Knepley 
66380e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
66390e2b6761SMatthew G. Knepley @*/
664075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
664175d3a19aSMatthew G. Knepley {
664275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
664375d3a19aSMatthew G. Knepley 
664475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
664575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
664675d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
664775d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
664875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
664975d3a19aSMatthew G. Knepley }
665075d3a19aSMatthew G. Knepley 
665175d3a19aSMatthew G. Knepley #undef __FUNCT__
665275d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit"
66530e2b6761SMatthew G. Knepley /*@
66540e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
66550e2b6761SMatthew G. Knepley 
66560e2b6761SMatthew G. Knepley   Input Parameters:
66570e2b6761SMatthew G. Knepley + dm - The DM
66580e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
66590e2b6761SMatthew G. Knepley 
66600e2b6761SMatthew G. Knepley   Level: developer
66610e2b6761SMatthew G. Knepley 
66620e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
66630e2b6761SMatthew G. Knepley @*/
666475d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
666575d3a19aSMatthew G. Knepley {
666675d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
666775d3a19aSMatthew G. Knepley 
666875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
666975d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
667075d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
667175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
667275d3a19aSMatthew G. Knepley }
667375d3a19aSMatthew G. Knepley 
667475d3a19aSMatthew G. Knepley #undef __FUNCT__
667575d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit"
66760e2b6761SMatthew G. Knepley /*@
66770e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
66780e2b6761SMatthew G. Knepley 
66790e2b6761SMatthew G. Knepley   Input Parameter:
66800e2b6761SMatthew G. Knepley . dm - The DM
66810e2b6761SMatthew G. Knepley 
66820e2b6761SMatthew G. Knepley   Output Parameter:
66830e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
66840e2b6761SMatthew G. Knepley 
66850e2b6761SMatthew G. Knepley   Level: developer
66860e2b6761SMatthew G. Knepley 
66870e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
66880e2b6761SMatthew G. Knepley @*/
668975d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
669075d3a19aSMatthew G. Knepley {
669175d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
669275d3a19aSMatthew G. Knepley 
669375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
669475d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
669575d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
669675d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
669775d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
669875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
669975d3a19aSMatthew G. Knepley }
670075d3a19aSMatthew G. Knepley 
670175d3a19aSMatthew G. Knepley #undef __FUNCT__
6702509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Internal"
6703509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
670475d3a19aSMatthew G. Knepley {
67053478d7aaSMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax;
670675d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
670775d3a19aSMatthew G. Knepley 
670875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
670975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr);
67103478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
67113478d7aaSMatthew G. Knepley   if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);}
671275d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
671375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr);
671475d3a19aSMatthew G. Knepley   switch (dim) {
671575d3a19aSMatthew G. Knepley   case 2:
671675d3a19aSMatthew G. Knepley     switch (coneSize) {
671775d3a19aSMatthew G. Knepley     case 3:
671875d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 3; /* Hybrid */
671975d3a19aSMatthew G. Knepley       else *cellRefiner = 1; /* Triangular */
672075d3a19aSMatthew G. Knepley       break;
672175d3a19aSMatthew G. Knepley     case 4:
672275d3a19aSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 4; /* Hybrid */
672375d3a19aSMatthew G. Knepley       else *cellRefiner = 2; /* Quadrilateral */
672475d3a19aSMatthew G. Knepley       break;
672575d3a19aSMatthew G. Knepley     default:
672675d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
672775d3a19aSMatthew G. Knepley     }
672875d3a19aSMatthew G. Knepley     break;
6729b5da9499SMatthew G. Knepley   case 3:
6730b5da9499SMatthew G. Knepley     switch (coneSize) {
6731b5da9499SMatthew G. Knepley     case 4:
6732b5da9499SMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 7; /* Hybrid */
6733b5da9499SMatthew G. Knepley       else *cellRefiner = 5; /* Tetrahedral */
6734b5da9499SMatthew G. Knepley       break;
67352eabf88fSMatthew G. Knepley     case 6:
67362eabf88fSMatthew G. Knepley       if (cMax >= 0) *cellRefiner = 8; /* Hybrid */
67372eabf88fSMatthew G. Knepley       else *cellRefiner = 6; /* hexahedral */
67382eabf88fSMatthew G. Knepley       break;
6739b5da9499SMatthew G. Knepley     default:
6740b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
6741b5da9499SMatthew G. Knepley     }
6742b5da9499SMatthew G. Knepley     break;
674375d3a19aSMatthew G. Knepley   default:
674475d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
674575d3a19aSMatthew G. Knepley   }
674675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
674775d3a19aSMatthew G. Knepley }
6748