xref: /petsc/src/dm/impls/plex/plexrefine.c (revision 9b1a0e7fa86b58a80439339ed5044a0dbe86012a)
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;
1015fa1f8eSMatthew G. Knepley   if (vStart) *vStart = depth < 0 ? 0 : depthSize[depth];
1115fa1f8eSMatthew G. Knepley   if (fStart) *fStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0];
1215fa1f8eSMatthew G. Knepley   if (eStart) *eStart = depth < 0 ? 0 : 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;
2115fa1f8eSMatthew G. Knepley   if (cEnd) *cEnd = depth < 0 ? 0 : depthSize[depth];
2215fa1f8eSMatthew G. Knepley   if (vEnd) *vEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0];
2315fa1f8eSMatthew G. Knepley   if (fEnd) *fEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1];
2415fa1f8eSMatthew G. Knepley   if (eEnd) *eEnd = depth < 0 ? 0 : 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) {
39*9b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
40*9b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
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;
82*9b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
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) {
149*9b1a0e7fSLawrence Mitchell   case REFINER_NOOP: 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) {
180*9b1a0e7fSLawrence Mitchell   case REFINER_NOOP:
1813478d7aaSMatthew G. Knepley     break;
182*9b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
18375d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart;         /* Add a vertex on every face */
18475d3a19aSMatthew 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 */
18575d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                     /* Every cell split into 4 cells */
18675d3a19aSMatthew G. Knepley     break;
187*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
18875d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
18975d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
19075d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart;                                         /* Add a vertex on every face, but not hybrid faces */
19175d3a19aSMatthew 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 */
19275d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax);                                   /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */
19375d3a19aSMatthew G. Knepley     break;
194*9b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
195149f48fdSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
19675d3a19aSMatthew 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 */
19775d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                             /* Every cell split into 4 cells */
19875d3a19aSMatthew G. Knepley     break;
199*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
200a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
201a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
202a97b51b8SMatthew G. Knepley     /* Quadrilateral */
203a97b51b8SMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart;                 /* Add a vertex on every face and cell */
204a97b51b8SMatthew 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 */
205a97b51b8SMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart);                                             /* Every cell split into 4 cells */
206a97b51b8SMatthew G. Knepley     /* Segment Prisms */
207a97b51b8SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
208a97b51b8SMatthew G. Knepley     depthSize[1] +=   (fEnd - fMax)  +   (cEnd - cMax);                           /* Every hybrid face remains and 1 faces is added for each hybrid cell */
209a97b51b8SMatthew G. Knepley     depthSize[2] += 2*(cEnd - cMax);                                              /* Every hybrid cell split into 2 cells */
210a97b51b8SMatthew G. Knepley     break;
211*9b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
212b5da9499SMatthew G. Knepley     depthSize[0] =    vEnd - vStart  +    eEnd - eStart;                    /* Add a vertex on every edge */
213b5da9499SMatthew 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 */
214b5da9499SMatthew G. Knepley     depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart);                   /* Every face split into 4 faces and 8 faces are added for each cell */
215b5da9499SMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                       /* Every cell split into 8 cells */
216b5da9499SMatthew G. Knepley     break;
217*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
218b5da9499SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2196ce3c06aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
220b5da9499SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
221dae4404aSMatthew G. Knepley     /* Tetrahedra */
222dae4404aSMatthew G. Knepley     depthSize[0]  =    vEnd - vStart  +    eMax - eStart;                    /* Add a vertex on every interior edge */
223dae4404aSMatthew 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 */
224dae4404aSMatthew G. Knepley     depthSize[2]  = 4*(fMax - fStart) + 8*(cMax - cStart);                   /* Every interior face split into 4 faces, 8 faces added for each interior cell */
225dae4404aSMatthew G. Knepley     depthSize[3]  = 8*(cMax - cStart);                                       /* Every interior cell split into 8 cells */
226dae4404aSMatthew G. Knepley     /* Triangular Prisms */
227dae4404aSMatthew G. Knepley     depthSize[0] += 0;                                                       /* No hybrid vertices */
228dae4404aSMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax);                     /* Every hybrid edge remains, 1 edge for every hybrid face */
2296ce3c06aSMatthew 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 */
230dae4404aSMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                         /* Every hybrid cell split into 4 cells */
231b5da9499SMatthew G. Knepley     break;
232*9b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
2336ce3c06aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
2346ce3c06aSMatthew 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 */
2356ce3c06aSMatthew 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 */
2366ce3c06aSMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                             /* Every cell split into 8 cells */
2376ce3c06aSMatthew G. Knepley     break;
238*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
23927fcede3SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
24027fcede3SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
24127fcede3SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
24227fcede3SMatthew G. Knepley     /* Hexahedra */
24327fcede3SMatthew G. Knepley     depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
24427fcede3SMatthew 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 */
24527fcede3SMatthew 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 */
24627fcede3SMatthew G. Knepley     depthSize[3] = 8*(cMax - cStart);                                             /* Every cell split into 8 cells */
24727fcede3SMatthew G. Knepley     /* Quadrilateral Prisms */
24827fcede3SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
24927fcede3SMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax)   +   (cEnd - cMax);      /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
25027fcede3SMatthew 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 */
25127fcede3SMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                              /* Every hybrid cell split into 4 cells */
25227fcede3SMatthew G. Knepley     break;
25375d3a19aSMatthew G. Knepley   default:
25475d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
25575d3a19aSMatthew G. Knepley   }
25675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
25775d3a19aSMatthew G. Knepley }
25875d3a19aSMatthew G. Knepley 
25942525629SMatthew G. Knepley /* Return triangle edge for orientation o, if it is r for o == 0 */
26042525629SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
261518a8359SMatthew G. Knepley   return (o < 0 ? 2-(o+r) : o+r)%3;
262518a8359SMatthew G. Knepley }
263de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
264de65f515SMatthew G. Knepley   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
265de65f515SMatthew G. Knepley }
266518a8359SMatthew G. Knepley 
267518a8359SMatthew G. Knepley /* Return triangle subface for orientation o, if it is r for o == 0 */
268518a8359SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
2694bae88c7SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%3;
27042525629SMatthew G. Knepley }
271de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
272de65f515SMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 3+s-o)%3;
273de65f515SMatthew G. Knepley }
27442525629SMatthew G. Knepley 
275431647a4SMatthew G. Knepley /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */
276431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) {
277431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+r) : o+r)%3;
278431647a4SMatthew G. Knepley }
279431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) {
280431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+s) : 3+s-o)%3;
281431647a4SMatthew G. Knepley }
282431647a4SMatthew G. Knepley 
28342525629SMatthew G. Knepley 
284e3f8b1d6SMatthew G. Knepley /* Return quad edge for orientation o, if it is r for o == 0 */
285e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
286e3f8b1d6SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%4;
287e3f8b1d6SMatthew G. Knepley }
288d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
289d6d937efSMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 4+s-o)%4;
290d6d937efSMatthew G. Knepley }
291e3f8b1d6SMatthew G. Knepley 
292e3f8b1d6SMatthew G. Knepley /* Return quad subface for orientation o, if it is r for o == 0 */
293e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
2944bae88c7SMatthew G. Knepley   return (o < 0 ? 4-(o+r) : o+r)%4;
29542525629SMatthew G. Knepley }
296d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
297d6d937efSMatthew G. Knepley   return (o < 0 ? 4-(o+s) : 4+s-o)%4;
298d6d937efSMatthew G. Knepley }
29942525629SMatthew G. Knepley 
30075d3a19aSMatthew G. Knepley #undef __FUNCT__
30175d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetConeSizes"
30286150812SJed Brown static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
30375d3a19aSMatthew G. Knepley {
304b5da9499SMatthew 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;
30575d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
30675d3a19aSMatthew G. Knepley 
30775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
3082a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
30975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
31075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
31175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
31275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
31375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
31475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
3152a5d0125SJed Brown   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
31675d3a19aSMatthew G. Knepley   switch (refiner) {
317*9b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
31875d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
31975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
32075d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
32175d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
32275d3a19aSMatthew G. Knepley 
32375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
32475d3a19aSMatthew G. Knepley       }
32575d3a19aSMatthew G. Knepley     }
32675d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
32775d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
32875d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
32975d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
33075d3a19aSMatthew G. Knepley         PetscInt       size;
33175d3a19aSMatthew G. Knepley 
33275d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
33375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
33475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
33575d3a19aSMatthew G. Knepley       }
33675d3a19aSMatthew G. Knepley     }
33775d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
33875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
33975d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
34075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
34175d3a19aSMatthew G. Knepley 
34275d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
34375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
34475d3a19aSMatthew G. Knepley       }
34575d3a19aSMatthew G. Knepley     }
34675d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
34775d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
34875d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
34975d3a19aSMatthew G. Knepley       PetscInt       size;
35075d3a19aSMatthew G. Knepley 
35175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
35275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
35375d3a19aSMatthew G. Knepley     }
35475d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
35575d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
35675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
35775d3a19aSMatthew G. Knepley       PetscInt       size;
35875d3a19aSMatthew G. Knepley 
35975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
36075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
36175d3a19aSMatthew G. Knepley     }
36275d3a19aSMatthew G. Knepley     break;
363*9b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
36475d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
36575d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
36675d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
367149f48fdSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
36875d3a19aSMatthew G. Knepley 
36975d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
37075d3a19aSMatthew G. Knepley       }
37175d3a19aSMatthew G. Knepley     }
37275d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
37375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
37475d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
37575d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
37675d3a19aSMatthew G. Knepley         PetscInt       size;
37775d3a19aSMatthew G. Knepley 
37875d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
37975d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
38075d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
38175d3a19aSMatthew G. Knepley       }
38275d3a19aSMatthew G. Knepley     }
38375d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
38475d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
38575d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
38675d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
38775d3a19aSMatthew G. Knepley 
38875d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
38975d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
39075d3a19aSMatthew G. Knepley       }
39175d3a19aSMatthew G. Knepley     }
39275d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
39375d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
39475d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
39575d3a19aSMatthew G. Knepley       PetscInt       size;
39675d3a19aSMatthew G. Knepley 
39775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
39875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
39975d3a19aSMatthew G. Knepley     }
40075d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
40175d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
40275d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
40375d3a19aSMatthew G. Knepley       PetscInt       size;
40475d3a19aSMatthew G. Knepley 
40575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
40675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
40775d3a19aSMatthew G. Knepley     }
40875d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
40975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
41075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
41175d3a19aSMatthew G. Knepley 
41275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
41375d3a19aSMatthew G. Knepley     }
41475d3a19aSMatthew G. Knepley     break;
415*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
41675d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
41775d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
41875d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
41975d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
42075d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
42175d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
42275d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
42375d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
42475d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
42575d3a19aSMatthew G. Knepley 
42675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
42775d3a19aSMatthew G. Knepley       }
42875d3a19aSMatthew G. Knepley     }
42975d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
43075d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
43175d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
43275d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
43375d3a19aSMatthew G. Knepley 
43475d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
43575d3a19aSMatthew G. Knepley       }
43675d3a19aSMatthew G. Knepley     }
43775d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
43875d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
43975d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
44075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
44175d3a19aSMatthew G. Knepley         PetscInt       size;
44275d3a19aSMatthew G. Knepley 
44375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
44475d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
44575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
44675d3a19aSMatthew G. Knepley       }
44775d3a19aSMatthew G. Knepley     }
44875d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
44975d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
45075d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
45175d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
45275d3a19aSMatthew G. Knepley 
45375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
45475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
45575d3a19aSMatthew G. Knepley       }
45675d3a19aSMatthew G. Knepley     }
45775d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
45875d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
45975d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
46075d3a19aSMatthew G. Knepley       PetscInt       size;
46175d3a19aSMatthew G. Knepley 
46275d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
46375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
46475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
46575d3a19aSMatthew G. Knepley     }
46675d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
46775d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
46875d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
46975d3a19aSMatthew G. Knepley 
47075d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
47175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
47275d3a19aSMatthew G. Knepley     }
47375d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
47475d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
47575d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
47675d3a19aSMatthew G. Knepley       PetscInt       size;
47775d3a19aSMatthew G. Knepley 
47875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
47975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
48075d3a19aSMatthew G. Knepley     }
48175d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
48275d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
48375d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
48475d3a19aSMatthew G. Knepley       const PetscInt *support;
48575d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
48675d3a19aSMatthew G. Knepley 
48775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
48875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
48975d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
49075d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
49175d3a19aSMatthew G. Knepley         else newSize += 2;
49275d3a19aSMatthew G. Knepley       }
49375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
49475d3a19aSMatthew G. Knepley     }
49575d3a19aSMatthew G. Knepley     break;
496*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
497a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
498a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
499a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
500a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
501a97b51b8SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
502a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
503a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
504a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
505a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
506a97b51b8SMatthew G. Knepley 
507a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
508a97b51b8SMatthew G. Knepley       }
509a97b51b8SMatthew G. Knepley     }
510a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
511a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
512a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
513a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
514a97b51b8SMatthew G. Knepley 
515a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
516a97b51b8SMatthew G. Knepley       }
517a97b51b8SMatthew G. Knepley     }
518a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
519a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
520a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
521a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
522a97b51b8SMatthew G. Knepley         PetscInt       size;
523a97b51b8SMatthew G. Knepley 
524a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
525a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
526a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
527a97b51b8SMatthew G. Knepley       }
528a97b51b8SMatthew G. Knepley     }
529a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
530a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
531a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
532a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
533a97b51b8SMatthew G. Knepley 
534a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
535a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
536a97b51b8SMatthew G. Knepley       }
537a97b51b8SMatthew G. Knepley     }
538a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
539a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
540a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
541a97b51b8SMatthew G. Knepley       PetscInt       size;
542a97b51b8SMatthew G. Knepley 
543a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
544a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
545a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
546a97b51b8SMatthew G. Knepley     }
547a97b51b8SMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
548a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
549a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
550a97b51b8SMatthew G. Knepley 
551a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
552a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
553a97b51b8SMatthew G. Knepley     }
554a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
555a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
556a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
557a97b51b8SMatthew G. Knepley       PetscInt       size;
558a97b51b8SMatthew G. Knepley 
559a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
560a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
561a97b51b8SMatthew G. Knepley     }
562a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
563a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
564a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
565a97b51b8SMatthew G. Knepley       PetscInt       size;
566a97b51b8SMatthew G. Knepley 
567a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
568a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
569a97b51b8SMatthew G. Knepley     }
570a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
571a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
572a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
573a97b51b8SMatthew G. Knepley 
574a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
575a97b51b8SMatthew G. Knepley     }
576a97b51b8SMatthew G. Knepley     break;
577*9b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
578b5da9499SMatthew G. Knepley     /* All cells have 4 faces */
579b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
580b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
581dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
582b5da9499SMatthew G. Knepley 
583b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
584b5da9499SMatthew G. Knepley       }
585b5da9499SMatthew G. Knepley     }
586b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
587b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
588b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
589b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
590b5da9499SMatthew G. Knepley         PetscInt       size;
591b5da9499SMatthew G. Knepley 
592b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
593b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
594b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
595b5da9499SMatthew G. Knepley       }
596b5da9499SMatthew G. Knepley     }
5979ddff745SMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
598b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
599b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
600b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
601b5da9499SMatthew G. Knepley 
602b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
603b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
604b5da9499SMatthew G. Knepley       }
605b5da9499SMatthew G. Knepley     }
606b5da9499SMatthew G. Knepley     /* Split edges have 2 vertices and the same faces */
607b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
608b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
609b5da9499SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
610b5da9499SMatthew G. Knepley         PetscInt       size;
611b5da9499SMatthew G. Knepley 
612b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
613b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
614b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
615b5da9499SMatthew G. Knepley       }
616b5da9499SMatthew G. Knepley     }
617b5da9499SMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
618b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
619b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
620b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
621b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
622b5da9499SMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
623b5da9499SMatthew G. Knepley 
624b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
625b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
626b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
627b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
628b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
629b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
630b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
631b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
63286f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
6339ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
634b5da9499SMatthew G. Knepley           if (er == eint[c]) {
635b5da9499SMatthew G. Knepley             intFaces += 1;
636b5da9499SMatthew G. Knepley           } else {
637b5da9499SMatthew G. Knepley             intFaces += 2;
638b5da9499SMatthew G. Knepley           }
639b5da9499SMatthew G. Knepley         }
640b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
641b5da9499SMatthew G. Knepley       }
642b5da9499SMatthew G. Knepley     }
6439ddff745SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
644b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
645b5da9499SMatthew G. Knepley       const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
646b5da9499SMatthew G. Knepley 
647b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
648b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
649b5da9499SMatthew G. Knepley     }
650b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
651b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
652b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
653b5da9499SMatthew G. Knepley       PetscInt       size;
654b5da9499SMatthew G. Knepley 
655b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
656b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
657b5da9499SMatthew G. Knepley     }
658b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
659b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
660b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
661b5da9499SMatthew G. Knepley       PetscInt       size, *star = NULL, starSize, s, cellSize = 0;
662b5da9499SMatthew G. Knepley 
663b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
664b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
665b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
666b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
667b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
668b5da9499SMatthew G. Knepley 
669b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
670b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
671b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
672b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
673b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
67442525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
675b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
676b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
677b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
67842525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
67942525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
680b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
681b5da9499SMatthew G. Knepley         }
682b5da9499SMatthew G. Knepley       }
683b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
684b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr);
685b5da9499SMatthew G. Knepley     }
686b5da9499SMatthew G. Knepley     break;
687*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
6886ce3c06aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
6896ce3c06aSMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
690dae4404aSMatthew G. Knepley     /* Interior cells have 4 faces */
691dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
692dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
693dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
694dae4404aSMatthew G. Knepley 
695dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
696dae4404aSMatthew G. Knepley       }
697dae4404aSMatthew G. Knepley     }
698dae4404aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
699dae4404aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
700dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
701dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
702dae4404aSMatthew G. Knepley 
703dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr);
704dae4404aSMatthew G. Knepley       }
705dae4404aSMatthew G. Knepley     }
7066ce3c06aSMatthew G. Knepley     /* Interior split faces have 3 edges and the same cells as the parent */
707dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
708dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
709dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
710dae4404aSMatthew G. Knepley         PetscInt       size;
711dae4404aSMatthew G. Knepley 
712dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
713dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
714dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
715dae4404aSMatthew G. Knepley       }
716dae4404aSMatthew G. Knepley     }
717dae4404aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
718dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
719dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
720dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
721dae4404aSMatthew G. Knepley 
722dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
723dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
724dae4404aSMatthew G. Knepley       }
725dae4404aSMatthew G. Knepley     }
7266ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
7276ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
7286ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
7296ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
7306ce3c06aSMatthew G. Knepley         PetscInt       size;
7316ce3c06aSMatthew G. Knepley 
7326ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
7336ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
7346ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
7356ce3c06aSMatthew G. Knepley       }
7366ce3c06aSMatthew G. Knepley     }
7376ce3c06aSMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
7386ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
7396ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
7406ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
7416ce3c06aSMatthew G. Knepley 
7426ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
7436ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
7446ce3c06aSMatthew G. Knepley       }
7456ce3c06aSMatthew G. Knepley     }
7466ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces */
747dae4404aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
748dae4404aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
749dae4404aSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
750dae4404aSMatthew G. Knepley         PetscInt       size;
751dae4404aSMatthew G. Knepley 
752dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
753dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
754dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
755dae4404aSMatthew G. Knepley       }
756dae4404aSMatthew G. Knepley     }
7576ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
758dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
759dae4404aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
760dae4404aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
761dae4404aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
762dae4404aSMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
763dae4404aSMatthew G. Knepley 
764dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
765dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
766dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
767dae4404aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
768dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
769dae4404aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
770dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
771dae4404aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
7726ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
773dae4404aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
7749ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
775dae4404aSMatthew G. Knepley             if (er == eint[c]) {
776dae4404aSMatthew G. Knepley               intFaces += 1;
777dae4404aSMatthew G. Knepley             } else {
778dae4404aSMatthew G. Knepley               intFaces += 2;
779dae4404aSMatthew G. Knepley             }
7806ce3c06aSMatthew G. Knepley           } else {
7816ce3c06aSMatthew G. Knepley             intFaces += 1;
7826ce3c06aSMatthew G. Knepley           }
783dae4404aSMatthew G. Knepley         }
784dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
785dae4404aSMatthew G. Knepley       }
786dae4404aSMatthew G. Knepley     }
7876ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
788dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
789dae4404aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
790dae4404aSMatthew G. Knepley 
791dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
792dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
793dae4404aSMatthew G. Knepley     }
7946ce3c06aSMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
795dae4404aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
7966ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
7976ce3c06aSMatthew G. Knepley       PetscInt       size;
7986ce3c06aSMatthew G. Knepley 
7996ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
8006ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
8016ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
8026ce3c06aSMatthew G. Knepley     }
8036ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
8046ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
8056ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
806dae4404aSMatthew G. Knepley       PetscInt       size;
807dae4404aSMatthew G. Knepley 
808dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
809dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
8106ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr);
811dae4404aSMatthew G. Knepley     }
8126ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
813dae4404aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
814dae4404aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
815dae4404aSMatthew G. Knepley       PetscInt       size;
816dae4404aSMatthew G. Knepley 
817dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
818dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
819dae4404aSMatthew G. Knepley     }
8206ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
8216ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
8226ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
823dae4404aSMatthew G. Knepley       const PetscInt *support;
8246ce3c06aSMatthew G. Knepley       PetscInt        size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
825dae4404aSMatthew G. Knepley 
8266ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
8276ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
828dae4404aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
8296ce3c06aSMatthew G. Knepley         if (support[s] < fMax) faceSize += 2;
8306ce3c06aSMatthew G. Knepley         else                   faceSize += 1;
831dae4404aSMatthew G. Knepley       }
8326ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
8336ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
8346ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
8356ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
8366ce3c06aSMatthew G. Knepley 
8376ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
8386ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
8396ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
8406ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
8416ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
8426ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
8436ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
8446ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
8456ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
8466ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
8476ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
8486ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
8496ce3c06aSMatthew G. Knepley         }
8506ce3c06aSMatthew G. Knepley       }
8516ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
8526ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr);
853dae4404aSMatthew G. Knepley     }
854dae4404aSMatthew G. Knepley     break;
855*9b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
8562eabf88fSMatthew G. Knepley     /* All cells have 6 faces */
8572eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
8582eabf88fSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
8592eabf88fSMatthew G. Knepley         const PetscInt newp = (c - cStart)*8 + r;
8602eabf88fSMatthew G. Knepley 
8612eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
8622eabf88fSMatthew G. Knepley       }
8632eabf88fSMatthew G. Knepley     }
8642eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
8652eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
8662eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
8672eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
8682eabf88fSMatthew G. Knepley         PetscInt       size;
8692eabf88fSMatthew G. Knepley 
8702eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
8712eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
8722eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
8732eabf88fSMatthew G. Knepley       }
8742eabf88fSMatthew G. Knepley     }
8752eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
8762eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
8772eabf88fSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
8782eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
8792eabf88fSMatthew G. Knepley 
8802eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
8812eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
8822eabf88fSMatthew G. Knepley       }
8832eabf88fSMatthew G. Knepley     }
8842eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
8852eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
8862eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
8872eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
8882eabf88fSMatthew G. Knepley         PetscInt       size;
8892eabf88fSMatthew G. Knepley 
8902eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
8912eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
8922eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
8932eabf88fSMatthew G. Knepley       }
8942eabf88fSMatthew G. Knepley     }
8952eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
8962eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
8972eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
8982eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
8992eabf88fSMatthew G. Knepley         PetscInt       size;
9002eabf88fSMatthew G. Knepley 
9012eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
9022eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
9032eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
9042eabf88fSMatthew G. Knepley       }
9052eabf88fSMatthew G. Knepley     }
9062eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
9072eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
9082eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
9092eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
9102eabf88fSMatthew G. Knepley 
9112eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
9122eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
9132eabf88fSMatthew G. Knepley       }
9142eabf88fSMatthew G. Knepley     }
9152eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
9162eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
9172eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
9182eabf88fSMatthew G. Knepley       PetscInt       size;
9192eabf88fSMatthew G. Knepley 
9202eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
9212eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
9222eabf88fSMatthew G. Knepley     }
9232eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
9242eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
9252eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
9262eabf88fSMatthew G. Knepley       PetscInt       size;
9272eabf88fSMatthew G. Knepley 
9282eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
9292eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
9302eabf88fSMatthew G. Knepley     }
9312eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
9322eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
9332eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
9342eabf88fSMatthew G. Knepley       PetscInt       size;
9352eabf88fSMatthew G. Knepley 
9362eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
9372eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
9382eabf88fSMatthew G. Knepley     }
9392eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
9402eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
9412eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
9422eabf88fSMatthew G. Knepley 
9432eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
9442eabf88fSMatthew G. Knepley     }
9452eabf88fSMatthew G. Knepley     break;
946*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
94727fcede3SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
94827fcede3SMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
94927fcede3SMatthew G. Knepley     /* Interior cells have 6 faces */
95027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
95127fcede3SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
95227fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
95327fcede3SMatthew G. Knepley 
95427fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
95527fcede3SMatthew G. Knepley       }
95627fcede3SMatthew G. Knepley     }
95727fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces */
95827fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
95927fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
96027fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
96127fcede3SMatthew G. Knepley 
96227fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
96327fcede3SMatthew G. Knepley       }
96427fcede3SMatthew G. Knepley     }
96527fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
96627fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
96727fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
96827fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
96927fcede3SMatthew G. Knepley         PetscInt       size;
97027fcede3SMatthew G. Knepley 
97127fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
97227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
97327fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
97427fcede3SMatthew G. Knepley       }
97527fcede3SMatthew G. Knepley     }
97627fcede3SMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
97727fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
97827fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
97927fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
98027fcede3SMatthew G. Knepley 
98127fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
98227fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
98327fcede3SMatthew G. Knepley       }
98427fcede3SMatthew G. Knepley     }
98527fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
98627fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
98727fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
98827fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
98927fcede3SMatthew G. Knepley         PetscInt       size;
99027fcede3SMatthew G. Knepley 
99127fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
99227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
99327fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
99427fcede3SMatthew G. Knepley       }
99527fcede3SMatthew G. Knepley     }
99627fcede3SMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
99727fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
99827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
99927fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
100027fcede3SMatthew G. Knepley 
100127fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
100227fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
100327fcede3SMatthew G. Knepley       }
100427fcede3SMatthew G. Knepley     }
100527fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
100627fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
100727fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
100827fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
100927fcede3SMatthew G. Knepley         PetscInt       size;
101027fcede3SMatthew G. Knepley 
101127fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
101227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
101327fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
101427fcede3SMatthew G. Knepley       }
101527fcede3SMatthew G. Knepley     }
101627fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
101727fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
101827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
101927fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
102027fcede3SMatthew G. Knepley         PetscInt       size;
102127fcede3SMatthew G. Knepley 
102227fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
102327fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
102427fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
102527fcede3SMatthew G. Knepley       }
102627fcede3SMatthew G. Knepley     }
102727fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
102827fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
102927fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
103027fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
103127fcede3SMatthew G. Knepley 
103227fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
103327fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
103427fcede3SMatthew G. Knepley       }
103527fcede3SMatthew G. Knepley     }
103627fcede3SMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
103727fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
103827fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
103927fcede3SMatthew G. Knepley       PetscInt       size;
104027fcede3SMatthew G. Knepley 
104127fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
104227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
104327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
104427fcede3SMatthew G. Knepley     }
104527fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
104627fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
104727fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
104827fcede3SMatthew G. Knepley       PetscInt       size;
104927fcede3SMatthew G. Knepley 
105027fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
105127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
105227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
105327fcede3SMatthew G. Knepley     }
105427fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
105527fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
105627fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
105727fcede3SMatthew G. Knepley 
105827fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
105927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
106027fcede3SMatthew G. Knepley     }
106127fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
106227fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
106327fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
106427fcede3SMatthew G. Knepley       PetscInt       size;
106527fcede3SMatthew G. Knepley 
106627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
106727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
106827fcede3SMatthew G. Knepley     }
106927fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
107027fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
107127fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
107227fcede3SMatthew G. Knepley       PetscInt       size;
107327fcede3SMatthew G. Knepley 
107427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
107527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
107627fcede3SMatthew G. Knepley     }
107727fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
107827fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
107927fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
108027fcede3SMatthew G. Knepley       PetscInt       size;
108127fcede3SMatthew G. Knepley 
108227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
108327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
108427fcede3SMatthew G. Knepley     }
108527fcede3SMatthew G. Knepley     /* Interior cell vertices have 6 supports */
108627fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
108727fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
108827fcede3SMatthew G. Knepley 
108927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
109027fcede3SMatthew G. Knepley     }
109127fcede3SMatthew G. Knepley     break;
109275d3a19aSMatthew G. Knepley   default:
109375d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
109475d3a19aSMatthew G. Knepley   }
109575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
109675d3a19aSMatthew G. Knepley }
109775d3a19aSMatthew G. Knepley 
109875d3a19aSMatthew G. Knepley #undef __FUNCT__
109975d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCones"
110086150812SJed Brown static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
110175d3a19aSMatthew G. Knepley {
1102b5da9499SMatthew G. Knepley   const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
11036ce3c06aSMatthew G. Knepley   PetscInt        cStart,    cEnd,    cMax,    vStart,    vEnd, vMax, fStart,    fEnd,    fMax,    eStart,    eEnd,    eMax;
11046ce3c06aSMatthew G. Knepley   PetscInt        cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew,    fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
11056ce3c06aSMatthew G. Knepley   PetscInt        depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
110675d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
110775d3a19aSMatthew G. Knepley 
110875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
11092a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
111075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
111175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
111275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
111375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
111475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
111575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
111675d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
111775d3a19aSMatthew G. Knepley   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
111875d3a19aSMatthew G. Knepley   switch (refiner) {
1119*9b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
112075d3a19aSMatthew G. Knepley     /*
112175d3a19aSMatthew G. Knepley      2
112275d3a19aSMatthew G. Knepley      |\
112375d3a19aSMatthew G. Knepley      | \
112475d3a19aSMatthew G. Knepley      |  \
112575d3a19aSMatthew G. Knepley      |   \
112675d3a19aSMatthew G. Knepley      | C  \
112775d3a19aSMatthew G. Knepley      |     \
112875d3a19aSMatthew G. Knepley      |      \
112975d3a19aSMatthew G. Knepley      2---1---1
113075d3a19aSMatthew G. Knepley      |\  D  / \
113175d3a19aSMatthew G. Knepley      | 2   0   \
113275d3a19aSMatthew G. Knepley      |A \ /  B  \
113375d3a19aSMatthew G. Knepley      0---0-------1
113475d3a19aSMatthew G. Knepley      */
113575d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
113675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
113775d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
113875d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
113975d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
114075d3a19aSMatthew G. Knepley 
114175d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
114275d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
114375d3a19aSMatthew G. Knepley       /* A triangle */
114475d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
114575d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
114675d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
114775d3a19aSMatthew G. Knepley       orntNew[1] = -2;
114875d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
114975d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
115075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
115175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
115275d3a19aSMatthew G. Knepley #if 1
115375d3a19aSMatthew 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);
115475d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
115575d3a19aSMatthew 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);
115675d3a19aSMatthew G. Knepley       }
115775d3a19aSMatthew G. Knepley #endif
115875d3a19aSMatthew G. Knepley       /* B triangle */
115975d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
116075d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
116175d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
116275d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
116375d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
116475d3a19aSMatthew G. Knepley       orntNew[2] = -2;
116575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
116675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
116775d3a19aSMatthew G. Knepley #if 1
116875d3a19aSMatthew 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);
116975d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
117075d3a19aSMatthew 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);
117175d3a19aSMatthew G. Knepley       }
117275d3a19aSMatthew G. Knepley #endif
117375d3a19aSMatthew G. Knepley       /* C triangle */
117475d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
117575d3a19aSMatthew G. Knepley       orntNew[0] = -2;
117675d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
117775d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
117875d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
117975d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
118075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
118175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
118275d3a19aSMatthew G. Knepley #if 1
118375d3a19aSMatthew 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);
118475d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
118575d3a19aSMatthew 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);
118675d3a19aSMatthew G. Knepley       }
118775d3a19aSMatthew G. Knepley #endif
118875d3a19aSMatthew G. Knepley       /* D triangle */
118975d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
119075d3a19aSMatthew G. Knepley       orntNew[0] = 0;
119175d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
119275d3a19aSMatthew G. Knepley       orntNew[1] = 0;
119375d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
119475d3a19aSMatthew G. Knepley       orntNew[2] = 0;
119575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
119675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
119775d3a19aSMatthew G. Knepley #if 1
119875d3a19aSMatthew G. Knepley       if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew);
119975d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
120075d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
120175d3a19aSMatthew G. Knepley       }
120275d3a19aSMatthew G. Knepley #endif
120375d3a19aSMatthew G. Knepley     }
120475d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
120575d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1206854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
120775d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
120875d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
120975d3a19aSMatthew G. Knepley 
121075d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
121175d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1212297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
121375d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
121475d3a19aSMatthew G. Knepley 
121575d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
121675d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
121775d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
121875d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
121975d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
122075d3a19aSMatthew G. Knepley #if 1
122175d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
122275d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
122375d3a19aSMatthew G. Knepley           if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew);
122475d3a19aSMatthew G. Knepley         }
122575d3a19aSMatthew G. Knepley #endif
122675d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
122775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
122875d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
122975d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
123075d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1231297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
123275d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
123375d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
123475d3a19aSMatthew G. Knepley           }
1235297d2bf4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
123675d3a19aSMatthew G. Knepley         }
123775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
123875d3a19aSMatthew G. Knepley #if 1
123975d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
124075d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
124175d3a19aSMatthew G. Knepley           if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew);
124275d3a19aSMatthew G. Knepley         }
124375d3a19aSMatthew G. Knepley #endif
124475d3a19aSMatthew G. Knepley       }
124575d3a19aSMatthew G. Knepley     }
124675d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
124775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
124875d3a19aSMatthew G. Knepley       const PetscInt *cone;
124975d3a19aSMatthew G. Knepley 
125075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
125175d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
125275d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
125375d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
125475d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
125575d3a19aSMatthew G. Knepley 
125675d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
125775d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
125875d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
125975d3a19aSMatthew G. Knepley #if 1
126075d3a19aSMatthew 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);
126175d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
126275d3a19aSMatthew 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);
126375d3a19aSMatthew G. Knepley         }
126475d3a19aSMatthew G. Knepley #endif
126575d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
126675d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
126775d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
126875d3a19aSMatthew G. Knepley #if 1
126975d3a19aSMatthew 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);
127075d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
127175d3a19aSMatthew 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);
127275d3a19aSMatthew G. Knepley         }
127375d3a19aSMatthew G. Knepley #endif
127475d3a19aSMatthew G. Knepley       }
127575d3a19aSMatthew G. Knepley     }
127675d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
127775d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
127875d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
127975d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
128075d3a19aSMatthew G. Knepley       PetscInt        size, s;
128175d3a19aSMatthew G. Knepley 
128275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
128375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
128475d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
128575d3a19aSMatthew G. Knepley         PetscInt r = 0;
128675d3a19aSMatthew G. Knepley 
128775d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
128875d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
128975d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
129075d3a19aSMatthew G. Knepley       }
129175d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
129275d3a19aSMatthew G. Knepley #if 1
129375d3a19aSMatthew 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);
129475d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
129575d3a19aSMatthew 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);
129675d3a19aSMatthew G. Knepley       }
129775d3a19aSMatthew G. Knepley #endif
129875d3a19aSMatthew G. Knepley     }
129975d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
130075d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
130175d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
130275d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
130375d3a19aSMatthew G. Knepley       PetscInt        size, s;
130475d3a19aSMatthew G. Knepley 
130575d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
130675d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
130775d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
130875d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
130975d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
131075d3a19aSMatthew G. Knepley         PetscInt r = 0;
131175d3a19aSMatthew G. Knepley 
131275d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
131375d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
131475d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
131575d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
131675d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
131775d3a19aSMatthew G. Knepley       }
131875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
131975d3a19aSMatthew G. Knepley #if 1
132075d3a19aSMatthew 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);
132175d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
132275d3a19aSMatthew 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);
132375d3a19aSMatthew G. Knepley       }
132475d3a19aSMatthew G. Knepley #endif
132575d3a19aSMatthew G. Knepley     }
132675d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
132775d3a19aSMatthew G. Knepley     break;
1328*9b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
132975d3a19aSMatthew G. Knepley     /*
133075d3a19aSMatthew G. Knepley      3---------2---------2
133175d3a19aSMatthew G. Knepley      |         |         |
133275d3a19aSMatthew G. Knepley      |    D    2    C    |
133375d3a19aSMatthew G. Knepley      |         |         |
133475d3a19aSMatthew G. Knepley      3----3----0----1----1
133575d3a19aSMatthew G. Knepley      |         |         |
133675d3a19aSMatthew G. Knepley      |    A    0    B    |
133775d3a19aSMatthew G. Knepley      |         |         |
133875d3a19aSMatthew G. Knepley      0---------0---------1
133975d3a19aSMatthew G. Knepley      */
134075d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
134175d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
134275d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
134375d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
134475d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
134575d3a19aSMatthew G. Knepley 
134675d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
134775d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
134875d3a19aSMatthew G. Knepley       /* A quad */
134975d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
135075d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
135175d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
135275d3a19aSMatthew G. Knepley       orntNew[1] = 0;
135375d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
135475d3a19aSMatthew G. Knepley       orntNew[2] = -2;
135575d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
135675d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
135775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
135875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
135975d3a19aSMatthew G. Knepley #if 1
136075d3a19aSMatthew G. Knepley       if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew);
136175d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
136275d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
136375d3a19aSMatthew G. Knepley       }
136475d3a19aSMatthew G. Knepley #endif
136575d3a19aSMatthew G. Knepley       /* B quad */
136675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
136775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
136875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
136975d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
137075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
137175d3a19aSMatthew G. Knepley       orntNew[2] = 0;
137275d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
137375d3a19aSMatthew G. Knepley       orntNew[3] = -2;
137475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
137575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
137675d3a19aSMatthew G. Knepley #if 1
137775d3a19aSMatthew G. Knepley       if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew);
137875d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
137975d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
138075d3a19aSMatthew G. Knepley       }
138175d3a19aSMatthew G. Knepley #endif
138275d3a19aSMatthew G. Knepley       /* C quad */
138375d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
138475d3a19aSMatthew G. Knepley       orntNew[0] = -2;
138575d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
138675d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
138775d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
138875d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
138975d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
139075d3a19aSMatthew G. Knepley       orntNew[3] = 0;
139175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
139275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
139375d3a19aSMatthew G. Knepley #if 1
139475d3a19aSMatthew 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);
139575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
139675d3a19aSMatthew 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);
139775d3a19aSMatthew G. Knepley       }
139875d3a19aSMatthew G. Knepley #endif
139975d3a19aSMatthew G. Knepley       /* D quad */
140075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
140175d3a19aSMatthew G. Knepley       orntNew[0] = 0;
140275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
140375d3a19aSMatthew G. Knepley       orntNew[1] = -2;
140475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
140575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
140675d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
140775d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
140875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
140975d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
141075d3a19aSMatthew G. Knepley #if 1
141175d3a19aSMatthew 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);
141275d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
141375d3a19aSMatthew 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);
141475d3a19aSMatthew G. Knepley       }
141575d3a19aSMatthew G. Knepley #endif
141675d3a19aSMatthew G. Knepley     }
141775d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
141875d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1419854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
142075d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
142175d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
142275d3a19aSMatthew G. Knepley 
142375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
142475d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1425455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
142675d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
142775d3a19aSMatthew G. Knepley 
142875d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
142975d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
143075d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
143175d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
143275d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
143375d3a19aSMatthew G. Knepley #if 1
143475d3a19aSMatthew 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);
143575d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
143675d3a19aSMatthew 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);
143775d3a19aSMatthew G. Knepley         }
143875d3a19aSMatthew G. Knepley #endif
143975d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
144075d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
144175d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
144275d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
144375d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1444455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
144575d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
144675d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
144775d3a19aSMatthew G. Knepley           }
1448455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
144975d3a19aSMatthew G. Knepley         }
145075d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);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 < supportSize; ++p) {
145475d3a19aSMatthew 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);
145575d3a19aSMatthew G. Knepley         }
145675d3a19aSMatthew G. Knepley #endif
145775d3a19aSMatthew G. Knepley       }
145875d3a19aSMatthew G. Knepley     }
145975d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
146075d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
146175d3a19aSMatthew G. Knepley       const PetscInt *cone;
146275d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
146375d3a19aSMatthew G. Knepley 
146475d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
146575d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
146675d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
146775d3a19aSMatthew G. Knepley 
146875d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
146975d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
147075d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
147175d3a19aSMatthew G. Knepley #if 1
147275d3a19aSMatthew 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);
147375d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
147475d3a19aSMatthew 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);
147575d3a19aSMatthew G. Knepley         }
147675d3a19aSMatthew G. Knepley #endif
147775d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
147875d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
147975d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
148075d3a19aSMatthew G. Knepley #if 1
148175d3a19aSMatthew 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);
148275d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
148375d3a19aSMatthew 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);
148475d3a19aSMatthew G. Knepley         }
148575d3a19aSMatthew G. Knepley #endif
148675d3a19aSMatthew G. Knepley       }
148775d3a19aSMatthew G. Knepley     }
148875d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
148975d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
149075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
149175d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
149275d3a19aSMatthew G. Knepley       PetscInt        size, s;
149375d3a19aSMatthew G. Knepley 
149475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
149575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
149675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
149775d3a19aSMatthew G. Knepley         PetscInt r = 0;
149875d3a19aSMatthew G. Knepley 
149975d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
150075d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
150175d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
150275d3a19aSMatthew G. Knepley       }
150375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
150475d3a19aSMatthew G. Knepley #if 1
150575d3a19aSMatthew 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);
150675d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
150775d3a19aSMatthew 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);
150875d3a19aSMatthew G. Knepley       }
150975d3a19aSMatthew G. Knepley #endif
151075d3a19aSMatthew G. Knepley     }
151175d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
151275d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
151375d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
151475d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
151575d3a19aSMatthew G. Knepley       PetscInt        size, s;
151675d3a19aSMatthew G. Knepley 
151775d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
151875d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
151975d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
152075d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
152175d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
152275d3a19aSMatthew G. Knepley         PetscInt r = 0;
152375d3a19aSMatthew G. Knepley 
152475d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
152575d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
152675d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
152775d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
152875d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
152975d3a19aSMatthew G. Knepley       }
153075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
153175d3a19aSMatthew G. Knepley #if 1
153275d3a19aSMatthew 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);
153375d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
153475d3a19aSMatthew 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);
153575d3a19aSMatthew G. Knepley       }
153675d3a19aSMatthew G. Knepley #endif
153775d3a19aSMatthew G. Knepley     }
153875d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
153975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
154075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
154175d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
154275d3a19aSMatthew G. Knepley 
154375d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
154475d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
154575d3a19aSMatthew G. Knepley       }
154675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
154775d3a19aSMatthew G. Knepley     }
1548da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
154975d3a19aSMatthew G. Knepley     break;
1550*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
155175d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
155275d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
155375d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
155475d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
1555149f48fdSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
155675d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
155775d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
155875d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
155975d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
156075d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
156175d3a19aSMatthew G. Knepley 
156275d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
156375d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
156475d3a19aSMatthew G. Knepley       /* A triangle */
156575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
156675d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
156775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
156875d3a19aSMatthew G. Knepley       orntNew[1] = -2;
156975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
157075d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
157175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
157275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
157375d3a19aSMatthew G. Knepley #if 1
1574149f48fdSMatthew 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);
157575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1576149f48fdSMatthew 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);
157775d3a19aSMatthew G. Knepley       }
157875d3a19aSMatthew G. Knepley #endif
157975d3a19aSMatthew G. Knepley       /* B triangle */
158075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
158175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
158275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
158375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
158475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
158575d3a19aSMatthew G. Knepley       orntNew[2] = -2;
158675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
158775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
158875d3a19aSMatthew G. Knepley #if 1
1589a97b51b8SMatthew 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);
159075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1591a97b51b8SMatthew 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);
159275d3a19aSMatthew G. Knepley       }
159375d3a19aSMatthew G. Knepley #endif
159475d3a19aSMatthew G. Knepley       /* C triangle */
159575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
159675d3a19aSMatthew G. Knepley       orntNew[0] = -2;
159775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
159875d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
159975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
160075d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
160175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
160275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
160375d3a19aSMatthew G. Knepley #if 1
1604a97b51b8SMatthew 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);
160575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1606a97b51b8SMatthew 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);
160775d3a19aSMatthew G. Knepley       }
160875d3a19aSMatthew G. Knepley #endif
160975d3a19aSMatthew G. Knepley       /* D triangle */
161075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
161175d3a19aSMatthew G. Knepley       orntNew[0] = 0;
161275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
161375d3a19aSMatthew G. Knepley       orntNew[1] = 0;
161475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
161575d3a19aSMatthew G. Knepley       orntNew[2] = 0;
161675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
161775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
161875d3a19aSMatthew G. Knepley #if 1
1619a97b51b8SMatthew 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);
162075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1621a97b51b8SMatthew 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);
162275d3a19aSMatthew G. Knepley       }
162375d3a19aSMatthew G. Knepley #endif
162475d3a19aSMatthew G. Knepley     }
162575d3a19aSMatthew G. Knepley     /*
162675d3a19aSMatthew G. Knepley      2----3----3
162775d3a19aSMatthew G. Knepley      |         |
162875d3a19aSMatthew G. Knepley      |    B    |
162975d3a19aSMatthew G. Knepley      |         |
163075d3a19aSMatthew G. Knepley      0----4--- 1
163175d3a19aSMatthew G. Knepley      |         |
163275d3a19aSMatthew G. Knepley      |    A    |
163375d3a19aSMatthew G. Knepley      |         |
163475d3a19aSMatthew G. Knepley      0----2----1
163575d3a19aSMatthew G. Knepley      */
163675d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
163775d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
163875d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
163975d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
1640ea00e70eSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4], r;
164175d3a19aSMatthew G. Knepley 
164275d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
164375d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1644ea00e70eSMatthew G. Knepley       r    = (ornt[0] < 0 ? 1 : 0);
164575d3a19aSMatthew G. Knepley       /* A quad */
1646ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + r;
164775d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
1648ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + r;
164975d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
1650ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax);
1651ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
1652ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
1653ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
165475d3a19aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
165575d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
165675d3a19aSMatthew G. Knepley #if 1
165775d3a19aSMatthew 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);
165875d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
165975d3a19aSMatthew 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);
166075d3a19aSMatthew G. Knepley       }
166175d3a19aSMatthew G. Knepley #endif
166275d3a19aSMatthew G. Knepley       /* B quad */
1663ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + 1-r;
166475d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
1665ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + 1-r;
166675d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
1667ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
1668ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
1669ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax);
1670ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
167175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
167275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
167375d3a19aSMatthew G. Knepley #if 1
167475d3a19aSMatthew 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);
167575d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
167675d3a19aSMatthew 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);
167775d3a19aSMatthew G. Knepley       }
167875d3a19aSMatthew G. Knepley #endif
167975d3a19aSMatthew G. Knepley     }
168075d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
168175d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1682854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
168375d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
168475d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
168575d3a19aSMatthew G. Knepley 
168675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
168775d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1688297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
168975d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
169075d3a19aSMatthew G. Knepley 
169175d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
169275d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
169375d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
169475d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
169575d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
169675d3a19aSMatthew G. Knepley #if 1
169775d3a19aSMatthew 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);
169875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
169975d3a19aSMatthew 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);
170075d3a19aSMatthew G. Knepley         }
170175d3a19aSMatthew G. Knepley #endif
170275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
170375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
170475d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
170575d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
170675d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1707297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1708ea00e70eSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == f) break;
1709ea00e70eSMatthew G. Knepley           if (support[s] >= cMax) {
1710ea00e70eSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r);
1711ea00e70eSMatthew G. Knepley           } else {
1712297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
171375d3a19aSMatthew G. Knepley           }
171475d3a19aSMatthew G. Knepley         }
171575d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
171675d3a19aSMatthew G. Knepley #if 1
171775d3a19aSMatthew 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);
171875d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
171975d3a19aSMatthew 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);
172075d3a19aSMatthew G. Knepley         }
172175d3a19aSMatthew G. Knepley #endif
172275d3a19aSMatthew G. Knepley       }
172375d3a19aSMatthew G. Knepley     }
172475d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
172575d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
172675d3a19aSMatthew G. Knepley       const PetscInt *cone;
172775d3a19aSMatthew G. Knepley 
172875d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
172975d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
173075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
173175d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
173275d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
173375d3a19aSMatthew G. Knepley 
173475d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
173575d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
173675d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
173775d3a19aSMatthew G. Knepley #if 1
173875d3a19aSMatthew 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);
173975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
174075d3a19aSMatthew 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);
174175d3a19aSMatthew G. Knepley         }
174275d3a19aSMatthew G. Knepley #endif
174375d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
174475d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
174575d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
174675d3a19aSMatthew G. Knepley #if 1
174775d3a19aSMatthew 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);
174875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
174975d3a19aSMatthew 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);
175075d3a19aSMatthew G. Knepley         }
175175d3a19aSMatthew G. Knepley #endif
175275d3a19aSMatthew G. Knepley       }
175375d3a19aSMatthew G. Knepley     }
175475d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
175575d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
175675d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
1757ea00e70eSMatthew G. Knepley       const PetscInt *cone, *ornt;
175875d3a19aSMatthew G. Knepley       const PetscInt *support;
175975d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
176075d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
176175d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
176275d3a19aSMatthew G. Knepley 
176375d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
176475d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
176575d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
176675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
176775d3a19aSMatthew G. Knepley #if 1
176875d3a19aSMatthew 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);
176975d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
177075d3a19aSMatthew 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);
177175d3a19aSMatthew G. Knepley       }
177275d3a19aSMatthew G. Knepley #endif
177375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
177475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
177575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
177675d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1777ea00e70eSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
177875d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
177975d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
178075d3a19aSMatthew G. Knepley         }
1781ea00e70eSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r);
178275d3a19aSMatthew G. Knepley       }
178375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
178475d3a19aSMatthew G. Knepley #if 1
178575d3a19aSMatthew 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);
178675d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
178775d3a19aSMatthew 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);
178875d3a19aSMatthew G. Knepley       }
178975d3a19aSMatthew G. Knepley #endif
179075d3a19aSMatthew G. Knepley     }
179175d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
179275d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
179375d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
179475d3a19aSMatthew G. Knepley       const PetscInt *cone;
179575d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
179675d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
179775d3a19aSMatthew G. Knepley 
179875d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
179975d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
180075d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
180175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
180275d3a19aSMatthew G. Knepley #if 1
180375d3a19aSMatthew 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);
180475d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
180575d3a19aSMatthew 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);
180675d3a19aSMatthew G. Knepley       }
180775d3a19aSMatthew G. Knepley #endif
180875d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
180975d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
181075d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
181175d3a19aSMatthew G. Knepley #if 1
181275d3a19aSMatthew 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);
181375d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
181475d3a19aSMatthew 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);
181575d3a19aSMatthew G. Knepley       }
181675d3a19aSMatthew G. Knepley #endif
181775d3a19aSMatthew G. Knepley     }
181875d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
181975d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
182075d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
182175d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
182275d3a19aSMatthew G. Knepley       PetscInt        size, s;
182375d3a19aSMatthew G. Knepley 
182475d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
182575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
182675d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
182775d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
182875d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
182975d3a19aSMatthew G. Knepley         } else {
183075d3a19aSMatthew G. Knepley           PetscInt r = 0;
183175d3a19aSMatthew G. Knepley 
183275d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
183375d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
183475d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
183575d3a19aSMatthew G. Knepley         }
183675d3a19aSMatthew G. Knepley       }
183775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
183875d3a19aSMatthew G. Knepley #if 1
183975d3a19aSMatthew 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);
184075d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
184175d3a19aSMatthew 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);
184275d3a19aSMatthew G. Knepley       }
184375d3a19aSMatthew G. Knepley #endif
184475d3a19aSMatthew G. Knepley     }
184575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
184675d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
184775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
184875d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
184975d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
185075d3a19aSMatthew G. Knepley 
185175d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
185275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
185375d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
185475d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
185575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
185675d3a19aSMatthew G. Knepley         PetscInt r = 0;
185775d3a19aSMatthew G. Knepley 
185875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
185975d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
186075d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
186175d3a19aSMatthew G. Knepley 
186275d3a19aSMatthew G. Knepley           newSize += 1;
186375d3a19aSMatthew G. Knepley         } else {
186475d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
186575d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
186675d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
186775d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
186875d3a19aSMatthew G. Knepley 
186975d3a19aSMatthew G. Knepley           newSize += 2;
187075d3a19aSMatthew G. Knepley         }
187175d3a19aSMatthew G. Knepley       }
187275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
187375d3a19aSMatthew G. Knepley #if 1
187475d3a19aSMatthew 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);
187575d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
187675d3a19aSMatthew 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);
187775d3a19aSMatthew G. Knepley       }
187875d3a19aSMatthew G. Knepley #endif
187975d3a19aSMatthew G. Knepley     }
188075d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
188175d3a19aSMatthew G. Knepley     break;
1882*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
1883a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
1884a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
1885a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
1886a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
1887a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
1888a97b51b8SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
1889a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
1890a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
1891a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
1892a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
1893a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1894a97b51b8SMatthew G. Knepley 
1895a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1896a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1897a97b51b8SMatthew G. Knepley       /* A quad */
1898a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1899a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1900a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
1901a97b51b8SMatthew G. Knepley       orntNew[1] = 0;
1902a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
1903a97b51b8SMatthew G. Knepley       orntNew[2] = -2;
1904a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
1905a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
1906a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1907a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1908a97b51b8SMatthew G. Knepley #if 1
1909a97b51b8SMatthew 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);
1910a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1911a97b51b8SMatthew 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);
1912a97b51b8SMatthew G. Knepley       }
1913a97b51b8SMatthew G. Knepley #endif
1914a97b51b8SMatthew G. Knepley       /* B quad */
1915a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1916a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1917a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1918a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1919a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
1920a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
1921a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
1922a97b51b8SMatthew G. Knepley       orntNew[3] = -2;
1923a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
1924a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
1925a97b51b8SMatthew G. Knepley #if 1
1926a97b51b8SMatthew 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);
1927a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1928a97b51b8SMatthew 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);
1929a97b51b8SMatthew G. Knepley       }
1930a97b51b8SMatthew G. Knepley #endif
1931a97b51b8SMatthew G. Knepley       /* C quad */
1932a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
1933a97b51b8SMatthew G. Knepley       orntNew[0] = -2;
1934a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
1935a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1936a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
1937a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
1938a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
1939a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
1940a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
1941a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
1942a97b51b8SMatthew G. Knepley #if 1
1943a97b51b8SMatthew 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);
1944a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1945a97b51b8SMatthew 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);
1946a97b51b8SMatthew G. Knepley       }
1947a97b51b8SMatthew G. Knepley #endif
1948a97b51b8SMatthew G. Knepley       /* D quad */
1949a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
1950a97b51b8SMatthew G. Knepley       orntNew[0] = 0;
1951a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
1952a97b51b8SMatthew G. Knepley       orntNew[1] = -2;
1953a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
1954a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
1955a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
1956a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
1957a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
1958a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
1959a97b51b8SMatthew G. Knepley #if 1
1960a97b51b8SMatthew 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);
1961a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1962a97b51b8SMatthew 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);
1963a97b51b8SMatthew G. Knepley       }
1964a97b51b8SMatthew G. Knepley #endif
1965a97b51b8SMatthew G. Knepley     }
1966a97b51b8SMatthew G. Knepley     /*
1967a97b51b8SMatthew G. Knepley      2----3----3
1968a97b51b8SMatthew G. Knepley      |         |
1969a97b51b8SMatthew G. Knepley      |    B    |
1970a97b51b8SMatthew G. Knepley      |         |
1971a97b51b8SMatthew G. Knepley      0----4--- 1
1972a97b51b8SMatthew G. Knepley      |         |
1973a97b51b8SMatthew G. Knepley      |    A    |
1974a97b51b8SMatthew G. Knepley      |         |
1975a97b51b8SMatthew G. Knepley      0----2----1
1976a97b51b8SMatthew G. Knepley      */
1977a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
1978a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
1979a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
1980a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
1981a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1982a97b51b8SMatthew G. Knepley 
1983a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1984a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1985a97b51b8SMatthew G. Knepley       /* A quad */
1986a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1987a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1988a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1989a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1990a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax);
1991a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
1992a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
1993a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
1994a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1995a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1996a97b51b8SMatthew G. Knepley #if 1
1997a97b51b8SMatthew 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);
1998a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1999a97b51b8SMatthew 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);
2000a97b51b8SMatthew G. Knepley       }
2001a97b51b8SMatthew G. Knepley #endif
2002a97b51b8SMatthew G. Knepley       /* B quad */
2003a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2004a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2005a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2006a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2007a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2008a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2009a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax);
2010a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2011a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2012a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2013a97b51b8SMatthew G. Knepley #if 1
2014a97b51b8SMatthew 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);
2015a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2016a97b51b8SMatthew 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);
2017a97b51b8SMatthew G. Knepley       }
2018a97b51b8SMatthew G. Knepley #endif
2019a97b51b8SMatthew G. Knepley     }
2020a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
2021a97b51b8SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2022854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2023a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2024a97b51b8SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2025a97b51b8SMatthew G. Knepley 
2026a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2027a97b51b8SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
2028a97b51b8SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2029a97b51b8SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2030a97b51b8SMatthew G. Knepley 
2031a97b51b8SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2032a97b51b8SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2033a97b51b8SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2034a97b51b8SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2035a97b51b8SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2036a97b51b8SMatthew G. Knepley #if 1
2037a97b51b8SMatthew 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);
2038a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2039a97b51b8SMatthew 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);
2040a97b51b8SMatthew G. Knepley         }
2041a97b51b8SMatthew G. Knepley #endif
2042a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2043a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2044a97b51b8SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2045a97b51b8SMatthew G. Knepley           if (support[s] >= cMax) {
2046a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2047a97b51b8SMatthew G. Knepley           } else {
2048a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2049a97b51b8SMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2050a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2051a97b51b8SMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
2052a97b51b8SMatthew G. Knepley               if (cone[c] == f) break;
2053a97b51b8SMatthew G. Knepley             }
2054a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
2055a97b51b8SMatthew G. Knepley           }
2056a97b51b8SMatthew G. Knepley         }
2057a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2058a97b51b8SMatthew G. Knepley #if 1
2059a97b51b8SMatthew 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);
2060a97b51b8SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2061a97b51b8SMatthew 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);
2062a97b51b8SMatthew G. Knepley         }
2063a97b51b8SMatthew G. Knepley #endif
2064a97b51b8SMatthew G. Knepley       }
2065a97b51b8SMatthew G. Knepley     }
2066a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
2067a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2068a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2069a97b51b8SMatthew G. Knepley 
2070a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2071a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2072a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2073a97b51b8SMatthew G. Knepley         PetscInt       coneNew[2], supportNew[2];
2074a97b51b8SMatthew G. Knepley 
2075a97b51b8SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2076a97b51b8SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fMax    - fStart) + (c - cStart);
2077a97b51b8SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2078a97b51b8SMatthew G. Knepley #if 1
2079a97b51b8SMatthew 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);
2080a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2081a97b51b8SMatthew 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);
2082a97b51b8SMatthew G. Knepley         }
2083a97b51b8SMatthew G. Knepley #endif
2084a97b51b8SMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
2085a97b51b8SMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
2086a97b51b8SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2087a97b51b8SMatthew G. Knepley #if 1
2088a97b51b8SMatthew 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);
2089a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2090a97b51b8SMatthew 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);
2091a97b51b8SMatthew G. Knepley         }
2092a97b51b8SMatthew G. Knepley #endif
2093a97b51b8SMatthew G. Knepley       }
2094a97b51b8SMatthew G. Knepley     }
2095a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
2096a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
2097a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
2098a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2099a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2100a97b51b8SMatthew G. Knepley       PetscInt        size, s, r;
2101a97b51b8SMatthew G. Knepley 
2102a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2103a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
2104a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
2105a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);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 ((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);
2110a97b51b8SMatthew G. Knepley       }
2111a97b51b8SMatthew G. Knepley #endif
2112a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2113a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2114a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2115a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2116a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r) {
2117a97b51b8SMatthew G. Knepley           if (cone[r+2] == f) break;
2118a97b51b8SMatthew G. Knepley         }
2119a97b51b8SMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2120a97b51b8SMatthew G. Knepley       }
2121a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2122a97b51b8SMatthew G. Knepley #if 1
2123a97b51b8SMatthew 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);
2124a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2125a97b51b8SMatthew 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);
2126a97b51b8SMatthew G. Knepley       }
2127a97b51b8SMatthew G. Knepley #endif
2128a97b51b8SMatthew G. Knepley     }
2129a97b51b8SMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
2130a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2131a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
2132a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2133a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2134a97b51b8SMatthew G. Knepley 
2135a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2136a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
2137a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
2138a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2139a97b51b8SMatthew G. Knepley #if 1
2140a97b51b8SMatthew 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);
2141a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2142a97b51b8SMatthew 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);
2143a97b51b8SMatthew G. Knepley       }
2144a97b51b8SMatthew G. Knepley #endif
2145a97b51b8SMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
2146a97b51b8SMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
2147a97b51b8SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2148a97b51b8SMatthew G. Knepley #if 1
2149a97b51b8SMatthew 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);
2150a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2151a97b51b8SMatthew 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);
2152a97b51b8SMatthew G. Knepley       }
2153a97b51b8SMatthew G. Knepley #endif
2154a97b51b8SMatthew G. Knepley     }
2155a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
2156a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2157a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2158a97b51b8SMatthew G. Knepley       const PetscInt *support, *cone;
2159a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2160a97b51b8SMatthew G. Knepley 
2161a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2162a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2163a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2164a97b51b8SMatthew G. Knepley         if (support[s] >= fMax) {
2165a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax);
2166a97b51b8SMatthew G. Knepley         } else {
2167a97b51b8SMatthew G. Knepley           PetscInt r = 0;
2168a97b51b8SMatthew G. Knepley 
2169a97b51b8SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2170a97b51b8SMatthew G. Knepley           if (cone[1] == v) r = 1;
2171a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2172a97b51b8SMatthew G. Knepley         }
2173a97b51b8SMatthew G. Knepley       }
2174a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2175a97b51b8SMatthew G. Knepley #if 1
2176a97b51b8SMatthew 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);
2177a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2178a97b51b8SMatthew 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);
2179a97b51b8SMatthew G. Knepley       }
2180a97b51b8SMatthew G. Knepley #endif
2181a97b51b8SMatthew G. Knepley     }
2182a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
2183a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2184a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
2185a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2186a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2187a97b51b8SMatthew G. Knepley 
2188a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2189a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2190a97b51b8SMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2191a97b51b8SMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2192a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2193a97b51b8SMatthew G. Knepley         PetscInt r = 0;
2194a97b51b8SMatthew G. Knepley 
2195a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2196a97b51b8SMatthew G. Knepley         if (support[s] >= cMax) {
2197a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax);
2198a97b51b8SMatthew G. Knepley         } else {
2199a97b51b8SMatthew G. Knepley           if      (cone[1] == f) r = 1;
2200a97b51b8SMatthew G. Knepley           else if (cone[2] == f) r = 2;
2201a97b51b8SMatthew G. Knepley           else if (cone[3] == f) r = 3;
2202a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r;
2203a97b51b8SMatthew G. Knepley         }
2204a97b51b8SMatthew G. Knepley       }
2205a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2206a97b51b8SMatthew G. Knepley #if 1
2207a97b51b8SMatthew 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);
2208a97b51b8SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
2209a97b51b8SMatthew 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);
2210a97b51b8SMatthew G. Knepley       }
2211a97b51b8SMatthew G. Knepley #endif
2212a97b51b8SMatthew G. Knepley     }
2213a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
2214a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2215a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
2216a97b51b8SMatthew G. Knepley       PetscInt       supportNew[4];
2217a97b51b8SMatthew G. Knepley 
2218a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2219a97b51b8SMatthew G. Knepley         supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2220a97b51b8SMatthew G. Knepley       }
2221a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2222a97b51b8SMatthew G. Knepley     }
2223a97b51b8SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2224a97b51b8SMatthew G. Knepley     break;
2225*9b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
2226b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
2227b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
2228b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2229b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
2230b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2231b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2232b5da9499SMatthew G. Knepley 
2233b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2234b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2235b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
2236518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
2237b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2238518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
2239b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2240518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
2241b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2242b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2243b5da9499SMatthew G. Knepley       orntNew[3] = 0;
2244b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2245b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2246b5da9499SMatthew G. Knepley #if 1
2247b5da9499SMatthew 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);
2248b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2249b5da9499SMatthew 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);
2250b5da9499SMatthew G. Knepley       }
2251b5da9499SMatthew G. Knepley #endif
2252b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
2253518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
2254b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2255518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
2256b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2257b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2258b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2259518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
2260b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2261b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2262b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2263b5da9499SMatthew G. Knepley #if 1
2264b5da9499SMatthew 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);
2265b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2266b5da9499SMatthew 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);
2267b5da9499SMatthew G. Knepley       }
2268b5da9499SMatthew G. Knepley #endif
2269b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
2270518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
2271b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2272b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2273b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2274518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
2275b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2276518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
2277b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2278b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2279b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2280b5da9499SMatthew G. Knepley #if 1
2281b5da9499SMatthew 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);
2282b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2283b5da9499SMatthew 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);
2284b5da9499SMatthew G. Knepley       }
2285b5da9499SMatthew G. Knepley #endif
2286b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
2287b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2288b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2289518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
2290b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2291518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
2292b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2293518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
2294b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2295b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2296b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2297b5da9499SMatthew G. Knepley #if 1
2298b5da9499SMatthew 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);
2299b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2300b5da9499SMatthew 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);
2301b5da9499SMatthew G. Knepley       }
2302b5da9499SMatthew G. Knepley #endif
2303b5da9499SMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
2304b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2305b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2306fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
2307db2c6090SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
2308fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2309fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
2310fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2311fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
2312b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
2313b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
2314b5da9499SMatthew G. Knepley #if 1
2315b5da9499SMatthew 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);
2316b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2317b5da9499SMatthew 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);
2318b5da9499SMatthew G. Knepley       }
2319b5da9499SMatthew G. Knepley #endif
2320b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
2321b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2322b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2323fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2324fac4ab25SMatthew G. Knepley       orntNew[1] = 1;
2325fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
2326b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2327fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
2328db2c6090SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
2329b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
2330b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
2331b5da9499SMatthew G. Knepley #if 1
2332b5da9499SMatthew 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);
2333b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2334b5da9499SMatthew 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);
2335b5da9499SMatthew G. Knepley       }
2336b5da9499SMatthew G. Knepley #endif
2337b5da9499SMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
2338b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2339b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2340fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
2341db2c6090SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
2342fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2343fac4ab25SMatthew G. Knepley       orntNew[2] = -3;
2344fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
2345fac4ab25SMatthew G. Knepley       orntNew[3] = -2;
2346b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
2347b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
2348b5da9499SMatthew G. Knepley #if 1
2349b5da9499SMatthew 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);
2350b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2351b5da9499SMatthew 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);
2352b5da9499SMatthew G. Knepley       }
2353b5da9499SMatthew G. Knepley #endif
2354b5da9499SMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
2355b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2356b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2357fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2358b5da9499SMatthew G. Knepley       orntNew[1] = -3;
2359fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
2360db2c6090SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
2361fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2362fac4ab25SMatthew G. Knepley       orntNew[3] = -3;
2363b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
2364b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
2365b5da9499SMatthew G. Knepley #if 1
2366b5da9499SMatthew 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);
2367b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2368b5da9499SMatthew 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);
2369b5da9499SMatthew G. Knepley       }
2370b5da9499SMatthew G. Knepley #endif
2371b5da9499SMatthew G. Knepley     }
2372b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
2373b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2374854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2375b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2376b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
2377b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2378b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
2379b5da9499SMatthew G. Knepley 
2380b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2381b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
2382b5da9499SMatthew G. Knepley       /* A triangle */
2383b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
2384b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2385b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2386b5da9499SMatthew G. Knepley       orntNew[1] = -2;
2387b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
2388b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2389b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2390b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2391b5da9499SMatthew G. Knepley #if 1
2392b5da9499SMatthew 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);
2393b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2394b5da9499SMatthew 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);
2395b5da9499SMatthew G. Knepley       }
2396b5da9499SMatthew G. Knepley #endif
2397b5da9499SMatthew G. Knepley       /* B triangle */
2398b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
2399b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2400b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
2401b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2402b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2403b5da9499SMatthew G. Knepley       orntNew[2] = -2;
2404b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2405b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2406b5da9499SMatthew G. Knepley #if 1
2407b5da9499SMatthew 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);
2408b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2409b5da9499SMatthew 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);
2410b5da9499SMatthew G. Knepley       }
2411b5da9499SMatthew G. Knepley #endif
2412b5da9499SMatthew G. Knepley       /* C triangle */
2413b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2414b5da9499SMatthew G. Knepley       orntNew[0] = -2;
2415b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
2416b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2417b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
2418b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2419b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2420b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2421b5da9499SMatthew G. Knepley #if 1
2422b5da9499SMatthew 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);
2423b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2424b5da9499SMatthew 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);
2425b5da9499SMatthew G. Knepley       }
2426b5da9499SMatthew G. Knepley #endif
2427b5da9499SMatthew G. Knepley       /* D triangle */
2428b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2429b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2430b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2431b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2432b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2433b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2434b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2435b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2436b5da9499SMatthew G. Knepley #if 1
2437b5da9499SMatthew 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);
2438b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2439b5da9499SMatthew 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);
2440b5da9499SMatthew G. Knepley       }
2441b5da9499SMatthew G. Knepley #endif
2442b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2443b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2444b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2445b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2446219f7b90SMatthew G. Knepley           PetscInt subf;
2447b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2448b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2449b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2450b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2451b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
2452b5da9499SMatthew G. Knepley           }
2453219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
2454219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
2455b5da9499SMatthew G. Knepley         }
2456b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
2457b5da9499SMatthew G. Knepley #if 1
24589ddff745SMatthew 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);
2459b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2460b5da9499SMatthew 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);
2461b5da9499SMatthew G. Knepley         }
2462b5da9499SMatthew G. Knepley #endif
2463b5da9499SMatthew G. Knepley       }
2464b5da9499SMatthew G. Knepley     }
2465b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
2466b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2467b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
2468b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2469b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
2470b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
2471b5da9499SMatthew G. Knepley 
2472b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2473b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2474b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
24754bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2476b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
24774bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2478b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
24794bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
2480b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2481b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2482b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2483b5da9499SMatthew G. Knepley #if 1
2484b5da9499SMatthew 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);
2485b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2486b5da9499SMatthew 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);
2487b5da9499SMatthew G. Knepley       }
2488b5da9499SMatthew G. Knepley #endif
2489b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
2490b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
2491b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2492b5da9499SMatthew G. Knepley #if 1
2493b5da9499SMatthew 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);
2494b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2495b5da9499SMatthew 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);
2496b5da9499SMatthew G. Knepley       }
2497b5da9499SMatthew G. Knepley #endif
2498b5da9499SMatthew G. Knepley       ++newp;
2499b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
25004bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2501b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
25024bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
2503b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
25044bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2505b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2506b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2507b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2508b5da9499SMatthew G. Knepley #if 1
25094bb260e2SMatthew 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);
2510b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2511b5da9499SMatthew 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);
2512b5da9499SMatthew G. Knepley       }
2513b5da9499SMatthew G. Knepley #endif
2514b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
2515b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
2516b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2517b5da9499SMatthew G. Knepley #if 1
2518b5da9499SMatthew 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);
2519b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2520b5da9499SMatthew 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);
2521b5da9499SMatthew G. Knepley       }
2522b5da9499SMatthew G. Knepley #endif
2523b5da9499SMatthew G. Knepley       ++newp;
2524b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
25254bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
2526b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
25274bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2528b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
25294bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
2530b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
2531b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2532b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2533b5da9499SMatthew G. Knepley #if 1
2534b5da9499SMatthew 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);
2535b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2536b5da9499SMatthew 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);
2537b5da9499SMatthew G. Knepley       }
2538b5da9499SMatthew G. Knepley #endif
2539b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
2540b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2541b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2542b5da9499SMatthew G. Knepley #if 1
2543b5da9499SMatthew 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);
2544b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2545b5da9499SMatthew 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);
2546b5da9499SMatthew G. Knepley       }
2547b5da9499SMatthew G. Knepley #endif
2548b5da9499SMatthew G. Knepley       ++newp;
2549b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
25504bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
2551b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
25524bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2553b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
25544bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2555b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2556b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2557b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2558b5da9499SMatthew G. Knepley #if 1
2559b5da9499SMatthew 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);
2560b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2561b5da9499SMatthew 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);
2562b5da9499SMatthew G. Knepley       }
2563b5da9499SMatthew G. Knepley #endif
2564b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
2565b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2566b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2567b5da9499SMatthew G. Knepley #if 1
2568b5da9499SMatthew 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);
2569b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2570b5da9499SMatthew 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);
2571b5da9499SMatthew G. Knepley       }
2572b5da9499SMatthew G. Knepley #endif
2573b5da9499SMatthew G. Knepley       ++newp;
2574b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
25754bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2576b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
2577b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
25784bb260e2SMatthew G. Knepley       orntNew[1] = -2;
25794bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2580b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2581b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2582b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2583b5da9499SMatthew G. Knepley #if 1
2584b5da9499SMatthew 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);
2585b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2586b5da9499SMatthew 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);
2587b5da9499SMatthew G. Knepley       }
2588b5da9499SMatthew G. Knepley #endif
2589b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2590b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2591b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2592b5da9499SMatthew G. Knepley #if 1
2593b5da9499SMatthew 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);
2594b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2595b5da9499SMatthew 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);
2596b5da9499SMatthew G. Knepley       }
2597b5da9499SMatthew G. Knepley #endif
2598b5da9499SMatthew G. Knepley       ++newp;
2599b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
26004bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2601b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2602b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
26034bb260e2SMatthew G. Knepley       orntNew[1] = 0;
26044bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
26052baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
2606b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2607b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2608b5da9499SMatthew G. Knepley #if 1
2609b5da9499SMatthew 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);
2610b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2611b5da9499SMatthew 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);
2612b5da9499SMatthew G. Knepley       }
2613b5da9499SMatthew G. Knepley #endif
2614b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2615b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2616b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2617b5da9499SMatthew G. Knepley #if 1
2618b5da9499SMatthew 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);
2619b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2620b5da9499SMatthew 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);
2621b5da9499SMatthew G. Knepley       }
2622b5da9499SMatthew G. Knepley #endif
2623b5da9499SMatthew G. Knepley       ++newp;
2624b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
26254bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2626b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
2627b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2628fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
26294bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2630b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
2631b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2632b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2633b5da9499SMatthew G. Knepley #if 1
2634b5da9499SMatthew 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);
2635b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2636b5da9499SMatthew 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);
2637b5da9499SMatthew G. Knepley       }
2638b5da9499SMatthew G. Knepley #endif
2639b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2640b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2641b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2642b5da9499SMatthew G. Knepley #if 1
2643b5da9499SMatthew 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);
2644b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2645b5da9499SMatthew 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);
2646b5da9499SMatthew G. Knepley       }
2647b5da9499SMatthew G. Knepley #endif
2648b5da9499SMatthew G. Knepley       ++newp;
2649b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
26504bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2651b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
26524bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2653b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
2654b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
26554bb260e2SMatthew G. Knepley       orntNew[2] = -2;
2656b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2657b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2658b5da9499SMatthew G. Knepley #if 1
2659b5da9499SMatthew 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);
2660b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2661b5da9499SMatthew 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);
2662b5da9499SMatthew G. Knepley       }
2663b5da9499SMatthew G. Knepley #endif
2664b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2665b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2666b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2667b5da9499SMatthew G. Knepley #if 1
2668b5da9499SMatthew 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);
2669b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2670b5da9499SMatthew 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);
2671b5da9499SMatthew G. Knepley       }
2672b5da9499SMatthew G. Knepley #endif
2673b5da9499SMatthew G. Knepley       ++newp;
2674b5da9499SMatthew G. Knepley     }
2675b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
2676b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2677b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
2678b5da9499SMatthew G. Knepley 
2679b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2680b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
2681b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2682b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2683b5da9499SMatthew G. Knepley 
2684b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
2685b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2686b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2687b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2688b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2689b5da9499SMatthew G. Knepley #if 1
2690b5da9499SMatthew 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);
2691b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2692b5da9499SMatthew 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);
2693b5da9499SMatthew G. Knepley         }
2694b5da9499SMatthew G. Knepley #endif
2695b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
2696b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2697b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2698b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2699b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2700b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2701b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2702b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
2703b5da9499SMatthew G. Knepley           }
2704b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
2705b5da9499SMatthew G. Knepley         }
2706b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2707b5da9499SMatthew G. Knepley #if 1
2708b5da9499SMatthew 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);
2709b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2710b5da9499SMatthew 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);
2711b5da9499SMatthew G. Knepley         }
2712b5da9499SMatthew G. Knepley #endif
2713b5da9499SMatthew G. Knepley       }
2714b5da9499SMatthew G. Knepley     }
271586f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
2716b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2717b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2718b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
2719b5da9499SMatthew G. Knepley 
2720b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2721b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2722b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
2723b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
2724b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
2725b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
2726b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
2727b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
2728b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
2729b5da9499SMatthew G. Knepley 
2730b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2731b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
2732b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
2733b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2734b5da9499SMatthew G. Knepley #if 1
2735b5da9499SMatthew 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);
2736b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2737b5da9499SMatthew 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);
2738b5da9499SMatthew G. Knepley         }
2739b5da9499SMatthew G. Knepley #endif
2740b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
2741b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
2742b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2743b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2744b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2745b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2746b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
274786f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
27489ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
2749b5da9499SMatthew G. Knepley           if (er == eint[c]) {
2750b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
2751b5da9499SMatthew G. Knepley           } else {
2752b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
2753b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
2754b5da9499SMatthew G. Knepley           }
2755b5da9499SMatthew G. Knepley         }
2756b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2757b5da9499SMatthew G. Knepley #if 1
2758b5da9499SMatthew 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);
2759b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
2760b5da9499SMatthew 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);
2761b5da9499SMatthew G. Knepley         }
2762b5da9499SMatthew G. Knepley #endif
2763b5da9499SMatthew G. Knepley       }
2764b5da9499SMatthew G. Knepley     }
2765b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
2766b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2767b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2768b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
27694a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
2770b5da9499SMatthew G. Knepley 
2771b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2772b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2773b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
277442525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
2775b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2776b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
277742525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
2778b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2779b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2780b5da9499SMatthew G. Knepley #if 1
2781b5da9499SMatthew 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);
2782b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2783b5da9499SMatthew 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);
2784b5da9499SMatthew G. Knepley       }
2785b5da9499SMatthew G. Knepley #endif
2786b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
2787b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
2788b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
2789b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
2790b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2791b5da9499SMatthew G. Knepley #if 1
2792b5da9499SMatthew 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);
2793b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2794b5da9499SMatthew 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);
2795b5da9499SMatthew G. Knepley       }
2796b5da9499SMatthew G. Knepley #endif
2797b5da9499SMatthew G. Knepley     }
2798b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
2799b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2800b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2801b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
2802b5da9499SMatthew G. Knepley       PetscInt        size, s;
2803b5da9499SMatthew G. Knepley 
2804b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2805b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2806b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2807b5da9499SMatthew G. Knepley         PetscInt r = 0;
2808b5da9499SMatthew G. Knepley 
2809b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2810b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
2811b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
2812b5da9499SMatthew G. Knepley       }
2813b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2814b5da9499SMatthew G. Knepley #if 1
2815b5da9499SMatthew 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);
2816b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2817b5da9499SMatthew 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);
2818b5da9499SMatthew G. Knepley       }
2819b5da9499SMatthew G. Knepley #endif
2820b5da9499SMatthew G. Knepley     }
2821b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
2822b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2823b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
2824b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
2825b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
2826b5da9499SMatthew G. Knepley 
2827b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
2828b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2829b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
2830b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
2831b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2832b5da9499SMatthew G. Knepley         PetscInt r = 0;
2833b5da9499SMatthew G. Knepley 
2834b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2835b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2836b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
2837b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
2838b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
2839b5da9499SMatthew G. Knepley       }
2840b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2841b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
2842b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
2843b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
2844b5da9499SMatthew G. Knepley 
2845b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
2846b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
2847b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2848b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
2849b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
285042525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
2851b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
2852b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2853b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
285442525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
285542525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
2856b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
2857b5da9499SMatthew G. Knepley         }
2858b5da9499SMatthew G. Knepley       }
2859b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2860b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2861b5da9499SMatthew G. Knepley #if 1
2862b5da9499SMatthew 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);
2863b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
2864b5da9499SMatthew 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);
2865b5da9499SMatthew G. Knepley       }
2866b5da9499SMatthew G. Knepley #endif
2867b5da9499SMatthew G. Knepley     }
2868b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2869b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
2870b5da9499SMatthew G. Knepley     break;
2871*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
28726ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
28736ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
28746ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
28756ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
28766ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
28776ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
28786ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
28796ce3c06aSMatthew G. Knepley 
28806ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
28816ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
28826ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
28836ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
28846ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
28856ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
28866ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
28876ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
28886ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
28896ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
28906ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
28916ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
28926ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
28936ce3c06aSMatthew G. Knepley #if 1
28946ce3c06aSMatthew 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);
28956ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
28966ce3c06aSMatthew 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);
28976ce3c06aSMatthew G. Knepley       }
28986ce3c06aSMatthew G. Knepley #endif
28996ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
29006ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
29016ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
29026ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
29036ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
29046ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
29056ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
29066ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
29076ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
29086ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
29096ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
29106ce3c06aSMatthew G. Knepley #if 1
29116ce3c06aSMatthew 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);
29126ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29136ce3c06aSMatthew 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);
29146ce3c06aSMatthew G. Knepley       }
29156ce3c06aSMatthew G. Knepley #endif
29166ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
29176ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
29186ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
29196ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
29206ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
29216ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
29226ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
29236ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
29246ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
29256ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
29266ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
29276ce3c06aSMatthew G. Knepley #if 1
29286ce3c06aSMatthew 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);
29296ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29306ce3c06aSMatthew 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);
29316ce3c06aSMatthew G. Knepley       }
29326ce3c06aSMatthew G. Knepley #endif
29336ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
29346ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
29356ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
29366ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
29376ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
29386ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
29396ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
29406ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
29416ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
29426ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
29436ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
29446ce3c06aSMatthew G. Knepley #if 1
29456ce3c06aSMatthew 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);
29466ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29476ce3c06aSMatthew 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);
29486ce3c06aSMatthew G. Knepley       }
29496ce3c06aSMatthew G. Knepley #endif
29506ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
29516ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
29526ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
29539ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
29549ddff745SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
29559ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
29569ddff745SMatthew G. Knepley       orntNew[2] = 0;
29579ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
29589ddff745SMatthew G. Knepley       orntNew[3] = 2;
29596ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
29606ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
29616ce3c06aSMatthew G. Knepley #if 1
29626ce3c06aSMatthew 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);
29636ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29646ce3c06aSMatthew 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);
29656ce3c06aSMatthew G. Knepley       }
29666ce3c06aSMatthew G. Knepley #endif
29676ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
29686ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
29696ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
29709ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
29719ddff745SMatthew G. Knepley       orntNew[1] = 1;
29729ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
29736ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
29749ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
29759ddff745SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
29766ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
29776ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
29786ce3c06aSMatthew G. Knepley #if 1
29796ce3c06aSMatthew 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);
29806ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29816ce3c06aSMatthew 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);
29826ce3c06aSMatthew G. Knepley       }
29836ce3c06aSMatthew G. Knepley #endif
29846ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
29856ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
29866ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
29879ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
29889ddff745SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
29899ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
29909ddff745SMatthew G. Knepley       orntNew[2] = -3;
29919ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
29929ddff745SMatthew G. Knepley       orntNew[3] = -2;
29936ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
29946ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
29956ce3c06aSMatthew G. Knepley #if 1
29966ce3c06aSMatthew 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);
29976ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29986ce3c06aSMatthew 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);
29996ce3c06aSMatthew G. Knepley       }
30006ce3c06aSMatthew G. Knepley #endif
30016ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
30026ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
30036ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
30049ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
30056ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
30069ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
30079ddff745SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
30089ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
30099ddff745SMatthew G. Knepley       orntNew[3] = -3;
30106ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
30116ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
30126ce3c06aSMatthew G. Knepley #if 1
30136ce3c06aSMatthew 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);
30146ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30156ce3c06aSMatthew 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);
30166ce3c06aSMatthew G. Knepley       }
30176ce3c06aSMatthew G. Knepley #endif
30186ce3c06aSMatthew G. Knepley     }
30196ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
30206ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
30216ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
3022d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
30233b61eb6dSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5], o, of, i;
30246ce3c06aSMatthew G. Knepley 
30256ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
30266ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3027d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
3028084f9c62SMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
30296ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
30306ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
30316ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
30326ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
30336ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
3034084f9c62SMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? -1 : 1;
30353b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], r)       + 2;
30363b61eb6dSMatthew 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);
30373b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
30383b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2;
30393b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
30403b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
30413b61eb6dSMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
30423b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2;
30433b61eb6dSMatthew 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);
30443b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
30456ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
30466ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
30476ce3c06aSMatthew G. Knepley #if 1
30486ce3c06aSMatthew 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);
30496ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
30506ce3c06aSMatthew 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);
30516ce3c06aSMatthew G. Knepley         }
30526ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
30536ce3c06aSMatthew 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);
30546ce3c06aSMatthew G. Knepley         }
30556ce3c06aSMatthew G. Knepley #endif
30566ce3c06aSMatthew G. Knepley       }
30576ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
30586ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
30596ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
30606ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
30613b61eb6dSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
30626ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
30633b61eb6dSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
30646ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
30653b61eb6dSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
30666ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
30676ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
30686ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
30696ce3c06aSMatthew G. Knepley #if 1
30706ce3c06aSMatthew 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);
30716ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
30726ce3c06aSMatthew 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);
30736ce3c06aSMatthew G. Knepley       }
30746ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
30756ce3c06aSMatthew 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);
30766ce3c06aSMatthew G. Knepley       }
30776ce3c06aSMatthew G. Knepley #endif
30786ce3c06aSMatthew G. Knepley     }
30796ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
30806ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3081854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
30826ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
30836ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
30846ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
30856ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
30866ce3c06aSMatthew G. Knepley 
30876ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
30886ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
30896ce3c06aSMatthew G. Knepley       /* A triangle */
30906ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
30916ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
30926ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
30936ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
30946ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
30956ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
30966ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
30976ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
30986ce3c06aSMatthew G. Knepley #if 1
30996ce3c06aSMatthew 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);
31006ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31016ce3c06aSMatthew 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);
31026ce3c06aSMatthew G. Knepley       }
31036ce3c06aSMatthew G. Knepley #endif
31046ce3c06aSMatthew G. Knepley       /* B triangle */
31056ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
31066ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
31076ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
31086ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
31096ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
31106ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
31116ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
31126ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
31136ce3c06aSMatthew G. Knepley #if 1
31146ce3c06aSMatthew 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);
31156ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31166ce3c06aSMatthew 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);
31176ce3c06aSMatthew G. Knepley       }
31186ce3c06aSMatthew G. Knepley #endif
31196ce3c06aSMatthew G. Knepley       /* C triangle */
31206ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
31216ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
31226ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
31236ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
31246ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
31256ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
31266ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
31276ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
31286ce3c06aSMatthew G. Knepley #if 1
31296ce3c06aSMatthew 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);
31306ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31316ce3c06aSMatthew 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);
31326ce3c06aSMatthew G. Knepley       }
31336ce3c06aSMatthew G. Knepley #endif
31346ce3c06aSMatthew G. Knepley       /* D triangle */
31356ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
31366ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
31376ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
31386ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
31396ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
31406ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
31416ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
31426ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
31436ce3c06aSMatthew G. Knepley #if 1
31446ce3c06aSMatthew 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);
31456ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31466ce3c06aSMatthew 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);
31476ce3c06aSMatthew G. Knepley       }
31486ce3c06aSMatthew G. Knepley #endif
31496ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
31506ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
31516ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
31526ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
31539ddff745SMatthew G. Knepley           PetscInt subf;
31546ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
31556ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
31566ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
31576ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
31586ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
31596ce3c06aSMatthew G. Knepley           }
31609ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
31616ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
31629ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
31636ce3c06aSMatthew G. Knepley           } else {
31649ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
31656ce3c06aSMatthew G. Knepley           }
31666ce3c06aSMatthew G. Knepley         }
31676ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
31686ce3c06aSMatthew G. Knepley #if 1
31699ddff745SMatthew 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);
31706ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
31716ce3c06aSMatthew 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);
31726ce3c06aSMatthew G. Knepley         }
31736ce3c06aSMatthew G. Knepley #endif
31746ce3c06aSMatthew G. Knepley       }
31756ce3c06aSMatthew G. Knepley     }
31766ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
31776ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
31786ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
31796ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
31806ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
31816ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
31826ce3c06aSMatthew G. Knepley 
31836ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
31846ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
31856ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
31869ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
31876ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
31889ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
31896ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
31909ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
31916ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
31926ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
31936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
31946ce3c06aSMatthew G. Knepley #if 1
31956ce3c06aSMatthew 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);
31966ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31976ce3c06aSMatthew 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);
31986ce3c06aSMatthew G. Knepley       }
31996ce3c06aSMatthew G. Knepley #endif
32006ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
32016ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
32026ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32036ce3c06aSMatthew G. Knepley #if 1
32046ce3c06aSMatthew 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);
32056ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32066ce3c06aSMatthew 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);
32076ce3c06aSMatthew G. Knepley       }
32086ce3c06aSMatthew G. Knepley #endif
32096ce3c06aSMatthew G. Knepley       ++newp;
32106ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
32119ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
32126ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
32139ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
32146ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
32159ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
32166ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
32176ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32186ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32196ce3c06aSMatthew G. Knepley #if 1
32206ce3c06aSMatthew 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);
32216ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32226ce3c06aSMatthew 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);
32236ce3c06aSMatthew G. Knepley       }
32246ce3c06aSMatthew G. Knepley #endif
32256ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
32266ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
32276ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32286ce3c06aSMatthew G. Knepley #if 1
32296ce3c06aSMatthew 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);
32306ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32316ce3c06aSMatthew 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);
32326ce3c06aSMatthew G. Knepley       }
32336ce3c06aSMatthew G. Knepley #endif
32346ce3c06aSMatthew G. Knepley       ++newp;
32356ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
32369ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
32376ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
32389ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
32396ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
32409ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
32416ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
32426ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32446ce3c06aSMatthew G. Knepley #if 1
32456ce3c06aSMatthew 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);
32466ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32476ce3c06aSMatthew 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);
32486ce3c06aSMatthew G. Knepley       }
32496ce3c06aSMatthew G. Knepley #endif
32506ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
32516ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
32526ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32536ce3c06aSMatthew G. Knepley #if 1
32546ce3c06aSMatthew 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);
32556ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32566ce3c06aSMatthew 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);
32576ce3c06aSMatthew G. Knepley       }
32586ce3c06aSMatthew G. Knepley #endif
32596ce3c06aSMatthew G. Knepley       ++newp;
32606ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
32619ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
32626ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
32639ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
32646ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
32659ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
32666ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
32676ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32686ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32696ce3c06aSMatthew G. Knepley #if 1
32706ce3c06aSMatthew 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);
32716ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32726ce3c06aSMatthew 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);
32736ce3c06aSMatthew G. Knepley       }
32746ce3c06aSMatthew G. Knepley #endif
32756ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
32766ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
32776ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32786ce3c06aSMatthew G. Knepley #if 1
32796ce3c06aSMatthew 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);
32806ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32816ce3c06aSMatthew 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);
32826ce3c06aSMatthew G. Knepley       }
32836ce3c06aSMatthew G. Knepley #endif
32846ce3c06aSMatthew G. Knepley       ++newp;
32856ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
32869ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
32876ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
32886ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
32899ddff745SMatthew G. Knepley       orntNew[1] = -2;
32909ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
32916ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
32926ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32946ce3c06aSMatthew G. Knepley #if 1
32956ce3c06aSMatthew 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);
32966ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32976ce3c06aSMatthew 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);
32986ce3c06aSMatthew G. Knepley       }
32996ce3c06aSMatthew G. Knepley #endif
33006ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
33016ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
33026ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33036ce3c06aSMatthew G. Knepley #if 1
33046ce3c06aSMatthew 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);
33056ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
33066ce3c06aSMatthew 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);
33076ce3c06aSMatthew G. Knepley       }
33086ce3c06aSMatthew G. Knepley #endif
33096ce3c06aSMatthew G. Knepley       ++newp;
33106ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
33119ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
33126ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
33136ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
33149ddff745SMatthew G. Knepley       orntNew[1] = 0;
33159ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
33169ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
33176ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33186ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33196ce3c06aSMatthew G. Knepley #if 1
33206ce3c06aSMatthew 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);
33216ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33226ce3c06aSMatthew 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);
33236ce3c06aSMatthew G. Knepley       }
33246ce3c06aSMatthew G. Knepley #endif
33256ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
33266ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
33276ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33286ce3c06aSMatthew G. Knepley #if 1
33296ce3c06aSMatthew 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);
33306ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
33316ce3c06aSMatthew 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);
33326ce3c06aSMatthew G. Knepley       }
33336ce3c06aSMatthew G. Knepley #endif
33346ce3c06aSMatthew G. Knepley       ++newp;
33356ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
33369ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
33376ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
33386ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
33399ddff745SMatthew G. Knepley       orntNew[1] = 0;
33409ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
33416ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
33426ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33446ce3c06aSMatthew G. Knepley #if 1
33456ce3c06aSMatthew 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);
33466ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33476ce3c06aSMatthew 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);
33486ce3c06aSMatthew G. Knepley       }
33496ce3c06aSMatthew G. Knepley #endif
33506ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
33516ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
33526ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33536ce3c06aSMatthew G. Knepley #if 1
33546ce3c06aSMatthew 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);
33556ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
33566ce3c06aSMatthew 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);
33576ce3c06aSMatthew G. Knepley       }
33586ce3c06aSMatthew G. Knepley #endif
33596ce3c06aSMatthew G. Knepley       ++newp;
33606ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
33619ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
33626ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
33639ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
33646ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
33656ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
33669ddff745SMatthew G. Knepley       orntNew[2] = -2;
33676ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33686ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33696ce3c06aSMatthew G. Knepley #if 1
33706ce3c06aSMatthew 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);
33716ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33726ce3c06aSMatthew 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);
33736ce3c06aSMatthew G. Knepley       }
33746ce3c06aSMatthew G. Knepley #endif
33756ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
33766ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
33776ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33786ce3c06aSMatthew G. Knepley #if 1
33796ce3c06aSMatthew 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);
33806ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
33816ce3c06aSMatthew 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);
33826ce3c06aSMatthew G. Knepley       }
33836ce3c06aSMatthew G. Knepley #endif
33846ce3c06aSMatthew G. Knepley       ++newp;
33856ce3c06aSMatthew G. Knepley     }
33866ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
33876ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
33886ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
33896ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
33906ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
33916ce3c06aSMatthew G. Knepley 
33926ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
33936ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
33946ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
33956ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
33966ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
33976ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
33986ce3c06aSMatthew G. Knepley 
33996ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
34006ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
34016ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
34026ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
34036ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
34046ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
34056ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
34066ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
34076ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34086ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
34096ce3c06aSMatthew G. Knepley #if 1
34106ce3c06aSMatthew 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);
34116ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34126ce3c06aSMatthew 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);
34136ce3c06aSMatthew G. Knepley         }
34146ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
34156ce3c06aSMatthew 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);
34166ce3c06aSMatthew G. Knepley         }
34176ce3c06aSMatthew G. Knepley #endif
34186ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
3419d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
3420084f9c62SMatthew G. Knepley           PetscInt        o, of;
34216ce3c06aSMatthew G. Knepley 
34226ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
34236ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
3424084f9c62SMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
34256ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
34266ce3c06aSMatthew 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]);
3427d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
3428084f9c62SMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
3429084f9c62SMatthew 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;
34306ce3c06aSMatthew G. Knepley         }
34316ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
34326ce3c06aSMatthew G. Knepley #if 1
34336ce3c06aSMatthew 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);
34346ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
34356ce3c06aSMatthew 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);
34366ce3c06aSMatthew G. Knepley         }
34376ce3c06aSMatthew G. Knepley #endif
34386ce3c06aSMatthew G. Knepley       }
34396ce3c06aSMatthew G. Knepley     }
34406ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
34416ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
34426ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
34436ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
34446ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
34456ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
34466ce3c06aSMatthew G. Knepley 
34476ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
34486ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
34496ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3450b598a9d5SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
34516ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
3452b598a9d5SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
34536ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
3454b598a9d5SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
34556ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
3456b598a9d5SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r]       - fMax);
34576ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
34586ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
34596ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
34606ce3c06aSMatthew G. Knepley #if 1
34616ce3c06aSMatthew 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);
34626ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34636ce3c06aSMatthew 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);
34646ce3c06aSMatthew G. Knepley         }
34656ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
34666ce3c06aSMatthew 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);
34676ce3c06aSMatthew G. Knepley         }
34686ce3c06aSMatthew G. Knepley #endif
34696ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
34706ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
34716ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
34726ce3c06aSMatthew G. Knepley #if 1
34736ce3c06aSMatthew 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);
34746ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34756ce3c06aSMatthew 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);
34766ce3c06aSMatthew G. Knepley         }
34776ce3c06aSMatthew G. Knepley #endif
34786ce3c06aSMatthew G. Knepley       }
34796ce3c06aSMatthew G. Knepley     }
34806ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
34816ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
34826ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
34836ce3c06aSMatthew G. Knepley 
34846ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
34856ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
34866ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
34876ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
34886ce3c06aSMatthew G. Knepley 
34896ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
34906ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
34916ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
34926ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
34936ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34946ce3c06aSMatthew G. Knepley #if 1
34956ce3c06aSMatthew 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);
34966ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34976ce3c06aSMatthew 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);
34986ce3c06aSMatthew G. Knepley         }
34996ce3c06aSMatthew G. Knepley #endif
35006ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
35016ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
35026ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
35036ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
35046ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
35056ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
35066ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
35076ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
35086ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
35096ce3c06aSMatthew G. Knepley           } else {
35106ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
35116ce3c06aSMatthew G. Knepley           }
35126ce3c06aSMatthew G. Knepley         }
35136ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35146ce3c06aSMatthew G. Knepley #if 1
35156ce3c06aSMatthew 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);
35166ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
35176ce3c06aSMatthew 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);
35186ce3c06aSMatthew G. Knepley         }
35196ce3c06aSMatthew G. Knepley #endif
35206ce3c06aSMatthew G. Knepley       }
35216ce3c06aSMatthew G. Knepley     }
35226ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
35236ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
35246ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
35256ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
35266ce3c06aSMatthew G. Knepley 
35276ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
35286ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
35296ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
35306ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
35316ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
35326ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
35336ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
35346ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
35356ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
35366ce3c06aSMatthew G. Knepley 
35376ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
35386ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
35396ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
35406ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35416ce3c06aSMatthew G. Knepley #if 1
35426ce3c06aSMatthew 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);
35436ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35446ce3c06aSMatthew 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);
35456ce3c06aSMatthew G. Knepley         }
35466ce3c06aSMatthew G. Knepley #endif
35476ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
35486ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
35496ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
35506ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
35516ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
35526ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
35536ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
35546ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
35556ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
35569ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
35576ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
35586ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
35596ce3c06aSMatthew G. Knepley             } else {
35606ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
35616ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
35626ce3c06aSMatthew G. Knepley             }
35636ce3c06aSMatthew G. Knepley           } else {
3564b598a9d5SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
35656ce3c06aSMatthew G. Knepley           }
35666ce3c06aSMatthew G. Knepley         }
35676ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35686ce3c06aSMatthew G. Knepley #if 1
35696ce3c06aSMatthew 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);
35706ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
35716ce3c06aSMatthew 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);
35726ce3c06aSMatthew G. Knepley         }
35736ce3c06aSMatthew G. Knepley #endif
35746ce3c06aSMatthew G. Knepley       }
35756ce3c06aSMatthew G. Knepley     }
35766ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
35776ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
35786ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
35796ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
35806ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
35816ce3c06aSMatthew G. Knepley 
35826ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
35836ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
35846ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
35856ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
35866ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
35876ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
35886ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
35896ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
35906ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35916ce3c06aSMatthew G. Knepley #if 1
35926ce3c06aSMatthew 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);
35936ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
35946ce3c06aSMatthew 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);
35956ce3c06aSMatthew G. Knepley       }
35966ce3c06aSMatthew G. Knepley #endif
35976ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
35986ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
35996ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
36006ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
36016ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36026ce3c06aSMatthew G. Knepley #if 1
36036ce3c06aSMatthew 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);
36046ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
36056ce3c06aSMatthew 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);
36066ce3c06aSMatthew G. Knepley       }
36076ce3c06aSMatthew G. Knepley #endif
36086ce3c06aSMatthew G. Knepley     }
36096ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
36106ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
36116ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
36126ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
36136ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
36146ce3c06aSMatthew G. Knepley 
36156ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
36166ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
36176ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
36186ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
36196ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
36206ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36216ce3c06aSMatthew G. Knepley #if 1
36226ce3c06aSMatthew 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);
36236ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36246ce3c06aSMatthew 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);
36256ce3c06aSMatthew G. Knepley       }
36266ce3c06aSMatthew G. Knepley #endif
36276ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36286ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
36296ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
36306ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
36316ce3c06aSMatthew 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]);
36326ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
36336ce3c06aSMatthew G. Knepley       }
36346ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36356ce3c06aSMatthew G. Knepley #if 1
36366ce3c06aSMatthew 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);
36376ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
36386ce3c06aSMatthew 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);
36396ce3c06aSMatthew G. Knepley       }
36406ce3c06aSMatthew G. Knepley #endif
36416ce3c06aSMatthew G. Knepley     }
36426ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
36436ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
36446ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
3645623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
36466ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
36476ce3c06aSMatthew G. Knepley 
36486ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
36496ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
36506ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
36516ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
36526ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
36536ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36546ce3c06aSMatthew G. Knepley #if 1
36556ce3c06aSMatthew 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);
36566ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36576ce3c06aSMatthew 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);
36586ce3c06aSMatthew G. Knepley       }
36596ce3c06aSMatthew G. Knepley #endif
36606ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
36616ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
36626ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36636ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
36646ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
3665623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
36666ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
36676ce3c06aSMatthew 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]);
3668b598a9d5SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
3669b598a9d5SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
36706ce3c06aSMatthew G. Knepley       }
36716ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36726ce3c06aSMatthew G. Knepley #if 1
36736ce3c06aSMatthew 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);
36746ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
36756ce3c06aSMatthew 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);
36766ce3c06aSMatthew G. Knepley       }
36776ce3c06aSMatthew G. Knepley #endif
36786ce3c06aSMatthew G. Knepley     }
36796ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
36806ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
36816ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
36826ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
36836ce3c06aSMatthew G. Knepley       PetscInt        size, s;
36846ce3c06aSMatthew G. Knepley 
36856ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
36866ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
36876ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
36886ce3c06aSMatthew G. Knepley         PetscInt r = 0;
36896ce3c06aSMatthew G. Knepley 
36906ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36916ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
36926ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
36936ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
36946ce3c06aSMatthew G. Knepley       }
36956ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36966ce3c06aSMatthew G. Knepley #if 1
36976ce3c06aSMatthew 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);
36986ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
36996ce3c06aSMatthew 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);
37006ce3c06aSMatthew G. Knepley       }
37016ce3c06aSMatthew G. Knepley #endif
37026ce3c06aSMatthew G. Knepley     }
37036ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
37046ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
37056ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
37066ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
37076ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
37086ce3c06aSMatthew G. Knepley 
37096ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
37106ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
37116ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
37126ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
37136ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
37146ce3c06aSMatthew G. Knepley         PetscInt r = 0;
37156ce3c06aSMatthew G. Knepley 
37166ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
37176ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
37186ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
37196ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
37206ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
37216ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
37226ce3c06aSMatthew G. Knepley           faceSize += 2;
37236ce3c06aSMatthew G. Knepley         } else {
37246ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
37256ce3c06aSMatthew G. Knepley           ++faceSize;
37266ce3c06aSMatthew G. Knepley         }
37276ce3c06aSMatthew G. Knepley       }
37286ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
37296ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
37306ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
37316ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
37326ce3c06aSMatthew G. Knepley 
37336ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
37346ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
37356ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
37366ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
37376ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
37386ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
37396ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
37406ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
37416ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
37426ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
37436ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
37446ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
37456ce3c06aSMatthew G. Knepley         }
37466ce3c06aSMatthew G. Knepley       }
37476ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
37486ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37496ce3c06aSMatthew G. Knepley #if 1
37506ce3c06aSMatthew 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);
37516ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
37526ce3c06aSMatthew 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);
37536ce3c06aSMatthew G. Knepley       }
37546ce3c06aSMatthew G. Knepley #endif
37556ce3c06aSMatthew G. Knepley     }
37566ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
37576ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
37586ce3c06aSMatthew G. Knepley     break;
3759*9b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
37602eabf88fSMatthew G. Knepley     /*
37612eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
37622eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
37632eabf88fSMatthew G. Knepley      |         |         |       |         |         |
37642eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
37652eabf88fSMatthew G. Knepley      |         |         |       |         |         |
37662eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
37672eabf88fSMatthew G. Knepley      |         |         |       |         |         |
37682eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
37692eabf88fSMatthew G. Knepley      |         |         |       |         |         |
37702eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
37712eabf88fSMatthew G. Knepley      */
37722eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
37732eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
37742eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
37752eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
37762eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
37772eabf88fSMatthew G. Knepley 
37782eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
37792eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
37802eabf88fSMatthew G. Knepley       /* A hex */
3781e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
37822eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
37832eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
37842eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3785e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
37862eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
37872eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
37882eabf88fSMatthew G. Knepley       orntNew[3] = 0;
37892eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
37902eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3791e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
37922eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
37932eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
37942eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
37952eabf88fSMatthew G. Knepley #if 1
37962eabf88fSMatthew 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);
37972eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
37982eabf88fSMatthew 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);
37992eabf88fSMatthew G. Knepley       }
38002eabf88fSMatthew G. Knepley #endif
38012eabf88fSMatthew G. Knepley       /* B hex */
3802e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
38032eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
38042eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
38052eabf88fSMatthew G. Knepley       orntNew[1] = 0;
38062eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
3807a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3808e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
38092eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
38102eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
38112eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3812e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
38132eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
38142eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
38152eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
38162eabf88fSMatthew G. Knepley #if 1
38172eabf88fSMatthew 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);
38182eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38192eabf88fSMatthew 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);
38202eabf88fSMatthew G. Knepley       }
38212eabf88fSMatthew G. Knepley #endif
38222eabf88fSMatthew G. Knepley       /* C hex */
3823e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
38242eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
38252eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
38262eabf88fSMatthew G. Knepley       orntNew[1] = 0;
38272eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3828a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3829e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
38302eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3831e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
38322eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
38332eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
3834a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
38352eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
38362eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
38372eabf88fSMatthew G. Knepley #if 1
38382eabf88fSMatthew 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);
38392eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38402eabf88fSMatthew 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);
38412eabf88fSMatthew G. Knepley       }
38422eabf88fSMatthew G. Knepley #endif
38432eabf88fSMatthew G. Knepley       /* D hex */
3844e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
38452eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
38462eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
38472eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3848e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
38492eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
38502eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3851a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3852e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
38532eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
38542eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
3855a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
38562eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
38572eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
38582eabf88fSMatthew G. Knepley #if 1
38592eabf88fSMatthew 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);
38602eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38612eabf88fSMatthew 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);
38622eabf88fSMatthew G. Knepley       }
38632eabf88fSMatthew G. Knepley #endif
38642eabf88fSMatthew G. Knepley       /* E hex */
38652eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
3866a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3867e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
38682eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3869e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
38702eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
38712eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
38722eabf88fSMatthew G. Knepley       orntNew[3] = 0;
38732eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3874a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
3875e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
38762eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3877b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
3878b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
38792eabf88fSMatthew G. Knepley #if 1
3880b164cbf2SMatthew 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);
38812eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38822eabf88fSMatthew 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);
38832eabf88fSMatthew G. Knepley       }
38842eabf88fSMatthew G. Knepley #endif
38852eabf88fSMatthew G. Knepley       /* F hex */
38862eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
3887a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3888e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
38892eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3890e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
38912eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
38922eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3893a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
3894e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
38952eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
38962eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3897a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
3898b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
3899b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
39002eabf88fSMatthew G. Knepley #if 1
3901b164cbf2SMatthew 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);
39022eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39032eabf88fSMatthew 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);
39042eabf88fSMatthew G. Knepley       }
39052eabf88fSMatthew G. Knepley #endif
39062eabf88fSMatthew G. Knepley       /* G hex */
39072eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
3908a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3909e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
39102eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
39112eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3912a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
3913e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
39142eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3915e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
39162eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
39172eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3918a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
3919b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
3920b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
39212eabf88fSMatthew G. Knepley #if 1
3922b164cbf2SMatthew 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);
39232eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39242eabf88fSMatthew 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);
39252eabf88fSMatthew G. Knepley       }
39262eabf88fSMatthew G. Knepley #endif
39272eabf88fSMatthew G. Knepley       /* H hex */
39282eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
3929a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3930e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
39312eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
39322eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
3933a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3934e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
39352eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
39362eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3937a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
3938e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
39392eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3940b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
3941b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
39422eabf88fSMatthew G. Knepley #if 1
3943b164cbf2SMatthew 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);
39442eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39452eabf88fSMatthew 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);
39462eabf88fSMatthew G. Knepley       }
39472eabf88fSMatthew G. Knepley #endif
39482eabf88fSMatthew G. Knepley     }
39492eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
39502eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3951854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
39522eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
39532eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
3954aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
39552eabf88fSMatthew 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};
39562eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
39572eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
3958aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
39592eabf88fSMatthew G. Knepley 
39602eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
3961aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
3962a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
3963a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
3964a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
3965a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
3966a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
3967a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
3968a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
3969a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
39702eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
3971aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
39722eabf88fSMatthew G. Knepley #if 1
39732eabf88fSMatthew 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);
39742eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
39752eabf88fSMatthew 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);
39762eabf88fSMatthew G. Knepley         }
39772eabf88fSMatthew G. Knepley #endif
39782eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
39792eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
39802eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
39812eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
39822eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
39832eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
39842eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
39852eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
39862eabf88fSMatthew G. Knepley           }
3987a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
39882eabf88fSMatthew G. Knepley         }
39892eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
39902eabf88fSMatthew G. Knepley #if 1
39912eabf88fSMatthew 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);
39922eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
39932eabf88fSMatthew 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);
39942eabf88fSMatthew G. Knepley         }
39952eabf88fSMatthew G. Knepley #endif
39962eabf88fSMatthew G. Knepley       }
39972eabf88fSMatthew G. Knepley     }
39982eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
39992eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
40002eabf88fSMatthew 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};
4001afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
4002afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
40032eabf88fSMatthew G. Knepley 
40042eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4005afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4006afb2665bSMatthew G. Knepley       /* A-D face */
4007afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
4008a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
4009a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4010a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4011afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4012a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4013a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4014a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
4015afb2665bSMatthew G. Knepley       orntNew[3] = -2;
40162eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4017afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
40182eabf88fSMatthew G. Knepley #if 1
40192eabf88fSMatthew 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);
40202eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
40212eabf88fSMatthew 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);
40222eabf88fSMatthew G. Knepley       }
40232eabf88fSMatthew G. Knepley #endif
4024afb2665bSMatthew G. Knepley       /* C-D face */
4025afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
4026a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
4027a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4028a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4029afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4030a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4031a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4032a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
4033afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4034afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4035afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4036afb2665bSMatthew G. Knepley #if 1
4037afb2665bSMatthew 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);
4038afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4039afb2665bSMatthew 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);
4040afb2665bSMatthew G. Knepley       }
4041afb2665bSMatthew G. Knepley #endif
4042afb2665bSMatthew G. Knepley       /* B-C face */
4043afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
4044afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
4045afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4046afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
4047afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4048afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4049afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4050afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4051afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4052afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4053afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4054afb2665bSMatthew G. Knepley #if 1
4055afb2665bSMatthew 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);
4056afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4057afb2665bSMatthew 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);
4058afb2665bSMatthew G. Knepley       }
4059afb2665bSMatthew G. Knepley #endif
4060afb2665bSMatthew G. Knepley       /* A-B face */
4061afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
4062afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
4063afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4064afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
4065afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4066afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4067afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4068afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4069afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4070afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4071afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4072afb2665bSMatthew G. Knepley #if 1
4073afb2665bSMatthew 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);
4074afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4075afb2665bSMatthew 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);
4076afb2665bSMatthew G. Knepley       }
4077afb2665bSMatthew G. Knepley #endif
4078afb2665bSMatthew G. Knepley       /* E-F face */
4079afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
4080a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4081afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4082a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
4083a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4084a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
4085afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4086a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4087a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4088afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4089afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4090afb2665bSMatthew G. Knepley #if 1
4091afb2665bSMatthew 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);
4092afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4093afb2665bSMatthew 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);
4094afb2665bSMatthew G. Knepley       }
4095afb2665bSMatthew G. Knepley #endif
4096afb2665bSMatthew G. Knepley       /* F-G face */
4097afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
4098a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4099afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4100a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
4101a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4102a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
4103afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4104a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4105a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4106afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4107afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4108afb2665bSMatthew G. Knepley #if 1
4109afb2665bSMatthew 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);
4110afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4111afb2665bSMatthew 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);
4112afb2665bSMatthew G. Knepley       }
4113afb2665bSMatthew G. Knepley #endif
4114afb2665bSMatthew G. Knepley       /* G-H face */
4115afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
4116afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
4117afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4118afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
4119afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4120afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4121afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4122afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4123afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4124afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4125afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4126afb2665bSMatthew G. Knepley #if 1
4127afb2665bSMatthew 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);
4128afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4129afb2665bSMatthew 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);
4130afb2665bSMatthew G. Knepley       }
4131afb2665bSMatthew G. Knepley #endif
4132afb2665bSMatthew G. Knepley       /* E-H face */
4133afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
4134a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4135afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4136a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
4137a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4138a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
4139afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4140a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4141a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4142afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4143afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4144afb2665bSMatthew G. Knepley #if 1
4145afb2665bSMatthew 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);
4146afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4147afb2665bSMatthew 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);
4148afb2665bSMatthew G. Knepley       }
4149afb2665bSMatthew G. Knepley #endif
4150afb2665bSMatthew G. Knepley       /* A-E face */
4151afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
4152a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
4153a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4154a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4155afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4156a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4157a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4158a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
4159afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4160afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4161afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4162afb2665bSMatthew G. Knepley #if 1
4163afb2665bSMatthew 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);
4164afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4165afb2665bSMatthew 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);
4166afb2665bSMatthew G. Knepley       }
4167afb2665bSMatthew G. Knepley #endif
4168afb2665bSMatthew G. Knepley       /* D-F face */
4169afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
4170afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
4171afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4172afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
4173afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4174afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4175afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4176afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4177afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4178afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4179afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4180afb2665bSMatthew G. Knepley #if 1
4181afb2665bSMatthew 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);
4182afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4183afb2665bSMatthew 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);
4184afb2665bSMatthew G. Knepley       }
4185afb2665bSMatthew G. Knepley #endif
4186afb2665bSMatthew G. Knepley       /* C-G face */
4187afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
4188a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4189afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4190a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
4191a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4192a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
4193afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4194a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4195a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4196afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4197afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4198afb2665bSMatthew G. Knepley #if 1
4199afb2665bSMatthew 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);
4200afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4201afb2665bSMatthew 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);
4202afb2665bSMatthew G. Knepley       }
4203afb2665bSMatthew G. Knepley #endif
4204afb2665bSMatthew G. Knepley       /* B-H face */
4205afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
4206a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4207a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4208a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4209a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4210a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
4211a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4212a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
4213a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4214afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4215afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4216afb2665bSMatthew G. Knepley #if 1
4217afb2665bSMatthew 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);
4218afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4219afb2665bSMatthew 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);
4220afb2665bSMatthew G. Knepley       }
4221afb2665bSMatthew G. Knepley #endif
4222afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
4223afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
42242eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
42252eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
42262eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
42272eabf88fSMatthew G. Knepley #if 1
42282eabf88fSMatthew 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);
42292eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
42302eabf88fSMatthew 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);
42312eabf88fSMatthew G. Knepley         }
42322eabf88fSMatthew G. Knepley #endif
42332eabf88fSMatthew G. Knepley       }
42342eabf88fSMatthew G. Knepley     }
42352eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
42362eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
42372eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
42382eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
42392eabf88fSMatthew G. Knepley 
42402eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
42412eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
42422eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
42432eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
42442eabf88fSMatthew G. Knepley 
42452eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
42462eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
42472eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
42482eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
42492eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
42502eabf88fSMatthew G. Knepley #if 1
42512eabf88fSMatthew 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);
42522eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
42532eabf88fSMatthew 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);
42542eabf88fSMatthew G. Knepley         }
42552eabf88fSMatthew G. Knepley #endif
42562eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
42572eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
42582eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
42592eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
42602eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
42612eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
42622eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
42632eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
42642eabf88fSMatthew G. Knepley           }
42652eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
42662eabf88fSMatthew G. Knepley         }
42672eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
42682eabf88fSMatthew G. Knepley #if 1
42692eabf88fSMatthew 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);
42702eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
42712eabf88fSMatthew 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);
42722eabf88fSMatthew G. Knepley         }
42732eabf88fSMatthew G. Knepley #endif
42742eabf88fSMatthew G. Knepley       }
42752eabf88fSMatthew G. Knepley     }
42762eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
42772eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
42786b852384SMatthew 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};
42792eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
42806b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
42812eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
42822eabf88fSMatthew G. Knepley 
42832eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
42842eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
42852eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
42862eabf88fSMatthew G. Knepley 
42872eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
42882eabf88fSMatthew G. Knepley         coneNew[1] = newv;
42892eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);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 < 2; ++p) {
42932eabf88fSMatthew 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);
42942eabf88fSMatthew G. Knepley         }
42952eabf88fSMatthew G. Knepley #endif
42962eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
42972eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
42982eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
42992eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
43002eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
43016b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
43026b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
43036b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
43042eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
4305a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
43062eabf88fSMatthew G. Knepley         }
43072eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
43082eabf88fSMatthew G. Knepley #if 1
43092eabf88fSMatthew 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);
43102eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
43112eabf88fSMatthew 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);
43122eabf88fSMatthew G. Knepley         }
43132eabf88fSMatthew G. Knepley #endif
43142eabf88fSMatthew G. Knepley       }
43152eabf88fSMatthew G. Knepley     }
43162eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
43172eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
43182eabf88fSMatthew 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};
43192eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
43202eabf88fSMatthew G. Knepley       const PetscInt *cone;
43212eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
43222eabf88fSMatthew G. Knepley 
43232eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
43242eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
43252eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
43262eabf88fSMatthew G. Knepley 
43272eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
43282eabf88fSMatthew G. Knepley         coneNew[1] = newv;
43292eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);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; ++p) {
43332eabf88fSMatthew 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);
43342eabf88fSMatthew G. Knepley         }
43352eabf88fSMatthew G. Knepley #endif
43362eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
43372eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
43382eabf88fSMatthew G. Knepley #if 1
43392eabf88fSMatthew 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);
43402eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
43412eabf88fSMatthew 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);
43422eabf88fSMatthew G. Knepley         }
43432eabf88fSMatthew G. Knepley #endif
43442eabf88fSMatthew G. Knepley       }
43452eabf88fSMatthew G. Knepley     }
43462eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
43472eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
43482eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
43492eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
43502eabf88fSMatthew G. Knepley       PetscInt        size, s;
43512eabf88fSMatthew G. Knepley 
43522eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
43532eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
43542eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
43552eabf88fSMatthew G. Knepley         PetscInt r = 0;
43562eabf88fSMatthew G. Knepley 
43572eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
43582eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
43592eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
43602eabf88fSMatthew G. Knepley       }
43612eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
43622eabf88fSMatthew G. Knepley #if 1
43632eabf88fSMatthew 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);
43642eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
43652eabf88fSMatthew 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);
43662eabf88fSMatthew G. Knepley       }
43672eabf88fSMatthew G. Knepley #endif
43682eabf88fSMatthew G. Knepley     }
43692eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
43702eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
43712eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
43722eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
43732eabf88fSMatthew G. Knepley       PetscInt        size, s;
43742eabf88fSMatthew G. Knepley 
43752eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
43762eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
43772eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
43782eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
43792eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
43802eabf88fSMatthew G. Knepley         PetscInt r;
43812eabf88fSMatthew G. Knepley 
43822eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4383a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
43842eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
43852eabf88fSMatthew G. Knepley       }
43862eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
43872eabf88fSMatthew G. Knepley #if 1
43882eabf88fSMatthew 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);
43892eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
43902eabf88fSMatthew 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);
43912eabf88fSMatthew G. Knepley       }
43922eabf88fSMatthew G. Knepley #endif
43932eabf88fSMatthew G. Knepley     }
43942eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
43952eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
43962eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
43972eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
43982eabf88fSMatthew G. Knepley       PetscInt        size, s;
43992eabf88fSMatthew G. Knepley 
44002eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
44012eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
44020793999aSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 +  (f - fStart)*4 + r;
44032eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
44042eabf88fSMatthew G. Knepley         PetscInt r;
44052eabf88fSMatthew G. Knepley 
44062eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
44072eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
44082eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
44092eabf88fSMatthew G. Knepley       }
44102eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
44112eabf88fSMatthew G. Knepley #if 1
44122eabf88fSMatthew 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);
44132eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
44142eabf88fSMatthew 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);
44152eabf88fSMatthew G. Knepley       }
44162eabf88fSMatthew G. Knepley #endif
44172eabf88fSMatthew G. Knepley     }
44182eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
44192eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
44202eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
44212eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
44222eabf88fSMatthew G. Knepley 
44232eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
44242eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
44252eabf88fSMatthew G. Knepley       }
44262eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
44272eabf88fSMatthew G. Knepley     }
4428da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
44292eabf88fSMatthew G. Knepley     break;
4430*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
443127fcede3SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
443227fcede3SMatthew G. Knepley     /*
443327fcede3SMatthew G. Knepley      Bottom (viewed from top)    Top
443427fcede3SMatthew G. Knepley      1---------2---------2       7---------2---------6
443527fcede3SMatthew G. Knepley      |         |         |       |         |         |
443627fcede3SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
443727fcede3SMatthew G. Knepley      |         |         |       |         |         |
443827fcede3SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
443927fcede3SMatthew G. Knepley      |         |         |       |         |         |
444027fcede3SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
444127fcede3SMatthew G. Knepley      |         |         |       |         |         |
444227fcede3SMatthew G. Knepley      0---------0---------3       4---------0---------5
444327fcede3SMatthew G. Knepley      */
444427fcede3SMatthew G. Knepley     /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
444527fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
444627fcede3SMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
444727fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
444827fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
444927fcede3SMatthew G. Knepley 
445027fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
445127fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
445227fcede3SMatthew G. Knepley       /* A hex */
445327fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
445427fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
445527fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
445627fcede3SMatthew G. Knepley       orntNew[1] = 0;
445727fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
445827fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
445927fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
446027fcede3SMatthew G. Knepley       orntNew[3] = 0;
446127fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
446227fcede3SMatthew G. Knepley       orntNew[4] = 0;
446327fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
446427fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
446527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
446627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
446727fcede3SMatthew G. Knepley #if 1
446827fcede3SMatthew 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);
446927fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
447027fcede3SMatthew 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);
447127fcede3SMatthew G. Knepley       }
447227fcede3SMatthew G. Knepley #endif
447327fcede3SMatthew G. Knepley       /* B hex */
447427fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
447527fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
447627fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
447727fcede3SMatthew G. Knepley       orntNew[1] = 0;
447827fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
447927fcede3SMatthew G. Knepley       orntNew[2] = -1;
448027fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
448127fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
448227fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
448327fcede3SMatthew G. Knepley       orntNew[4] = 0;
448427fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
448527fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
448627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
448727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
448827fcede3SMatthew G. Knepley #if 1
448927fcede3SMatthew 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);
449027fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
449127fcede3SMatthew 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);
449227fcede3SMatthew G. Knepley       }
449327fcede3SMatthew G. Knepley #endif
449427fcede3SMatthew G. Knepley       /* C hex */
449527fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
449627fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
449727fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
449827fcede3SMatthew G. Knepley       orntNew[1] = 0;
449927fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
450027fcede3SMatthew G. Knepley       orntNew[2] = -1;
450127fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
450227fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
450327fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
450427fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
450527fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
450627fcede3SMatthew G. Knepley       orntNew[5] = -4;
450727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
450827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
450927fcede3SMatthew G. Knepley #if 1
451027fcede3SMatthew 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);
451127fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
451227fcede3SMatthew 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);
451327fcede3SMatthew G. Knepley       }
451427fcede3SMatthew G. Knepley #endif
451527fcede3SMatthew G. Knepley       /* D hex */
451627fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
451727fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
451827fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
451927fcede3SMatthew G. Knepley       orntNew[1] = 0;
452027fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
452127fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
452227fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
452327fcede3SMatthew G. Knepley       orntNew[3] = 0;
452427fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
452527fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
452627fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
452727fcede3SMatthew G. Knepley       orntNew[5] = -4;
452827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
452927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
453027fcede3SMatthew G. Knepley #if 1
453127fcede3SMatthew 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);
453227fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
453327fcede3SMatthew 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);
453427fcede3SMatthew G. Knepley       }
453527fcede3SMatthew G. Knepley #endif
453627fcede3SMatthew G. Knepley       /* E hex */
453727fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
453827fcede3SMatthew G. Knepley       orntNew[0] = -4;
453927fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
454027fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
454127fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
454227fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
454327fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
454427fcede3SMatthew G. Knepley       orntNew[3] = 0;
454527fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
454627fcede3SMatthew G. Knepley       orntNew[4] = -1;
454727fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
454827fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
454927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
455027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
455127fcede3SMatthew G. Knepley #if 1
455227fcede3SMatthew 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);
455327fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
455427fcede3SMatthew 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);
455527fcede3SMatthew G. Knepley       }
455627fcede3SMatthew G. Knepley #endif
455727fcede3SMatthew G. Knepley       /* F hex */
455827fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
455927fcede3SMatthew G. Knepley       orntNew[0] = -4;
456027fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
456127fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
456227fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
456327fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
456427fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
456527fcede3SMatthew G. Knepley       orntNew[3] = -1;
456627fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
456727fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
456827fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
456927fcede3SMatthew G. Knepley       orntNew[5] = 1;
457027fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
457127fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
457227fcede3SMatthew G. Knepley #if 1
457327fcede3SMatthew 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);
457427fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
457527fcede3SMatthew 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);
457627fcede3SMatthew G. Knepley       }
457727fcede3SMatthew G. Knepley #endif
457827fcede3SMatthew G. Knepley       /* G hex */
457927fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
458027fcede3SMatthew G. Knepley       orntNew[0] = -4;
458127fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
458227fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
458327fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
458427fcede3SMatthew G. Knepley       orntNew[2] = 0;
458527fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
458627fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
458727fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
458827fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
458927fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
459027fcede3SMatthew G. Knepley       orntNew[5] = -3;
459127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
459227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
459327fcede3SMatthew G. Knepley #if 1
459427fcede3SMatthew 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);
459527fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
459627fcede3SMatthew 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);
459727fcede3SMatthew G. Knepley       }
459827fcede3SMatthew G. Knepley #endif
459927fcede3SMatthew G. Knepley       /* H hex */
460027fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
460127fcede3SMatthew G. Knepley       orntNew[0] = -4;
460227fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
460327fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
460427fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
460527fcede3SMatthew G. Knepley       orntNew[2] = -1;
460627fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
460727fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
460827fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
460927fcede3SMatthew G. Knepley       orntNew[4] = 3;
461027fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
461127fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
461227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
461327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
461427fcede3SMatthew G. Knepley #if 1
461527fcede3SMatthew 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);
461627fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
461727fcede3SMatthew 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);
461827fcede3SMatthew G. Knepley       }
461927fcede3SMatthew G. Knepley #endif
462027fcede3SMatthew G. Knepley     }
462127fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces: Front, Back, Sides */
462227fcede3SMatthew G. Knepley     /*
462327fcede3SMatthew G. Knepley      3---------2---------2
462427fcede3SMatthew G. Knepley      |         |         |
462527fcede3SMatthew G. Knepley      |    D    2    C    |
462627fcede3SMatthew G. Knepley      |         |         |
462727fcede3SMatthew G. Knepley      3----3----0----1----1
462827fcede3SMatthew G. Knepley      |         |         |
462927fcede3SMatthew G. Knepley      |    A    0    B    |
463027fcede3SMatthew G. Knepley      |         |         |
463127fcede3SMatthew G. Knepley      0---------0---------1
463227fcede3SMatthew G. Knepley      */
463327fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
463427fcede3SMatthew G. Knepley       const PetscInt  newp = (cMax - cStart)*8 + (c - cMax)*4;
463527fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
4636d273725eSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6], o, of, i;
463727fcede3SMatthew G. Knepley 
463827fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
463927fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
464027fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
4641d273725eSMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
464227fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
464327fcede3SMatthew G. Knepley         PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
464427fcede3SMatthew G. Knepley         PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
4645d273725eSMatthew G. Knepley         PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4);
464627fcede3SMatthew 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]);
464727fcede3SMatthew G. Knepley         coneNew[0]         = fStartNew + (cone[0] - fStart)*4 + subfA;
464827fcede3SMatthew G. Knepley         orntNew[0]         = ornt[0];
464927fcede3SMatthew G. Knepley         coneNew[1]         = fStartNew + (cone[1] - fStart)*4 + subfA;
465027fcede3SMatthew G. Knepley         orntNew[1]         = ornt[0];
4651d273725eSMatthew G. Knepley         of = fornt[edgeA] < 0 ? -1 : 1;
4652d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], r) + 2;
4653d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0);
4654d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeA];
4655d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2;
4656d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeA;
4657d273725eSMatthew G. Knepley         orntNew[i] = 0;
4658d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2;
4659d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeB;
4660d273725eSMatthew G. Knepley         orntNew[i] = -2;
4661d273725eSMatthew G. Knepley         of = fornt[edgeB] < 0 ? -1 : 1;
4662d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2;
4663d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1);
4664d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeB];
466527fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
466627fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
466727fcede3SMatthew G. Knepley #if 1
466827fcede3SMatthew 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);
466927fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
467027fcede3SMatthew 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);
467127fcede3SMatthew G. Knepley         }
467227fcede3SMatthew G. Knepley         for (p = 2; p < 6; ++p) {
467327fcede3SMatthew 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);
467427fcede3SMatthew G. Knepley         }
467527fcede3SMatthew G. Knepley #endif
467627fcede3SMatthew G. Knepley       }
467727fcede3SMatthew G. Knepley     }
467827fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
467927fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4680854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
468127fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
468227fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
468327fcede3SMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
468427fcede3SMatthew 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};
468527fcede3SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
468627fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
468727fcede3SMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
468827fcede3SMatthew G. Knepley 
468927fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
469027fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
469127fcede3SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
469227fcede3SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
469327fcede3SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
469427fcede3SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
469527fcede3SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
469627fcede3SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
469727fcede3SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
469827fcede3SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
469927fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
470027fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
470127fcede3SMatthew G. Knepley #if 1
470227fcede3SMatthew 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);
470327fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
470427fcede3SMatthew 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);
470527fcede3SMatthew G. Knepley         }
470627fcede3SMatthew G. Knepley #endif
470727fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
470827fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
470927fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
471027fcede3SMatthew G. Knepley           PetscInt subf;
471127fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
471227fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
471327fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
471427fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
471527fcede3SMatthew G. Knepley             if (cone[c] == f) break;
471627fcede3SMatthew G. Knepley           }
471727fcede3SMatthew G. Knepley           subf = GetQuadSubfaceInverse_Static(ornt[c], r);
471827fcede3SMatthew G. Knepley           if (support[s] < cMax) {
471927fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
472027fcede3SMatthew G. Knepley           } else {
472127fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax       - cStart)*8 + (support[s] - cMax)*4 + subf;
472227fcede3SMatthew G. Knepley           }
472327fcede3SMatthew G. Knepley         }
472427fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
472527fcede3SMatthew G. Knepley #if 1
472627fcede3SMatthew 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);
472727fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
472827fcede3SMatthew 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);
472927fcede3SMatthew G. Knepley         }
473027fcede3SMatthew G. Knepley #endif
473127fcede3SMatthew G. Knepley       }
473227fcede3SMatthew G. Knepley     }
4733d273725eSMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
473427fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
473527fcede3SMatthew 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};
473627fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
473727fcede3SMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
473827fcede3SMatthew G. Knepley 
473927fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
474027fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
474127fcede3SMatthew G. Knepley       /* A-D face */
474227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
474327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
474427fcede3SMatthew G. Knepley       orntNew[0] = 0;
474527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
474627fcede3SMatthew G. Knepley       orntNew[1] = 0;
474727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
474827fcede3SMatthew G. Knepley       orntNew[2] = -2;
474927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
475027fcede3SMatthew G. Knepley       orntNew[3] = -2;
475127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
475227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
475327fcede3SMatthew G. Knepley #if 1
475427fcede3SMatthew 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);
475527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
475627fcede3SMatthew 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);
475727fcede3SMatthew G. Knepley       }
475827fcede3SMatthew G. Knepley #endif
475927fcede3SMatthew G. Knepley       /* C-D face */
476027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
476127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
476227fcede3SMatthew G. Knepley       orntNew[0] = 0;
476327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
476427fcede3SMatthew G. Knepley       orntNew[1] = 0;
476527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
476627fcede3SMatthew G. Knepley       orntNew[2] = -2;
476727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
476827fcede3SMatthew G. Knepley       orntNew[3] = -2;
476927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
477027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
477127fcede3SMatthew G. Knepley #if 1
477227fcede3SMatthew 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);
477327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
477427fcede3SMatthew 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);
477527fcede3SMatthew G. Knepley       }
477627fcede3SMatthew G. Knepley #endif
477727fcede3SMatthew G. Knepley       /* B-C face */
477827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
477927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
478027fcede3SMatthew G. Knepley       orntNew[0] = -2;
478127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
478227fcede3SMatthew G. Knepley       orntNew[1] = 0;
478327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
478427fcede3SMatthew G. Knepley       orntNew[2] = 0;
478527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
478627fcede3SMatthew G. Knepley       orntNew[3] = -2;
478727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
478827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
478927fcede3SMatthew G. Knepley #if 1
479027fcede3SMatthew 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);
479127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
479227fcede3SMatthew 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);
479327fcede3SMatthew G. Knepley       }
479427fcede3SMatthew G. Knepley #endif
479527fcede3SMatthew G. Knepley       /* A-B face */
479627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
479727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
479827fcede3SMatthew G. Knepley       orntNew[0] = -2;
479927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
480027fcede3SMatthew G. Knepley       orntNew[1] = 0;
480127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
480227fcede3SMatthew G. Knepley       orntNew[2] = 0;
480327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
480427fcede3SMatthew G. Knepley       orntNew[3] = -2;
480527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
480627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
480727fcede3SMatthew G. Knepley #if 1
480827fcede3SMatthew 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);
480927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
481027fcede3SMatthew 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);
481127fcede3SMatthew G. Knepley       }
481227fcede3SMatthew G. Knepley #endif
481327fcede3SMatthew G. Knepley       /* E-F face */
481427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
481527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
481627fcede3SMatthew G. Knepley       orntNew[0] = -2;
481727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
481827fcede3SMatthew G. Knepley       orntNew[1] = -2;
481927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
482027fcede3SMatthew G. Knepley       orntNew[2] = 0;
482127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
482227fcede3SMatthew G. Knepley       orntNew[3] = 0;
482327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
482427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
482527fcede3SMatthew G. Knepley #if 1
482627fcede3SMatthew 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);
482727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
482827fcede3SMatthew 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);
482927fcede3SMatthew G. Knepley       }
483027fcede3SMatthew G. Knepley #endif
483127fcede3SMatthew G. Knepley       /* F-G face */
483227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
483327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
483427fcede3SMatthew G. Knepley       orntNew[0] = -2;
483527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
483627fcede3SMatthew G. Knepley       orntNew[1] = -2;
483727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
483827fcede3SMatthew G. Knepley       orntNew[2] = 0;
483927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
484027fcede3SMatthew G. Knepley       orntNew[3] = 0;
484127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
484227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
484327fcede3SMatthew G. Knepley #if 1
484427fcede3SMatthew 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);
484527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
484627fcede3SMatthew 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);
484727fcede3SMatthew G. Knepley       }
484827fcede3SMatthew G. Knepley #endif
484927fcede3SMatthew G. Knepley       /* G-H face */
485027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
485127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
485227fcede3SMatthew G. Knepley       orntNew[0] = -2;
485327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
485427fcede3SMatthew G. Knepley       orntNew[1] = 0;
485527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
485627fcede3SMatthew G. Knepley       orntNew[2] = 0;
485727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
485827fcede3SMatthew G. Knepley       orntNew[3] = -2;
485927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
486027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
486127fcede3SMatthew G. Knepley #if 1
486227fcede3SMatthew 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);
486327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
486427fcede3SMatthew 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);
486527fcede3SMatthew G. Knepley       }
486627fcede3SMatthew G. Knepley #endif
486727fcede3SMatthew G. Knepley       /* E-H face */
486827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
486927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
487027fcede3SMatthew G. Knepley       orntNew[0] = -2;
487127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
487227fcede3SMatthew G. Knepley       orntNew[1] = -2;
487327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
487427fcede3SMatthew G. Knepley       orntNew[2] = 0;
487527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
487627fcede3SMatthew G. Knepley       orntNew[3] = 0;
487727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
487827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
487927fcede3SMatthew G. Knepley #if 1
488027fcede3SMatthew 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);
488127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
488227fcede3SMatthew 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);
488327fcede3SMatthew G. Knepley       }
488427fcede3SMatthew G. Knepley #endif
488527fcede3SMatthew G. Knepley       /* A-E face */
488627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
488727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
488827fcede3SMatthew G. Knepley       orntNew[0] = 0;
488927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
489027fcede3SMatthew G. Knepley       orntNew[1] = 0;
489127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
489227fcede3SMatthew G. Knepley       orntNew[2] = -2;
489327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
489427fcede3SMatthew G. Knepley       orntNew[3] = -2;
489527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
489627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
489727fcede3SMatthew G. Knepley #if 1
489827fcede3SMatthew 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);
489927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
490027fcede3SMatthew 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);
490127fcede3SMatthew G. Knepley       }
490227fcede3SMatthew G. Knepley #endif
490327fcede3SMatthew G. Knepley       /* D-F face */
490427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
490527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
490627fcede3SMatthew G. Knepley       orntNew[0] = -2;
490727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
490827fcede3SMatthew G. Knepley       orntNew[1] = 0;
490927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
491027fcede3SMatthew G. Knepley       orntNew[2] = 0;
491127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
491227fcede3SMatthew G. Knepley       orntNew[3] = -2;
491327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
491427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
491527fcede3SMatthew G. Knepley #if 1
491627fcede3SMatthew 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);
491727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
491827fcede3SMatthew 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);
491927fcede3SMatthew G. Knepley       }
492027fcede3SMatthew G. Knepley #endif
492127fcede3SMatthew G. Knepley       /* C-G face */
492227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
492327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
492427fcede3SMatthew G. Knepley       orntNew[0] = -2;
492527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
492627fcede3SMatthew G. Knepley       orntNew[1] = -2;
492727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
492827fcede3SMatthew G. Knepley       orntNew[2] = 0;
492927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
493027fcede3SMatthew G. Knepley       orntNew[3] = 0;
493127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
493227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
493327fcede3SMatthew G. Knepley #if 1
493427fcede3SMatthew 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);
493527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
493627fcede3SMatthew 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);
493727fcede3SMatthew G. Knepley       }
493827fcede3SMatthew G. Knepley #endif
493927fcede3SMatthew G. Knepley       /* B-H face */
494027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
494127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
494227fcede3SMatthew G. Knepley       orntNew[0] = 0;
494327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
494427fcede3SMatthew G. Knepley       orntNew[1] = -2;
494527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
494627fcede3SMatthew G. Knepley       orntNew[2] = -2;
494727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
494827fcede3SMatthew G. Knepley       orntNew[3] = 0;
494927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
495027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
495127fcede3SMatthew G. Knepley #if 1
495227fcede3SMatthew 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);
495327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
495427fcede3SMatthew 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);
495527fcede3SMatthew G. Knepley       }
495627fcede3SMatthew G. Knepley #endif
495727fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
495827fcede3SMatthew G. Knepley         newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
495927fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
496027fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
496127fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
496227fcede3SMatthew G. Knepley #if 1
496327fcede3SMatthew 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);
496427fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
496527fcede3SMatthew 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);
496627fcede3SMatthew G. Knepley         }
496727fcede3SMatthew G. Knepley #endif
496827fcede3SMatthew G. Knepley       }
496927fcede3SMatthew G. Knepley     }
497027fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
497127fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
497227fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
497327fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
497427fcede3SMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
497527fcede3SMatthew G. Knepley 
497627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
497727fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
497827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
497927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
498027fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
498127fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
498227fcede3SMatthew G. Knepley 
498327fcede3SMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
498427fcede3SMatthew G. Knepley         orntNew[0]   = ornt[0];
498527fcede3SMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
498627fcede3SMatthew G. Knepley         orntNew[1]   = ornt[1];
498727fcede3SMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
498827fcede3SMatthew G. Knepley         orntNew[2+r] = 0;
498927fcede3SMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd      - eMax) + (f - fMax);
499027fcede3SMatthew G. Knepley         orntNew[3-r] = 0;
499127fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
499227fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
499327fcede3SMatthew G. Knepley #if 1
499427fcede3SMatthew 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);
499527fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
499627fcede3SMatthew 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);
499727fcede3SMatthew G. Knepley         }
499827fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
499927fcede3SMatthew 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);
500027fcede3SMatthew G. Knepley         }
500127fcede3SMatthew G. Knepley #endif
500227fcede3SMatthew G. Knepley         for (s = 0; s < size; ++s) {
500327fcede3SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
5004d273725eSMatthew G. Knepley           PetscInt        o, of;
500527fcede3SMatthew G. Knepley 
500627fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
500727fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
5008d273725eSMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
500927fcede3SMatthew G. Knepley           for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
501027fcede3SMatthew 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]);
501127fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
5012d273725eSMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
5013d273725eSMatthew 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;
501427fcede3SMatthew G. Knepley         }
501527fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);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 < size; ++p) {
501927fcede3SMatthew 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);
502027fcede3SMatthew G. Knepley         }
502127fcede3SMatthew G. Knepley #endif
502227fcede3SMatthew G. Knepley       }
502327fcede3SMatthew G. Knepley     }
502427fcede3SMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
502527fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
502627fcede3SMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
502727fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
502827fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
502927fcede3SMatthew G. Knepley       PetscInt        supportNew[2];
503027fcede3SMatthew G. Knepley 
503127fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
503227fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
503327fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
5034d273725eSMatthew G. Knepley #if 0
503527fcede3SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
503627fcede3SMatthew G. Knepley         orntNew[0] = 0;
503727fcede3SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
503827fcede3SMatthew G. Knepley         orntNew[1] = 0;
503927fcede3SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
504027fcede3SMatthew G. Knepley         orntNew[2] = 0;
504127fcede3SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd                                   - fMax) + (c - cMax);
504227fcede3SMatthew G. Knepley         orntNew[3] = 0;
5043d273725eSMatthew G. Knepley #else
5044d273725eSMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r;
5045d273725eSMatthew G. Knepley         orntNew[0] = 0;
5046d273725eSMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r;
5047d273725eSMatthew G. Knepley         orntNew[1] = 0;
5048d273725eSMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax);
5049d273725eSMatthew G. Knepley         orntNew[2] = 0;
5050d273725eSMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd      - fMax) + (c - cMax);
5051d273725eSMatthew G. Knepley         orntNew[3] = 0;
5052d273725eSMatthew G. Knepley #endif
505327fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
505427fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
505527fcede3SMatthew G. Knepley #if 1
505627fcede3SMatthew 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);
505727fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
505827fcede3SMatthew 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);
505927fcede3SMatthew G. Knepley         }
506027fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
506127fcede3SMatthew 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);
506227fcede3SMatthew G. Knepley         }
506327fcede3SMatthew G. Knepley #endif
506427fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
506527fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
506627fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
506727fcede3SMatthew G. Knepley #if 1
506827fcede3SMatthew 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);
506927fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
507027fcede3SMatthew 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);
507127fcede3SMatthew G. Knepley         }
507227fcede3SMatthew G. Knepley #endif
507327fcede3SMatthew G. Knepley       }
507427fcede3SMatthew G. Knepley     }
507527fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
507627fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
507727fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
507827fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
507927fcede3SMatthew G. Knepley 
508027fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
508127fcede3SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
508227fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
508327fcede3SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
508427fcede3SMatthew G. Knepley 
508527fcede3SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
508627fcede3SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
508727fcede3SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
508827fcede3SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
508927fcede3SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
509027fcede3SMatthew G. Knepley #if 1
509127fcede3SMatthew 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);
509227fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
509327fcede3SMatthew 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);
509427fcede3SMatthew G. Knepley         }
509527fcede3SMatthew G. Knepley #endif
509627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
509727fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
509827fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
509927fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
510027fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
510127fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
510227fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
510327fcede3SMatthew G. Knepley             if (cone[c] == e) break;
510427fcede3SMatthew G. Knepley           }
510527fcede3SMatthew G. Knepley           if (support[s] < fMax) {
510627fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
510727fcede3SMatthew G. Knepley           } else {
510827fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
510927fcede3SMatthew G. Knepley           }
511027fcede3SMatthew G. Knepley         }
511127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
511227fcede3SMatthew G. Knepley #if 1
511327fcede3SMatthew 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);
511427fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
511527fcede3SMatthew 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);
511627fcede3SMatthew G. Knepley         }
511727fcede3SMatthew G. Knepley #endif
511827fcede3SMatthew G. Knepley       }
511927fcede3SMatthew G. Knepley     }
512027fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
512127fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
512227fcede3SMatthew 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};
512327fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
512427fcede3SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
512527fcede3SMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
512627fcede3SMatthew G. Knepley 
512727fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
512827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
512927fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
513027fcede3SMatthew G. Knepley 
513127fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
513227fcede3SMatthew G. Knepley         coneNew[1] = newv;
513327fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
513427fcede3SMatthew G. Knepley #if 1
513527fcede3SMatthew 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);
513627fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
513727fcede3SMatthew 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);
513827fcede3SMatthew G. Knepley         }
513927fcede3SMatthew G. Knepley #endif
514027fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
514127fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
514227fcede3SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
514327fcede3SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
514427fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
514527fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
514627fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
514727fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
514827fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
514927fcede3SMatthew G. Knepley           if (support[s] < cMax) {
515027fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
515127fcede3SMatthew G. Knepley           } else {
5152d273725eSMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r;
515327fcede3SMatthew G. Knepley           }
515427fcede3SMatthew G. Knepley         }
515527fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
515627fcede3SMatthew G. Knepley #if 1
515727fcede3SMatthew 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);
515827fcede3SMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
515927fcede3SMatthew 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);
516027fcede3SMatthew G. Knepley         }
516127fcede3SMatthew G. Knepley #endif
516227fcede3SMatthew G. Knepley       }
516327fcede3SMatthew G. Knepley     }
516427fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
516527fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
516627fcede3SMatthew 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};
516727fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
516827fcede3SMatthew G. Knepley       const PetscInt *cone;
516927fcede3SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
517027fcede3SMatthew G. Knepley 
517127fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
517227fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
517327fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
517427fcede3SMatthew G. Knepley 
517527fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
517627fcede3SMatthew G. Knepley         coneNew[1] = newv;
517727fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
517827fcede3SMatthew G. Knepley #if 1
517927fcede3SMatthew 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);
518027fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
518127fcede3SMatthew 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);
518227fcede3SMatthew G. Knepley         }
518327fcede3SMatthew G. Knepley #endif
518427fcede3SMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
518527fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
518627fcede3SMatthew G. Knepley #if 1
518727fcede3SMatthew 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);
518827fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
518927fcede3SMatthew 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);
519027fcede3SMatthew G. Knepley         }
519127fcede3SMatthew G. Knepley #endif
519227fcede3SMatthew G. Knepley       }
519327fcede3SMatthew G. Knepley     }
519427fcede3SMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
519527fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
519627fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
519727fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
519827fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
519927fcede3SMatthew G. Knepley 
520027fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
520127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
520227fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
520327fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
520427fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
520527fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
520627fcede3SMatthew G. Knepley #if 1
520727fcede3SMatthew 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);
520827fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
520927fcede3SMatthew 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);
521027fcede3SMatthew G. Knepley       }
521127fcede3SMatthew G. Knepley #endif
521227fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
521327fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
521427fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
521527fcede3SMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
521627fcede3SMatthew 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]);
521727fcede3SMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
521827fcede3SMatthew G. Knepley       }
521927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
522027fcede3SMatthew G. Knepley #if 1
522127fcede3SMatthew 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);
522227fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
522327fcede3SMatthew 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);
522427fcede3SMatthew G. Knepley       }
522527fcede3SMatthew G. Knepley #endif
522627fcede3SMatthew G. Knepley     }
522727fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
522827fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
522927fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
523027fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
523127fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
523227fcede3SMatthew G. Knepley 
523327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
523427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
523527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
523627fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
523727fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
523827fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
523927fcede3SMatthew G. Knepley #if 1
524027fcede3SMatthew 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);
524127fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
524227fcede3SMatthew 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);
524327fcede3SMatthew G. Knepley       }
524427fcede3SMatthew G. Knepley #endif
524527fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
524627fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
524727fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
524827fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
524927fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
525027fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
525127fcede3SMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
525227fcede3SMatthew 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]);
5253d273725eSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2;
525427fcede3SMatthew G. Knepley       }
525527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
525627fcede3SMatthew G. Knepley #if 1
525727fcede3SMatthew 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);
525827fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
525927fcede3SMatthew 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);
526027fcede3SMatthew G. Knepley       }
526127fcede3SMatthew G. Knepley #endif
526227fcede3SMatthew G. Knepley     }
526327fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
526427fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
526527fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
526627fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
526727fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size;
526827fcede3SMatthew G. Knepley 
526927fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
527027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr);
527127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr);
527227fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
527327fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
527427fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
527527fcede3SMatthew G. Knepley #if 1
527627fcede3SMatthew 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);
527727fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
527827fcede3SMatthew 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);
527927fcede3SMatthew G. Knepley       }
528027fcede3SMatthew G. Knepley #endif
528127fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
528227fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
528327fcede3SMatthew G. Knepley       supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
528427fcede3SMatthew G. Knepley       supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
528527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
528627fcede3SMatthew G. Knepley #if 1
528727fcede3SMatthew 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);
528827fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
528927fcede3SMatthew 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);
529027fcede3SMatthew G. Knepley       }
529127fcede3SMatthew G. Knepley #endif
529227fcede3SMatthew G. Knepley     }
529327fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
529427fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
529527fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
529627fcede3SMatthew G. Knepley       const PetscInt *support, *cone;
529727fcede3SMatthew G. Knepley       PetscInt        size, s;
529827fcede3SMatthew G. Knepley 
529927fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
530027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
530127fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
530227fcede3SMatthew G. Knepley         PetscInt r = 0;
530327fcede3SMatthew G. Knepley 
530427fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
530527fcede3SMatthew G. Knepley         if (cone[1] == v) r = 1;
530627fcede3SMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
530727fcede3SMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
530827fcede3SMatthew G. Knepley       }
530927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
531027fcede3SMatthew G. Knepley #if 1
531127fcede3SMatthew 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);
531227fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
531327fcede3SMatthew 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);
531427fcede3SMatthew G. Knepley       }
531527fcede3SMatthew G. Knepley #endif
531627fcede3SMatthew G. Knepley     }
531727fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
531827fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
531927fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
532027fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
532127fcede3SMatthew G. Knepley       PetscInt        size, s;
532227fcede3SMatthew G. Knepley 
532327fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
532427fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
532527fcede3SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
532627fcede3SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
532727fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
532827fcede3SMatthew G. Knepley         PetscInt r;
532927fcede3SMatthew G. Knepley 
533027fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
533127fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
533227fcede3SMatthew G. Knepley         if (support[s] < fMax) {
533327fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
533427fcede3SMatthew G. Knepley         } else {
533527fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
533627fcede3SMatthew G. Knepley         }
533727fcede3SMatthew G. Knepley       }
533827fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
533927fcede3SMatthew G. Knepley #if 1
534027fcede3SMatthew 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);
534127fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
534227fcede3SMatthew 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);
534327fcede3SMatthew G. Knepley       }
534427fcede3SMatthew G. Knepley #endif
534527fcede3SMatthew G. Knepley     }
534627fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
534727fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
534827fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
534927fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
535027fcede3SMatthew G. Knepley       PetscInt        size, s;
535127fcede3SMatthew G. Knepley 
535227fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
535327fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
535427fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 +  (f - fStart)*4 + r;
535527fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
535627fcede3SMatthew G. Knepley         PetscInt r;
535727fcede3SMatthew G. Knepley 
535827fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
535927fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
536027fcede3SMatthew G. Knepley         if (support[s] < cMax) {
536127fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
536227fcede3SMatthew G. Knepley         } else {
536327fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax       - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
536427fcede3SMatthew G. Knepley         }
536527fcede3SMatthew G. Knepley       }
536627fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
536727fcede3SMatthew G. Knepley #if 1
536827fcede3SMatthew 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);
536927fcede3SMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
537027fcede3SMatthew 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);
537127fcede3SMatthew G. Knepley       }
537227fcede3SMatthew G. Knepley #endif
537327fcede3SMatthew G. Knepley     }
537427fcede3SMatthew G. Knepley     /* Cell vertices have 6 supports */
537527fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
537627fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
537727fcede3SMatthew G. Knepley       PetscInt       supportNew[6];
537827fcede3SMatthew G. Knepley 
537927fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
538027fcede3SMatthew G. Knepley         supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
538127fcede3SMatthew G. Knepley       }
538227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
538327fcede3SMatthew G. Knepley     }
538427fcede3SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
538527fcede3SMatthew G. Knepley     break;
538675d3a19aSMatthew G. Knepley   default:
538775d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
538875d3a19aSMatthew G. Knepley   }
538975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
539075d3a19aSMatthew G. Knepley }
539175d3a19aSMatthew G. Knepley 
539275d3a19aSMatthew G. Knepley #undef __FUNCT__
539375d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerSetCoordinates"
539486150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
539575d3a19aSMatthew G. Knepley {
539675d3a19aSMatthew G. Knepley   PetscSection   coordSection, coordSectionNew;
539775d3a19aSMatthew G. Knepley   Vec            coordinates, coordinatesNew;
539875d3a19aSMatthew G. Knepley   PetscScalar   *coords, *coordsNew;
53993478d7aaSMatthew G. Knepley   const PetscInt numVertices = depthSize ? depthSize[0] : 0;
5400f1d7821bSLawrence Mitchell   PetscInt       spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
540175d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
540275d3a19aSMatthew G. Knepley 
540375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
540475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
540575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
5406b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
540775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
540875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
540927fcede3SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr);
54103478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);}
541175d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);
5412f719d809SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
5413f1d7821bSLawrence Mitchell   ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr);
541475d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
541575d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
5416f1d7821bSLawrence Mitchell   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr);
54173478d7aaSMatthew G. Knepley   ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
541827fcede3SMatthew G. Knepley   if (cMax < 0) cMax = cEnd;
541975d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
5420b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
5421f1d7821bSLawrence Mitchell   /* All vertices have the spaceDim coordinates */
54223478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
5423f1d7821bSLawrence Mitchell     ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr);
5424f1d7821bSLawrence Mitchell     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr);
542575d3a19aSMatthew G. Knepley   }
542675d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
542746e270d4SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr);
542875d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
542975d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
543075d3a19aSMatthew G. Knepley   ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr);
543175d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
543275d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
543360b9e8a1SMatthew G. Knepley   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
543460b9e8a1SMatthew G. Knepley   ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr);
543575d3a19aSMatthew G. Knepley   ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr);
543675d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
543775d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
5438b5da9499SMatthew G. Knepley   switch (refiner) {
5439*9b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
5440*9b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
5441*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
5442b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
5443d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
544427fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
5445b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
5446b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
5447b5da9499SMatthew G. Knepley 
5448b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5449b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
5450b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
5451b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
5452b5da9499SMatthew G. Knepley       }
5453b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
5454b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
5455b5da9499SMatthew G. Knepley       }
5456b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5457f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
5458f1d7821bSLawrence Mitchell       for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
5459f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
5460b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5461b5da9499SMatthew G. Knepley     }
5462*9b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
5463*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
5464b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
546527fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
5466f1d7821bSLawrence Mitchell       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (spaceDim > 2 ? (fMax - fStart) : 0);
5467b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
5468b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
5469b5da9499SMatthew G. Knepley 
5470b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5471b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
5472b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
5473b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
5474b5da9499SMatthew G. Knepley       }
5475b5da9499SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {
5476b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
5477b5da9499SMatthew G. Knepley       }
5478b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5479f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
5480f1d7821bSLawrence Mitchell       for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
5481f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
5482b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5483b5da9499SMatthew G. Knepley     }
5484*9b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
5485*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
5486*9b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
5487*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
5488b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
5489b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
5490b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
5491b5da9499SMatthew G. Knepley       const PetscInt *cone;
5492b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
5493b5da9499SMatthew G. Knepley 
5494b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
5495b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
5496b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
5497b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
5498b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
5499b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5500f1d7821bSLawrence Mitchell       ierr = DMPlexLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr);
5501f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
5502a96104c9SMatthew G. Knepley         coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]);
5503b5da9499SMatthew G. Knepley       }
5504b5da9499SMatthew G. Knepley     }
550575d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
550675d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
550775d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
550875d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
550975d3a19aSMatthew G. Knepley 
551075d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
551175d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5512f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
551375d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
551475d3a19aSMatthew G. Knepley       }
551575d3a19aSMatthew G. Knepley     }
5516b5da9499SMatthew G. Knepley     break;
5517b5da9499SMatthew G. Knepley   default:
5518b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
551975d3a19aSMatthew G. Knepley   }
552075d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
552175d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
552275d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
552375d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
552475d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
5525a96104c9SMatthew G. Knepley   if (dm->maxCell) {
5526a96104c9SMatthew G. Knepley     const PetscReal *maxCell, *L;
5527a96104c9SMatthew G. Knepley     ierr = DMGetPeriodicity(dm,  &maxCell, &L);CHKERRQ(ierr);
5528a96104c9SMatthew G. Knepley     ierr = DMSetPeriodicity(rdm,  maxCell,  L);CHKERRQ(ierr);
5529a96104c9SMatthew G. Knepley   }
553075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
553175d3a19aSMatthew G. Knepley }
553275d3a19aSMatthew G. Knepley 
553375d3a19aSMatthew G. Knepley #undef __FUNCT__
553475d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateProcessSF"
5535963fc26aSMatthew G. Knepley /*@
5536963fc26aSMatthew G. Knepley   DMPlexCreateProcessSF - Create an SF which just has process connectivity
5537963fc26aSMatthew G. Knepley 
5538963fc26aSMatthew G. Knepley   Collective on DM
5539963fc26aSMatthew G. Knepley 
5540963fc26aSMatthew G. Knepley   Input Parameters:
5541963fc26aSMatthew G. Knepley + dm      - The DM
5542963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity
5543963fc26aSMatthew G. Knepley 
5544963fc26aSMatthew G. Knepley   Output Parameters:
5545963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL
5546963fc26aSMatthew G. Knepley - sfProcess    - An SF encoding the process connectivity, or NULL
5547963fc26aSMatthew G. Knepley 
5548963fc26aSMatthew G. Knepley   Level: developer
5549963fc26aSMatthew G. Knepley 
5550963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF()
5551963fc26aSMatthew G. Knepley @*/
5552963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
555375d3a19aSMatthew G. Knepley {
555475d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
555575d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
555675d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
555775d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
555875d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
555975d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
5560963fc26aSMatthew G. Knepley   PetscMPIInt        numProcs;
556175d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
556275d3a19aSMatthew G. Knepley 
556375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
5564963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
5565963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2);
5566963fc26aSMatthew G. Knepley   if (processRanks) {PetscValidPointer(processRanks, 3);}
5567963fc26aSMatthew G. Knepley   if (sfProcess)    {PetscValidPointer(sfProcess, 4);}
5568963fc26aSMatthew G. Knepley   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &numProcs);CHKERRQ(ierr);
556975d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
5570785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
557175d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
557275d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
557375d3a19aSMatthew G. Knepley   }
557475d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
5575785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr);
5576785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr);
5577785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
557875d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
557975d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
558075d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
558175d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
558275d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
558375d3a19aSMatthew G. Knepley   }
558475d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
5585963fc26aSMatthew G. Knepley   if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);}
5586963fc26aSMatthew G. Knepley   else              {ierr = PetscFree(ranksNew);CHKERRQ(ierr);}
5587963fc26aSMatthew G. Knepley   if (sfProcess) {
558875d3a19aSMatthew G. Knepley     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
5589963fc26aSMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr);
559075d3a19aSMatthew G. Knepley     ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
5591963fc26aSMatthew G. Knepley     ierr = PetscSFSetGraph(*sfProcess, numProcs, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
5592963fc26aSMatthew G. Knepley   }
559375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
559475d3a19aSMatthew G. Knepley }
559575d3a19aSMatthew G. Knepley 
559675d3a19aSMatthew G. Knepley #undef __FUNCT__
559775d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateSF"
559886150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
559975d3a19aSMatthew G. Knepley {
560075d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
560175d3a19aSMatthew G. Knepley   IS                 processRanks;
560275d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
560375d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
560475d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
560575d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
560675d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
560775d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
560875d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
56097ba685a0SMatthew G. Knepley   PetscInt           depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
56107ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
561175d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
561275d3a19aSMatthew G. Knepley 
561375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
561475d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
561575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
561675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
561775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
561875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
561975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
562075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
5621add09238SMatthew G. Knepley   cMax = cMax < 0 ? cEnd : cMax;
5622add09238SMatthew G. Knepley   fMax = fMax < 0 ? fEnd : fMax;
5623add09238SMatthew G. Knepley   eMax = eMax < 0 ? eEnd : eMax;
56243478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
562575d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
562675d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
5627add09238SMatthew G. Knepley   /* Calculate size of new SF */
562875d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
562975d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
563075d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
563175d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
563275d3a19aSMatthew G. Knepley 
563375d3a19aSMatthew G. Knepley     switch (refiner) {
5634*9b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
5635*9b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_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;
5653*9b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
5654*9b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
5655a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5656a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
5657a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5658a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5659a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
5660a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5661a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5662a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
5663a97b51b8SMatthew G. Knepley         ++numLeavesNew;
5664a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5665a97b51b8SMatthew G. Knepley         /* Interior cells add new cells, interior faces, and vertex */
5666a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
5667a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
5668a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
5669a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
5670a97b51b8SMatthew G. Knepley       }
5671a97b51b8SMatthew G. Knepley       break;
5672*9b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
5673*9b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
56746ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
56756ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
56766ce3c06aSMatthew G. Knepley         ++numLeavesNew;
56776ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
56786ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
56796ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
56806ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
56816ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
56826ce3c06aSMatthew G. Knepley         ++numLeavesNew;
56836ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
56846ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
56856ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
56866ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
56876ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
56886ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
56896ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
56906ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
56916ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
56926ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
56936ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
56946ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
56956ce3c06aSMatthew G. Knepley       }
56966ce3c06aSMatthew G. Knepley       break;
5697*9b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
5698*9b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
569927fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
570027fcede3SMatthew G. Knepley         /* Old vertices stay the same */
570127fcede3SMatthew G. Knepley         ++numLeavesNew;
570227fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
570327fcede3SMatthew G. Knepley         /* Interior edges add new edges, and vertex */
570427fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
570527fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
570627fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
570727fcede3SMatthew G. Knepley         ++numLeavesNew;
570827fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
570927fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
571027fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
571127fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
571227fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
571327fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
571427fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
571527fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
571627fcede3SMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
571727fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
571827fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
571927fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
572027fcede3SMatthew G. Knepley       }
572127fcede3SMatthew G. Knepley       break;
572275d3a19aSMatthew G. Knepley     default:
572375d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
572475d3a19aSMatthew G. Knepley     }
572575d3a19aSMatthew G. Knepley   }
572675d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
572775d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
572875d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
5729dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
5730dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
573175d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
573275d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
573375d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
573475d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
573575d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
573675d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
573775d3a19aSMatthew G. Knepley   }
573875d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
573975d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
574075d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
574175d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
574275d3a19aSMatthew G. Knepley 
574375d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
574475d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
574575d3a19aSMatthew G. Knepley 
574675d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
574775d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
574875d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
574975d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
575075d3a19aSMatthew G. Knepley 
575175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
575275d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
575375d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
575475d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
57550252e7f5SMatthew 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];
57560252e7f5SMatthew 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];
57570252e7f5SMatthew 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];
575875d3a19aSMatthew G. Knepley   }
575975d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
576075d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
576175d3a19aSMatthew G. Knepley   /* Calculate new point SF */
5762785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr);
5763785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
576475d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
576575d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
576675d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
576775d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
576875d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
576975d3a19aSMatthew G. Knepley 
577075d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
577175d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
577275d3a19aSMatthew G. Knepley     switch (refiner) {
5773*9b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
5774*9b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_2D:
577575d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
577675d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
577775d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
577875d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
577975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
578075d3a19aSMatthew G. Knepley         ++m;
578175d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
578275d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
578375d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
578475d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
578575d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
578675d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
578775d3a19aSMatthew G. Knepley         }
5788add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
5789add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
5790add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5791add09238SMatthew G. Knepley         ++m;
579275d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
579375d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
579475d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
579575d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
579675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
579775d3a19aSMatthew G. Knepley         ++m;
579875d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
579975d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
580075d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
580175d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
580275d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
580375d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
580475d3a19aSMatthew G. Knepley         }
580575d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
580675d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
580775d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
580875d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
580975d3a19aSMatthew G. Knepley         }
5810add09238SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
581175d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
581275d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
581375d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
581475d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
581575d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
581675d3a19aSMatthew G. Knepley         }
581775d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
581875d3a19aSMatthew 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]);
581975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
582075d3a19aSMatthew G. Knepley         ++m;
582175d3a19aSMatthew G. Knepley       }
582275d3a19aSMatthew G. Knepley       break;
5823*9b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
5824*9b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
5825a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
5826a97b51b8SMatthew G. Knepley         /* Old vertices stay the same */
5827a97b51b8SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
5828a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
5829a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5830a97b51b8SMatthew G. Knepley         ++m;
5831a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
5832a97b51b8SMatthew G. Knepley         /* Old interior faces add new faces and vertex */
5833a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5834a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
5835a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
5836a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5837a97b51b8SMatthew G. Knepley         }
5838add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
5839add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
5840add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5841add09238SMatthew G. Knepley         ++m;
5842a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
5843a97b51b8SMatthew G. Knepley         /* Old hybrid faces stay the same */
5844a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
5845a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
5846a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5847a97b51b8SMatthew G. Knepley         ++m;
5848a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5849a97b51b8SMatthew G. Knepley         /* Old interior cells add new cells, interior faces, and vertex */
5850a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5851a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
5852a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5853a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5854a97b51b8SMatthew G. Knepley         }
5855a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
5856a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*4     + r;
5857a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r;
5858a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5859a97b51b8SMatthew G. Knepley         }
5860add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)               + (fMax                              - fStart)     + (p  - cStart);
5861add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0]  + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]);
5862add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5863add09238SMatthew G. Knepley         ++m;
5864a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
5865a97b51b8SMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
5866a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5867a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
5868a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
5869a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
5870a97b51b8SMatthew G. Knepley         }
5871a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*4     + (p  - cMax);
5872a97b51b8SMatthew 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]);
5873a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
5874a97b51b8SMatthew G. Knepley         ++m;
5875a97b51b8SMatthew G. Knepley       }
5876a97b51b8SMatthew G. Knepley       break;
5877*9b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
5878*9b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
58796ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
58806ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
58816ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
58826ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
58836ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
58846ce3c06aSMatthew G. Knepley         ++m;
58856ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
58866ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
58876ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
58886ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
58896ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
58906ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
58916ce3c06aSMatthew G. Knepley         }
58926ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
58936ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
58946ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
58956ce3c06aSMatthew G. Knepley         ++m;
58966ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
58976ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
58986ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
58997d5cd7d5SMatthew 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]);
59006ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
59016ce3c06aSMatthew G. Knepley         ++m;
59026ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
59036ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
59046ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
59056ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
59066ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
59076ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59086ce3c06aSMatthew G. Knepley         }
59096ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
59106ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
59116ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
59126ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59136ce3c06aSMatthew G. Knepley         }
59146ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
59156ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
59166ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5917899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
5918899f98d0SMatthew 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;
59196ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59206ce3c06aSMatthew G. Knepley         }
59217d5cd7d5SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (eEnd                                    - eMax)                        + (p  - fMax);
59227d5cd7d5SMatthew 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]);
59236ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
592409b1338fSMatthew G. Knepley         ++m;
59256ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
59266ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
59276ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
59286ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
59296ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
59306ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59316ce3c06aSMatthew G. Knepley         }
59326ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
59336ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
59346ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
59356ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59366ce3c06aSMatthew G. Knepley         }
5937c7c54c77SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + 0;
5938c7c54c77SMatthew 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 + 0;
59396ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
594009b1338fSMatthew G. Knepley         ++m;
59416ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
59426ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
59436ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
59446ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
59456ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
59466ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59476ce3c06aSMatthew G. Knepley         }
59486ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
5949899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*3                            + r;
5950899f98d0SMatthew 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;
59516ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
59526ce3c06aSMatthew G. Knepley         }
59536ce3c06aSMatthew G. Knepley       }
59546ce3c06aSMatthew G. Knepley       break;
5955*9b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
5956*9b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
595727fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
595827fcede3SMatthew G. Knepley         /* Interior vertices stay the same */
595927fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
596027fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
596127fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
596227fcede3SMatthew G. Knepley         ++m;
596327fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
596427fcede3SMatthew G. Knepley         /* Interior edges add new edges and vertex */
596527fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
596627fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
596727fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
596827fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
596927fcede3SMatthew G. Knepley         }
597027fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
597127fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
597227fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
597327fcede3SMatthew G. Knepley         ++m;
597427fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
597527fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
597627fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (p  - eMax);
5977d2701f60SMatthew 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]);
597827fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
597927fcede3SMatthew G. Knepley         ++m;
598027fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
598127fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
598227fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
598327fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
598427fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
598527fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
598627fcede3SMatthew G. Knepley         }
598727fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
598827fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*4     + r;
598927fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
599027fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
599127fcede3SMatthew G. Knepley         }
599227fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eMax                        - eStart)     + (p  - fStart);
599327fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
599427fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
599527fcede3SMatthew G. Knepley         ++m;
599627fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
599727fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
599827fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
5999d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (p  - fMax)*2                              + r;
6000d2701f60SMatthew 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;
600127fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
600227fcede3SMatthew G. Knepley         }
6003d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (p  - fMax);
6004d2701f60SMatthew 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]);
600527fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
600627fcede3SMatthew G. Knepley         ++m;
600727fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
600827fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
600927fcede3SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
601027fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
601127fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
601227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
601327fcede3SMatthew G. Knepley         }
601427fcede3SMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
601527fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*12     + r;
601627fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
601727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
601827fcede3SMatthew G. Knepley         }
601927fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
602027fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (p  - cStart)*6     + r;
602127fcede3SMatthew 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;
602227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
602327fcede3SMatthew G. Knepley         }
602427fcede3SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
602527fcede3SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eMax                        - eStart)     + (fMax                              - fStart)     + (p  - cStart)     + r;
602627fcede3SMatthew 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;
602727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
602827fcede3SMatthew G. Knepley         }
602927fcede3SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
603027fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
603127fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
603227fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
603327fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
603427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
603527fcede3SMatthew G. Knepley         }
603627fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
6037d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (fEnd                                          - fMax)*2                              + (p  - cMax)*4                            + r;
6038d2701f60SMatthew 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;
603927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
604027fcede3SMatthew G. Knepley         }
6041d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (fEnd                                          - fMax)                              + (p  - cMax);
6042d2701f60SMatthew 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]);
604327fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
604427fcede3SMatthew G. Knepley         ++m;
604527fcede3SMatthew G. Knepley       }
604627fcede3SMatthew G. Knepley       break;
604775d3a19aSMatthew G. Knepley     default:
604875d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
604975d3a19aSMatthew G. Knepley     }
605075d3a19aSMatthew G. Knepley   }
605109b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
605275d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
605375d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
6054ba3c3d50SMatthew G. Knepley   {
6055ba3c3d50SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
6056ba3c3d50SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
6057ba3c3d50SMatthew G. Knepley 
6058ba3c3d50SMatthew G. Knepley     /* SF needs sorted leaves to correct calculate Gather */
6059ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr);
6060ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr);
6061ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr);
6062c7c54c77SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
6063c7c54c77SMatthew G. Knepley       if ((localPointsNew[i] < pStartNew) || (localPointsNew[i] >= pEndNew)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local SF point %d (%d) not in [%d, %d)", localPointsNew[i], i, pStartNew, pEndNew);
6064c7c54c77SMatthew G. Knepley       idx[i] = i;
6065c7c54c77SMatthew G. Knepley     }
6066ba3c3d50SMatthew G. Knepley     ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr);
6067ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
6068ba3c3d50SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
6069ba3c3d50SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
6070ba3c3d50SMatthew G. Knepley     }
6071ba3c3d50SMatthew G. Knepley     ltmp            = localPointsNew;
6072ba3c3d50SMatthew G. Knepley     localPointsNew  = lp;
6073ba3c3d50SMatthew G. Knepley     rtmp            = remotePointsNew;
6074ba3c3d50SMatthew G. Knepley     remotePointsNew = rp;
6075ba3c3d50SMatthew G. Knepley     ierr = PetscFree(idx);CHKERRQ(ierr);
6076ba3c3d50SMatthew G. Knepley     ierr = PetscFree(ltmp);CHKERRQ(ierr);
6077ba3c3d50SMatthew G. Knepley     ierr = PetscFree(rtmp);CHKERRQ(ierr);
6078ba3c3d50SMatthew G. Knepley   }
607975d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
608075d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
608106a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
608275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
608375d3a19aSMatthew G. Knepley }
608475d3a19aSMatthew G. Knepley 
608575d3a19aSMatthew G. Knepley #undef __FUNCT__
608675d3a19aSMatthew G. Knepley #define __FUNCT__ "CellRefinerCreateLabels"
608786150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
608875d3a19aSMatthew G. Knepley {
608975d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
60907ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
60917ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
609275d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
609375d3a19aSMatthew G. Knepley 
609475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
609575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
609675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
609775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
609875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
6099d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
61003478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
610175d3a19aSMatthew G. Knepley   ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
610275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
610375d3a19aSMatthew G. Knepley   switch (refiner) {
6104*9b1a0e7fSLawrence Mitchell   case REFINER_NOOP:
6105*9b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
6106*9b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
6107*9b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
6108*9b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
6109*9b1a0e7fSLawrence Mitchell     break;
6110*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
6111*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
611258b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
6113*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
6114*9b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
611575d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
611675d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
6117*9b1a0e7fSLawrence Mitchell   default:
6118*9b1a0e7fSLawrence Mitchell     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
611975d3a19aSMatthew G. Knepley   }
612075d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
612175d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
612275d3a19aSMatthew G. Knepley     const char     *lname;
612375d3a19aSMatthew G. Knepley     PetscBool       isDepth;
612475d3a19aSMatthew G. Knepley     IS              valueIS;
612575d3a19aSMatthew G. Knepley     const PetscInt *values;
612675d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
612775d3a19aSMatthew G. Knepley 
612875d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr);
612975d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
613075d3a19aSMatthew G. Knepley     if (isDepth) continue;
613175d3a19aSMatthew G. Knepley     ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr);
613275d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr);
613375d3a19aSMatthew G. Knepley     ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
613475d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
613575d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
613675d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
613775d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
613875d3a19aSMatthew G. Knepley       IS              pointIS;
613975d3a19aSMatthew G. Knepley       const PetscInt *points;
614075d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
614175d3a19aSMatthew G. Knepley 
614275d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
614375d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
614475d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
61452bc5314cSMichael Lange       /* Ensure refined label is created with same number of strata as
61462bc5314cSMichael Lange        * original (even if no entries here). */
61472bc5314cSMichael Lange       if (!numPoints) {
61482bc5314cSMichael Lange         ierr = DMLabelSetValue(labelNew, 0, values[val]);CHKERRQ(ierr);
61492bc5314cSMichael Lange         ierr = DMLabelClearValue(labelNew, 0, values[val]);CHKERRQ(ierr);
61502bc5314cSMichael Lange       }
615175d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
615275d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
615375d3a19aSMatthew G. Knepley         switch (refiner) {
6154*9b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_2D:
615575d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
615675d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
615775d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
615875d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
615975d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
616075d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
616175d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
616275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
616375d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
616475d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
616575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
616675d3a19aSMatthew G. Knepley             }
616775d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
616875d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
616975d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
617075d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
617175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
617275d3a19aSMatthew G. Knepley             }
617375d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
617475d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
617575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
617675d3a19aSMatthew G. Knepley             }
617775d3a19aSMatthew G. Knepley           }
617875d3a19aSMatthew G. Knepley           break;
6179*9b1a0e7fSLawrence Mitchell         case REFINER_HEX_2D:
618075d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
618175d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
618275d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
618375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
618475d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
618575d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
618675d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
618775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
618875d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
618975d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
619075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
619175d3a19aSMatthew G. Knepley             }
619275d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
619375d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
619475d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
619575d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
619675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
619775d3a19aSMatthew G. Knepley             }
619875d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
619975d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
620075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
620175d3a19aSMatthew G. Knepley             }
620275d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
620375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
620475d3a19aSMatthew G. Knepley           }
620575d3a19aSMatthew G. Knepley           break;
6206*9b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_2D:
620775d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
620875d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
620975d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
621075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
621175d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
621275d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
621375d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
621475d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
621575d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
621675d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
621775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
621875d3a19aSMatthew G. Knepley             }
621975d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
622075d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
622175d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
622275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
622375d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
622475d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
622575d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
622675d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
622775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
622875d3a19aSMatthew G. Knepley             }
622975d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
623075d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
623175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
623275d3a19aSMatthew G. Knepley             }
623375d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
623475d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
623575d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
623675d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
623775d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
623875d3a19aSMatthew G. Knepley             }
623975d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
624075d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
624175d3a19aSMatthew G. Knepley           }
624275d3a19aSMatthew G. Knepley           break;
6243*9b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_2D:
6244a97b51b8SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
6245a97b51b8SMatthew G. Knepley             /* Old vertices stay the same */
6246a97b51b8SMatthew G. Knepley             newp = vStartNew + (p - vStart);
6247a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6248a97b51b8SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
6249a97b51b8SMatthew G. Knepley             /* Old interior faces add new faces and vertex */
6250a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
6251a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6252a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6253a97b51b8SMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
6254a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6255a97b51b8SMatthew G. Knepley             }
6256a97b51b8SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
6257a97b51b8SMatthew G. Knepley             /* Old hybrid faces stay the same */
6258a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
6259a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6260a97b51b8SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
6261a97b51b8SMatthew G. Knepley             /* Old interior cells add new cells, interior faces, and vertex */
6262a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6263a97b51b8SMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
6264a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6265a97b51b8SMatthew G. Knepley             }
6266a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6267a97b51b8SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
6268a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6269a97b51b8SMatthew G. Knepley             }
6270a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
6271a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6272a97b51b8SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
6273a97b51b8SMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
6274a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6275a97b51b8SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
6276a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6277a97b51b8SMatthew G. Knepley             }
6278a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
6279a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6280a97b51b8SMatthew G. Knepley           }
6281a97b51b8SMatthew G. Knepley           break;
6282*9b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_3D:
6283b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
6284b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
6285b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
6286b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6287b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
6288b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
6289b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6290b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
6291b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6292b5da9499SMatthew G. Knepley             }
6293b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
6294b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6295b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
6296b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
6297b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6298b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
6299b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6300b5da9499SMatthew G. Knepley             }
6301b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
6302b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
6303b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6304b5da9499SMatthew G. Knepley             }
6305b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
6306b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
6307b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
6308b5da9499SMatthew G. Knepley               newp = cStartNew + (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 < 8; ++r) {
6312b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
6313b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6314b5da9499SMatthew G. Knepley             }
6315b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
6316b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
6317b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6318b5da9499SMatthew G. Knepley             }
6319b5da9499SMatthew G. Knepley           }
6320b5da9499SMatthew G. Knepley           break;
6321*9b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_3D:
63226ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
63236ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
63246ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
63256ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63266ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
63276ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
63286ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
63296ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
63306ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63316ce3c06aSMatthew G. Knepley             }
63326ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
63336ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63346ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
63356ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
63366ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
63376ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63386ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
63396ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
63406ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
63416ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
63426ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63436ce3c06aSMatthew G. Knepley             }
63446ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
63456ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
63466ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63476ce3c06aSMatthew G. Knepley             }
63486ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
63496ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
63506ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
63516ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
63526ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63536ce3c06aSMatthew G. Knepley             }
63546ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
63556ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63566ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
63576ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
63586ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
63596ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
63606ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63616ce3c06aSMatthew G. Knepley             }
63626ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
63636ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
63646ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63656ce3c06aSMatthew G. Knepley             }
63666ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
63676ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
636858b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
63696ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
63706ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
63716ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
63726ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63736ce3c06aSMatthew G. Knepley             }
63746ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
63756ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
63766ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63776ce3c06aSMatthew G. Knepley             }
63786ce3c06aSMatthew G. Knepley           }
63796ce3c06aSMatthew G. Knepley           break;
6380*9b1a0e7fSLawrence Mitchell         case REFINER_HEX_3D:
63812eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
63822eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
63832eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
63842eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
638519d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
63862eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
63872eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
63882eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
63892eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63902eabf88fSMatthew G. Knepley             }
63912eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
63922eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63932eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
63942eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
63952eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
63962eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
63972eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
63982eabf88fSMatthew G. Knepley             }
63992eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
64002eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
64012eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64022eabf88fSMatthew G. Knepley             }
64032eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
64042eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64052eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
64062eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
64072eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
64082eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
64092eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64102eabf88fSMatthew G. Knepley             }
64112eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
64122eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
64132eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64142eabf88fSMatthew G. Knepley             }
64152eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
64162eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
64172eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64182eabf88fSMatthew G. Knepley             }
64192eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
64202eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
64212eabf88fSMatthew G. Knepley           }
64222eabf88fSMatthew G. Knepley           break;
6423*9b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_3D:
642427fcede3SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
642527fcede3SMatthew G. Knepley             /* Interior vertices stay the same */
642627fcede3SMatthew G. Knepley             newp = vStartNew + (p - vStart);
642727fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
642827fcede3SMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
642927fcede3SMatthew G. Knepley             /* Interior edges add new edges and vertex */
643027fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
643127fcede3SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
643227fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
643327fcede3SMatthew G. Knepley             }
643427fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
643527fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
643627fcede3SMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
643727fcede3SMatthew G. Knepley             /* Hybrid edges stay the same */
643827fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
643927fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
644027fcede3SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
644127fcede3SMatthew G. Knepley             /* Interior faces add new faces, edges, and vertex */
644227fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
644327fcede3SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
644427fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
644527fcede3SMatthew G. Knepley             }
644627fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
644727fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
644827fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
644927fcede3SMatthew G. Knepley             }
645027fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
645127fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
645227fcede3SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
645327fcede3SMatthew G. Knepley             /* Hybrid faces add new faces and edges */
645427fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
645527fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
645627fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
645727fcede3SMatthew G. Knepley             }
645827fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
645927fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
646027fcede3SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
646127fcede3SMatthew G. Knepley             /* Interior cells add new cells, faces, edges, and vertex */
646227fcede3SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
646327fcede3SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
646427fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
646527fcede3SMatthew G. Knepley             }
646627fcede3SMatthew G. Knepley             for (r = 0; r < 12; ++r) {
646727fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
646827fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
646927fcede3SMatthew G. Knepley             }
647027fcede3SMatthew G. Knepley             for (r = 0; r < 6; ++r) {
647127fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
647227fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
647327fcede3SMatthew G. Knepley             }
647427fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
647527fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
647627fcede3SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
647727fcede3SMatthew G. Knepley             /* Hybrid cells add new cells, faces, and edges */
647827fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
647927fcede3SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
648027fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
648127fcede3SMatthew G. Knepley             }
648227fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
648327fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
648427fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
648527fcede3SMatthew G. Knepley             }
648627fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
648727fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
648827fcede3SMatthew G. Knepley           }
648927fcede3SMatthew G. Knepley           break;
649075d3a19aSMatthew G. Knepley         default:
649175d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
649275d3a19aSMatthew G. Knepley         }
649375d3a19aSMatthew G. Knepley       }
649475d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
649575d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
649675d3a19aSMatthew G. Knepley     }
649775d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
649875d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
649975d3a19aSMatthew G. Knepley     if (0) {
650075d3a19aSMatthew G. Knepley       ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr);
650175d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
650275d3a19aSMatthew G. Knepley       ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
650375d3a19aSMatthew G. Knepley     }
650475d3a19aSMatthew G. Knepley   }
650575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
650675d3a19aSMatthew G. Knepley }
650775d3a19aSMatthew G. Knepley 
650875d3a19aSMatthew G. Knepley #undef __FUNCT__
6509509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexRefineUniform_Internal"
651075d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
6511509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
651275d3a19aSMatthew G. Knepley {
651375d3a19aSMatthew G. Knepley   DM             rdm;
651475d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
651575d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
651675d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
651775d3a19aSMatthew G. Knepley 
651875d3a19aSMatthew G. Knepley   PetscFunctionBegin;
651975d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
652075d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
6521c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
6522c73cfb54SMatthew G. Knepley   ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr);
652375d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
652475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
6525854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
652675d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
652775d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
652875d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
652975d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
653075d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
653175d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
653275d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
653375d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
653475d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
653575d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
653675d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
653775d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
653875d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
65390fadad52SMatthew G. Knepley   /* Step 6: Create pointSF */
654075d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
65410fadad52SMatthew G. Knepley   /* Step 7: Set coordinates for vertices */
65420fadad52SMatthew G. Knepley   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
654375d3a19aSMatthew G. Knepley   /* Step 8: Create labels */
654475d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
654575d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
654675d3a19aSMatthew G. Knepley 
654775d3a19aSMatthew G. Knepley   *dmRefined = rdm;
654875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
654975d3a19aSMatthew G. Knepley }
655075d3a19aSMatthew G. Knepley 
655175d3a19aSMatthew G. Knepley #undef __FUNCT__
65522389894bSMatthew G. Knepley #define __FUNCT__ "DMPlexCreateCoarsePointIS"
65532389894bSMatthew G. Knepley /*@
65542389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
65552389894bSMatthew G. Knepley 
65562389894bSMatthew G. Knepley   Input Parameter:
65572389894bSMatthew G. Knepley . dm - The coarse DM
65582389894bSMatthew G. Knepley 
65592389894bSMatthew G. Knepley   Output Parameter:
65602389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
65612389894bSMatthew G. Knepley 
65622389894bSMatthew G. Knepley   Level: developer
65632389894bSMatthew G. Knepley 
65642389894bSMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS()
65652389894bSMatthew G. Knepley @*/
65662389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
65672389894bSMatthew G. Knepley {
65682389894bSMatthew G. Knepley   CellRefiner    cellRefiner;
65692389894bSMatthew G. Knepley   PetscInt      *depthSize, *fpoints;
65702389894bSMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
65712389894bSMatthew G. Knepley   PetscInt       depth, pStart, pEnd, p, vStart, vEnd, v;
65722389894bSMatthew G. Knepley   PetscErrorCode ierr;
65732389894bSMatthew G. Knepley 
65742389894bSMatthew G. Knepley   PetscFunctionBegin;
65752389894bSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
65762389894bSMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
65772389894bSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
65782389894bSMatthew G. Knepley   ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr);
6579854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
65802389894bSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
65812389894bSMatthew G. Knepley   if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
65822389894bSMatthew G. Knepley   ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr);
65832389894bSMatthew G. Knepley   for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
65842389894bSMatthew G. Knepley   switch (cellRefiner) {
65852389894bSMatthew G. Knepley   case 1: /* Simplicial 2D */
65862389894bSMatthew G. Knepley   case 3: /* Hybrid simplicial 2D */
65872389894bSMatthew G. Knepley   case 2: /* Hex 2D */
65882389894bSMatthew G. Knepley   case 4: /* Hybrid Hex 2D */
65892389894bSMatthew G. Knepley   case 5: /* Simplicial 3D */
65902389894bSMatthew G. Knepley   case 7: /* Hybrid Simplicial 3D */
65912389894bSMatthew G. Knepley   case 6: /* Hex 3D */
65922389894bSMatthew G. Knepley   case 8: /* Hybrid Hex 3D */
65932389894bSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart);
65942389894bSMatthew G. Knepley     break;
65952389894bSMatthew G. Knepley   default:
65962389894bSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner);
65972389894bSMatthew G. Knepley   }
65982389894bSMatthew G. Knepley   ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr);
65992389894bSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
66002389894bSMatthew G. Knepley   PetscFunctionReturn(0);
66012389894bSMatthew G. Knepley }
66022389894bSMatthew G. Knepley 
66032389894bSMatthew G. Knepley #undef __FUNCT__
660475d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementUniform"
66050e2b6761SMatthew G. Knepley /*@
66060e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
66070e2b6761SMatthew G. Knepley 
66080e2b6761SMatthew G. Knepley   Input Parameters:
66090e2b6761SMatthew G. Knepley + dm - The DM
66100e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
66110e2b6761SMatthew G. Knepley 
66120e2b6761SMatthew G. Knepley   Level: developer
66130e2b6761SMatthew G. Knepley 
66140e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
66150e2b6761SMatthew G. Knepley @*/
661675d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
661775d3a19aSMatthew G. Knepley {
661875d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
661975d3a19aSMatthew G. Knepley 
662075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
662175d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
662275d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
662375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
662475d3a19aSMatthew G. Knepley }
662575d3a19aSMatthew G. Knepley 
662675d3a19aSMatthew G. Knepley #undef __FUNCT__
662775d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementUniform"
66280e2b6761SMatthew G. Knepley /*@
66290e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
66300e2b6761SMatthew G. Knepley 
66310e2b6761SMatthew G. Knepley   Input Parameter:
66320e2b6761SMatthew G. Knepley . dm - The DM
66330e2b6761SMatthew G. Knepley 
66340e2b6761SMatthew G. Knepley   Output Parameter:
66350e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
66360e2b6761SMatthew G. Knepley 
66370e2b6761SMatthew G. Knepley   Level: developer
66380e2b6761SMatthew G. Knepley 
66390e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
66400e2b6761SMatthew G. Knepley @*/
664175d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
664275d3a19aSMatthew G. Knepley {
664375d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
664475d3a19aSMatthew G. Knepley 
664575d3a19aSMatthew G. Knepley   PetscFunctionBegin;
664675d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
664775d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
664875d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
664975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
665075d3a19aSMatthew G. Knepley }
665175d3a19aSMatthew G. Knepley 
665275d3a19aSMatthew G. Knepley #undef __FUNCT__
665375d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexSetRefinementLimit"
66540e2b6761SMatthew G. Knepley /*@
66550e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
66560e2b6761SMatthew G. Knepley 
66570e2b6761SMatthew G. Knepley   Input Parameters:
66580e2b6761SMatthew G. Knepley + dm - The DM
66590e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
66600e2b6761SMatthew G. Knepley 
66610e2b6761SMatthew G. Knepley   Level: developer
66620e2b6761SMatthew G. Knepley 
66630e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
66640e2b6761SMatthew G. Knepley @*/
666575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
666675d3a19aSMatthew G. Knepley {
666775d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
666875d3a19aSMatthew G. Knepley 
666975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
667075d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
667175d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
667275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
667375d3a19aSMatthew G. Knepley }
667475d3a19aSMatthew G. Knepley 
667575d3a19aSMatthew G. Knepley #undef __FUNCT__
667675d3a19aSMatthew G. Knepley #define __FUNCT__ "DMPlexGetRefinementLimit"
66770e2b6761SMatthew G. Knepley /*@
66780e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
66790e2b6761SMatthew G. Knepley 
66800e2b6761SMatthew G. Knepley   Input Parameter:
66810e2b6761SMatthew G. Knepley . dm - The DM
66820e2b6761SMatthew G. Knepley 
66830e2b6761SMatthew G. Knepley   Output Parameter:
66840e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
66850e2b6761SMatthew G. Knepley 
66860e2b6761SMatthew G. Knepley   Level: developer
66870e2b6761SMatthew G. Knepley 
66880e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
66890e2b6761SMatthew G. Knepley @*/
669075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
669175d3a19aSMatthew G. Knepley {
669275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
669375d3a19aSMatthew G. Knepley 
669475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
669575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
669675d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
669775d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
669875d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
669975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
670075d3a19aSMatthew G. Knepley }
670175d3a19aSMatthew G. Knepley 
670275d3a19aSMatthew G. Knepley #undef __FUNCT__
6703509c9b89SMatthew G. Knepley #define __FUNCT__ "DMPlexGetCellRefiner_Internal"
6704509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
670575d3a19aSMatthew G. Knepley {
67063478d7aaSMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax;
670775d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
670875d3a19aSMatthew G. Knepley 
670975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
6710c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
67113478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
6712*9b1a0e7fSLawrence Mitchell   if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);}
671375d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
671475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr);
671575d3a19aSMatthew G. Knepley   switch (dim) {
671675d3a19aSMatthew G. Knepley   case 2:
671775d3a19aSMatthew G. Knepley     switch (coneSize) {
671875d3a19aSMatthew G. Knepley     case 3:
6719*9b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D;
6720*9b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_2D;
672175d3a19aSMatthew G. Knepley       break;
672275d3a19aSMatthew G. Knepley     case 4:
6723*9b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D;
6724*9b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_2D;
672575d3a19aSMatthew G. Knepley       break;
672675d3a19aSMatthew G. Knepley     default:
672775d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
672875d3a19aSMatthew G. Knepley     }
672975d3a19aSMatthew G. Knepley     break;
6730b5da9499SMatthew G. Knepley   case 3:
6731b5da9499SMatthew G. Knepley     switch (coneSize) {
6732b5da9499SMatthew G. Knepley     case 4:
6733*9b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D;
6734*9b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_3D;
6735b5da9499SMatthew G. Knepley       break;
67362eabf88fSMatthew G. Knepley     case 6:
6737*9b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D;
6738*9b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_3D;
67392eabf88fSMatthew G. Knepley       break;
6740b5da9499SMatthew G. Knepley     default:
6741b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
6742b5da9499SMatthew G. Knepley     }
6743b5da9499SMatthew G. Knepley     break;
674475d3a19aSMatthew G. Knepley   default:
674575d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
674675d3a19aSMatthew G. Knepley   }
674775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
674875d3a19aSMatthew G. Knepley }
6749