xref: /petsc/src/dm/impls/plex/plexrefine.c (revision 3548e9b60dcb5707af254b16ca03bdb62b941e5c)
1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h>   /*I      "petscdmplex.h"   I*/
275d3a19aSMatthew G. Knepley #include <petscsf.h>
375d3a19aSMatthew G. Knepley 
475d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart)
575d3a19aSMatthew G. Knepley {
675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
775d3a19aSMatthew G. Knepley   if (cStart) *cStart = 0;
815fa1f8eSMatthew G. Knepley   if (vStart) *vStart = depth < 0 ? 0 : depthSize[depth];
915fa1f8eSMatthew G. Knepley   if (fStart) *fStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0];
1015fa1f8eSMatthew G. Knepley   if (eStart) *eStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1];
1175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
1275d3a19aSMatthew G. Knepley }
1375d3a19aSMatthew G. Knepley 
1475d3a19aSMatthew G. Knepley PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd)
1575d3a19aSMatthew G. Knepley {
1675d3a19aSMatthew G. Knepley   PetscFunctionBegin;
1715fa1f8eSMatthew G. Knepley   if (cEnd) *cEnd = depth < 0 ? 0 : depthSize[depth];
1815fa1f8eSMatthew G. Knepley   if (vEnd) *vEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0];
1915fa1f8eSMatthew G. Knepley   if (fEnd) *fEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1];
2015fa1f8eSMatthew G. Knepley   if (eEnd) *eEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1];
2175d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
2275d3a19aSMatthew G. Knepley }
2375d3a19aSMatthew G. Knepley 
24bed052eaSMatthew G. Knepley /* Gets the affine map from the original cell to each subcell */
25bed052eaSMatthew G. Knepley PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
26bed052eaSMatthew G. Knepley {
27bed052eaSMatthew G. Knepley   PetscReal     *v = NULL, *j = NULL, *invj = NULL, detJ;
28bed052eaSMatthew G. Knepley   PetscInt       dim, s;
29bed052eaSMatthew G. Knepley   PetscErrorCode ierr;
30bed052eaSMatthew G. Knepley 
31bed052eaSMatthew G. Knepley   PetscFunctionBegin;
32bed052eaSMatthew G. Knepley   switch (refiner) {
339b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
349b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
35260b6d3fSMatthew G. Knepley     /*
36260b6d3fSMatthew G. Knepley      2
37260b6d3fSMatthew G. Knepley      |\
38260b6d3fSMatthew G. Knepley      | \
39260b6d3fSMatthew G. Knepley      |  \
40260b6d3fSMatthew G. Knepley      |   \
41260b6d3fSMatthew G. Knepley      | C  \
42260b6d3fSMatthew G. Knepley      |     \
43260b6d3fSMatthew G. Knepley      |      \
44260b6d3fSMatthew G. Knepley      2---1---1
45260b6d3fSMatthew G. Knepley      |\  D  / \
46260b6d3fSMatthew G. Knepley      | 2   0   \
47260b6d3fSMatthew G. Knepley      |A \ /  B  \
48260b6d3fSMatthew G. Knepley      0---0-------1
49260b6d3fSMatthew G. Knepley      */
50bed052eaSMatthew G. Knepley     dim = 2;
51bed052eaSMatthew G. Knepley     if (numSubcells) *numSubcells = 4;
52bed052eaSMatthew G. Knepley     if (v0) {
53bed052eaSMatthew G. Knepley       ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr);
54bed052eaSMatthew G. Knepley       /* A */
55bed052eaSMatthew G. Knepley       v[0+0] = -1.0; v[0+1] = -1.0;
56bed052eaSMatthew G. Knepley       j[0+0] =  0.5; j[0+1] =  0.0;
57bed052eaSMatthew G. Knepley       j[0+2] =  0.0; j[0+3] =  0.5;
58bed052eaSMatthew G. Knepley       /* B */
59bed052eaSMatthew G. Knepley       v[2+0] =  0.0; v[2+1] = -1.0;
60bed052eaSMatthew G. Knepley       j[4+0] =  0.5; j[4+1] =  0.0;
61bed052eaSMatthew G. Knepley       j[4+2] =  0.0; j[4+3] =  0.5;
62bed052eaSMatthew G. Knepley       /* C */
63bed052eaSMatthew G. Knepley       v[4+0] = -1.0; v[4+1] =  0.0;
64bed052eaSMatthew G. Knepley       j[8+0] =  0.5; j[8+1] =  0.0;
65bed052eaSMatthew G. Knepley       j[8+2] =  0.0; j[8+3] =  0.5;
66bed052eaSMatthew G. Knepley       /* D */
67bed052eaSMatthew G. Knepley       v[6+0]  =  0.0; v[6+1]  = -1.0;
68bed052eaSMatthew G. Knepley       j[12+0] =  0.0; j[12+1] = -0.5;
69bed052eaSMatthew G. Knepley       j[12+2] =  0.5; j[12+3] =  0.5;
70bed052eaSMatthew G. Knepley       for (s = 0; s < 4; ++s) {
71bed052eaSMatthew G. Knepley         DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
72bed052eaSMatthew G. Knepley         DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
73bed052eaSMatthew G. Knepley       }
74bed052eaSMatthew G. Knepley     }
75bed052eaSMatthew G. Knepley     break;
769b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
77260b6d3fSMatthew G. Knepley     /*
78260b6d3fSMatthew G. Knepley      3---------2---------2
79260b6d3fSMatthew G. Knepley      |         |         |
80260b6d3fSMatthew G. Knepley      |    D    2    C    |
81260b6d3fSMatthew G. Knepley      |         |         |
82260b6d3fSMatthew G. Knepley      3----3----0----1----1
83260b6d3fSMatthew G. Knepley      |         |         |
84260b6d3fSMatthew G. Knepley      |    A    0    B    |
85260b6d3fSMatthew G. Knepley      |         |         |
86260b6d3fSMatthew G. Knepley      0---------0---------1
87260b6d3fSMatthew G. Knepley      */
88260b6d3fSMatthew G. Knepley     dim = 2;
89260b6d3fSMatthew G. Knepley     if (numSubcells) *numSubcells = 4;
90260b6d3fSMatthew G. Knepley     if (v0) {
91260b6d3fSMatthew G. Knepley       ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr);
92260b6d3fSMatthew G. Knepley       /* A */
93260b6d3fSMatthew G. Knepley       v[0+0] = -1.0; v[0+1] = -1.0;
94260b6d3fSMatthew G. Knepley       j[0+0] =  0.5; j[0+1] =  0.0;
95260b6d3fSMatthew G. Knepley       j[0+2] =  0.0; j[0+3] =  0.5;
96260b6d3fSMatthew G. Knepley       /* B */
97260b6d3fSMatthew G. Knepley       v[2+0] =  0.0; v[2+1] = -1.0;
98260b6d3fSMatthew G. Knepley       j[4+0] =  0.5; j[4+1] =  0.0;
99260b6d3fSMatthew G. Knepley       j[4+2] =  0.0; j[4+3] =  0.5;
100260b6d3fSMatthew G. Knepley       /* C */
101260b6d3fSMatthew G. Knepley       v[4+0] =  0.0; v[4+1] =  0.0;
102260b6d3fSMatthew G. Knepley       j[8+0] =  0.5; j[8+1] =  0.0;
103260b6d3fSMatthew G. Knepley       j[8+2] =  0.0; j[8+3] =  0.5;
104260b6d3fSMatthew G. Knepley       /* D */
105260b6d3fSMatthew G. Knepley       v[6+0]  = -1.0; v[6+1]  =  0.0;
106260b6d3fSMatthew G. Knepley       j[12+0] =  0.5; j[12+1] =  0.0;
107260b6d3fSMatthew G. Knepley       j[12+2] =  0.0; j[12+3] =  0.5;
108260b6d3fSMatthew G. Knepley       for (s = 0; s < 4; ++s) {
109260b6d3fSMatthew G. Knepley         DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]);
110260b6d3fSMatthew G. Knepley         DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ);
111260b6d3fSMatthew G. Knepley       }
112260b6d3fSMatthew G. Knepley     }
113260b6d3fSMatthew G. Knepley     break;
114bed052eaSMatthew G. Knepley   default:
115bed052eaSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
116bed052eaSMatthew G. Knepley   }
117bed052eaSMatthew G. Knepley   if (v0) {*v0 = v; *jac = j; *invjac = invj;}
118bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
119bed052eaSMatthew G. Knepley }
120bed052eaSMatthew G. Knepley 
121bed052eaSMatthew G. Knepley PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[])
122bed052eaSMatthew G. Knepley {
123bed052eaSMatthew G. Knepley   PetscErrorCode ierr;
124bed052eaSMatthew G. Knepley 
125bed052eaSMatthew G. Knepley   PetscFunctionBegin;
126bed052eaSMatthew G. Knepley   ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr);
127bed052eaSMatthew G. Knepley   PetscFunctionReturn(0);
128bed052eaSMatthew G. Knepley }
129bed052eaSMatthew G. Knepley 
13080389061SMatthew G. Knepley /* Should this be here or in the DualSpace somehow? */
13180389061SMatthew G. Knepley PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside)
13280389061SMatthew G. Knepley {
13380389061SMatthew G. Knepley   PetscReal sum = 0.0;
13480389061SMatthew G. Knepley   PetscInt  d;
13580389061SMatthew G. Knepley 
13680389061SMatthew G. Knepley   PetscFunctionBegin;
13780389061SMatthew G. Knepley   *inside = PETSC_TRUE;
13880389061SMatthew G. Knepley   switch (refiner) {
1399b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
1406c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_2D:
14180389061SMatthew G. Knepley     for (d = 0; d < 2; ++d) {
14280389061SMatthew G. Knepley       if (point[d] < -1.0) {*inside = PETSC_FALSE; break;}
14380389061SMatthew G. Knepley       sum += point[d];
14480389061SMatthew G. Knepley     }
14580389061SMatthew G. Knepley     if (sum > 0.0) {*inside = PETSC_FALSE; break;}
14680389061SMatthew G. Knepley     break;
1476c0c04f5SMatthew G. Knepley   case REFINER_HEX_2D:
14880389061SMatthew G. Knepley     for (d = 0; d < 2; ++d) if ((point[d] < -1.0) || (point[d] > 1.0)) {*inside = PETSC_FALSE; break;}
14980389061SMatthew G. Knepley     break;
15080389061SMatthew G. Knepley   default:
15180389061SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
15280389061SMatthew G. Knepley   }
15380389061SMatthew G. Knepley   PetscFunctionReturn(0);
15480389061SMatthew G. Knepley }
15580389061SMatthew G. Knepley 
15686150812SJed Brown static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[])
15775d3a19aSMatthew G. Knepley {
1586ce3c06aSMatthew G. Knepley   PetscInt       cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax;
15975d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
16075d3a19aSMatthew G. Knepley 
16175d3a19aSMatthew G. Knepley   PetscFunctionBegin;
16275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
16375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
16475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
16575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
16675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
16775d3a19aSMatthew G. Knepley   switch (refiner) {
1689b1a0e7fSLawrence Mitchell   case REFINER_NOOP:
1693478d7aaSMatthew G. Knepley     break;
1700314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
1710314a74cSLawrence Mitchell     depthSize[0] = vEnd - vStart + cEnd - cStart;         /* Add a vertex on every cell. */
1720314a74cSLawrence Mitchell     depthSize[1] = 2*(cEnd - cStart);                     /* Split every cell in 2. */
1730314a74cSLawrence Mitchell     break;
1749b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
17575d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart;         /* Add a vertex on every face */
17675d3a19aSMatthew 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 */
17775d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                     /* Every cell split into 4 cells */
17875d3a19aSMatthew G. Knepley     break;
1799b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
18075d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
18175d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
18275d3a19aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart;                                         /* Add a vertex on every face, but not hybrid faces */
18375d3a19aSMatthew 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 */
18475d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax);                                   /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */
18575d3a19aSMatthew G. Knepley     break;
1869b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
187149f48fdSMatthew G. Knepley     depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */
18875d3a19aSMatthew 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 */
18975d3a19aSMatthew G. Knepley     depthSize[2] = 4*(cEnd - cStart);                             /* Every cell split into 4 cells */
19075d3a19aSMatthew G. Knepley     break;
1919b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
192a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
193a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
194a97b51b8SMatthew G. Knepley     /* Quadrilateral */
195a97b51b8SMatthew G. Knepley     depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart;                 /* Add a vertex on every face and cell */
196a97b51b8SMatthew 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 */
197a97b51b8SMatthew G. Knepley     depthSize[2] = 4*(cMax - cStart);                                             /* Every cell split into 4 cells */
198a97b51b8SMatthew G. Knepley     /* Segment Prisms */
199a97b51b8SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
200a97b51b8SMatthew G. Knepley     depthSize[1] +=   (fEnd - fMax)  +   (cEnd - cMax);                           /* Every hybrid face remains and 1 faces is added for each hybrid cell */
201a97b51b8SMatthew G. Knepley     depthSize[2] += 2*(cEnd - cMax);                                              /* Every hybrid cell split into 2 cells */
202a97b51b8SMatthew G. Knepley     break;
2039b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
204b5da9499SMatthew G. Knepley     depthSize[0] =    vEnd - vStart  +    eEnd - eStart;                    /* Add a vertex on every edge */
205b5da9499SMatthew 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 */
206b5da9499SMatthew G. Knepley     depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart);                   /* Every face split into 4 faces and 8 faces are added for each cell */
207b5da9499SMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                       /* Every cell split into 8 cells */
208b5da9499SMatthew G. Knepley     break;
2099b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
210b5da9499SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
2116ce3c06aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
212b5da9499SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
213dae4404aSMatthew G. Knepley     /* Tetrahedra */
214dae4404aSMatthew G. Knepley     depthSize[0]  =    vEnd - vStart  +    eMax - eStart;                    /* Add a vertex on every interior edge */
215dae4404aSMatthew 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 */
216dae4404aSMatthew G. Knepley     depthSize[2]  = 4*(fMax - fStart) + 8*(cMax - cStart);                   /* Every interior face split into 4 faces, 8 faces added for each interior cell */
217dae4404aSMatthew G. Knepley     depthSize[3]  = 8*(cMax - cStart);                                       /* Every interior cell split into 8 cells */
218dae4404aSMatthew G. Knepley     /* Triangular Prisms */
219dae4404aSMatthew G. Knepley     depthSize[0] += 0;                                                       /* No hybrid vertices */
220dae4404aSMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax);                     /* Every hybrid edge remains, 1 edge for every hybrid face */
2216ce3c06aSMatthew 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 */
222dae4404aSMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                         /* Every hybrid cell split into 4 cells */
223b5da9499SMatthew G. Knepley     break;
2249b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
2256ce3c06aSMatthew G. Knepley     depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */
2266ce3c06aSMatthew 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 */
2276ce3c06aSMatthew 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 */
2286ce3c06aSMatthew G. Knepley     depthSize[3] = 8*(cEnd - cStart);                                             /* Every cell split into 8 cells */
2296ce3c06aSMatthew G. Knepley     break;
2309b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
23127fcede3SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
23227fcede3SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
23327fcede3SMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
23427fcede3SMatthew G. Knepley     /* Hexahedra */
23527fcede3SMatthew G. Knepley     depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */
23627fcede3SMatthew 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 */
23727fcede3SMatthew 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 */
23827fcede3SMatthew G. Knepley     depthSize[3] = 8*(cMax - cStart);                                             /* Every cell split into 8 cells */
23927fcede3SMatthew G. Knepley     /* Quadrilateral Prisms */
24027fcede3SMatthew G. Knepley     depthSize[0] += 0;                                                            /* No hybrid vertices */
24127fcede3SMatthew G. Knepley     depthSize[1] +=   (eEnd - eMax)   +   (fEnd - fMax)   +   (cEnd - cMax);      /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */
24227fcede3SMatthew 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 */
24327fcede3SMatthew G. Knepley     depthSize[3] += 4*(cEnd - cMax);                                              /* Every hybrid cell split into 4 cells */
24427fcede3SMatthew G. Knepley     break;
24575d3a19aSMatthew G. Knepley   default:
24675d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
24775d3a19aSMatthew G. Knepley   }
24875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
24975d3a19aSMatthew G. Knepley }
25075d3a19aSMatthew G. Knepley 
25142525629SMatthew G. Knepley /* Return triangle edge for orientation o, if it is r for o == 0 */
25242525629SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) {
253518a8359SMatthew G. Knepley   return (o < 0 ? 2-(o+r) : o+r)%3;
254518a8359SMatthew G. Knepley }
255de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) {
256de65f515SMatthew G. Knepley   return (o < 0 ? 2-(o+s) : 3+s-o)%3;
257de65f515SMatthew G. Knepley }
258518a8359SMatthew G. Knepley 
259518a8359SMatthew G. Knepley /* Return triangle subface for orientation o, if it is r for o == 0 */
260518a8359SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) {
2614bae88c7SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%3;
26242525629SMatthew G. Knepley }
263de65f515SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) {
264de65f515SMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 3+s-o)%3;
265de65f515SMatthew G. Knepley }
26642525629SMatthew G. Knepley 
267431647a4SMatthew G. Knepley /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */
268431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) {
269431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+r) : o+r)%3;
270431647a4SMatthew G. Knepley }
271431647a4SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) {
272431647a4SMatthew G. Knepley   return (o < 0 ? 1-(o+s) : 3+s-o)%3;
273431647a4SMatthew G. Knepley }
274431647a4SMatthew G. Knepley 
27542525629SMatthew G. Knepley 
276e3f8b1d6SMatthew G. Knepley /* Return quad edge for orientation o, if it is r for o == 0 */
277e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) {
278e3f8b1d6SMatthew G. Knepley   return (o < 0 ? 3-(o+r) : o+r)%4;
279e3f8b1d6SMatthew G. Knepley }
280d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) {
281d6d937efSMatthew G. Knepley   return (o < 0 ? 3-(o+s) : 4+s-o)%4;
282d6d937efSMatthew G. Knepley }
283e3f8b1d6SMatthew G. Knepley 
284e3f8b1d6SMatthew G. Knepley /* Return quad subface for orientation o, if it is r for o == 0 */
285e3f8b1d6SMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) {
2864bae88c7SMatthew G. Knepley   return (o < 0 ? 4-(o+r) : o+r)%4;
28742525629SMatthew G. Knepley }
288d6d937efSMatthew G. Knepley PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) {
289d6d937efSMatthew G. Knepley   return (o < 0 ? 4-(o+s) : 4+s-o)%4;
290d6d937efSMatthew G. Knepley }
29142525629SMatthew G. Knepley 
29286150812SJed Brown static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
29375d3a19aSMatthew G. Knepley {
294b5da9499SMatthew 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;
29575d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
29675d3a19aSMatthew G. Knepley 
29775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
2982a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
29975d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
30075d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
30175d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
30275d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
30375d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
30475d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
3052a5d0125SJed Brown   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
30675d3a19aSMatthew G. Knepley   switch (refiner) {
3070314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
3080314a74cSLawrence Mitchell     /* All cells have 2 vertices */
3090314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
3100314a74cSLawrence Mitchell       for (r = 0; r < 2; ++r) {
3110314a74cSLawrence Mitchell         const PetscInt newp = cStartNew + (c - cStart)*2 + r;
3120314a74cSLawrence Mitchell 
3130314a74cSLawrence Mitchell         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
3140314a74cSLawrence Mitchell       }
3150314a74cSLawrence Mitchell     }
3160314a74cSLawrence Mitchell     /* Old vertices have identical supports */
3170314a74cSLawrence Mitchell     for (v = vStart; v < vEnd; ++v) {
3180314a74cSLawrence Mitchell       const PetscInt newp = vStartNew + (v - vStart);
3190314a74cSLawrence Mitchell       PetscInt       size;
3200314a74cSLawrence Mitchell 
3210314a74cSLawrence Mitchell       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
3220314a74cSLawrence Mitchell       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
3230314a74cSLawrence Mitchell     }
3240314a74cSLawrence Mitchell     /* Cell vertices have support 2 */
3250314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
3260314a74cSLawrence Mitchell       const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart);
3270314a74cSLawrence Mitchell 
3280314a74cSLawrence Mitchell       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
3290314a74cSLawrence Mitchell     }
3300314a74cSLawrence Mitchell     break;
3319b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
33275d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
33375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
33475d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
33575d3a19aSMatthew G. Knepley         const PetscInt newp = (c - cStart)*4 + r;
33675d3a19aSMatthew G. Knepley 
33775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
33875d3a19aSMatthew G. Knepley       }
33975d3a19aSMatthew G. Knepley     }
34075d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
34175d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
34275d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
34375d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
34475d3a19aSMatthew G. Knepley         PetscInt       size;
34575d3a19aSMatthew G. Knepley 
34675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
34775d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
34875d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
34975d3a19aSMatthew G. Knepley       }
35075d3a19aSMatthew G. Knepley     }
35175d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
35275d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
35375d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
35475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
35575d3a19aSMatthew G. Knepley 
35675d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
35775d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
35875d3a19aSMatthew G. Knepley       }
35975d3a19aSMatthew G. Knepley     }
36075d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
36175d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
36275d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
36375d3a19aSMatthew G. Knepley       PetscInt       size;
36475d3a19aSMatthew G. Knepley 
36575d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
36675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
36775d3a19aSMatthew G. Knepley     }
36875d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
36975d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
37075d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
37175d3a19aSMatthew G. Knepley       PetscInt       size;
37275d3a19aSMatthew G. Knepley 
37375d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
37475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr);
37575d3a19aSMatthew G. Knepley     }
37675d3a19aSMatthew G. Knepley     break;
3779b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
37875d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
37975d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
38075d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
381149f48fdSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
38275d3a19aSMatthew G. Knepley 
38375d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
38475d3a19aSMatthew G. Knepley       }
38575d3a19aSMatthew G. Knepley     }
38675d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
38775d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
38875d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
38975d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
39075d3a19aSMatthew G. Knepley         PetscInt       size;
39175d3a19aSMatthew G. Knepley 
39275d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
39375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
39475d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
39575d3a19aSMatthew G. Knepley       }
39675d3a19aSMatthew G. Knepley     }
39775d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
39875d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
39975d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
40075d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
40175d3a19aSMatthew G. Knepley 
40275d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
40375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
40475d3a19aSMatthew G. Knepley       }
40575d3a19aSMatthew G. Knepley     }
40675d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
40775d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
40875d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
40975d3a19aSMatthew G. Knepley       PetscInt       size;
41075d3a19aSMatthew G. Knepley 
41175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
41275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
41375d3a19aSMatthew G. Knepley     }
41475d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
41575d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
41675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
41775d3a19aSMatthew G. Knepley       PetscInt       size;
41875d3a19aSMatthew G. Knepley 
41975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
42075d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
42175d3a19aSMatthew G. Knepley     }
42275d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
42375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
42475d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
42575d3a19aSMatthew G. Knepley 
42675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
42775d3a19aSMatthew G. Knepley     }
42875d3a19aSMatthew G. Knepley     break;
4299b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
43075d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
43175d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
43275d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
43375d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
43475d3a19aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
43575d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
43675d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
43775d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
43875d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
43975d3a19aSMatthew G. Knepley 
44075d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
44175d3a19aSMatthew G. Knepley       }
44275d3a19aSMatthew G. Knepley     }
44375d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
44475d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
44575d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
44675d3a19aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
44775d3a19aSMatthew G. Knepley 
44875d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
44975d3a19aSMatthew G. Knepley       }
45075d3a19aSMatthew G. Knepley     }
45175d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
45275d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
45375d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
45475d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
45575d3a19aSMatthew G. Knepley         PetscInt       size;
45675d3a19aSMatthew G. Knepley 
45775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
45875d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
45975d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
46075d3a19aSMatthew G. Knepley       }
46175d3a19aSMatthew G. Knepley     }
46275d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
46375d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
46475d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
46575d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
46675d3a19aSMatthew G. Knepley 
46775d3a19aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
46875d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
46975d3a19aSMatthew G. Knepley       }
47075d3a19aSMatthew G. Knepley     }
47175d3a19aSMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
47275d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
47375d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
47475d3a19aSMatthew G. Knepley       PetscInt       size;
47575d3a19aSMatthew G. Knepley 
47675d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
47775d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
47875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
47975d3a19aSMatthew G. Knepley     }
48075d3a19aSMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
48175d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
48275d3a19aSMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
48375d3a19aSMatthew G. Knepley 
48475d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
48575d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
48675d3a19aSMatthew G. Knepley     }
48775d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
48875d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
48975d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
49075d3a19aSMatthew G. Knepley       PetscInt       size;
49175d3a19aSMatthew G. Knepley 
49275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
49375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
49475d3a19aSMatthew G. Knepley     }
49575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
49675d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
49775d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
49875d3a19aSMatthew G. Knepley       const PetscInt *support;
49975d3a19aSMatthew G. Knepley       PetscInt       size, newSize = 2, s;
50075d3a19aSMatthew G. Knepley 
50175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
50275d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
50375d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
50475d3a19aSMatthew G. Knepley         if (support[s] >= cMax) newSize += 1;
50575d3a19aSMatthew G. Knepley         else newSize += 2;
50675d3a19aSMatthew G. Knepley       }
50775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr);
50875d3a19aSMatthew G. Knepley     }
50975d3a19aSMatthew G. Knepley     break;
5109b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
511a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
512a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
513a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
514a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
515a97b51b8SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
516a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
517a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
518a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
519a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*4 + r;
520a97b51b8SMatthew G. Knepley 
521a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
522a97b51b8SMatthew G. Knepley       }
523a97b51b8SMatthew G. Knepley     }
524a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
525a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
526a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
527a97b51b8SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r;
528a97b51b8SMatthew G. Knepley 
529a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
530a97b51b8SMatthew G. Knepley       }
531a97b51b8SMatthew G. Knepley     }
532a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
533a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
534a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
535a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*2 + r;
536a97b51b8SMatthew G. Knepley         PetscInt       size;
537a97b51b8SMatthew G. Knepley 
538a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
539a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
540a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
541a97b51b8SMatthew G. Knepley       }
542a97b51b8SMatthew G. Knepley     }
543a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
544a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
545a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
546a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
547a97b51b8SMatthew G. Knepley 
548a97b51b8SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
549a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
550a97b51b8SMatthew G. Knepley       }
551a97b51b8SMatthew G. Knepley     }
552a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
553a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
554a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
555a97b51b8SMatthew G. Knepley       PetscInt       size;
556a97b51b8SMatthew G. Knepley 
557a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
558a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
559a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
560a97b51b8SMatthew G. Knepley     }
561a97b51b8SMatthew G. Knepley     /* Hybrid cell faces have 2 vertices and 2 cells */
562a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
563a97b51b8SMatthew G. Knepley       const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
564a97b51b8SMatthew G. Knepley 
565a97b51b8SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
566a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
567a97b51b8SMatthew G. Knepley     }
568a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
569a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
570a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
571a97b51b8SMatthew G. Knepley       PetscInt       size;
572a97b51b8SMatthew G. Knepley 
573a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
574a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
575a97b51b8SMatthew G. Knepley     }
576a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
577a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
578a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart);
579a97b51b8SMatthew G. Knepley       PetscInt       size;
580a97b51b8SMatthew G. Knepley 
581a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
582a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
583a97b51b8SMatthew G. Knepley     }
584a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
585a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
586a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
587a97b51b8SMatthew G. Knepley 
588a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
589a97b51b8SMatthew G. Knepley     }
590a97b51b8SMatthew G. Knepley     break;
5919b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
592b5da9499SMatthew G. Knepley     /* All cells have 4 faces */
593b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
594b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
595dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
596b5da9499SMatthew G. Knepley 
597b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
598b5da9499SMatthew G. Knepley       }
599b5da9499SMatthew G. Knepley     }
600b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
601b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
602b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
603b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
604b5da9499SMatthew G. Knepley         PetscInt       size;
605b5da9499SMatthew G. Knepley 
606b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
607b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
608b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
609b5da9499SMatthew G. Knepley       }
610b5da9499SMatthew G. Knepley     }
6119ddff745SMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
612b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
613b5da9499SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
614b5da9499SMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r;
615b5da9499SMatthew G. Knepley 
616b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
617b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
618b5da9499SMatthew G. Knepley       }
619b5da9499SMatthew G. Knepley     }
620b5da9499SMatthew G. Knepley     /* Split edges have 2 vertices and the same faces */
621b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
622b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
623b5da9499SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
624b5da9499SMatthew G. Knepley         PetscInt       size;
625b5da9499SMatthew G. Knepley 
626b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
627b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
628b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
629b5da9499SMatthew G. Knepley       }
630b5da9499SMatthew G. Knepley     }
631b5da9499SMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
632b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
633b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
634b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
635b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
636b5da9499SMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
637b5da9499SMatthew G. Knepley 
638b5da9499SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
639b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
640b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
641b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
642b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
643b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
644b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
645b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
64686f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
6479ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
648b5da9499SMatthew G. Knepley           if (er == eint[c]) {
649b5da9499SMatthew G. Knepley             intFaces += 1;
650b5da9499SMatthew G. Knepley           } else {
651b5da9499SMatthew G. Knepley             intFaces += 2;
652b5da9499SMatthew G. Knepley           }
653b5da9499SMatthew G. Knepley         }
654b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
655b5da9499SMatthew G. Knepley       }
656b5da9499SMatthew G. Knepley     }
6579ddff745SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
658b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
659b5da9499SMatthew G. Knepley       const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
660b5da9499SMatthew G. Knepley 
661b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
662b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
663b5da9499SMatthew G. Knepley     }
664b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
665b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
666b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
667b5da9499SMatthew G. Knepley       PetscInt       size;
668b5da9499SMatthew G. Knepley 
669b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
670b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
671b5da9499SMatthew G. Knepley     }
672b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + faces*2 + cells*0/1 supports */
673b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
674b5da9499SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
675b5da9499SMatthew G. Knepley       PetscInt       size, *star = NULL, starSize, s, cellSize = 0;
676b5da9499SMatthew G. Knepley 
677b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
678b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
679b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
680b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
681b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
682b5da9499SMatthew G. Knepley 
683b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
684b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
685b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
686b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
687b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
68842525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
689b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
690b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
691b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
69242525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
69342525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
694b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
695b5da9499SMatthew G. Knepley         }
696b5da9499SMatthew G. Knepley       }
697b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
698b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr);
699b5da9499SMatthew G. Knepley     }
700b5da9499SMatthew G. Knepley     break;
7019b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
7026ce3c06aSMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart),
7036ce3c06aSMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
704dae4404aSMatthew G. Knepley     /* Interior cells have 4 faces */
705dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
706dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
707dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
708dae4404aSMatthew G. Knepley 
709dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
710dae4404aSMatthew G. Knepley       }
711dae4404aSMatthew G. Knepley     }
712dae4404aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
713dae4404aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
714dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
715dae4404aSMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
716dae4404aSMatthew G. Knepley 
717dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr);
718dae4404aSMatthew G. Knepley       }
719dae4404aSMatthew G. Knepley     }
7206ce3c06aSMatthew G. Knepley     /* Interior split faces have 3 edges and the same cells as the parent */
721dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
722dae4404aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
723dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
724dae4404aSMatthew G. Knepley         PetscInt       size;
725dae4404aSMatthew G. Knepley 
726dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
727dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
728dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
729dae4404aSMatthew G. Knepley       }
730dae4404aSMatthew G. Knepley     }
731dae4404aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
732dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
733dae4404aSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
734dae4404aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r;
735dae4404aSMatthew G. Knepley 
736dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr);
737dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
738dae4404aSMatthew G. Knepley       }
739dae4404aSMatthew G. Knepley     }
7406ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
7416ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
7426ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
7436ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
7446ce3c06aSMatthew G. Knepley         PetscInt       size;
7456ce3c06aSMatthew G. Knepley 
7466ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
7476ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
7486ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
7496ce3c06aSMatthew G. Knepley       }
7506ce3c06aSMatthew G. Knepley     }
7516ce3c06aSMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
7526ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
7536ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
7546ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r;
7556ce3c06aSMatthew G. Knepley 
7566ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
7576ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
7586ce3c06aSMatthew G. Knepley       }
7596ce3c06aSMatthew G. Knepley     }
7606ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces */
761dae4404aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
762dae4404aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
763dae4404aSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
764dae4404aSMatthew G. Knepley         PetscInt       size;
765dae4404aSMatthew G. Knepley 
766dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
767dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
768dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
769dae4404aSMatthew G. Knepley       }
770dae4404aSMatthew G. Knepley     }
7716ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
772dae4404aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
773dae4404aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
774dae4404aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
775dae4404aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0};
776dae4404aSMatthew G. Knepley         PetscInt        coneSize, c, supportSize, s, er, intFaces = 0;
777dae4404aSMatthew G. Knepley 
778dae4404aSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
779dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
780dae4404aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
781dae4404aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
782dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
783dae4404aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
784dae4404aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
785dae4404aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
7866ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
787dae4404aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
7889ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
789dae4404aSMatthew G. Knepley             if (er == eint[c]) {
790dae4404aSMatthew G. Knepley               intFaces += 1;
791dae4404aSMatthew G. Knepley             } else {
792dae4404aSMatthew G. Knepley               intFaces += 2;
793dae4404aSMatthew G. Knepley             }
7946ce3c06aSMatthew G. Knepley           } else {
7956ce3c06aSMatthew G. Knepley             intFaces += 1;
7966ce3c06aSMatthew G. Knepley           }
797dae4404aSMatthew G. Knepley         }
798dae4404aSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr);
799dae4404aSMatthew G. Knepley       }
800dae4404aSMatthew G. Knepley     }
8016ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
802dae4404aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
803dae4404aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
804dae4404aSMatthew G. Knepley 
805dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
806dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
807dae4404aSMatthew G. Knepley     }
8086ce3c06aSMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
809dae4404aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
8106ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
8116ce3c06aSMatthew G. Knepley       PetscInt       size;
8126ce3c06aSMatthew G. Knepley 
8136ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
8146ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
8156ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
8166ce3c06aSMatthew G. Knepley     }
8176ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
8186ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
8196ce3c06aSMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
820dae4404aSMatthew G. Knepley       PetscInt       size;
821dae4404aSMatthew G. Knepley 
822dae4404aSMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
823dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
8246ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr);
825dae4404aSMatthew G. Knepley     }
8266ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
827dae4404aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
828dae4404aSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
829dae4404aSMatthew G. Knepley       PetscInt       size;
830dae4404aSMatthew G. Knepley 
831dae4404aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
832dae4404aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
833dae4404aSMatthew G. Knepley     }
8346ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
8356ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
8366ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
837dae4404aSMatthew G. Knepley       const PetscInt *support;
8386ce3c06aSMatthew G. Knepley       PetscInt        size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0;
839dae4404aSMatthew G. Knepley 
8406ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
8416ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
842dae4404aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
8436ce3c06aSMatthew G. Knepley         if (support[s] < fMax) faceSize += 2;
8446ce3c06aSMatthew G. Knepley         else                   faceSize += 1;
845dae4404aSMatthew G. Knepley       }
8466ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
8476ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
8486ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
8496ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
8506ce3c06aSMatthew G. Knepley 
8516ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
8526ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
8536ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
8546ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
8556ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
8566ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
8576ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
8586ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
8596ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
8606ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
8616ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
8626ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) ++cellSize;
8636ce3c06aSMatthew G. Knepley         }
8646ce3c06aSMatthew G. Knepley       }
8656ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
8666ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr);
867dae4404aSMatthew G. Knepley     }
868dae4404aSMatthew G. Knepley     break;
8699b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
8702eabf88fSMatthew G. Knepley     /* All cells have 6 faces */
8712eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
8722eabf88fSMatthew G. Knepley       for (r = 0; r < 8; ++r) {
8732eabf88fSMatthew G. Knepley         const PetscInt newp = (c - cStart)*8 + r;
8742eabf88fSMatthew G. Knepley 
8752eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
8762eabf88fSMatthew G. Knepley       }
8772eabf88fSMatthew G. Knepley     }
8782eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
8792eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
8802eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
8812eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
8822eabf88fSMatthew G. Knepley         PetscInt       size;
8832eabf88fSMatthew G. Knepley 
8842eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
8852eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
8862eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
8872eabf88fSMatthew G. Knepley       }
8882eabf88fSMatthew G. Knepley     }
8892eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
8902eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
8912eabf88fSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
8922eabf88fSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
8932eabf88fSMatthew G. Knepley 
8942eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
8952eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
8962eabf88fSMatthew G. Knepley       }
8972eabf88fSMatthew G. Knepley     }
8982eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
8992eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
9002eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
9012eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
9022eabf88fSMatthew G. Knepley         PetscInt       size;
9032eabf88fSMatthew G. Knepley 
9042eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
9052eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
9062eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
9072eabf88fSMatthew G. Knepley       }
9082eabf88fSMatthew G. Knepley     }
9092eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
9102eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
9112eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
9122eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
9132eabf88fSMatthew G. Knepley         PetscInt       size;
9142eabf88fSMatthew G. Knepley 
9152eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
9162eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
9172eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
9182eabf88fSMatthew G. Knepley       }
9192eabf88fSMatthew G. Knepley     }
9202eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
9212eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
9222eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
9232eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
9242eabf88fSMatthew G. Knepley 
9252eabf88fSMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
9262eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
9272eabf88fSMatthew G. Knepley       }
9282eabf88fSMatthew G. Knepley     }
9292eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
9302eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
9312eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
9322eabf88fSMatthew G. Knepley       PetscInt       size;
9332eabf88fSMatthew G. Knepley 
9342eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
9352eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
9362eabf88fSMatthew G. Knepley     }
9372eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
9382eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
9392eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
9402eabf88fSMatthew G. Knepley       PetscInt       size;
9412eabf88fSMatthew G. Knepley 
9422eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
9432eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
9442eabf88fSMatthew G. Knepley     }
9452eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
9462eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
9472eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
9482eabf88fSMatthew G. Knepley       PetscInt       size;
9492eabf88fSMatthew G. Knepley 
9502eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
9512eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
9522eabf88fSMatthew G. Knepley     }
9532eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
9542eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
9552eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
9562eabf88fSMatthew G. Knepley 
9572eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
9582eabf88fSMatthew G. Knepley     }
9592eabf88fSMatthew G. Knepley     break;
9609b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
96127fcede3SMatthew G. Knepley     ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart),
96227fcede3SMatthew G. Knepley                                  eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr);
96327fcede3SMatthew G. Knepley     /* Interior cells have 6 faces */
96427fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
96527fcede3SMatthew G. Knepley       for (r = 0; r < 8; ++r) {
96627fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (c - cStart)*8 + r;
96727fcede3SMatthew G. Knepley 
96827fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
96927fcede3SMatthew G. Knepley       }
97027fcede3SMatthew G. Knepley     }
97127fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces */
97227fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
97327fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
97427fcede3SMatthew G. Knepley         const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r;
97527fcede3SMatthew G. Knepley 
97627fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr);
97727fcede3SMatthew G. Knepley       }
97827fcede3SMatthew G. Knepley     }
97927fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
98027fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
98127fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
98227fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (f - fStart)*4 + r;
98327fcede3SMatthew G. Knepley         PetscInt       size;
98427fcede3SMatthew G. Knepley 
98527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
98627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
98727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
98827fcede3SMatthew G. Knepley       }
98927fcede3SMatthew G. Knepley     }
99027fcede3SMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
99127fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
99227fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
99327fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
99427fcede3SMatthew G. Knepley 
99527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
99627fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
99727fcede3SMatthew G. Knepley       }
99827fcede3SMatthew G. Knepley     }
99927fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and the same cells as the parent */
100027fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
100127fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
100227fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
100327fcede3SMatthew G. Knepley         PetscInt       size;
100427fcede3SMatthew G. Knepley 
100527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
100627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
100727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
100827fcede3SMatthew G. Knepley       }
100927fcede3SMatthew G. Knepley     }
101027fcede3SMatthew G. Knepley     /* Hybrid cells faces have 4 edges and 2 cells */
101127fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
101227fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
101327fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r;
101427fcede3SMatthew G. Knepley 
101527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr);
101627fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr);
101727fcede3SMatthew G. Knepley       }
101827fcede3SMatthew G. Knepley     }
101927fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
102027fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
102127fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
102227fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (e - eStart)*2 + r;
102327fcede3SMatthew G. Knepley         PetscInt       size;
102427fcede3SMatthew G. Knepley 
102527fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
102627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
102727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
102827fcede3SMatthew G. Knepley       }
102927fcede3SMatthew G. Knepley     }
103027fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
103127fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
103227fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
103327fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
103427fcede3SMatthew G. Knepley         PetscInt       size;
103527fcede3SMatthew G. Knepley 
103627fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
103727fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
103827fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
103927fcede3SMatthew G. Knepley       }
104027fcede3SMatthew G. Knepley     }
104127fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
104227fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
104327fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
104427fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
104527fcede3SMatthew G. Knepley 
104627fcede3SMatthew G. Knepley         ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
104727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
104827fcede3SMatthew G. Knepley       }
104927fcede3SMatthew G. Knepley     }
105027fcede3SMatthew G. Knepley     /* Hybrid edges have 2 vertices and the same faces */
105127fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
105227fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
105327fcede3SMatthew G. Knepley       PetscInt       size;
105427fcede3SMatthew G. Knepley 
105527fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
105627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
105727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
105827fcede3SMatthew G. Knepley     }
105927fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
106027fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
106127fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
106227fcede3SMatthew G. Knepley       PetscInt       size;
106327fcede3SMatthew G. Knepley 
106427fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
106527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
106627fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr);
106727fcede3SMatthew G. Knepley     }
106827fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
106927fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
107027fcede3SMatthew G. Knepley       const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
107127fcede3SMatthew G. Knepley 
107227fcede3SMatthew G. Knepley       ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr);
107327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr);
107427fcede3SMatthew G. Knepley     }
107527fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
107627fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
107727fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (v - vStart);
107827fcede3SMatthew G. Knepley       PetscInt       size;
107927fcede3SMatthew G. Knepley 
108027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
108127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr);
108227fcede3SMatthew G. Knepley     }
108327fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
108427fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
108527fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart);
108627fcede3SMatthew G. Knepley       PetscInt       size;
108727fcede3SMatthew G. Knepley 
108827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
108927fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr);
109027fcede3SMatthew G. Knepley     }
109127fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
109227fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
109327fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
109427fcede3SMatthew G. Knepley       PetscInt       size;
109527fcede3SMatthew G. Knepley 
109627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
109727fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr);
109827fcede3SMatthew G. Knepley     }
109927fcede3SMatthew G. Knepley     /* Interior cell vertices have 6 supports */
110027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
110127fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
110227fcede3SMatthew G. Knepley 
110327fcede3SMatthew G. Knepley       ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr);
110427fcede3SMatthew G. Knepley     }
110527fcede3SMatthew G. Knepley     break;
110675d3a19aSMatthew G. Knepley   default:
110775d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
110875d3a19aSMatthew G. Knepley   }
110975d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
111075d3a19aSMatthew G. Knepley }
111175d3a19aSMatthew G. Knepley 
111286150812SJed Brown static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
111375d3a19aSMatthew G. Knepley {
1114b5da9499SMatthew G. Knepley   const PetscInt *faces, cellInd[4] = {0, 1, 2, 3};
11156ce3c06aSMatthew G. Knepley   PetscInt        cStart,    cEnd,    cMax,    vStart,    vEnd, vMax, fStart,    fEnd,    fMax,    eStart,    eEnd,    eMax;
11166ce3c06aSMatthew G. Knepley   PetscInt        cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew,    fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew;
11176ce3c06aSMatthew G. Knepley   PetscInt        depth, maxSupportSize, *supportRef, c, f, e, v, r, p;
111875d3a19aSMatthew G. Knepley   PetscErrorCode  ierr;
111975d3a19aSMatthew G. Knepley 
112075d3a19aSMatthew G. Knepley   PetscFunctionBegin;
11212a5d0125SJed Brown   if (!refiner) PetscFunctionReturn(0);
112275d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
112375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
112475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
112575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
112675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
112775d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
112875d3a19aSMatthew G. Knepley   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);
112975d3a19aSMatthew G. Knepley   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr);
113075d3a19aSMatthew G. Knepley   switch (refiner) {
11310314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
11320314a74cSLawrence Mitchell     /* Max support size of refined mesh is 2 */
11330314a74cSLawrence Mitchell     ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr);
11340314a74cSLawrence Mitchell     /* All cells have 2 vertices */
11350314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
11360314a74cSLawrence Mitchell       const PetscInt  newv = vStartNew + (vEnd - vStart) + (c - cStart);
11370314a74cSLawrence Mitchell 
11380314a74cSLawrence Mitchell       for (r = 0; r < 2; ++r) {
11390314a74cSLawrence Mitchell         const PetscInt newp = cStartNew + (c - cStart)*2 + r;
11400314a74cSLawrence Mitchell         const PetscInt *cone;
11410314a74cSLawrence Mitchell         PetscInt        coneNew[2];
11420314a74cSLawrence Mitchell 
11430314a74cSLawrence Mitchell         ierr             = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
11440314a74cSLawrence Mitchell         coneNew[0]       = vStartNew + (cone[0] - vStart);
11450314a74cSLawrence Mitchell         coneNew[1]       = vStartNew + (cone[1] - vStart);
11460314a74cSLawrence Mitchell         coneNew[(r+1)%2] = newv;
11470314a74cSLawrence Mitchell         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
11480314a74cSLawrence Mitchell #if 1
11490314a74cSLawrence Mitchell         if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp, cStartNew, cEndNew);
11500314a74cSLawrence Mitchell         for (p = 0; p < 2; ++p) {
11510314a74cSLawrence Mitchell           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);
11520314a74cSLawrence Mitchell         }
11530314a74cSLawrence Mitchell #endif
11540314a74cSLawrence Mitchell       }
11550314a74cSLawrence Mitchell     }
11560314a74cSLawrence Mitchell     /* Old vertices have identical supports */
11570314a74cSLawrence Mitchell     for (v = vStart; v < vEnd; ++v) {
11580314a74cSLawrence Mitchell       const PetscInt  newp = vStartNew + (v - vStart);
11590314a74cSLawrence Mitchell       const PetscInt *support, *cone;
11600314a74cSLawrence Mitchell       PetscInt        size, s;
11610314a74cSLawrence Mitchell 
11620314a74cSLawrence Mitchell       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
11630314a74cSLawrence Mitchell       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
11640314a74cSLawrence Mitchell       for (s = 0; s < size; ++s) {
11650314a74cSLawrence Mitchell         PetscInt r = 0;
11660314a74cSLawrence Mitchell 
11670314a74cSLawrence Mitchell         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
11680314a74cSLawrence Mitchell         if (cone[1] == v) r = 1;
11690314a74cSLawrence Mitchell         supportRef[s] = cStartNew + (support[s] - cStart)*2 + r;
11700314a74cSLawrence Mitchell       }
11710314a74cSLawrence Mitchell       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
11720314a74cSLawrence Mitchell #if 1
11730314a74cSLawrence Mitchell       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
11740314a74cSLawrence Mitchell       for (p = 0; p < size; ++p) {
11750314a74cSLawrence Mitchell         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);
11760314a74cSLawrence Mitchell       }
11770314a74cSLawrence Mitchell #endif
11780314a74cSLawrence Mitchell     }
11790314a74cSLawrence Mitchell     /* Cell vertices have support of 2 cells */
11800314a74cSLawrence Mitchell     for (c = cStart; c < cEnd; ++c) {
11810314a74cSLawrence Mitchell       const PetscInt  newp = vStartNew + (vEnd - vStart) + (c - cStart);
11820314a74cSLawrence Mitchell 
11830314a74cSLawrence Mitchell       supportRef[0] = cStartNew + (c - cStart)*2 + 0;
11840314a74cSLawrence Mitchell       supportRef[1] = cStartNew + (c - cStart)*2 + 1;
11850314a74cSLawrence Mitchell       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
11860314a74cSLawrence Mitchell #if 1
11870314a74cSLawrence Mitchell       if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew);
11880314a74cSLawrence Mitchell       for (p = 0; p < 2; ++p) {
11890314a74cSLawrence Mitchell         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);
11900314a74cSLawrence Mitchell       }
11910314a74cSLawrence Mitchell #endif
11920314a74cSLawrence Mitchell     }
11930314a74cSLawrence Mitchell     ierr = PetscFree(supportRef);CHKERRQ(ierr);
11940314a74cSLawrence Mitchell     break;
11959b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
119675d3a19aSMatthew G. Knepley     /*
119775d3a19aSMatthew G. Knepley      2
119875d3a19aSMatthew G. Knepley      |\
119975d3a19aSMatthew G. Knepley      | \
120075d3a19aSMatthew G. Knepley      |  \
120175d3a19aSMatthew G. Knepley      |   \
120275d3a19aSMatthew G. Knepley      | C  \
120375d3a19aSMatthew G. Knepley      |     \
120475d3a19aSMatthew G. Knepley      |      \
120575d3a19aSMatthew G. Knepley      2---1---1
120675d3a19aSMatthew G. Knepley      |\  D  / \
120775d3a19aSMatthew G. Knepley      | 2   0   \
120875d3a19aSMatthew G. Knepley      |A \ /  B  \
120975d3a19aSMatthew G. Knepley      0---0-------1
121075d3a19aSMatthew G. Knepley      */
121175d3a19aSMatthew G. Knepley     /* All cells have 3 faces */
121275d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
121375d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
121475d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
121575d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
121675d3a19aSMatthew G. Knepley 
121775d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
121875d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
121975d3a19aSMatthew G. Knepley       /* A triangle */
122075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
122175d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
122275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
122375d3a19aSMatthew G. Knepley       orntNew[1] = -2;
122475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
122575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
122675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
122775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
122875d3a19aSMatthew G. Knepley #if 1
122975d3a19aSMatthew 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);
123075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
123175d3a19aSMatthew 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);
123275d3a19aSMatthew G. Knepley       }
123375d3a19aSMatthew G. Knepley #endif
123475d3a19aSMatthew G. Knepley       /* B triangle */
123575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
123675d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
123775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
123875d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
123975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
124075d3a19aSMatthew G. Knepley       orntNew[2] = -2;
124175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
124275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
124375d3a19aSMatthew G. Knepley #if 1
124475d3a19aSMatthew 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);
124575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
124675d3a19aSMatthew 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);
124775d3a19aSMatthew G. Knepley       }
124875d3a19aSMatthew G. Knepley #endif
124975d3a19aSMatthew G. Knepley       /* C triangle */
125075d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
125175d3a19aSMatthew G. Knepley       orntNew[0] = -2;
125275d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
125375d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
125475d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
125575d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
125675d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
125775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
125875d3a19aSMatthew G. Knepley #if 1
125975d3a19aSMatthew 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);
126075d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
126175d3a19aSMatthew 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);
126275d3a19aSMatthew G. Knepley       }
126375d3a19aSMatthew G. Knepley #endif
126475d3a19aSMatthew G. Knepley       /* D triangle */
126575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 0;
126675d3a19aSMatthew G. Knepley       orntNew[0] = 0;
126775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 1;
126875d3a19aSMatthew G. Knepley       orntNew[1] = 0;
126975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*3 + 2;
127075d3a19aSMatthew G. Knepley       orntNew[2] = 0;
127175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
127275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
127375d3a19aSMatthew G. Knepley #if 1
127475d3a19aSMatthew 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);
127575d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
127675d3a19aSMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew);
127775d3a19aSMatthew G. Knepley       }
127875d3a19aSMatthew G. Knepley #endif
127975d3a19aSMatthew G. Knepley     }
128075d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
128175d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1282854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
128375d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
128475d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
128575d3a19aSMatthew G. Knepley 
128675d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
128775d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1288297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
128975d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
129075d3a19aSMatthew G. Knepley 
129175d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
129275d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
129375d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
129475d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
129575d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
129675d3a19aSMatthew G. Knepley #if 1
129775d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
129875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
129975d3a19aSMatthew 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);
130075d3a19aSMatthew G. Knepley         }
130175d3a19aSMatthew G. Knepley #endif
130275d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
130375d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
130475d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
130575d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
130675d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1307297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
130875d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
130975d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
131075d3a19aSMatthew G. Knepley           }
1311297d2bf4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
131275d3a19aSMatthew G. Knepley         }
131375d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
131475d3a19aSMatthew G. Knepley #if 1
131575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
131675d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
131775d3a19aSMatthew 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);
131875d3a19aSMatthew G. Knepley         }
131975d3a19aSMatthew G. Knepley #endif
132075d3a19aSMatthew G. Knepley       }
132175d3a19aSMatthew G. Knepley     }
132275d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
132375d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
132475d3a19aSMatthew G. Knepley       const PetscInt *cone;
132575d3a19aSMatthew G. Knepley 
132675d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
132775d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
132875d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r;
132975d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
133075d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
133175d3a19aSMatthew G. Knepley 
133275d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
133375d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
133475d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
133575d3a19aSMatthew G. Knepley #if 1
133675d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
133775d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
133875d3a19aSMatthew 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);
133975d3a19aSMatthew G. Knepley         }
134075d3a19aSMatthew G. Knepley #endif
134175d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
134275d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
134375d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
134475d3a19aSMatthew G. Knepley #if 1
134575d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
134675d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
134775d3a19aSMatthew 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);
134875d3a19aSMatthew G. Knepley         }
134975d3a19aSMatthew G. Knepley #endif
135075d3a19aSMatthew G. Knepley       }
135175d3a19aSMatthew G. Knepley     }
135275d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
135375d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
135475d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
135575d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
135675d3a19aSMatthew G. Knepley       PetscInt        size, s;
135775d3a19aSMatthew G. Knepley 
135875d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
135975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
136075d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
136175d3a19aSMatthew G. Knepley         PetscInt r = 0;
136275d3a19aSMatthew G. Knepley 
136375d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
136475d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
136575d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
136675d3a19aSMatthew G. Knepley       }
136775d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
136875d3a19aSMatthew G. Knepley #if 1
136975d3a19aSMatthew 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);
137075d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
137175d3a19aSMatthew 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);
137275d3a19aSMatthew G. Knepley       }
137375d3a19aSMatthew G. Knepley #endif
137475d3a19aSMatthew G. Knepley     }
137575d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells*2 supports */
137675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
137775d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
137875d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
137975d3a19aSMatthew G. Knepley       PetscInt        size, s;
138075d3a19aSMatthew G. Knepley 
138175d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
138275d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
138375d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
138475d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
138575d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
138675d3a19aSMatthew G. Knepley         PetscInt r = 0;
138775d3a19aSMatthew G. Knepley 
138875d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
138975d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
139075d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
139175d3a19aSMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
139275d3a19aSMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r;
139375d3a19aSMatthew G. Knepley       }
139475d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
139575d3a19aSMatthew G. Knepley #if 1
139675d3a19aSMatthew 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);
139775d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
139875d3a19aSMatthew 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);
139975d3a19aSMatthew G. Knepley       }
140075d3a19aSMatthew G. Knepley #endif
140175d3a19aSMatthew G. Knepley     }
140275d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
140375d3a19aSMatthew G. Knepley     break;
14049b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
140575d3a19aSMatthew G. Knepley     /*
140675d3a19aSMatthew G. Knepley      3---------2---------2
140775d3a19aSMatthew G. Knepley      |         |         |
140875d3a19aSMatthew G. Knepley      |    D    2    C    |
140975d3a19aSMatthew G. Knepley      |         |         |
141075d3a19aSMatthew G. Knepley      3----3----0----1----1
141175d3a19aSMatthew G. Knepley      |         |         |
141275d3a19aSMatthew G. Knepley      |    A    0    B    |
141375d3a19aSMatthew G. Knepley      |         |         |
141475d3a19aSMatthew G. Knepley      0---------0---------1
141575d3a19aSMatthew G. Knepley      */
141675d3a19aSMatthew G. Knepley     /* All cells have 4 faces */
141775d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
141875d3a19aSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*4;
141975d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
142075d3a19aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
142175d3a19aSMatthew G. Knepley 
142275d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
142375d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
142475d3a19aSMatthew G. Knepley       /* A quad */
142575d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
142675d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
142775d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
142875d3a19aSMatthew G. Knepley       orntNew[1] = 0;
142975d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
143075d3a19aSMatthew G. Knepley       orntNew[2] = -2;
143175d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
143275d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
143375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
143475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
143575d3a19aSMatthew G. Knepley #if 1
143675d3a19aSMatthew 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);
143775d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
143875d3a19aSMatthew 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);
143975d3a19aSMatthew G. Knepley       }
144075d3a19aSMatthew G. Knepley #endif
144175d3a19aSMatthew G. Knepley       /* B quad */
144275d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
144375d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
144475d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
144575d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
144675d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
144775d3a19aSMatthew G. Knepley       orntNew[2] = 0;
144875d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 0;
144975d3a19aSMatthew G. Knepley       orntNew[3] = -2;
145075d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
145175d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
145275d3a19aSMatthew G. Knepley #if 1
145375d3a19aSMatthew 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);
145475d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
145575d3a19aSMatthew 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);
145675d3a19aSMatthew G. Knepley       }
145775d3a19aSMatthew G. Knepley #endif
145875d3a19aSMatthew G. Knepley       /* C quad */
145975d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 1;
146075d3a19aSMatthew G. Knepley       orntNew[0] = -2;
146175d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
146275d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
146375d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
146475d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
146575d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
146675d3a19aSMatthew G. Knepley       orntNew[3] = 0;
146775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
146875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
146975d3a19aSMatthew G. Knepley #if 1
147075d3a19aSMatthew 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);
147175d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
147275d3a19aSMatthew 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);
147375d3a19aSMatthew G. Knepley       }
147475d3a19aSMatthew G. Knepley #endif
147575d3a19aSMatthew G. Knepley       /* D quad */
147675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 3;
147775d3a19aSMatthew G. Knepley       orntNew[0] = 0;
147875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*2 + (c - cStart)*4 + 2;
147975d3a19aSMatthew G. Knepley       orntNew[1] = -2;
148075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
148175d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
148275d3a19aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
148375d3a19aSMatthew G. Knepley       orntNew[3] = ornt[3];
148475d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
148575d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
148675d3a19aSMatthew G. Knepley #if 1
148775d3a19aSMatthew 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);
148875d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
148975d3a19aSMatthew 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);
149075d3a19aSMatthew G. Knepley       }
149175d3a19aSMatthew G. Knepley #endif
149275d3a19aSMatthew G. Knepley     }
149375d3a19aSMatthew G. Knepley     /* Split faces have 2 vertices and the same cells as the parent */
149475d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1495854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
149675d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
149775d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
149875d3a19aSMatthew G. Knepley 
149975d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
150075d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1501455d6cd4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
150275d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
150375d3a19aSMatthew G. Knepley 
150475d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
150575d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
150675d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
150775d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
150875d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
150975d3a19aSMatthew G. Knepley #if 1
151075d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
151175d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
151275d3a19aSMatthew 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);
151375d3a19aSMatthew G. Knepley         }
151475d3a19aSMatthew G. Knepley #endif
151575d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
151675d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
151775d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
151875d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
151975d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1520455d6cd4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
152175d3a19aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
152275d3a19aSMatthew G. Knepley             if (cone[c] == f) break;
152375d3a19aSMatthew G. Knepley           }
1524455d6cd4SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
152575d3a19aSMatthew G. Knepley         }
152675d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
152775d3a19aSMatthew G. Knepley #if 1
152875d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
152975d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
153075d3a19aSMatthew 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);
153175d3a19aSMatthew G. Knepley         }
153275d3a19aSMatthew G. Knepley #endif
153375d3a19aSMatthew G. Knepley       }
153475d3a19aSMatthew G. Knepley     }
153575d3a19aSMatthew G. Knepley     /* Interior faces have 2 vertices and 2 cells */
153675d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
153775d3a19aSMatthew G. Knepley       const PetscInt *cone;
153875d3a19aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
153975d3a19aSMatthew G. Knepley 
154075d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
154175d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
154275d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
154375d3a19aSMatthew G. Knepley 
154475d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
154575d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd    - fStart) + (c - cStart);
154675d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
154775d3a19aSMatthew G. Knepley #if 1
154875d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
154975d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
155075d3a19aSMatthew 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);
155175d3a19aSMatthew G. Knepley         }
155275d3a19aSMatthew G. Knepley #endif
155375d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
155475d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
155575d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
155675d3a19aSMatthew G. Knepley #if 1
155775d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
155875d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
155975d3a19aSMatthew G. Knepley           if ((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);
156075d3a19aSMatthew G. Knepley         }
156175d3a19aSMatthew G. Knepley #endif
156275d3a19aSMatthew G. Knepley       }
156375d3a19aSMatthew G. Knepley     }
156475d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
156575d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
156675d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
156775d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
156875d3a19aSMatthew G. Knepley       PetscInt        size, s;
156975d3a19aSMatthew G. Knepley 
157075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
157175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
157275d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
157375d3a19aSMatthew G. Knepley         PetscInt r = 0;
157475d3a19aSMatthew G. Knepley 
157575d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
157675d3a19aSMatthew G. Knepley         if (cone[1] == v) r = 1;
157775d3a19aSMatthew G. Knepley         supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
157875d3a19aSMatthew G. Knepley       }
157975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
158075d3a19aSMatthew G. Knepley #if 1
158175d3a19aSMatthew 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);
158275d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
158375d3a19aSMatthew 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);
158475d3a19aSMatthew G. Knepley       }
158575d3a19aSMatthew G. Knepley #endif
158675d3a19aSMatthew G. Knepley     }
158775d3a19aSMatthew G. Knepley     /* Face vertices have 2 + cells supports */
158875d3a19aSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
158975d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
159075d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
159175d3a19aSMatthew G. Knepley       PetscInt        size, s;
159275d3a19aSMatthew G. Knepley 
159375d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
159475d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
159575d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
159675d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
159775d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
159875d3a19aSMatthew G. Knepley         PetscInt r = 0;
159975d3a19aSMatthew G. Knepley 
160075d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
160175d3a19aSMatthew G. Knepley         if      (cone[1] == f) r = 1;
160275d3a19aSMatthew G. Knepley         else if (cone[2] == f) r = 2;
160375d3a19aSMatthew G. Knepley         else if (cone[3] == f) r = 3;
160475d3a19aSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r;
160575d3a19aSMatthew G. Knepley       }
160675d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
160775d3a19aSMatthew G. Knepley #if 1
160875d3a19aSMatthew 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);
160975d3a19aSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
161075d3a19aSMatthew 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);
161175d3a19aSMatthew G. Knepley       }
161275d3a19aSMatthew G. Knepley #endif
161375d3a19aSMatthew G. Knepley     }
161475d3a19aSMatthew G. Knepley     /* Cell vertices have 4 supports */
161575d3a19aSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
161675d3a19aSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart);
161775d3a19aSMatthew G. Knepley       PetscInt       supportNew[4];
161875d3a19aSMatthew G. Knepley 
161975d3a19aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
162075d3a19aSMatthew G. Knepley         supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r;
162175d3a19aSMatthew G. Knepley       }
162275d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
162375d3a19aSMatthew G. Knepley     }
1624da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
162575d3a19aSMatthew G. Knepley     break;
16269b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
162775d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
162875d3a19aSMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
162975d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
163075d3a19aSMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
1631149f48fdSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
163275d3a19aSMatthew G. Knepley     /* Interior cells have 3 faces */
163375d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
163475d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
163575d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
163675d3a19aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
163775d3a19aSMatthew G. Knepley 
163875d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
163975d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
164075d3a19aSMatthew G. Knepley       /* A triangle */
164175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
164275d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
164375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
164475d3a19aSMatthew G. Knepley       orntNew[1] = -2;
164575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
164675d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
164775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
164875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
164975d3a19aSMatthew G. Knepley #if 1
1650149f48fdSMatthew 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);
165175d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1652149f48fdSMatthew 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);
165375d3a19aSMatthew G. Knepley       }
165475d3a19aSMatthew G. Knepley #endif
165575d3a19aSMatthew G. Knepley       /* B triangle */
165675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
165775d3a19aSMatthew G. Knepley       orntNew[0] = ornt[0];
165875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
165975d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
166075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
166175d3a19aSMatthew G. Knepley       orntNew[2] = -2;
166275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
166375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
166475d3a19aSMatthew G. Knepley #if 1
1665a97b51b8SMatthew 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);
166675d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1667a97b51b8SMatthew 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);
166875d3a19aSMatthew G. Knepley       }
166975d3a19aSMatthew G. Knepley #endif
167075d3a19aSMatthew G. Knepley       /* C triangle */
167175d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
167275d3a19aSMatthew G. Knepley       orntNew[0] = -2;
167375d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
167475d3a19aSMatthew G. Knepley       orntNew[1] = ornt[1];
167575d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
167675d3a19aSMatthew G. Knepley       orntNew[2] = ornt[2];
167775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
167875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
167975d3a19aSMatthew G. Knepley #if 1
1680a97b51b8SMatthew 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);
168175d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1682a97b51b8SMatthew 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);
168375d3a19aSMatthew G. Knepley       }
168475d3a19aSMatthew G. Knepley #endif
168575d3a19aSMatthew G. Knepley       /* D triangle */
168675d3a19aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 0;
168775d3a19aSMatthew G. Knepley       orntNew[0] = 0;
168875d3a19aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 1;
168975d3a19aSMatthew G. Knepley       orntNew[1] = 0;
169075d3a19aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*3 + 2;
169175d3a19aSMatthew G. Knepley       orntNew[2] = 0;
169275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
169375d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
169475d3a19aSMatthew G. Knepley #if 1
1695a97b51b8SMatthew 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);
169675d3a19aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
1697a97b51b8SMatthew 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);
169875d3a19aSMatthew G. Knepley       }
169975d3a19aSMatthew G. Knepley #endif
170075d3a19aSMatthew G. Knepley     }
170175d3a19aSMatthew G. Knepley     /*
170275d3a19aSMatthew G. Knepley      2----3----3
170375d3a19aSMatthew G. Knepley      |         |
170475d3a19aSMatthew G. Knepley      |    B    |
170575d3a19aSMatthew G. Knepley      |         |
170675d3a19aSMatthew G. Knepley      0----4--- 1
170775d3a19aSMatthew G. Knepley      |         |
170875d3a19aSMatthew G. Knepley      |    A    |
170975d3a19aSMatthew G. Knepley      |         |
171075d3a19aSMatthew G. Knepley      0----2----1
171175d3a19aSMatthew G. Knepley      */
171275d3a19aSMatthew G. Knepley     /* Hybrid cells have 4 faces */
171375d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
171475d3a19aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
171575d3a19aSMatthew G. Knepley       const PetscInt *cone, *ornt;
1716ea00e70eSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4], r;
171775d3a19aSMatthew G. Knepley 
171875d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
171975d3a19aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1720ea00e70eSMatthew G. Knepley       r    = (ornt[0] < 0 ? 1 : 0);
172175d3a19aSMatthew G. Knepley       /* A quad */
1722ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + r;
172375d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
1724ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + r;
172575d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
1726ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax);
1727ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
1728ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
1729ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
173075d3a19aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
173175d3a19aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
173275d3a19aSMatthew G. Knepley #if 1
173375d3a19aSMatthew 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);
173475d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
173575d3a19aSMatthew 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);
173675d3a19aSMatthew G. Knepley       }
173775d3a19aSMatthew G. Knepley #endif
173875d3a19aSMatthew G. Knepley       /* B quad */
1739ea00e70eSMatthew G. Knepley       coneNew[0]   = fStartNew + (cone[0] - fStart)*2 + 1-r;
174075d3a19aSMatthew G. Knepley       orntNew[0]   = ornt[0];
1741ea00e70eSMatthew G. Knepley       coneNew[1]   = fStartNew + (cone[1] - fStart)*2 + 1-r;
174275d3a19aSMatthew G. Knepley       orntNew[1]   = ornt[1];
1743ea00e70eSMatthew G. Knepley       coneNew[2+r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (fEnd    - fMax) + (c - cMax);
1744ea00e70eSMatthew G. Knepley       orntNew[2+r] = 0;
1745ea00e70eSMatthew G. Knepley       coneNew[3-r] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax);
1746ea00e70eSMatthew G. Knepley       orntNew[3-r] = 0;
174775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
174875d3a19aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
174975d3a19aSMatthew G. Knepley #if 1
175075d3a19aSMatthew 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);
175175d3a19aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
175275d3a19aSMatthew 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);
175375d3a19aSMatthew G. Knepley       }
175475d3a19aSMatthew G. Knepley #endif
175575d3a19aSMatthew G. Knepley     }
175675d3a19aSMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
175775d3a19aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
1758854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
175975d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
176075d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
176175d3a19aSMatthew G. Knepley 
176275d3a19aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
176375d3a19aSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
1764297d2bf4SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
176575d3a19aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
176675d3a19aSMatthew G. Knepley 
176775d3a19aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
176875d3a19aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
176975d3a19aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
177075d3a19aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
177175d3a19aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
177275d3a19aSMatthew G. Knepley #if 1
177375d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
177475d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
177575d3a19aSMatthew 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);
177675d3a19aSMatthew G. Knepley         }
177775d3a19aSMatthew G. Knepley #endif
177875d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
177975d3a19aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
178075d3a19aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
178175d3a19aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
178275d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1783297d2bf4SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
1784ea00e70eSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == f) break;
1785ea00e70eSMatthew G. Knepley           if (support[s] >= cMax) {
1786ea00e70eSMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r);
1787ea00e70eSMatthew G. Knepley           } else {
1788297d2bf4SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3);
178975d3a19aSMatthew G. Knepley           }
179075d3a19aSMatthew G. Knepley         }
179175d3a19aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
179275d3a19aSMatthew G. Knepley #if 1
179375d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
179475d3a19aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
179575d3a19aSMatthew 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);
179675d3a19aSMatthew G. Knepley         }
179775d3a19aSMatthew G. Knepley #endif
179875d3a19aSMatthew G. Knepley       }
179975d3a19aSMatthew G. Knepley     }
180075d3a19aSMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
180175d3a19aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
180275d3a19aSMatthew G. Knepley       const PetscInt *cone;
180375d3a19aSMatthew G. Knepley 
180475d3a19aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
180575d3a19aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
180675d3a19aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r;
180775d3a19aSMatthew G. Knepley         PetscInt       coneNew[2];
180875d3a19aSMatthew G. Knepley         PetscInt       supportNew[2];
180975d3a19aSMatthew G. Knepley 
181075d3a19aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r]       - fStart);
181175d3a19aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart);
181275d3a19aSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
181375d3a19aSMatthew G. Knepley #if 1
181475d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
181575d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
181675d3a19aSMatthew 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);
181775d3a19aSMatthew G. Knepley         }
181875d3a19aSMatthew G. Knepley #endif
181975d3a19aSMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + (r+1)%3;
182075d3a19aSMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + 3;
182175d3a19aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
182275d3a19aSMatthew G. Knepley #if 1
182375d3a19aSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
182475d3a19aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
182575d3a19aSMatthew 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);
182675d3a19aSMatthew G. Knepley         }
182775d3a19aSMatthew G. Knepley #endif
182875d3a19aSMatthew G. Knepley       }
182975d3a19aSMatthew G. Knepley     }
183075d3a19aSMatthew G. Knepley     /* Interior hybrid faces have 2 vertices and the same cells */
183175d3a19aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
183275d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax);
1833ea00e70eSMatthew G. Knepley       const PetscInt *cone, *ornt;
183475d3a19aSMatthew G. Knepley       const PetscInt *support;
183575d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
183675d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
183775d3a19aSMatthew G. Knepley       PetscInt        size, s, r;
183875d3a19aSMatthew G. Knepley 
183975d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
184075d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
184175d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
184275d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
184375d3a19aSMatthew G. Knepley #if 1
184475d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
184575d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
184675d3a19aSMatthew 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);
184775d3a19aSMatthew G. Knepley       }
184875d3a19aSMatthew G. Knepley #endif
184975d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
185075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
185175d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
185275d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
1853ea00e70eSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
185475d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r) {
185575d3a19aSMatthew G. Knepley           if (cone[r+2] == f) break;
185675d3a19aSMatthew G. Knepley         }
1857ea00e70eSMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r);
185875d3a19aSMatthew G. Knepley       }
185975d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
186075d3a19aSMatthew G. Knepley #if 1
186175d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
186275d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
186375d3a19aSMatthew 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);
186475d3a19aSMatthew G. Knepley       }
186575d3a19aSMatthew G. Knepley #endif
186675d3a19aSMatthew G. Knepley     }
186775d3a19aSMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
186875d3a19aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
186975d3a19aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax);
187075d3a19aSMatthew G. Knepley       const PetscInt *cone;
187175d3a19aSMatthew G. Knepley       PetscInt        coneNew[2];
187275d3a19aSMatthew G. Knepley       PetscInt        supportNew[2];
187375d3a19aSMatthew G. Knepley 
187475d3a19aSMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
187575d3a19aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
187675d3a19aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
187775d3a19aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
187875d3a19aSMatthew G. Knepley #if 1
187975d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
188075d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
188175d3a19aSMatthew 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);
188275d3a19aSMatthew G. Knepley       }
188375d3a19aSMatthew G. Knepley #endif
188475d3a19aSMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
188575d3a19aSMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
188675d3a19aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
188775d3a19aSMatthew G. Knepley #if 1
188875d3a19aSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
188975d3a19aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
189075d3a19aSMatthew 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);
189175d3a19aSMatthew G. Knepley       }
189275d3a19aSMatthew G. Knepley #endif
189375d3a19aSMatthew G. Knepley     }
189475d3a19aSMatthew G. Knepley     /* Old vertices have identical supports */
189575d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
189675d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
189775d3a19aSMatthew G. Knepley       const PetscInt *support, *cone;
189875d3a19aSMatthew G. Knepley       PetscInt        size, s;
189975d3a19aSMatthew G. Knepley 
190075d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
190175d3a19aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
190275d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
190375d3a19aSMatthew G. Knepley         if (support[s] >= fMax) {
190475d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax);
190575d3a19aSMatthew G. Knepley         } else {
190675d3a19aSMatthew G. Knepley           PetscInt r = 0;
190775d3a19aSMatthew G. Knepley 
190875d3a19aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
190975d3a19aSMatthew G. Knepley           if (cone[1] == v) r = 1;
191075d3a19aSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
191175d3a19aSMatthew G. Knepley         }
191275d3a19aSMatthew G. Knepley       }
191375d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
191475d3a19aSMatthew G. Knepley #if 1
191575d3a19aSMatthew 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);
191675d3a19aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
191775d3a19aSMatthew 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);
191875d3a19aSMatthew G. Knepley       }
191975d3a19aSMatthew G. Knepley #endif
192075d3a19aSMatthew G. Knepley     }
192175d3a19aSMatthew G. Knepley     /* Face vertices have 2 + (2 interior, 1 hybrid) supports */
192275d3a19aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
192375d3a19aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
192475d3a19aSMatthew G. Knepley       const PetscInt *cone, *support;
192575d3a19aSMatthew G. Knepley       PetscInt        size, newSize = 2, s;
192675d3a19aSMatthew G. Knepley 
192775d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
192875d3a19aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
192975d3a19aSMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
193075d3a19aSMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
193175d3a19aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
193275d3a19aSMatthew G. Knepley         PetscInt r = 0;
193375d3a19aSMatthew G. Knepley 
193475d3a19aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
193575d3a19aSMatthew G. Knepley         if (support[s] >= cMax) {
193675d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax);
193775d3a19aSMatthew G. Knepley 
193875d3a19aSMatthew G. Knepley           newSize += 1;
193975d3a19aSMatthew G. Knepley         } else {
194075d3a19aSMatthew G. Knepley           if      (cone[1] == f) r = 1;
194175d3a19aSMatthew G. Knepley           else if (cone[2] == f) r = 2;
194275d3a19aSMatthew G. Knepley           supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3;
194375d3a19aSMatthew G. Knepley           supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r;
194475d3a19aSMatthew G. Knepley 
194575d3a19aSMatthew G. Knepley           newSize += 2;
194675d3a19aSMatthew G. Knepley         }
194775d3a19aSMatthew G. Knepley       }
194875d3a19aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
194975d3a19aSMatthew G. Knepley #if 1
195075d3a19aSMatthew 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);
195175d3a19aSMatthew G. Knepley       for (p = 0; p < newSize; ++p) {
195275d3a19aSMatthew 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);
195375d3a19aSMatthew G. Knepley       }
195475d3a19aSMatthew G. Knepley #endif
195575d3a19aSMatthew G. Knepley     }
195675d3a19aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
195775d3a19aSMatthew G. Knepley     break;
19589b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
1959a97b51b8SMatthew G. Knepley     /* Hybrid Hex 2D */
1960a97b51b8SMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
1961a97b51b8SMatthew G. Knepley     cMax = PetscMin(cEnd, cMax);
1962a97b51b8SMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
1963a97b51b8SMatthew G. Knepley     fMax = PetscMin(fEnd, fMax);
1964a97b51b8SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr);
1965a97b51b8SMatthew G. Knepley     /* Interior cells have 4 faces */
1966a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
1967a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*4;
1968a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
1969a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
1970a97b51b8SMatthew G. Knepley 
1971a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
1972a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
1973a97b51b8SMatthew G. Knepley       /* A quad */
1974a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
1975a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1976a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
1977a97b51b8SMatthew G. Knepley       orntNew[1] = 0;
1978a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
1979a97b51b8SMatthew G. Knepley       orntNew[2] = -2;
1980a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1);
1981a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
1982a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
1983a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
1984a97b51b8SMatthew G. Knepley #if 1
1985a97b51b8SMatthew 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);
1986a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
1987a97b51b8SMatthew 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);
1988a97b51b8SMatthew G. Knepley       }
1989a97b51b8SMatthew G. Knepley #endif
1990a97b51b8SMatthew G. Knepley       /* B quad */
1991a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
1992a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
1993a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
1994a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
1995a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
1996a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
1997a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 0;
1998a97b51b8SMatthew G. Knepley       orntNew[3] = -2;
1999a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2000a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2001a97b51b8SMatthew G. Knepley #if 1
2002a97b51b8SMatthew 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);
2003a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2004a97b51b8SMatthew 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);
2005a97b51b8SMatthew G. Knepley       }
2006a97b51b8SMatthew G. Knepley #endif
2007a97b51b8SMatthew G. Knepley       /* C quad */
2008a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 1;
2009a97b51b8SMatthew G. Knepley       orntNew[0] = -2;
2010a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2011a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2012a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0);
2013a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
2014a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
2015a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2016a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2017a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2018a97b51b8SMatthew G. Knepley #if 1
2019a97b51b8SMatthew 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);
2020a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2021a97b51b8SMatthew 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);
2022a97b51b8SMatthew G. Knepley       }
2023a97b51b8SMatthew G. Knepley #endif
2024a97b51b8SMatthew G. Knepley       /* D quad */
2025a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 3;
2026a97b51b8SMatthew G. Knepley       orntNew[0] = 0;
2027a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*2 + (c - cStart)*4 + 2;
2028a97b51b8SMatthew G. Knepley       orntNew[1] = -2;
2029a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1);
2030a97b51b8SMatthew G. Knepley       orntNew[2] = ornt[2];
2031a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0);
2032a97b51b8SMatthew G. Knepley       orntNew[3] = ornt[3];
2033a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2034a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2035a97b51b8SMatthew G. Knepley #if 1
2036a97b51b8SMatthew 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);
2037a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2038a97b51b8SMatthew 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);
2039a97b51b8SMatthew G. Knepley       }
2040a97b51b8SMatthew G. Knepley #endif
2041a97b51b8SMatthew G. Knepley     }
2042a97b51b8SMatthew G. Knepley     /*
2043a97b51b8SMatthew G. Knepley      2----3----3
2044a97b51b8SMatthew G. Knepley      |         |
2045a97b51b8SMatthew G. Knepley      |    B    |
2046a97b51b8SMatthew G. Knepley      |         |
2047a97b51b8SMatthew G. Knepley      0----4--- 1
2048a97b51b8SMatthew G. Knepley      |         |
2049a97b51b8SMatthew G. Knepley      |    A    |
2050a97b51b8SMatthew G. Knepley      |         |
2051a97b51b8SMatthew G. Knepley      0----2----1
2052a97b51b8SMatthew G. Knepley      */
2053a97b51b8SMatthew G. Knepley     /* Hybrid cells have 4 faces */
2054a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2055a97b51b8SMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2;
2056a97b51b8SMatthew G. Knepley       const PetscInt *cone, *ornt;
2057a97b51b8SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2058a97b51b8SMatthew G. Knepley 
2059a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2060a97b51b8SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2061a97b51b8SMatthew G. Knepley       /* A quad */
2062a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0);
2063a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2064a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0);
2065a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2066a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax);
2067a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2068a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2069a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2070a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2071a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2072a97b51b8SMatthew G. Knepley #if 1
2073a97b51b8SMatthew 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);
2074a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2075a97b51b8SMatthew 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);
2076a97b51b8SMatthew G. Knepley       }
2077a97b51b8SMatthew G. Knepley #endif
2078a97b51b8SMatthew G. Knepley       /* B quad */
2079a97b51b8SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1);
2080a97b51b8SMatthew G. Knepley       orntNew[0] = ornt[0];
2081a97b51b8SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1);
2082a97b51b8SMatthew G. Knepley       orntNew[1] = ornt[1];
2083a97b51b8SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (fEnd    - fMax) + (c - cMax);
2084a97b51b8SMatthew G. Knepley       orntNew[2] = 0;
2085a97b51b8SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax);
2086a97b51b8SMatthew G. Knepley       orntNew[3] = 0;
2087a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2088a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2089a97b51b8SMatthew G. Knepley #if 1
2090a97b51b8SMatthew 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);
2091a97b51b8SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2092a97b51b8SMatthew 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);
2093a97b51b8SMatthew G. Knepley       }
2094a97b51b8SMatthew G. Knepley #endif
2095a97b51b8SMatthew G. Knepley     }
2096a97b51b8SMatthew G. Knepley     /* Interior split faces have 2 vertices and the same cells as the parent */
2097a97b51b8SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2098854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2099a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2100a97b51b8SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart);
2101a97b51b8SMatthew G. Knepley 
2102a97b51b8SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2103a97b51b8SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*2 + r;
2104a97b51b8SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2105a97b51b8SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2106a97b51b8SMatthew G. Knepley 
2107a97b51b8SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2108a97b51b8SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2109a97b51b8SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2110a97b51b8SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2111a97b51b8SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2112a97b51b8SMatthew G. Knepley #if 1
2113a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2114a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2115a97b51b8SMatthew 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);
2116a97b51b8SMatthew G. Knepley         }
2117a97b51b8SMatthew G. Knepley #endif
2118a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2119a97b51b8SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2120a97b51b8SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2121a97b51b8SMatthew G. Knepley           if (support[s] >= cMax) {
2122a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2123a97b51b8SMatthew G. Knepley           } else {
2124a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2125a97b51b8SMatthew G. Knepley             ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2126a97b51b8SMatthew G. Knepley             ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2127a97b51b8SMatthew G. Knepley             for (c = 0; c < coneSize; ++c) {
2128a97b51b8SMatthew G. Knepley               if (cone[c] == f) break;
2129a97b51b8SMatthew G. Knepley             }
2130a97b51b8SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
2131a97b51b8SMatthew G. Knepley           }
2132a97b51b8SMatthew G. Knepley         }
2133a97b51b8SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2134a97b51b8SMatthew G. Knepley #if 1
2135a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2136a97b51b8SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2137a97b51b8SMatthew 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);
2138a97b51b8SMatthew G. Knepley         }
2139a97b51b8SMatthew G. Knepley #endif
2140a97b51b8SMatthew G. Knepley       }
2141a97b51b8SMatthew G. Knepley     }
2142a97b51b8SMatthew G. Knepley     /* Interior cell faces have 2 vertices and 2 cells */
2143a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2144a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2145a97b51b8SMatthew G. Knepley 
2146a97b51b8SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2147a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2148a97b51b8SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2149a97b51b8SMatthew G. Knepley         PetscInt       coneNew[2], supportNew[2];
2150a97b51b8SMatthew G. Knepley 
2151a97b51b8SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart);
2152a97b51b8SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (fMax    - fStart) + (c - cStart);
2153a97b51b8SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2154a97b51b8SMatthew G. Knepley #if 1
2155a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2156a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2157a97b51b8SMatthew 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);
2158a97b51b8SMatthew G. Knepley         }
2159a97b51b8SMatthew G. Knepley #endif
2160a97b51b8SMatthew G. Knepley         supportNew[0] = (c - cStart)*4 + r;
2161a97b51b8SMatthew G. Knepley         supportNew[1] = (c - cStart)*4 + (r+1)%4;
2162a97b51b8SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2163a97b51b8SMatthew G. Knepley #if 1
2164a97b51b8SMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2165a97b51b8SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2166a97b51b8SMatthew 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);
2167a97b51b8SMatthew G. Knepley         }
2168a97b51b8SMatthew G. Knepley #endif
2169a97b51b8SMatthew G. Knepley       }
2170a97b51b8SMatthew G. Knepley     }
2171a97b51b8SMatthew G. Knepley     /* Hybrid faces have 2 vertices and the same cells */
2172a97b51b8SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
2173a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax);
2174a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2175a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2176a97b51b8SMatthew G. Knepley       PetscInt        size, s, r;
2177a97b51b8SMatthew G. Knepley 
2178a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2179a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
2180a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
2181a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2182a97b51b8SMatthew G. Knepley #if 1
2183a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2184a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2185a97b51b8SMatthew 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);
2186a97b51b8SMatthew G. Knepley       }
2187a97b51b8SMatthew G. Knepley #endif
2188a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2189a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2190a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2191a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2192a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r) {
2193a97b51b8SMatthew G. Knepley           if (cone[r+2] == f) break;
2194a97b51b8SMatthew G. Knepley         }
2195a97b51b8SMatthew G. Knepley         supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r;
2196a97b51b8SMatthew G. Knepley       }
2197a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2198a97b51b8SMatthew G. Knepley #if 1
2199a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2200a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2201a97b51b8SMatthew 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);
2202a97b51b8SMatthew G. Knepley       }
2203a97b51b8SMatthew G. Knepley #endif
2204a97b51b8SMatthew G. Knepley     }
2205a97b51b8SMatthew G. Knepley     /* Cell hybrid faces have 2 vertices and 2 cells */
2206a97b51b8SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
2207a97b51b8SMatthew G. Knepley       const PetscInt  newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax);
2208a97b51b8SMatthew G. Knepley       const PetscInt *cone;
2209a97b51b8SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[2];
2210a97b51b8SMatthew G. Knepley 
2211a97b51b8SMatthew G. Knepley       ierr       = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2212a97b51b8SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart);
2213a97b51b8SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart);
2214a97b51b8SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2215a97b51b8SMatthew G. Knepley #if 1
2216a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2217a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2218a97b51b8SMatthew 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);
2219a97b51b8SMatthew G. Knepley       }
2220a97b51b8SMatthew G. Knepley #endif
2221a97b51b8SMatthew G. Knepley       supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0;
2222a97b51b8SMatthew G. Knepley       supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1;
2223a97b51b8SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2224a97b51b8SMatthew G. Knepley #if 1
2225a97b51b8SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2226a97b51b8SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2227a97b51b8SMatthew 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);
2228a97b51b8SMatthew G. Knepley       }
2229a97b51b8SMatthew G. Knepley #endif
2230a97b51b8SMatthew G. Knepley     }
2231a97b51b8SMatthew G. Knepley     /* Old vertices have identical supports */
2232a97b51b8SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2233a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2234a97b51b8SMatthew G. Knepley       const PetscInt *support, *cone;
2235a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2236a97b51b8SMatthew G. Knepley 
2237a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2238a97b51b8SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2239a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2240a97b51b8SMatthew G. Knepley         if (support[s] >= fMax) {
2241a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax);
2242a97b51b8SMatthew G. Knepley         } else {
2243a97b51b8SMatthew G. Knepley           PetscInt r = 0;
2244a97b51b8SMatthew G. Knepley 
2245a97b51b8SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2246a97b51b8SMatthew G. Knepley           if (cone[1] == v) r = 1;
2247a97b51b8SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*2 + r;
2248a97b51b8SMatthew G. Knepley         }
2249a97b51b8SMatthew G. Knepley       }
2250a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2251a97b51b8SMatthew G. Knepley #if 1
2252a97b51b8SMatthew 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);
2253a97b51b8SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2254a97b51b8SMatthew 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);
2255a97b51b8SMatthew G. Knepley       }
2256a97b51b8SMatthew G. Knepley #endif
2257a97b51b8SMatthew G. Knepley     }
2258a97b51b8SMatthew G. Knepley     /* Face vertices have 2 + cells supports */
2259a97b51b8SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
2260a97b51b8SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (f - fStart);
2261a97b51b8SMatthew G. Knepley       const PetscInt *cone, *support;
2262a97b51b8SMatthew G. Knepley       PetscInt        size, s;
2263a97b51b8SMatthew G. Knepley 
2264a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
2265a97b51b8SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2266a97b51b8SMatthew G. Knepley       supportRef[0] = fStartNew + (f - fStart)*2 + 0;
2267a97b51b8SMatthew G. Knepley       supportRef[1] = fStartNew + (f - fStart)*2 + 1;
2268a97b51b8SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2269a97b51b8SMatthew G. Knepley         PetscInt r = 0;
2270a97b51b8SMatthew G. Knepley 
2271a97b51b8SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2272a97b51b8SMatthew G. Knepley         if (support[s] >= cMax) {
2273a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax);
2274a97b51b8SMatthew G. Knepley         } else {
2275a97b51b8SMatthew G. Knepley           if      (cone[1] == f) r = 1;
2276a97b51b8SMatthew G. Knepley           else if (cone[2] == f) r = 2;
2277a97b51b8SMatthew G. Knepley           else if (cone[3] == f) r = 3;
2278a97b51b8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r;
2279a97b51b8SMatthew G. Knepley         }
2280a97b51b8SMatthew G. Knepley       }
2281a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2282a97b51b8SMatthew G. Knepley #if 1
2283a97b51b8SMatthew 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);
2284a97b51b8SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
2285a97b51b8SMatthew 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);
2286a97b51b8SMatthew G. Knepley       }
2287a97b51b8SMatthew G. Knepley #endif
2288a97b51b8SMatthew G. Knepley     }
2289a97b51b8SMatthew G. Knepley     /* Cell vertices have 4 supports */
2290a97b51b8SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
2291a97b51b8SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart);
2292a97b51b8SMatthew G. Knepley       PetscInt       supportNew[4];
2293a97b51b8SMatthew G. Knepley 
2294a97b51b8SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2295a97b51b8SMatthew G. Knepley         supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r;
2296a97b51b8SMatthew G. Knepley       }
2297a97b51b8SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2298a97b51b8SMatthew G. Knepley     }
2299a97b51b8SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2300a97b51b8SMatthew G. Knepley     break;
23019b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
2302b5da9499SMatthew G. Knepley     /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
2303b5da9499SMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
2304b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2305b5da9499SMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
2306b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2307b5da9499SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
2308b5da9499SMatthew G. Knepley 
2309b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2310b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2311b5da9499SMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
2312518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
2313b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2314518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
2315b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2316518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
2317b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2318b5da9499SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2319b5da9499SMatthew G. Knepley       orntNew[3] = 0;
2320b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2321b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2322b5da9499SMatthew G. Knepley #if 1
2323b5da9499SMatthew 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);
2324b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2325b5da9499SMatthew 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);
2326b5da9499SMatthew G. Knepley       }
2327b5da9499SMatthew G. Knepley #endif
2328b5da9499SMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
2329518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
2330b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2331518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
2332b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2333b5da9499SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
2334b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2335518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
2336b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2337b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2338b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2339b5da9499SMatthew G. Knepley #if 1
2340b5da9499SMatthew 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);
2341b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2342b5da9499SMatthew 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);
2343b5da9499SMatthew G. Knepley       }
2344b5da9499SMatthew G. Knepley #endif
2345b5da9499SMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
2346518a8359SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
2347b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2348b5da9499SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
2349b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2350518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
2351b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2352518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
2353b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2354b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2355b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2356b5da9499SMatthew G. Knepley #if 1
2357b5da9499SMatthew 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);
2358b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2359b5da9499SMatthew 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);
2360b5da9499SMatthew G. Knepley       }
2361b5da9499SMatthew G. Knepley #endif
2362b5da9499SMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
2363b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
2364b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2365518a8359SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
2366b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2367518a8359SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
2368b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2369518a8359SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
2370b5da9499SMatthew G. Knepley       orntNew[3] = ornt[3];
2371b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2372b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2373b5da9499SMatthew G. Knepley #if 1
2374b5da9499SMatthew 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);
2375b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2376b5da9499SMatthew 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);
2377b5da9499SMatthew G. Knepley       }
2378b5da9499SMatthew G. Knepley #endif
23793fe31fa2SToby Isaac       /* A' tetrahedron: {c, d, a, f} */
2380b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 0;
2381b5da9499SMatthew G. Knepley       orntNew[0] = -3;
2382fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
2383db2c6090SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
2384fac4ab25SMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
2385fac4ab25SMatthew G. Knepley       orntNew[2] = 0;
2386fac4ab25SMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
2387fac4ab25SMatthew G. Knepley       orntNew[3] = 2;
2388b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
2389b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
2390b5da9499SMatthew G. Knepley #if 1
2391b5da9499SMatthew 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);
2392b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2393b5da9499SMatthew 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);
2394b5da9499SMatthew G. Knepley       }
2395b5da9499SMatthew G. Knepley #endif
2396b5da9499SMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
2397b5da9499SMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 1;
23983fe31fa2SToby Isaac       orntNew[0] = -2;
23993fe31fa2SToby Isaac       coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3;
24003fe31fa2SToby Isaac       orntNew[1] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 1)+1) : GetTetSomething_Static(ornt[3], 1);
24013fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
2402b5da9499SMatthew G. Knepley       orntNew[2] = 0;
24033fe31fa2SToby Isaac       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
24043fe31fa2SToby Isaac       orntNew[3] = 0;
2405b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
2406b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
2407b5da9499SMatthew G. Knepley #if 1
2408b5da9499SMatthew 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);
2409b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2410b5da9499SMatthew 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);
2411b5da9499SMatthew G. Knepley       }
2412b5da9499SMatthew G. Knepley #endif
24133fe31fa2SToby Isaac       /* C' tetrahedron: {f, a, c, b} */
24143fe31fa2SToby Isaac       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 5;
24153fe31fa2SToby Isaac       orntNew[0] = -2;
24163fe31fa2SToby Isaac       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 7;
24173fe31fa2SToby Isaac       orntNew[1] = -2;
24183fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 2;
24193fe31fa2SToby Isaac       orntNew[2] = -1;
24203fe31fa2SToby Isaac       coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3;
24213fe31fa2SToby Isaac       orntNew[3] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
2422b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
2423b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
2424b5da9499SMatthew G. Knepley #if 1
2425b5da9499SMatthew 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);
2426b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2427b5da9499SMatthew 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);
2428b5da9499SMatthew G. Knepley       }
2429b5da9499SMatthew G. Knepley #endif
24303fe31fa2SToby Isaac       /* D' tetrahedron: {f, a, e, d} */
24313fe31fa2SToby Isaac       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 6;
24323fe31fa2SToby Isaac       orntNew[0] = -2;
2433fac4ab25SMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 4;
24343fe31fa2SToby Isaac       orntNew[1] = -1;
24353fe31fa2SToby Isaac       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*8 + 3;
24363fe31fa2SToby Isaac       orntNew[2] = -2;
24373fe31fa2SToby Isaac       coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3;
24383fe31fa2SToby Isaac       orntNew[3] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 1)+1) : GetTetSomething_Static(ornt[1], 1);
2439b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
2440b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
2441b5da9499SMatthew G. Knepley #if 1
2442b5da9499SMatthew 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);
2443b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2444b5da9499SMatthew 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);
2445b5da9499SMatthew G. Knepley       }
2446b5da9499SMatthew G. Knepley #endif
2447b5da9499SMatthew G. Knepley     }
2448b5da9499SMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
2449b5da9499SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
2450854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
2451b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2452b5da9499SMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
2453b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2454b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
2455b5da9499SMatthew G. Knepley 
2456b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2457b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
2458b5da9499SMatthew G. Knepley       /* A triangle */
2459b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
2460b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2461b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2462b5da9499SMatthew G. Knepley       orntNew[1] = -2;
2463b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
2464b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2465b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
2466b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
2467b5da9499SMatthew G. Knepley #if 1
2468b5da9499SMatthew 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);
2469b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2470b5da9499SMatthew 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);
2471b5da9499SMatthew G. Knepley       }
2472b5da9499SMatthew G. Knepley #endif
2473b5da9499SMatthew G. Knepley       /* B triangle */
2474b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
2475b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0];
2476b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
2477b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2478b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2479b5da9499SMatthew G. Knepley       orntNew[2] = -2;
2480b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
2481b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
2482b5da9499SMatthew G. Knepley #if 1
2483b5da9499SMatthew 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);
2484b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2485b5da9499SMatthew 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);
2486b5da9499SMatthew G. Knepley       }
2487b5da9499SMatthew G. Knepley #endif
2488b5da9499SMatthew G. Knepley       /* C triangle */
2489b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2490b5da9499SMatthew G. Knepley       orntNew[0] = -2;
2491b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
2492b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1];
2493b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
2494b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2];
2495b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
2496b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
2497b5da9499SMatthew G. Knepley #if 1
2498b5da9499SMatthew 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);
2499b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2500b5da9499SMatthew 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);
2501b5da9499SMatthew G. Knepley       }
2502b5da9499SMatthew G. Knepley #endif
2503b5da9499SMatthew G. Knepley       /* D triangle */
2504b5da9499SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 0;
2505b5da9499SMatthew G. Knepley       orntNew[0] = 0;
2506b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 1;
2507b5da9499SMatthew G. Knepley       orntNew[1] = 0;
2508b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd    - eStart)*2 + (f - fStart)*3 + 2;
2509b5da9499SMatthew G. Knepley       orntNew[2] = 0;
2510b5da9499SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
2511b5da9499SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
2512b5da9499SMatthew G. Knepley #if 1
2513b5da9499SMatthew 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);
2514b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2515b5da9499SMatthew 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);
2516b5da9499SMatthew G. Knepley       }
2517b5da9499SMatthew G. Knepley #endif
2518b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2519b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2520b5da9499SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
2521b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2522219f7b90SMatthew G. Knepley           PetscInt subf;
2523b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2524b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2525b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2526b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2527b5da9499SMatthew G. Knepley             if (cone[c] == f) break;
2528b5da9499SMatthew G. Knepley           }
2529219f7b90SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
2530219f7b90SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
2531b5da9499SMatthew G. Knepley         }
2532b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
2533b5da9499SMatthew G. Knepley #if 1
25349ddff745SMatthew 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);
2535b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2536b5da9499SMatthew 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);
2537b5da9499SMatthew G. Knepley         }
2538b5da9499SMatthew G. Knepley #endif
2539b5da9499SMatthew G. Knepley       }
2540b5da9499SMatthew G. Knepley     }
2541b5da9499SMatthew G. Knepley     /* Interior faces have 3 edges and 2 cells */
2542b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2543b5da9499SMatthew G. Knepley       PetscInt        newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8;
2544b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt;
2545b5da9499SMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
2546b5da9499SMatthew G. Knepley       PetscInt        supportNew[2];
2547b5da9499SMatthew G. Knepley 
2548b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2549b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2550b5da9499SMatthew G. Knepley       /* Face A: {c, a, d} */
25514bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2552b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
25534bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2554b5da9499SMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
25554bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
2556b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2557b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2558b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2559b5da9499SMatthew G. Knepley #if 1
2560b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2561b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2562b5da9499SMatthew 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);
2563b5da9499SMatthew G. Knepley       }
2564b5da9499SMatthew G. Knepley #endif
2565b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
2566b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
2567b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2568b5da9499SMatthew G. Knepley #if 1
2569b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2570b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2571b5da9499SMatthew 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);
2572b5da9499SMatthew G. Knepley       }
2573b5da9499SMatthew G. Knepley #endif
2574b5da9499SMatthew G. Knepley       ++newp;
2575b5da9499SMatthew G. Knepley       /* Face B: {a, b, e} */
25764bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2577b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
25784bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
2579b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
25804bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2581b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2582b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2583b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2584b5da9499SMatthew G. Knepley #if 1
25854bb260e2SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2586b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2587b5da9499SMatthew 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);
2588b5da9499SMatthew G. Knepley       }
2589b5da9499SMatthew G. Knepley #endif
2590b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
2591b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
2592b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2593b5da9499SMatthew G. Knepley #if 1
2594b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2595b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2596b5da9499SMatthew 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);
2597b5da9499SMatthew G. Knepley       }
2598b5da9499SMatthew G. Knepley #endif
2599b5da9499SMatthew G. Knepley       ++newp;
2600b5da9499SMatthew G. Knepley       /* Face C: {c, f, b} */
26014bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
2602b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
26034bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2604b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
26054bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
2606b5da9499SMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
2607b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2608b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2609b5da9499SMatthew G. Knepley #if 1
2610b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2611b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2612b5da9499SMatthew 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);
2613b5da9499SMatthew G. Knepley       }
2614b5da9499SMatthew G. Knepley #endif
2615b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
2616b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2617b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2618b5da9499SMatthew G. Knepley #if 1
2619b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2620b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2621b5da9499SMatthew 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);
2622b5da9499SMatthew G. Knepley       }
2623b5da9499SMatthew G. Knepley #endif
2624b5da9499SMatthew G. Knepley       ++newp;
2625b5da9499SMatthew G. Knepley       /* Face D: {d, e, f} */
26264bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
2627b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
26284bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2629b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
26304bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2631b5da9499SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
2632b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2633b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2634b5da9499SMatthew G. Knepley #if 1
2635b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2636b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2637b5da9499SMatthew 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);
2638b5da9499SMatthew G. Knepley       }
2639b5da9499SMatthew G. Knepley #endif
2640b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
2641b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2642b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2643b5da9499SMatthew G. Knepley #if 1
2644b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2645b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2646b5da9499SMatthew 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);
2647b5da9499SMatthew G. Knepley       }
2648b5da9499SMatthew G. Knepley #endif
2649b5da9499SMatthew G. Knepley       ++newp;
2650b5da9499SMatthew G. Knepley       /* Face E: {d, f, a} */
26514bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
2652b5da9499SMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
2653b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
26544bb260e2SMatthew G. Knepley       orntNew[1] = -2;
26554bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
2656b5da9499SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
2657b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2658b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2659b5da9499SMatthew G. Knepley #if 1
2660b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2661b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2662b5da9499SMatthew 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);
2663b5da9499SMatthew G. Knepley       }
2664b5da9499SMatthew G. Knepley #endif
2665b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2666b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2667b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2668b5da9499SMatthew G. Knepley #if 1
2669b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2670b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2671b5da9499SMatthew 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);
2672b5da9499SMatthew G. Knepley       }
2673b5da9499SMatthew G. Knepley #endif
2674b5da9499SMatthew G. Knepley       ++newp;
2675b5da9499SMatthew G. Knepley       /* Face F: {c, a, f} */
26764bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
2677b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
2678b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
26794bb260e2SMatthew G. Knepley       orntNew[1] = 0;
26804bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
26812baf2947SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
2682b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2683b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2684b5da9499SMatthew G. Knepley #if 1
2685b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2686b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2687b5da9499SMatthew 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);
2688b5da9499SMatthew G. Knepley       }
2689b5da9499SMatthew G. Knepley #endif
2690b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
2691b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2692b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2693b5da9499SMatthew G. Knepley #if 1
2694b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2695b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2696b5da9499SMatthew 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);
2697b5da9499SMatthew G. Knepley       }
2698b5da9499SMatthew G. Knepley #endif
2699b5da9499SMatthew G. Knepley       ++newp;
2700b5da9499SMatthew G. Knepley       /* Face G: {e, a, f} */
27014bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
2702b5da9499SMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
2703b5da9499SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2704fac4ab25SMatthew G. Knepley       orntNew[1] = 0;
27054bb260e2SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
2706b5da9499SMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
2707b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2708b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2709b5da9499SMatthew G. Knepley #if 1
2710b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2711b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2712b5da9499SMatthew 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);
2713b5da9499SMatthew G. Knepley       }
2714b5da9499SMatthew G. Knepley #endif
2715b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2716b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
2717b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2718b5da9499SMatthew G. Knepley #if 1
2719b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2720b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2721b5da9499SMatthew 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);
2722b5da9499SMatthew G. Knepley       }
2723b5da9499SMatthew G. Knepley #endif
2724b5da9499SMatthew G. Knepley       ++newp;
2725b5da9499SMatthew G. Knepley       /* Face H: {a, b, f} */
27264bb260e2SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
2727b5da9499SMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
27284bb260e2SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
2729b5da9499SMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
2730b5da9499SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
27314bb260e2SMatthew G. Knepley       orntNew[2] = -2;
2732b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2733b5da9499SMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
2734b5da9499SMatthew G. Knepley #if 1
2735b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2736b5da9499SMatthew G. Knepley       for (p = 0; p < 3; ++p) {
2737b5da9499SMatthew 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);
2738b5da9499SMatthew G. Knepley       }
2739b5da9499SMatthew G. Knepley #endif
2740b5da9499SMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
2741b5da9499SMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
2742b5da9499SMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2743b5da9499SMatthew G. Knepley #if 1
2744b5da9499SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
2745b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2746b5da9499SMatthew 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);
2747b5da9499SMatthew G. Knepley       }
2748b5da9499SMatthew G. Knepley #endif
2749b5da9499SMatthew G. Knepley       ++newp;
2750b5da9499SMatthew G. Knepley     }
2751b5da9499SMatthew G. Knepley     /* Split Edges have 2 vertices and the same faces as the parent */
2752b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2753b5da9499SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
2754b5da9499SMatthew G. Knepley 
2755b5da9499SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
2756b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
2757b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
2758b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
2759b5da9499SMatthew G. Knepley 
2760b5da9499SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
2761b5da9499SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
2762b5da9499SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
2763b5da9499SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
2764b5da9499SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2765b5da9499SMatthew G. Knepley #if 1
2766b5da9499SMatthew 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);
2767b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2768b5da9499SMatthew 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);
2769b5da9499SMatthew G. Knepley         }
2770b5da9499SMatthew G. Knepley #endif
2771b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
2772b5da9499SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2773b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2774b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2775b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2776b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2777b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
2778b5da9499SMatthew G. Knepley             if (cone[c] == e) break;
2779b5da9499SMatthew G. Knepley           }
2780b5da9499SMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
2781b5da9499SMatthew G. Knepley         }
2782b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2783b5da9499SMatthew G. Knepley #if 1
2784b5da9499SMatthew 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);
2785b5da9499SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
2786b5da9499SMatthew 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);
2787b5da9499SMatthew G. Knepley         }
2788b5da9499SMatthew G. Knepley #endif
2789b5da9499SMatthew G. Knepley       }
2790b5da9499SMatthew G. Knepley     }
279186f0afeeSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells*(1/2) faces */
2792b5da9499SMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
2793b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
2794b5da9499SMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
2795b5da9499SMatthew G. Knepley 
2796b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
2797b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
2798b5da9499SMatthew G. Knepley       for (r = 0; r < 3; ++r) {
2799b5da9499SMatthew G. Knepley         const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r;
2800b5da9499SMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
2801b5da9499SMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
2802b5da9499SMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
2803b5da9499SMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
2804b5da9499SMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
2805b5da9499SMatthew G. Knepley 
2806b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
2807b5da9499SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
2808b5da9499SMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
2809b5da9499SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2810b5da9499SMatthew G. Knepley #if 1
2811b5da9499SMatthew 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);
2812b5da9499SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
2813b5da9499SMatthew 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);
2814b5da9499SMatthew G. Knepley         }
2815b5da9499SMatthew G. Knepley #endif
2816b5da9499SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
2817b5da9499SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
2818b5da9499SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
2819b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2820b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2821b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
2822b5da9499SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
282386f0afeeSMatthew G. Knepley           /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
28249ddff745SMatthew G. Knepley           er = GetTetSomethingInverse_Static(ornt[c], r);
2825b5da9499SMatthew G. Knepley           if (er == eint[c]) {
2826b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
2827b5da9499SMatthew G. Knepley           } else {
2828b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
2829b5da9499SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
2830b5da9499SMatthew G. Knepley           }
2831b5da9499SMatthew G. Knepley         }
2832b5da9499SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2833b5da9499SMatthew G. Knepley #if 1
2834b5da9499SMatthew 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);
2835b5da9499SMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
2836b5da9499SMatthew 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);
2837b5da9499SMatthew G. Knepley         }
2838b5da9499SMatthew G. Knepley #endif
2839b5da9499SMatthew G. Knepley       }
2840b5da9499SMatthew G. Knepley     }
2841b5da9499SMatthew G. Knepley     /* Interior edges have 2 vertices and 4 faces */
2842b5da9499SMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
2843b5da9499SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart);
2844b5da9499SMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
28454a40f731SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
2846b5da9499SMatthew G. Knepley 
2847b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
2848b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
2849b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
285042525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
2851b5da9499SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2852b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
285342525629SMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
2854b5da9499SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
2855b5da9499SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
2856b5da9499SMatthew G. Knepley #if 1
2857b5da9499SMatthew 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);
2858b5da9499SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
2859b5da9499SMatthew 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);
2860b5da9499SMatthew G. Knepley       }
2861b5da9499SMatthew G. Knepley #endif
2862b5da9499SMatthew G. Knepley       supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4;
2863b5da9499SMatthew G. Knepley       supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5;
2864b5da9499SMatthew G. Knepley       supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6;
2865b5da9499SMatthew G. Knepley       supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7;
2866b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
2867b5da9499SMatthew G. Knepley #if 1
2868b5da9499SMatthew 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);
2869b5da9499SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
2870b5da9499SMatthew 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);
2871b5da9499SMatthew G. Knepley       }
2872b5da9499SMatthew G. Knepley #endif
2873b5da9499SMatthew G. Knepley     }
2874b5da9499SMatthew G. Knepley     /* Old vertices have identical supports */
2875b5da9499SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
2876b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
2877b5da9499SMatthew G. Knepley       const PetscInt *support, *cone;
2878b5da9499SMatthew G. Knepley       PetscInt        size, s;
2879b5da9499SMatthew G. Knepley 
2880b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
2881b5da9499SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
2882b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2883b5da9499SMatthew G. Knepley         PetscInt r = 0;
2884b5da9499SMatthew G. Knepley 
2885b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2886b5da9499SMatthew G. Knepley         if (cone[1] == v) r = 1;
2887b5da9499SMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
2888b5da9499SMatthew G. Knepley       }
2889b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2890b5da9499SMatthew G. Knepley #if 1
2891b5da9499SMatthew 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);
2892b5da9499SMatthew G. Knepley       for (p = 0; p < size; ++p) {
2893b5da9499SMatthew 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);
2894b5da9499SMatthew G. Knepley       }
2895b5da9499SMatthew G. Knepley #endif
2896b5da9499SMatthew G. Knepley     }
2897b5da9499SMatthew G. Knepley     /* Edge vertices have 2 + face*2 + 0/1 supports */
2898b5da9499SMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
2899b5da9499SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
2900b5da9499SMatthew G. Knepley       const PetscInt *cone, *support;
2901b5da9499SMatthew G. Knepley       PetscInt       *star = NULL, starSize, cellSize = 0, coneSize, size, s;
2902b5da9499SMatthew G. Knepley 
2903b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
2904b5da9499SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
2905b5da9499SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
2906b5da9499SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
2907b5da9499SMatthew G. Knepley       for (s = 0; s < size; ++s) {
2908b5da9499SMatthew G. Knepley         PetscInt r = 0;
2909b5da9499SMatthew G. Knepley 
2910b5da9499SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
2911b5da9499SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
2912b5da9499SMatthew G. Knepley         for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
2913b5da9499SMatthew G. Knepley         supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
2914b5da9499SMatthew G. Knepley         supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
2915b5da9499SMatthew G. Knepley       }
2916b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2917b5da9499SMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
2918b5da9499SMatthew G. Knepley         const PetscInt *cone, *ornt;
2919b5da9499SMatthew G. Knepley         PetscInt        e01, e23;
2920b5da9499SMatthew G. Knepley 
2921b5da9499SMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cEnd)) {
2922b5da9499SMatthew G. Knepley           /* Check edge 0-1 */
2923b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2924b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
2925b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
292642525629SMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
2927b5da9499SMatthew G. Knepley           /* Check edge 2-3 */
2928b5da9499SMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
2929b5da9499SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
293042525629SMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
293142525629SMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
2932b5da9499SMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);}
2933b5da9499SMatthew G. Knepley         }
2934b5da9499SMatthew G. Knepley       }
2935b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
2936b5da9499SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
2937b5da9499SMatthew G. Knepley #if 1
2938b5da9499SMatthew 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);
2939b5da9499SMatthew G. Knepley       for (p = 0; p < 2+size*2+cellSize; ++p) {
2940b5da9499SMatthew 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);
2941b5da9499SMatthew G. Knepley       }
2942b5da9499SMatthew G. Knepley #endif
2943b5da9499SMatthew G. Knepley     }
2944b5da9499SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
2945b5da9499SMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
2946b5da9499SMatthew G. Knepley     break;
29479b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
29486ce3c06aSMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
29496ce3c06aSMatthew G. Knepley     /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */
29506ce3c06aSMatthew G. Knepley     ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr);
29516ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
29526ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (c - cStart)*8;
29536ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
29546ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
29556ce3c06aSMatthew G. Knepley 
29566ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
29576ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
29586ce3c06aSMatthew G. Knepley       /* A tetrahedron: {0, a, c, d} */
29596ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */
29606ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
29616ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */
29626ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
29636ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */
29646ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
29656ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
29666ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
29676ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
29686ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
29696ce3c06aSMatthew G. Knepley #if 1
29706ce3c06aSMatthew 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);
29716ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29726ce3c06aSMatthew 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);
29736ce3c06aSMatthew G. Knepley       }
29746ce3c06aSMatthew G. Knepley #endif
29756ce3c06aSMatthew G. Knepley       /* B tetrahedron: {a, 1, b, e} */
29766ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */
29776ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
29786ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */
29796ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
29806ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
29816ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
29826ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */
29836ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
29846ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
29856ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
29866ce3c06aSMatthew G. Knepley #if 1
29876ce3c06aSMatthew 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);
29886ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
29896ce3c06aSMatthew 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);
29906ce3c06aSMatthew G. Knepley       }
29916ce3c06aSMatthew G. Knepley #endif
29926ce3c06aSMatthew G. Knepley       /* C tetrahedron: {c, b, 2, f} */
29936ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */
29946ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
29956ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
29966ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
29976ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */
29986ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
29996ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */
30006ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
30016ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
30026ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
30036ce3c06aSMatthew G. Knepley #if 1
30046ce3c06aSMatthew 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);
30056ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30066ce3c06aSMatthew 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);
30076ce3c06aSMatthew G. Knepley       }
30086ce3c06aSMatthew G. Knepley #endif
30096ce3c06aSMatthew G. Knepley       /* D tetrahedron: {d, e, f, 3} */
30106ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
30116ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
30126ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */
30136ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
30146ce3c06aSMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */
30156ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
30166ce3c06aSMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */
30176ce3c06aSMatthew G. Knepley       orntNew[3] = ornt[3];
30186ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
30196ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
30206ce3c06aSMatthew G. Knepley #if 1
30216ce3c06aSMatthew 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);
30226ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30236ce3c06aSMatthew 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);
30246ce3c06aSMatthew G. Knepley       }
30256ce3c06aSMatthew G. Knepley #endif
30266ce3c06aSMatthew G. Knepley       /* A' tetrahedron: {d, a, c, f} */
30276ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 0;
30286ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
30299ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3;
30309ddff745SMatthew G. Knepley       orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0);
30319ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
30329ddff745SMatthew G. Knepley       orntNew[2] = 0;
30339ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
30349ddff745SMatthew G. Knepley       orntNew[3] = 2;
30356ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
30366ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
30376ce3c06aSMatthew G. Knepley #if 1
30386ce3c06aSMatthew 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);
30396ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30406ce3c06aSMatthew 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);
30416ce3c06aSMatthew G. Knepley       }
30426ce3c06aSMatthew G. Knepley #endif
30436ce3c06aSMatthew G. Knepley       /* B' tetrahedron: {e, b, a, f} */
30446ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 1;
30456ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
30469ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
30479ddff745SMatthew G. Knepley       orntNew[1] = 1;
30489ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
30496ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
30509ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3;
30519ddff745SMatthew G. Knepley       orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0);
30526ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
30536ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
30546ce3c06aSMatthew G. Knepley #if 1
30556ce3c06aSMatthew 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);
30566ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30576ce3c06aSMatthew 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);
30586ce3c06aSMatthew G. Knepley       }
30596ce3c06aSMatthew G. Knepley #endif
30606ce3c06aSMatthew G. Knepley       /* C' tetrahedron: {b, f, c, a} */
30616ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 2;
30626ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
30639ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3;
30649ddff745SMatthew G. Knepley       orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2);
30659ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 5;
30669ddff745SMatthew G. Knepley       orntNew[2] = -3;
30679ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 7;
30689ddff745SMatthew G. Knepley       orntNew[3] = -2;
30696ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
30706ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
30716ce3c06aSMatthew G. Knepley #if 1
30726ce3c06aSMatthew 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);
30736ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30746ce3c06aSMatthew 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);
30756ce3c06aSMatthew G. Knepley       }
30766ce3c06aSMatthew G. Knepley #endif
30776ce3c06aSMatthew G. Knepley       /* D' tetrahedron: {f, e, d, a} */
30786ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 3;
30796ce3c06aSMatthew G. Knepley       orntNew[0] = -3;
30809ddff745SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 4;
30816ce3c06aSMatthew G. Knepley       orntNew[1] = -3;
30829ddff745SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3;
30839ddff745SMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0);
30849ddff745SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*8 + 6;
30859ddff745SMatthew G. Knepley       orntNew[3] = -3;
30866ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
30876ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
30886ce3c06aSMatthew G. Knepley #if 1
30896ce3c06aSMatthew 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);
30906ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
30916ce3c06aSMatthew 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);
30926ce3c06aSMatthew G. Knepley       }
30936ce3c06aSMatthew G. Knepley #endif
30946ce3c06aSMatthew G. Knepley     }
30956ce3c06aSMatthew G. Knepley     /* Hybrid cells have 5 faces */
30966ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
30976ce3c06aSMatthew G. Knepley       const PetscInt  newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4;
3098d3a1cc75SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
30993b61eb6dSMatthew G. Knepley       PetscInt        coneNew[5], orntNew[5], o, of, i;
31006ce3c06aSMatthew G. Knepley 
31016ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
31026ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
3103d3a1cc75SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
3104084f9c62SMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
31056ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
31066ce3c06aSMatthew G. Knepley         coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r);
31076ce3c06aSMatthew G. Knepley         orntNew[0] = ornt[0];
31086ce3c06aSMatthew G. Knepley         coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r);
31096ce3c06aSMatthew G. Knepley         orntNew[1] = ornt[1];
3110084f9c62SMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], r)]       < 0 ? -1 : 1;
31113b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], r)       + 2;
31123b61eb6dSMatthew 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);
31133b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
31143b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2;
31153b61eb6dSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r);
31163b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
31173b61eb6dSMatthew G. Knepley         of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1;
31183b61eb6dSMatthew G. Knepley         i  = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2;
31193b61eb6dSMatthew 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);
31203b61eb6dSMatthew G. Knepley         orntNew[i] = 0;
31216ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
31226ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
31236ce3c06aSMatthew G. Knepley #if 1
31246ce3c06aSMatthew 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);
31256ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
31266ce3c06aSMatthew 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);
31276ce3c06aSMatthew G. Knepley         }
31286ce3c06aSMatthew G. Knepley         for (p = 2; p < 5; ++p) {
31296ce3c06aSMatthew 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);
31306ce3c06aSMatthew G. Knepley         }
31316ce3c06aSMatthew G. Knepley #endif
31326ce3c06aSMatthew G. Knepley       }
31336ce3c06aSMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3;
31346ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
31356ce3c06aSMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3;
31366ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
31373b61eb6dSMatthew G. Knepley       coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1;
31386ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
31393b61eb6dSMatthew G. Knepley       coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2;
31406ce3c06aSMatthew G. Knepley       orntNew[3] = 0;
31413b61eb6dSMatthew G. Knepley       coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0;
31426ce3c06aSMatthew G. Knepley       orntNew[4] = 0;
31436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
31446ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
31456ce3c06aSMatthew G. Knepley #if 1
31466ce3c06aSMatthew 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);
31476ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
31486ce3c06aSMatthew 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);
31496ce3c06aSMatthew G. Knepley       }
31506ce3c06aSMatthew G. Knepley       for (p = 2; p < 5; ++p) {
31516ce3c06aSMatthew 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);
31526ce3c06aSMatthew G. Knepley       }
31536ce3c06aSMatthew G. Knepley #endif
31546ce3c06aSMatthew G. Knepley     }
31556ce3c06aSMatthew G. Knepley     /* Split faces have 3 edges and the same cells as the parent */
31566ce3c06aSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
3157854ce69bSBarry Smith     ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
31586ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
31596ce3c06aSMatthew G. Knepley       const PetscInt  newp = fStartNew + (f - fStart)*4;
31606ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
31616ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3], coneSize, supportSize, s;
31626ce3c06aSMatthew G. Knepley 
31636ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
31646ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
31656ce3c06aSMatthew G. Knepley       /* A triangle */
31666ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0);
31676ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
31686ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
31696ce3c06aSMatthew G. Knepley       orntNew[1] = -2;
31706ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1);
31716ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
31726ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
31736ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
31746ce3c06aSMatthew G. Knepley #if 1
31756ce3c06aSMatthew 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);
31766ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31776ce3c06aSMatthew 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);
31786ce3c06aSMatthew G. Knepley       }
31796ce3c06aSMatthew G. Knepley #endif
31806ce3c06aSMatthew G. Knepley       /* B triangle */
31816ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1);
31826ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0];
31836ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0);
31846ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
31856ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
31866ce3c06aSMatthew G. Knepley       orntNew[2] = -2;
31876ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
31886ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
31896ce3c06aSMatthew G. Knepley #if 1
31906ce3c06aSMatthew 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);
31916ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
31926ce3c06aSMatthew 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);
31936ce3c06aSMatthew G. Knepley       }
31946ce3c06aSMatthew G. Knepley #endif
31956ce3c06aSMatthew G. Knepley       /* C triangle */
31966ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
31976ce3c06aSMatthew G. Knepley       orntNew[0] = -2;
31986ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1);
31996ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1];
32006ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0);
32016ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2];
32026ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
32036ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
32046ce3c06aSMatthew G. Knepley #if 1
32056ce3c06aSMatthew 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);
32066ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32076ce3c06aSMatthew 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);
32086ce3c06aSMatthew G. Knepley       }
32096ce3c06aSMatthew G. Knepley #endif
32106ce3c06aSMatthew G. Knepley       /* D triangle */
32116ce3c06aSMatthew G. Knepley       coneNew[0] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 0;
32126ce3c06aSMatthew G. Knepley       orntNew[0] = 0;
32136ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 1;
32146ce3c06aSMatthew G. Knepley       orntNew[1] = 0;
32156ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax    - eStart)*2 + (f - fStart)*3 + 2;
32166ce3c06aSMatthew G. Knepley       orntNew[2] = 0;
32176ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
32186ce3c06aSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
32196ce3c06aSMatthew G. Knepley #if 1
32206ce3c06aSMatthew 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);
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       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
32266ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
32276ce3c06aSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
32286ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
32299ddff745SMatthew G. Knepley           PetscInt subf;
32306ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
32316ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
32326ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
32336ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
32346ce3c06aSMatthew G. Knepley             if (cone[c] == f) break;
32356ce3c06aSMatthew G. Knepley           }
32369ddff745SMatthew G. Knepley           subf = GetTriSubfaceInverse_Static(ornt[c], r);
32376ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
32389ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]);
32396ce3c06aSMatthew G. Knepley           } else {
32409ddff745SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf);
32416ce3c06aSMatthew G. Knepley           }
32426ce3c06aSMatthew G. Knepley         }
32436ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr);
32446ce3c06aSMatthew G. Knepley #if 1
32459ddff745SMatthew 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);
32466ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
32476ce3c06aSMatthew 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);
32486ce3c06aSMatthew G. Knepley         }
32496ce3c06aSMatthew G. Knepley #endif
32506ce3c06aSMatthew G. Knepley       }
32516ce3c06aSMatthew G. Knepley     }
32526ce3c06aSMatthew G. Knepley     /* Interior cell faces have 3 edges and 2 cells */
32536ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
32546ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8;
32556ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
32566ce3c06aSMatthew G. Knepley       PetscInt        coneNew[3], orntNew[3];
32576ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
32586ce3c06aSMatthew G. Knepley 
32596ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
32606ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
32616ce3c06aSMatthew G. Knepley       /* Face A: {c, a, d} */
32629ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
32636ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
32649ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
32656ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[1] < 0 ? -2 : 0;
32669ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2);
32676ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
32686ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32696ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32706ce3c06aSMatthew G. Knepley #if 1
32716ce3c06aSMatthew 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);
32726ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32736ce3c06aSMatthew 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);
32746ce3c06aSMatthew G. Knepley       }
32756ce3c06aSMatthew G. Knepley #endif
32766ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0;
32776ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 0+4;
32786ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
32796ce3c06aSMatthew G. Knepley #if 1
32806ce3c06aSMatthew 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);
32816ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
32826ce3c06aSMatthew 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);
32836ce3c06aSMatthew G. Knepley       }
32846ce3c06aSMatthew G. Knepley #endif
32856ce3c06aSMatthew G. Knepley       ++newp;
32866ce3c06aSMatthew G. Knepley       /* Face B: {a, b, e} */
32879ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
32886ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
32899ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0);
32906ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
32919ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
32926ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
32936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
32946ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
32956ce3c06aSMatthew G. Knepley #if 1
32966ce3c06aSMatthew 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);
32976ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
32986ce3c06aSMatthew 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);
32996ce3c06aSMatthew G. Knepley       }
33006ce3c06aSMatthew G. Knepley #endif
33016ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1;
33026ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 1+4;
33036ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33046ce3c06aSMatthew G. Knepley #if 1
33056ce3c06aSMatthew 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);
33066ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
33076ce3c06aSMatthew 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);
33086ce3c06aSMatthew G. Knepley       }
33096ce3c06aSMatthew G. Knepley #endif
33106ce3c06aSMatthew G. Knepley       ++newp;
33116ce3c06aSMatthew G. Knepley       /* Face C: {c, f, b} */
33129ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
33136ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? -2 : 0;
33149ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
33156ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
33169ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1);
33176ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[0] < 0 ? -2 : 0;
33186ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33196ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33206ce3c06aSMatthew G. Knepley #if 1
33216ce3c06aSMatthew 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);
33226ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33236ce3c06aSMatthew 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);
33246ce3c06aSMatthew G. Knepley       }
33256ce3c06aSMatthew G. Knepley #endif
33266ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 2;
33276ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
33286ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33296ce3c06aSMatthew G. Knepley #if 1
33306ce3c06aSMatthew 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);
33316ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
33326ce3c06aSMatthew 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);
33336ce3c06aSMatthew G. Knepley       }
33346ce3c06aSMatthew G. Knepley #endif
33356ce3c06aSMatthew G. Knepley       ++newp;
33366ce3c06aSMatthew G. Knepley       /* Face D: {d, e, f} */
33379ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0);
33386ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
33399ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
33406ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? -2 : 0;
33419ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
33426ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? -2 : 0;
33436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33446ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33456ce3c06aSMatthew G. Knepley #if 1
33466ce3c06aSMatthew 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);
33476ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33486ce3c06aSMatthew 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);
33496ce3c06aSMatthew G. Knepley       }
33506ce3c06aSMatthew G. Knepley #endif
33516ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 3;
33526ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
33536ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33546ce3c06aSMatthew G. Knepley #if 1
33556ce3c06aSMatthew 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);
33566ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
33576ce3c06aSMatthew 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);
33586ce3c06aSMatthew G. Knepley       }
33596ce3c06aSMatthew G. Knepley #endif
33606ce3c06aSMatthew G. Knepley       ++newp;
33616ce3c06aSMatthew G. Knepley       /* Face E: {d, f, a} */
33629ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1);
33636ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[2] < 0 ? 0 : -2;
33646ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
33659ddff745SMatthew G. Knepley       orntNew[1] = -2;
33669ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2);
33676ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[1] < 0 ? -2 : 0;
33686ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33696ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33706ce3c06aSMatthew G. Knepley #if 1
33716ce3c06aSMatthew 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);
33726ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33736ce3c06aSMatthew 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);
33746ce3c06aSMatthew G. Knepley       }
33756ce3c06aSMatthew G. Knepley #endif
33766ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
33776ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
33786ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
33796ce3c06aSMatthew G. Knepley #if 1
33806ce3c06aSMatthew 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);
33816ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
33826ce3c06aSMatthew 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);
33836ce3c06aSMatthew G. Knepley       }
33846ce3c06aSMatthew G. Knepley #endif
33856ce3c06aSMatthew G. Knepley       ++newp;
33866ce3c06aSMatthew G. Knepley       /* Face F: {c, a, f} */
33879ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2);
33886ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
33896ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
33909ddff745SMatthew G. Knepley       orntNew[1] = 0;
33919ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0);
33929ddff745SMatthew G. Knepley       orntNew[2] = ornt[2] < 0 ? 0 : -2;
33936ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
33946ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
33956ce3c06aSMatthew G. Knepley #if 1
33966ce3c06aSMatthew 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);
33976ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
33986ce3c06aSMatthew 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);
33996ce3c06aSMatthew G. Knepley       }
34006ce3c06aSMatthew G. Knepley #endif
34016ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 0+4;
34026ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
34036ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
34046ce3c06aSMatthew G. Knepley #if 1
34056ce3c06aSMatthew 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);
34066ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
34076ce3c06aSMatthew 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);
34086ce3c06aSMatthew G. Knepley       }
34096ce3c06aSMatthew G. Knepley #endif
34106ce3c06aSMatthew G. Knepley       ++newp;
34116ce3c06aSMatthew G. Knepley       /* Face G: {e, a, f} */
34129ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1);
34136ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[1] < 0 ? -2 : 0;
34146ce3c06aSMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
34159ddff745SMatthew G. Knepley       orntNew[1] = 0;
34169ddff745SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1);
34176ce3c06aSMatthew G. Knepley       orntNew[2] = ornt[3] < 0 ? 0 : -2;
34186ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34196ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
34206ce3c06aSMatthew G. Knepley #if 1
34216ce3c06aSMatthew 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);
34226ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
34236ce3c06aSMatthew 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);
34246ce3c06aSMatthew G. Knepley       }
34256ce3c06aSMatthew G. Knepley #endif
34266ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
34276ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 3+4;
34286ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
34296ce3c06aSMatthew G. Knepley #if 1
34306ce3c06aSMatthew 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);
34316ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
34326ce3c06aSMatthew 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);
34336ce3c06aSMatthew G. Knepley       }
34346ce3c06aSMatthew G. Knepley #endif
34356ce3c06aSMatthew G. Knepley       ++newp;
34366ce3c06aSMatthew G. Knepley       /* Face H: {a, b, f} */
34379ddff745SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0);
34386ce3c06aSMatthew G. Knepley       orntNew[0] = ornt[0] < 0 ? -2 : 0;
34399ddff745SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2);
34406ce3c06aSMatthew G. Knepley       orntNew[1] = ornt[3] < 0 ? 0 : -2;
34416ce3c06aSMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
34429ddff745SMatthew G. Knepley       orntNew[2] = -2;
34436ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34446ce3c06aSMatthew G. Knepley       ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
34456ce3c06aSMatthew G. Knepley #if 1
34466ce3c06aSMatthew 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);
34476ce3c06aSMatthew G. Knepley       for (p = 0; p < 3; ++p) {
34486ce3c06aSMatthew 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);
34496ce3c06aSMatthew G. Knepley       }
34506ce3c06aSMatthew G. Knepley #endif
34516ce3c06aSMatthew G. Knepley       supportNew[0] = (c - cStart)*8 + 1+4;
34526ce3c06aSMatthew G. Knepley       supportNew[1] = (c - cStart)*8 + 2+4;
34536ce3c06aSMatthew G. Knepley       ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
34546ce3c06aSMatthew G. Knepley #if 1
34556ce3c06aSMatthew 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);
34566ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
34576ce3c06aSMatthew 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);
34586ce3c06aSMatthew G. Knepley       }
34596ce3c06aSMatthew G. Knepley #endif
34606ce3c06aSMatthew G. Knepley       ++newp;
34616ce3c06aSMatthew G. Knepley     }
34626ce3c06aSMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
34636ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
34646ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
34656ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
34666ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
34676ce3c06aSMatthew G. Knepley 
34686ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
34696ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
34706ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
34716ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
34726ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
34736ce3c06aSMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r;
34746ce3c06aSMatthew G. Knepley 
34756ce3c06aSMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
34766ce3c06aSMatthew G. Knepley         orntNew[0]   = ornt[0];
34776ce3c06aSMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
34786ce3c06aSMatthew G. Knepley         orntNew[1]   = ornt[1];
34796ce3c06aSMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax);
34806ce3c06aSMatthew G. Knepley         orntNew[2+r] = 0;
34816ce3c06aSMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd      - eMax) + (f - fMax);
34826ce3c06aSMatthew G. Knepley         orntNew[3-r] = 0;
34836ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
34846ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
34856ce3c06aSMatthew G. Knepley #if 1
34866ce3c06aSMatthew 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);
34876ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
34886ce3c06aSMatthew 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);
34896ce3c06aSMatthew G. Knepley         }
34906ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
34916ce3c06aSMatthew 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);
34926ce3c06aSMatthew G. Knepley         }
34936ce3c06aSMatthew G. Knepley #endif
34946ce3c06aSMatthew G. Knepley         for (s = 0; s < size; ++s) {
3495d3a1cc75SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
3496084f9c62SMatthew G. Knepley           PetscInt        o, of;
34976ce3c06aSMatthew G. Knepley 
34986ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
34996ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
3500084f9c62SMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
35016ce3c06aSMatthew G. Knepley           for (c = 2; c < 5; ++c) if (coneCell[c] == f) break;
35026ce3c06aSMatthew 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]);
3503d3a1cc75SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
3504084f9c62SMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
3505084f9c62SMatthew 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;
35066ce3c06aSMatthew G. Knepley         }
35076ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
35086ce3c06aSMatthew G. Knepley #if 1
35096ce3c06aSMatthew 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);
35106ce3c06aSMatthew G. Knepley         for (p = 0; p < size; ++p) {
35116ce3c06aSMatthew 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);
35126ce3c06aSMatthew G. Knepley         }
35136ce3c06aSMatthew G. Knepley #endif
35146ce3c06aSMatthew G. Knepley       }
35156ce3c06aSMatthew G. Knepley     }
35166ce3c06aSMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
35176ce3c06aSMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
35186ce3c06aSMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3;
35196ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt;
35206ce3c06aSMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
35216ce3c06aSMatthew G. Knepley       PetscInt        supportNew[2];
35226ce3c06aSMatthew G. Knepley 
35236ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
35246ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
35256ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
3526b598a9d5SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3;
35276ce3c06aSMatthew G. Knepley         orntNew[0] = 0;
3528b598a9d5SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3;
35296ce3c06aSMatthew G. Knepley         orntNew[1] = 0;
3530b598a9d5SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax);
35316ce3c06aSMatthew G. Knepley         orntNew[2] = 0;
3532b598a9d5SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r]       - fMax);
35336ce3c06aSMatthew G. Knepley         orntNew[3] = 0;
35346ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
35356ce3c06aSMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
35366ce3c06aSMatthew G. Knepley #if 1
35376ce3c06aSMatthew 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);
35386ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35396ce3c06aSMatthew 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);
35406ce3c06aSMatthew G. Knepley         }
35416ce3c06aSMatthew G. Knepley         for (p = 2; p < 4; ++p) {
35426ce3c06aSMatthew 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);
35436ce3c06aSMatthew G. Knepley         }
35446ce3c06aSMatthew G. Knepley #endif
35456ce3c06aSMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r);
35466ce3c06aSMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3;
35476ce3c06aSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
35486ce3c06aSMatthew G. Knepley #if 1
35496ce3c06aSMatthew 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);
35506ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35516ce3c06aSMatthew 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);
35526ce3c06aSMatthew G. Knepley         }
35536ce3c06aSMatthew G. Knepley #endif
35546ce3c06aSMatthew G. Knepley       }
35556ce3c06aSMatthew G. Knepley     }
35566ce3c06aSMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
35576ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
35586ce3c06aSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
35596ce3c06aSMatthew G. Knepley 
35606ce3c06aSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
35616ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
35626ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
35636ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
35646ce3c06aSMatthew G. Knepley 
35656ce3c06aSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
35666ce3c06aSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
35676ce3c06aSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
35686ce3c06aSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
35696ce3c06aSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
35706ce3c06aSMatthew G. Knepley #if 1
35716ce3c06aSMatthew 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);
35726ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
35736ce3c06aSMatthew 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);
35746ce3c06aSMatthew G. Knepley         }
35756ce3c06aSMatthew G. Knepley #endif
35766ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
35776ce3c06aSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
35786ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
35796ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
35806ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
35816ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
35826ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (cone[c] == e) break;
35836ce3c06aSMatthew G. Knepley           if (support[s] < fMax) {
35846ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3;
35856ce3c06aSMatthew G. Knepley           } else {
35866ce3c06aSMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
35876ce3c06aSMatthew G. Knepley           }
35886ce3c06aSMatthew G. Knepley         }
35896ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
35906ce3c06aSMatthew G. Knepley #if 1
35916ce3c06aSMatthew 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);
35926ce3c06aSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
35936ce3c06aSMatthew 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);
35946ce3c06aSMatthew G. Knepley         }
35956ce3c06aSMatthew G. Knepley #endif
35966ce3c06aSMatthew G. Knepley       }
35976ce3c06aSMatthew G. Knepley     }
35986ce3c06aSMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */
35996ce3c06aSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
36006ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
36016ce3c06aSMatthew G. Knepley       PetscInt        coneSize, supportSize, s;
36026ce3c06aSMatthew G. Knepley 
36036ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
36046ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
36056ce3c06aSMatthew G. Knepley       for (r = 0; r < 3; ++r) {
36066ce3c06aSMatthew G. Knepley         const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r;
36076ce3c06aSMatthew G. Knepley         PetscInt        coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0};
36086ce3c06aSMatthew G. Knepley         PetscInt        fint[24] = { 1,  7, -1, -1,  0,  5,
36096ce3c06aSMatthew G. Knepley                                     -1, -1,  1,  6,  0,  4,
36106ce3c06aSMatthew G. Knepley                                      2,  5,  3,  4, -1, -1,
36116ce3c06aSMatthew G. Knepley                                     -1, -1,  3,  6,  2,  7};
36126ce3c06aSMatthew G. Knepley 
36136ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
36146ce3c06aSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart);
36156ce3c06aSMatthew G. Knepley         coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart);
36166ce3c06aSMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36176ce3c06aSMatthew G. Knepley #if 1
36186ce3c06aSMatthew 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);
36196ce3c06aSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
36206ce3c06aSMatthew 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);
36216ce3c06aSMatthew G. Knepley         }
36226ce3c06aSMatthew G. Knepley #endif
36236ce3c06aSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3;
36246ce3c06aSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + 3;
36256ce3c06aSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
36266ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
36276ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
36286ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
36296ce3c06aSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;}
36306ce3c06aSMatthew G. Knepley           if (support[s] < cMax) {
36316ce3c06aSMatthew G. Knepley             /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */
36329ddff745SMatthew G. Knepley             er = GetTetSomethingInverse_Static(ornt[c], r);
36336ce3c06aSMatthew G. Knepley             if (er == eint[c]) {
36346ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4;
36356ce3c06aSMatthew G. Knepley             } else {
36366ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0];
36376ce3c06aSMatthew G. Knepley               supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1];
36386ce3c06aSMatthew G. Knepley             }
36396ce3c06aSMatthew G. Knepley           } else {
3640b598a9d5SMatthew G. Knepley             supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3;
36416ce3c06aSMatthew G. Knepley           }
36426ce3c06aSMatthew G. Knepley         }
36436ce3c06aSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
36446ce3c06aSMatthew G. Knepley #if 1
36456ce3c06aSMatthew 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);
36466ce3c06aSMatthew G. Knepley         for (p = 0; p < intFaces; ++p) {
36476ce3c06aSMatthew 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);
36486ce3c06aSMatthew G. Knepley         }
36496ce3c06aSMatthew G. Knepley #endif
36506ce3c06aSMatthew G. Knepley       }
36516ce3c06aSMatthew G. Knepley     }
36526ce3c06aSMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
36536ce3c06aSMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
36546ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart);
36556ce3c06aSMatthew G. Knepley       const PetscInt *cone, *ornt, *fcone;
36566ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4], find;
36576ce3c06aSMatthew G. Knepley 
36586ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
36596ce3c06aSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
36606ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr);
36616ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[0], 0);
36626ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
36636ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr);
36646ce3c06aSMatthew G. Knepley       find = GetTriEdge_Static(ornt[2], 1);
36656ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart);
36666ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36676ce3c06aSMatthew G. Knepley #if 1
36686ce3c06aSMatthew 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);
36696ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
36706ce3c06aSMatthew 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);
36716ce3c06aSMatthew G. Knepley       }
36726ce3c06aSMatthew G. Knepley #endif
36736ce3c06aSMatthew G. Knepley       supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4;
36746ce3c06aSMatthew G. Knepley       supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5;
36756ce3c06aSMatthew G. Knepley       supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6;
36766ce3c06aSMatthew G. Knepley       supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7;
36776ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
36786ce3c06aSMatthew G. Knepley #if 1
36796ce3c06aSMatthew 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);
36806ce3c06aSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
36816ce3c06aSMatthew 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);
36826ce3c06aSMatthew G. Knepley       }
36836ce3c06aSMatthew G. Knepley #endif
36846ce3c06aSMatthew G. Knepley     }
36856ce3c06aSMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
36866ce3c06aSMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
36876ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax);
36886ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
36896ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
36906ce3c06aSMatthew G. Knepley 
36916ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
36926ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
36936ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
36946ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
36956ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
36966ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
36976ce3c06aSMatthew G. Knepley #if 1
36986ce3c06aSMatthew 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);
36996ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37006ce3c06aSMatthew 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);
37016ce3c06aSMatthew G. Knepley       }
37026ce3c06aSMatthew G. Knepley #endif
37036ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
37046ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
37056ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
37066ce3c06aSMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
37076ce3c06aSMatthew 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]);
37086ce3c06aSMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2;
37096ce3c06aSMatthew G. Knepley       }
37106ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37116ce3c06aSMatthew G. Knepley #if 1
37126ce3c06aSMatthew 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);
37136ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
37146ce3c06aSMatthew 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);
37156ce3c06aSMatthew G. Knepley       }
37166ce3c06aSMatthew G. Knepley #endif
37176ce3c06aSMatthew G. Knepley     }
37186ce3c06aSMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+2*cells faces */
37196ce3c06aSMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
37206ce3c06aSMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax);
3721623f4348SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
37226ce3c06aSMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
37236ce3c06aSMatthew G. Knepley 
37246ce3c06aSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
37256ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
37266ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
37276ce3c06aSMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
37286ce3c06aSMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
37296ce3c06aSMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
37306ce3c06aSMatthew G. Knepley #if 1
37316ce3c06aSMatthew 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);
37326ce3c06aSMatthew G. Knepley       for (p = 0; p < 2; ++p) {
37336ce3c06aSMatthew 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);
37346ce3c06aSMatthew G. Knepley       }
37356ce3c06aSMatthew G. Knepley #endif
37366ce3c06aSMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0;
37376ce3c06aSMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1;
37386ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
37396ce3c06aSMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
37406ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
3741623f4348SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
37426ce3c06aSMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
37436ce3c06aSMatthew 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]);
3744b598a9d5SMatthew G. Knepley         supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2;
3745b598a9d5SMatthew G. Knepley         supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3;
37466ce3c06aSMatthew G. Knepley       }
37476ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37486ce3c06aSMatthew G. Knepley #if 1
37496ce3c06aSMatthew 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);
37506ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+size*2; ++p) {
37516ce3c06aSMatthew 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);
37526ce3c06aSMatthew G. Knepley       }
37536ce3c06aSMatthew G. Knepley #endif
37546ce3c06aSMatthew G. Knepley     }
37556ce3c06aSMatthew G. Knepley     /* Interior vertices have identical supports */
37566ce3c06aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
37576ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
37586ce3c06aSMatthew G. Knepley       const PetscInt *support, *cone;
37596ce3c06aSMatthew G. Knepley       PetscInt        size, s;
37606ce3c06aSMatthew G. Knepley 
37616ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
37626ce3c06aSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
37636ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
37646ce3c06aSMatthew G. Knepley         PetscInt r = 0;
37656ce3c06aSMatthew G. Knepley 
37666ce3c06aSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
37676ce3c06aSMatthew G. Knepley         if (cone[1] == v) r = 1;
37686ce3c06aSMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
37696ce3c06aSMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax);
37706ce3c06aSMatthew G. Knepley       }
37716ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
37726ce3c06aSMatthew G. Knepley #if 1
37736ce3c06aSMatthew 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);
37746ce3c06aSMatthew G. Knepley       for (p = 0; p < size; ++p) {
37756ce3c06aSMatthew 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);
37766ce3c06aSMatthew G. Knepley       }
37776ce3c06aSMatthew G. Knepley #endif
37786ce3c06aSMatthew G. Knepley     }
37796ce3c06aSMatthew G. Knepley     /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */
37806ce3c06aSMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
37816ce3c06aSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
37826ce3c06aSMatthew G. Knepley       const PetscInt *cone, *support;
37836ce3c06aSMatthew G. Knepley       PetscInt       *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s;
37846ce3c06aSMatthew G. Knepley 
37856ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
37866ce3c06aSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
37876ce3c06aSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
37886ce3c06aSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
37896ce3c06aSMatthew G. Knepley       for (s = 0; s < size; ++s) {
37906ce3c06aSMatthew G. Knepley         PetscInt r = 0;
37916ce3c06aSMatthew G. Knepley 
37926ce3c06aSMatthew G. Knepley         if (support[s] < fMax) {
37936ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
37946ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
37956ce3c06aSMatthew G. Knepley           for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;}
37966ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3;
37976ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3;
37986ce3c06aSMatthew G. Knepley           faceSize += 2;
37996ce3c06aSMatthew G. Knepley         } else {
38006ce3c06aSMatthew G. Knepley           supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax);
38016ce3c06aSMatthew G. Knepley           ++faceSize;
38026ce3c06aSMatthew G. Knepley         }
38036ce3c06aSMatthew G. Knepley       }
38046ce3c06aSMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
38056ce3c06aSMatthew G. Knepley       for (s = 0; s < starSize*2; s += 2) {
38066ce3c06aSMatthew G. Knepley         const PetscInt *cone, *ornt;
38076ce3c06aSMatthew G. Knepley         PetscInt        e01, e23;
38086ce3c06aSMatthew G. Knepley 
38096ce3c06aSMatthew G. Knepley         if ((star[s] >= cStart) && (star[s] < cMax)) {
38106ce3c06aSMatthew G. Knepley           /* Check edge 0-1 */
38116ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
38126ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
38136ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr);
38146ce3c06aSMatthew G. Knepley           e01  = cone[GetTriEdge_Static(ornt[0], 0)];
38156ce3c06aSMatthew G. Knepley           /* Check edge 2-3 */
38166ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr);
38176ce3c06aSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr);
38186ce3c06aSMatthew G. Knepley           ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr);
38196ce3c06aSMatthew G. Knepley           e23  = cone[GetTriEdge_Static(ornt[2], 1)];
38206ce3c06aSMatthew G. Knepley           if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);}
38216ce3c06aSMatthew G. Knepley         }
38226ce3c06aSMatthew G. Knepley       }
38236ce3c06aSMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr);
38246ce3c06aSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
38256ce3c06aSMatthew G. Knepley #if 1
38266ce3c06aSMatthew 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);
38276ce3c06aSMatthew G. Knepley       for (p = 0; p < 2+faceSize+cellSize; ++p) {
38286ce3c06aSMatthew 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);
38296ce3c06aSMatthew G. Knepley       }
38306ce3c06aSMatthew G. Knepley #endif
38316ce3c06aSMatthew G. Knepley     }
38326ce3c06aSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
38336ce3c06aSMatthew G. Knepley     ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr);
38346ce3c06aSMatthew G. Knepley     break;
38359b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
38362eabf88fSMatthew G. Knepley     /*
38372eabf88fSMatthew G. Knepley      Bottom (viewed from top)    Top
38382eabf88fSMatthew G. Knepley      1---------2---------2       7---------2---------6
38392eabf88fSMatthew G. Knepley      |         |         |       |         |         |
38402eabf88fSMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
38412eabf88fSMatthew G. Knepley      |         |         |       |         |         |
38422eabf88fSMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
38432eabf88fSMatthew G. Knepley      |         |         |       |         |         |
38442eabf88fSMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
38452eabf88fSMatthew G. Knepley      |         |         |       |         |         |
38462eabf88fSMatthew G. Knepley      0---------0---------3       4---------0---------5
38472eabf88fSMatthew G. Knepley      */
38482eabf88fSMatthew G. Knepley     /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
38492eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
38502eabf88fSMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
38512eabf88fSMatthew G. Knepley       const PetscInt *cone, *ornt;
38522eabf88fSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
38532eabf88fSMatthew G. Knepley 
38542eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
38552eabf88fSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
38562eabf88fSMatthew G. Knepley       /* A hex */
3857e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
38582eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
38592eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
38602eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3861e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
38622eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
38632eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
38642eabf88fSMatthew G. Knepley       orntNew[3] = 0;
38652eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
38662eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3867e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
38682eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
38692eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
38702eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
38712eabf88fSMatthew G. Knepley #if 1
38722eabf88fSMatthew 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);
38732eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38742eabf88fSMatthew 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);
38752eabf88fSMatthew G. Knepley       }
38762eabf88fSMatthew G. Knepley #endif
38772eabf88fSMatthew G. Knepley       /* B hex */
3878e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
38792eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
38802eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
38812eabf88fSMatthew G. Knepley       orntNew[1] = 0;
38822eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
3883a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3884e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
38852eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
38862eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
38872eabf88fSMatthew G. Knepley       orntNew[4] = 0;
3888e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
38892eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
38902eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
38912eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
38922eabf88fSMatthew G. Knepley #if 1
38932eabf88fSMatthew 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);
38942eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
38952eabf88fSMatthew 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);
38962eabf88fSMatthew G. Knepley       }
38972eabf88fSMatthew G. Knepley #endif
38982eabf88fSMatthew G. Knepley       /* C hex */
3899e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
39002eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
39012eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
39022eabf88fSMatthew G. Knepley       orntNew[1] = 0;
39032eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3904a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
3905e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
39062eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3907e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
39082eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
39092eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
3910a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
39112eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
39122eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
39132eabf88fSMatthew G. Knepley #if 1
39142eabf88fSMatthew 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);
39152eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39162eabf88fSMatthew 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);
39172eabf88fSMatthew G. Knepley       }
39182eabf88fSMatthew G. Knepley #endif
39192eabf88fSMatthew G. Knepley       /* D hex */
3920e3f8b1d6SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
39212eabf88fSMatthew G. Knepley       orntNew[0] = ornt[0];
39222eabf88fSMatthew G. Knepley       coneNew[1] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
39232eabf88fSMatthew G. Knepley       orntNew[1] = 0;
3924e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
39252eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
39262eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
3927a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
3928e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
39292eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
39302eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
3931a3cddbf8SMatthew G. Knepley       orntNew[5] = -4;
39322eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
39332eabf88fSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
39342eabf88fSMatthew G. Knepley #if 1
39352eabf88fSMatthew 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);
39362eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39372eabf88fSMatthew 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);
39382eabf88fSMatthew G. Knepley       }
39392eabf88fSMatthew G. Knepley #endif
39402eabf88fSMatthew G. Knepley       /* E hex */
39412eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
3942a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3943e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
39442eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3945e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
39462eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
39472eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
39482eabf88fSMatthew G. Knepley       orntNew[3] = 0;
39492eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3950a3cddbf8SMatthew G. Knepley       orntNew[4] = -1;
3951e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
39522eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
3953b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
3954b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
39552eabf88fSMatthew G. Knepley #if 1
3956b164cbf2SMatthew 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);
39572eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39582eabf88fSMatthew 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);
39592eabf88fSMatthew G. Knepley       }
39602eabf88fSMatthew G. Knepley #endif
39612eabf88fSMatthew G. Knepley       /* F hex */
39622eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
3963a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3964e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
39652eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
3966e3f8b1d6SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
39672eabf88fSMatthew G. Knepley       orntNew[2] = ornt[2];
39682eabf88fSMatthew G. Knepley       coneNew[3] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3969a3cddbf8SMatthew G. Knepley       orntNew[3] = -1;
3970e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
39712eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
39722eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
3973a3cddbf8SMatthew G. Knepley       orntNew[5] = 1;
3974b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
3975b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
39762eabf88fSMatthew G. Knepley #if 1
3977b164cbf2SMatthew 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);
39782eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
39792eabf88fSMatthew 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);
39802eabf88fSMatthew G. Knepley       }
39812eabf88fSMatthew G. Knepley #endif
39822eabf88fSMatthew G. Knepley       /* G hex */
39832eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
3984a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
3985e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
39862eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
39872eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
3988a3cddbf8SMatthew G. Knepley       orntNew[2] = 0;
3989e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
39902eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
3991e3f8b1d6SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
39922eabf88fSMatthew G. Knepley       orntNew[4] = ornt[4];
39932eabf88fSMatthew G. Knepley       coneNew[5] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
3994a3cddbf8SMatthew G. Knepley       orntNew[5] = -3;
3995b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
3996b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
39972eabf88fSMatthew G. Knepley #if 1
3998b164cbf2SMatthew 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);
39992eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
40002eabf88fSMatthew 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);
40012eabf88fSMatthew G. Knepley       }
40022eabf88fSMatthew G. Knepley #endif
40032eabf88fSMatthew G. Knepley       /* H hex */
40042eabf88fSMatthew G. Knepley       coneNew[0] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
4005a3cddbf8SMatthew G. Knepley       orntNew[0] = -4;
4006e3f8b1d6SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
40072eabf88fSMatthew G. Knepley       orntNew[1] = ornt[1];
40082eabf88fSMatthew G. Knepley       coneNew[2] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
4009a3cddbf8SMatthew G. Knepley       orntNew[2] = -1;
4010e3f8b1d6SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
40112eabf88fSMatthew G. Knepley       orntNew[3] = ornt[3];
40122eabf88fSMatthew G. Knepley       coneNew[4] = fStartNew + (fEnd    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
4013a3cddbf8SMatthew G. Knepley       orntNew[4] = 3;
4014e3f8b1d6SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
40152eabf88fSMatthew G. Knepley       orntNew[5] = ornt[5];
4016b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
4017b164cbf2SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
40182eabf88fSMatthew G. Knepley #if 1
4019b164cbf2SMatthew 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);
40202eabf88fSMatthew G. Knepley       for (p = 0; p < 6; ++p) {
40212eabf88fSMatthew 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);
40222eabf88fSMatthew G. Knepley       }
40232eabf88fSMatthew G. Knepley #endif
40242eabf88fSMatthew G. Knepley     }
40252eabf88fSMatthew G. Knepley     /* Split faces have 4 edges and the same cells as the parent */
40262eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4027854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
40282eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
40292eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
4030aaebbb9dSMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
40312eabf88fSMatthew 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};
40322eabf88fSMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
40332eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
4034aaebbb9dSMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
40352eabf88fSMatthew G. Knepley 
40362eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
4037aaebbb9dSMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
4038a3cddbf8SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
4039a3cddbf8SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
4040a3cddbf8SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
4041a3cddbf8SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
4042a3cddbf8SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
4043a3cddbf8SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
4044a3cddbf8SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4;
4045a3cddbf8SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
40462eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4047aaebbb9dSMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
40482eabf88fSMatthew G. Knepley #if 1
40492eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
40502eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
40512eabf88fSMatthew 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);
40522eabf88fSMatthew G. Knepley         }
40532eabf88fSMatthew G. Knepley #endif
40542eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
40552eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
40562eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
40572eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
40582eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
40592eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
40602eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
40612eabf88fSMatthew G. Knepley             if (cone[c] == f) break;
40622eabf88fSMatthew G. Knepley           }
4063a3cddbf8SMatthew G. Knepley           supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)];
40642eabf88fSMatthew G. Knepley         }
40652eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
40662eabf88fSMatthew G. Knepley #if 1
40672eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
40682eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
40692eabf88fSMatthew 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);
40702eabf88fSMatthew G. Knepley         }
40712eabf88fSMatthew G. Knepley #endif
40722eabf88fSMatthew G. Knepley       }
40732eabf88fSMatthew G. Knepley     }
40742eabf88fSMatthew G. Knepley     /* Interior faces have 4 edges and 2 cells */
40752eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
40762eabf88fSMatthew 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};
4077afb2665bSMatthew G. Knepley       const PetscInt *cone, *ornt;
4078afb2665bSMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
40792eabf88fSMatthew G. Knepley 
40802eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
4081afb2665bSMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
4082afb2665bSMatthew G. Knepley       /* A-D face */
4083afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0;
4084a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
4085a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4086a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4087afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4088a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4089a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4090a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
4091afb2665bSMatthew G. Knepley       orntNew[3] = -2;
40922eabf88fSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4093afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
40942eabf88fSMatthew G. Knepley #if 1
40952eabf88fSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
40962eabf88fSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
40972eabf88fSMatthew 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);
40982eabf88fSMatthew G. Knepley       }
40992eabf88fSMatthew G. Knepley #endif
4100afb2665bSMatthew G. Knepley       /* C-D face */
4101afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1;
4102a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
4103a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4104a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4105afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4106a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4107a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4108a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
4109afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4110afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4111afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4112afb2665bSMatthew G. Knepley #if 1
4113afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4114afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4115afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4116afb2665bSMatthew G. Knepley       }
4117afb2665bSMatthew G. Knepley #endif
4118afb2665bSMatthew G. Knepley       /* B-C face */
4119afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2;
4120afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
4121afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4122afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
4123afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4124afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4125afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4126afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4127afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4128afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4129afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4130afb2665bSMatthew G. Knepley #if 1
4131afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4132afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4133afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4134afb2665bSMatthew G. Knepley       }
4135afb2665bSMatthew G. Knepley #endif
4136afb2665bSMatthew G. Knepley       /* A-B face */
4137afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3;
4138afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
4139afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4140afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
4141afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4142afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4143afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4144afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 0;
4145afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4146afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4147afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4148afb2665bSMatthew G. Knepley #if 1
4149afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4150afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4151afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4152afb2665bSMatthew G. Knepley       }
4153afb2665bSMatthew G. Knepley #endif
4154afb2665bSMatthew G. Knepley       /* E-F face */
4155afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4;
4156a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4157afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4158a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
4159a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4160a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
4161afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4162a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4163a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4164afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4165afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4166afb2665bSMatthew G. Knepley #if 1
4167afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4168afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4169afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4170afb2665bSMatthew G. Knepley       }
4171afb2665bSMatthew G. Knepley #endif
4172afb2665bSMatthew G. Knepley       /* F-G face */
4173afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5;
4174a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4175afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4176a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
4177a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4178a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
4179afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4180a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4181a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4182afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4183afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4184afb2665bSMatthew G. Knepley #if 1
4185afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4186afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4187afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4188afb2665bSMatthew G. Knepley       }
4189afb2665bSMatthew G. Knepley #endif
4190afb2665bSMatthew G. Knepley       /* G-H face */
4191afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6;
4192afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
4193afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4194afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
4195afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4196afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4197afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4198afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4199afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4200afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4201afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4202afb2665bSMatthew G. Knepley #if 1
4203afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4204afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4205afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4206afb2665bSMatthew G. Knepley       }
4207afb2665bSMatthew G. Knepley #endif
4208afb2665bSMatthew G. Knepley       /* E-H face */
4209afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7;
4210a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4211afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4212a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
4213a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4214a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
4215afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4216a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 1;
4217a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4218afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4219afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4220afb2665bSMatthew G. Knepley #if 1
4221afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4222afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4223afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4224afb2665bSMatthew G. Knepley       }
4225afb2665bSMatthew G. Knepley #endif
4226afb2665bSMatthew G. Knepley       /* A-E face */
4227afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8;
4228a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
4229a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4230a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4231afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4232a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4233a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4234a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
4235afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4236afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4237afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4238afb2665bSMatthew G. Knepley #if 1
4239afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4240afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4241afb2665bSMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew);
4242afb2665bSMatthew G. Knepley       }
4243afb2665bSMatthew G. Knepley #endif
4244afb2665bSMatthew G. Knepley       /* D-F face */
4245afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9;
4246afb2665bSMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
4247afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4248afb2665bSMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
4249afb2665bSMatthew G. Knepley       orntNew[1] = 0;
4250afb2665bSMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4251afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4252afb2665bSMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 2;
4253afb2665bSMatthew G. Knepley       orntNew[3] = -2;
4254afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4255afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4256afb2665bSMatthew G. Knepley #if 1
4257afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4258afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4259afb2665bSMatthew 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);
4260afb2665bSMatthew G. Knepley       }
4261afb2665bSMatthew G. Knepley #endif
4262afb2665bSMatthew G. Knepley       /* C-G face */
4263afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10;
4264a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 4;
4265afb2665bSMatthew G. Knepley       orntNew[0] = -2;
4266a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
4267a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4268a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
4269afb2665bSMatthew G. Knepley       orntNew[2] = 0;
4270a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4271a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4272afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4273afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4274afb2665bSMatthew G. Knepley #if 1
4275afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4276afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4277afb2665bSMatthew 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);
4278afb2665bSMatthew G. Knepley       }
4279afb2665bSMatthew G. Knepley #endif
4280afb2665bSMatthew G. Knepley       /* B-H face */
4281afb2665bSMatthew G. Knepley       newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11;
4282a3cddbf8SMatthew G. Knepley       coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 5;
4283a3cddbf8SMatthew G. Knepley       orntNew[0] = 0;
4284a3cddbf8SMatthew G. Knepley       coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd    - fStart)*4 + (c - cStart)*6 + 3;
4285a3cddbf8SMatthew G. Knepley       orntNew[1] = -2;
4286a3cddbf8SMatthew G. Knepley       coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
4287a3cddbf8SMatthew G. Knepley       orntNew[2] = -2;
4288a3cddbf8SMatthew G. Knepley       coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
4289a3cddbf8SMatthew G. Knepley       orntNew[3] = 0;
4290afb2665bSMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
4291afb2665bSMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
4292afb2665bSMatthew G. Knepley #if 1
4293afb2665bSMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
4294afb2665bSMatthew G. Knepley       for (p = 0; p < 4; ++p) {
4295afb2665bSMatthew 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);
4296afb2665bSMatthew G. Knepley       }
4297afb2665bSMatthew G. Knepley #endif
4298afb2665bSMatthew G. Knepley       for (r = 0; r < 12; ++r) {
4299afb2665bSMatthew G. Knepley         newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r;
43002eabf88fSMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
43012eabf88fSMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
43022eabf88fSMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
43032eabf88fSMatthew G. Knepley #if 1
43042eabf88fSMatthew G. Knepley         if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew);
43052eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
43062eabf88fSMatthew 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);
43072eabf88fSMatthew G. Knepley         }
43082eabf88fSMatthew G. Knepley #endif
43092eabf88fSMatthew G. Knepley       }
43102eabf88fSMatthew G. Knepley     }
43112eabf88fSMatthew G. Knepley     /* Split edges have 2 vertices and the same faces as the parent */
43122eabf88fSMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
43132eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
43142eabf88fSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
43152eabf88fSMatthew G. Knepley 
43162eabf88fSMatthew G. Knepley       for (r = 0; r < 2; ++r) {
43172eabf88fSMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
43182eabf88fSMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
43192eabf88fSMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
43202eabf88fSMatthew G. Knepley 
43212eabf88fSMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
43222eabf88fSMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
43232eabf88fSMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
43242eabf88fSMatthew G. Knepley         coneNew[(r+1)%2] = newv;
43252eabf88fSMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
43262eabf88fSMatthew G. Knepley #if 1
43272eabf88fSMatthew 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);
43282eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
43292eabf88fSMatthew 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);
43302eabf88fSMatthew G. Knepley         }
43312eabf88fSMatthew G. Knepley #endif
43322eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
43332eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
43342eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
43352eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
43362eabf88fSMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
43372eabf88fSMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
43382eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
43392eabf88fSMatthew G. Knepley             if (cone[c] == e) break;
43402eabf88fSMatthew G. Knepley           }
43412eabf88fSMatthew G. Knepley           supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4);
43422eabf88fSMatthew G. Knepley         }
43432eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
43442eabf88fSMatthew G. Knepley #if 1
43452eabf88fSMatthew 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);
43462eabf88fSMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
43472eabf88fSMatthew 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);
43482eabf88fSMatthew G. Knepley         }
43492eabf88fSMatthew G. Knepley #endif
43502eabf88fSMatthew G. Knepley       }
43512eabf88fSMatthew G. Knepley     }
43522eabf88fSMatthew G. Knepley     /* Face edges have 2 vertices and 2+cells faces */
43532eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
43546b852384SMatthew 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};
43552eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
43566b852384SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
43572eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
43582eabf88fSMatthew G. Knepley 
43592eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
43602eabf88fSMatthew G. Knepley       for (r = 0; r < 4; ++r) {
43612eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r;
43622eabf88fSMatthew G. Knepley 
43632eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
43642eabf88fSMatthew G. Knepley         coneNew[1] = newv;
43652eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
43662eabf88fSMatthew G. Knepley #if 1
43672eabf88fSMatthew 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);
43682eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
43692eabf88fSMatthew 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);
43702eabf88fSMatthew G. Knepley         }
43712eabf88fSMatthew G. Knepley #endif
43722eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
43732eabf88fSMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
43742eabf88fSMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
43752eabf88fSMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
43762eabf88fSMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
43776b852384SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
43786b852384SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
43796b852384SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
43802eabf88fSMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
4381a3cddbf8SMatthew G. Knepley           supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
43822eabf88fSMatthew G. Knepley         }
43832eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
43842eabf88fSMatthew G. Knepley #if 1
43852eabf88fSMatthew 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);
43862eabf88fSMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
43872eabf88fSMatthew 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);
43882eabf88fSMatthew G. Knepley         }
43892eabf88fSMatthew G. Knepley #endif
43902eabf88fSMatthew G. Knepley       }
43912eabf88fSMatthew G. Knepley     }
43922eabf88fSMatthew G. Knepley     /* Cell edges have 2 vertices and 4 faces */
43932eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
43942eabf88fSMatthew 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};
43952eabf88fSMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
43962eabf88fSMatthew G. Knepley       const PetscInt *cone;
43972eabf88fSMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
43982eabf88fSMatthew G. Knepley 
43992eabf88fSMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
44002eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
44012eabf88fSMatthew G. Knepley         const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
44022eabf88fSMatthew G. Knepley 
44032eabf88fSMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart);
44042eabf88fSMatthew G. Knepley         coneNew[1] = newv;
44052eabf88fSMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
44062eabf88fSMatthew G. Knepley #if 1
44072eabf88fSMatthew 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);
44082eabf88fSMatthew G. Knepley         for (p = 0; p < 2; ++p) {
44092eabf88fSMatthew 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);
44102eabf88fSMatthew G. Knepley         }
44112eabf88fSMatthew G. Knepley #endif
44122eabf88fSMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
44132eabf88fSMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
44142eabf88fSMatthew G. Knepley #if 1
44152eabf88fSMatthew 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);
44162eabf88fSMatthew G. Knepley         for (p = 0; p < 4; ++p) {
44172eabf88fSMatthew 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);
44182eabf88fSMatthew G. Knepley         }
44192eabf88fSMatthew G. Knepley #endif
44202eabf88fSMatthew G. Knepley       }
44212eabf88fSMatthew G. Knepley     }
44222eabf88fSMatthew G. Knepley     /* Old vertices have identical supports */
44232eabf88fSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
44242eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
44252eabf88fSMatthew G. Knepley       const PetscInt *support, *cone;
44262eabf88fSMatthew G. Knepley       PetscInt        size, s;
44272eabf88fSMatthew G. Knepley 
44282eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
44292eabf88fSMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
44302eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
44312eabf88fSMatthew G. Knepley         PetscInt r = 0;
44322eabf88fSMatthew G. Knepley 
44332eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
44342eabf88fSMatthew G. Knepley         if (cone[1] == v) r = 1;
44352eabf88fSMatthew G. Knepley         supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
44362eabf88fSMatthew G. Knepley       }
44372eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
44382eabf88fSMatthew G. Knepley #if 1
44392eabf88fSMatthew 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);
44402eabf88fSMatthew G. Knepley       for (p = 0; p < size; ++p) {
44412eabf88fSMatthew 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);
44422eabf88fSMatthew G. Knepley       }
44432eabf88fSMatthew G. Knepley #endif
44442eabf88fSMatthew G. Knepley     }
44452eabf88fSMatthew G. Knepley     /* Edge vertices have 2 + faces supports */
44462eabf88fSMatthew G. Knepley     for (e = eStart; e < eEnd; ++e) {
44472eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
44482eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
44492eabf88fSMatthew G. Knepley       PetscInt        size, s;
44502eabf88fSMatthew G. Knepley 
44512eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
44522eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
44532eabf88fSMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
44542eabf88fSMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
44552eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
44562eabf88fSMatthew G. Knepley         PetscInt r;
44572eabf88fSMatthew G. Knepley 
44582eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
4459a660e16cSMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
44602eabf88fSMatthew G. Knepley         supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r;
44612eabf88fSMatthew G. Knepley       }
44622eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
44632eabf88fSMatthew G. Knepley #if 1
44642eabf88fSMatthew 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);
44652eabf88fSMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
44662eabf88fSMatthew 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);
44672eabf88fSMatthew G. Knepley       }
44682eabf88fSMatthew G. Knepley #endif
44692eabf88fSMatthew G. Knepley     }
44702eabf88fSMatthew G. Knepley     /* Face vertices have 4 + cells supports */
44712eabf88fSMatthew G. Knepley     for (f = fStart; f < fEnd; ++f) {
44722eabf88fSMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart);
44732eabf88fSMatthew G. Knepley       const PetscInt *cone, *support;
44742eabf88fSMatthew G. Knepley       PetscInt        size, s;
44752eabf88fSMatthew G. Knepley 
44762eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
44772eabf88fSMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
44780793999aSMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 +  (f - fStart)*4 + r;
44792eabf88fSMatthew G. Knepley       for (s = 0; s < size; ++s) {
44802eabf88fSMatthew G. Knepley         PetscInt r;
44812eabf88fSMatthew G. Knepley 
44822eabf88fSMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
44832eabf88fSMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
44842eabf88fSMatthew G. Knepley         supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r;
44852eabf88fSMatthew G. Knepley       }
44862eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
44872eabf88fSMatthew G. Knepley #if 1
44882eabf88fSMatthew 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);
44892eabf88fSMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
44902eabf88fSMatthew 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);
44912eabf88fSMatthew G. Knepley       }
44922eabf88fSMatthew G. Knepley #endif
44932eabf88fSMatthew G. Knepley     }
44942eabf88fSMatthew G. Knepley     /* Cell vertices have 6 supports */
44952eabf88fSMatthew G. Knepley     for (c = cStart; c < cEnd; ++c) {
44962eabf88fSMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart);
44972eabf88fSMatthew G. Knepley       PetscInt       supportNew[6];
44982eabf88fSMatthew G. Knepley 
44992eabf88fSMatthew G. Knepley       for (r = 0; r < 6; ++r) {
45002eabf88fSMatthew G. Knepley         supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r;
45012eabf88fSMatthew G. Knepley       }
45022eabf88fSMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
45032eabf88fSMatthew G. Knepley     }
4504da00770fSMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
45052eabf88fSMatthew G. Knepley     break;
45069b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
450727fcede3SMatthew G. Knepley     ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr);
450827fcede3SMatthew G. Knepley     /*
450927fcede3SMatthew G. Knepley      Bottom (viewed from top)    Top
451027fcede3SMatthew G. Knepley      1---------2---------2       7---------2---------6
451127fcede3SMatthew G. Knepley      |         |         |       |         |         |
451227fcede3SMatthew G. Knepley      |    B    2    C    |       |    H    2    G    |
451327fcede3SMatthew G. Knepley      |         |         |       |         |         |
451427fcede3SMatthew G. Knepley      3----3----0----1----1       3----3----0----1----1
451527fcede3SMatthew G. Knepley      |         |         |       |         |         |
451627fcede3SMatthew G. Knepley      |    A    0    D    |       |    E    0    F    |
451727fcede3SMatthew G. Knepley      |         |         |       |         |         |
451827fcede3SMatthew G. Knepley      0---------0---------3       4---------0---------5
451927fcede3SMatthew G. Knepley      */
452027fcede3SMatthew G. Knepley     /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */
452127fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
452227fcede3SMatthew G. Knepley       const PetscInt  newp = (c - cStart)*8;
452327fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
452427fcede3SMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6];
452527fcede3SMatthew G. Knepley 
452627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
452727fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
452827fcede3SMatthew G. Knepley       /* A hex */
452927fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0);
453027fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
453127fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
453227fcede3SMatthew G. Knepley       orntNew[1] = 0;
453327fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0);
453427fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
453527fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
453627fcede3SMatthew G. Knepley       orntNew[3] = 0;
453727fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
453827fcede3SMatthew G. Knepley       orntNew[4] = 0;
453927fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0);
454027fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
454127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr);
454227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr);
454327fcede3SMatthew G. Knepley #if 1
454427fcede3SMatthew 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);
454527fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
454627fcede3SMatthew 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);
454727fcede3SMatthew G. Knepley       }
454827fcede3SMatthew G. Knepley #endif
454927fcede3SMatthew G. Knepley       /* B hex */
455027fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1);
455127fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
455227fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
455327fcede3SMatthew G. Knepley       orntNew[1] = 0;
455427fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  3; /* AB */
455527fcede3SMatthew G. Knepley       orntNew[2] = -1;
455627fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1);
455727fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
455827fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
455927fcede3SMatthew G. Knepley       orntNew[4] = 0;
456027fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3);
456127fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
456227fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr);
456327fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr);
456427fcede3SMatthew G. Knepley #if 1
456527fcede3SMatthew 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);
456627fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
456727fcede3SMatthew 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);
456827fcede3SMatthew G. Knepley       }
456927fcede3SMatthew G. Knepley #endif
457027fcede3SMatthew G. Knepley       /* C hex */
457127fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2);
457227fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
457327fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
457427fcede3SMatthew G. Knepley       orntNew[1] = 0;
457527fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
457627fcede3SMatthew G. Knepley       orntNew[2] = -1;
457727fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0);
457827fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
457927fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1);
458027fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
458127fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  2; /* BC */
458227fcede3SMatthew G. Knepley       orntNew[5] = -4;
458327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr);
458427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr);
458527fcede3SMatthew G. Knepley #if 1
458627fcede3SMatthew 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);
458727fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
458827fcede3SMatthew 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);
458927fcede3SMatthew G. Knepley       }
459027fcede3SMatthew G. Knepley #endif
459127fcede3SMatthew G. Knepley       /* D hex */
459227fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3);
459327fcede3SMatthew G. Knepley       orntNew[0] = ornt[0];
459427fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
459527fcede3SMatthew G. Knepley       orntNew[1] = 0;
459627fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1);
459727fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
459827fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  1; /* CD */
459927fcede3SMatthew G. Knepley       orntNew[3] = 0;
460027fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0);
460127fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
460227fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  0; /* AD */
460327fcede3SMatthew G. Knepley       orntNew[5] = -4;
460427fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr);
460527fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr);
460627fcede3SMatthew G. Knepley #if 1
460727fcede3SMatthew 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);
460827fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
460927fcede3SMatthew 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);
461027fcede3SMatthew G. Knepley       }
461127fcede3SMatthew G. Knepley #endif
461227fcede3SMatthew G. Knepley       /* E hex */
461327fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  8; /* AE */
461427fcede3SMatthew G. Knepley       orntNew[0] = -4;
461527fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0);
461627fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
461727fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3);
461827fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
461927fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
462027fcede3SMatthew G. Knepley       orntNew[3] = 0;
462127fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
462227fcede3SMatthew G. Knepley       orntNew[4] = -1;
462327fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1);
462427fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
462527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr);
462627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr);
462727fcede3SMatthew G. Knepley #if 1
462827fcede3SMatthew 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);
462927fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
463027fcede3SMatthew 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);
463127fcede3SMatthew G. Knepley       }
463227fcede3SMatthew G. Knepley #endif
463327fcede3SMatthew G. Knepley       /* F hex */
463427fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  9; /* DF */
463527fcede3SMatthew G. Knepley       orntNew[0] = -4;
463627fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1);
463727fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
463827fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2);
463927fcede3SMatthew G. Knepley       orntNew[2] = ornt[2];
464027fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
464127fcede3SMatthew G. Knepley       orntNew[3] = -1;
464227fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3);
464327fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
464427fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  4; /* EF */
464527fcede3SMatthew G. Knepley       orntNew[5] = 1;
464627fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr);
464727fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr);
464827fcede3SMatthew G. Knepley #if 1
464927fcede3SMatthew 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);
465027fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
465127fcede3SMatthew 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);
465227fcede3SMatthew G. Knepley       }
465327fcede3SMatthew G. Knepley #endif
465427fcede3SMatthew G. Knepley       /* G hex */
465527fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 10; /* CG */
465627fcede3SMatthew G. Knepley       orntNew[0] = -4;
465727fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2);
465827fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
465927fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  5; /* FG */
466027fcede3SMatthew G. Knepley       orntNew[2] = 0;
466127fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3);
466227fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
466327fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2);
466427fcede3SMatthew G. Knepley       orntNew[4] = ornt[4];
466527fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
466627fcede3SMatthew G. Knepley       orntNew[5] = -3;
466727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr);
466827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr);
466927fcede3SMatthew G. Knepley #if 1
467027fcede3SMatthew 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);
467127fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
467227fcede3SMatthew 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);
467327fcede3SMatthew G. Knepley       }
467427fcede3SMatthew G. Knepley #endif
467527fcede3SMatthew G. Knepley       /* H hex */
467627fcede3SMatthew G. Knepley       coneNew[0] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 + 11; /* BH */
467727fcede3SMatthew G. Knepley       orntNew[0] = -4;
467827fcede3SMatthew G. Knepley       coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3);
467927fcede3SMatthew G. Knepley       orntNew[1] = ornt[1];
468027fcede3SMatthew G. Knepley       coneNew[2] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  7; /* EH */
468127fcede3SMatthew G. Knepley       orntNew[2] = -1;
468227fcede3SMatthew G. Knepley       coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2);
468327fcede3SMatthew G. Knepley       orntNew[3] = ornt[3];
468427fcede3SMatthew G. Knepley       coneNew[4] = fStartNew + (fMax    - fStart)*4 + (c - cStart)*12 +  6; /* GH */
468527fcede3SMatthew G. Knepley       orntNew[4] = 3;
468627fcede3SMatthew G. Knepley       coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2);
468727fcede3SMatthew G. Knepley       orntNew[5] = ornt[5];
468827fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr);
468927fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr);
469027fcede3SMatthew G. Knepley #if 1
469127fcede3SMatthew 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);
469227fcede3SMatthew G. Knepley       for (p = 0; p < 6; ++p) {
469327fcede3SMatthew G. Knepley         if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew);
469427fcede3SMatthew G. Knepley       }
469527fcede3SMatthew G. Knepley #endif
469627fcede3SMatthew G. Knepley     }
469727fcede3SMatthew G. Knepley     /* Hybrid cells have 6 faces: Front, Back, Sides */
469827fcede3SMatthew G. Knepley     /*
469927fcede3SMatthew G. Knepley      3---------2---------2
470027fcede3SMatthew G. Knepley      |         |         |
470127fcede3SMatthew G. Knepley      |    D    2    C    |
470227fcede3SMatthew G. Knepley      |         |         |
470327fcede3SMatthew G. Knepley      3----3----0----1----1
470427fcede3SMatthew G. Knepley      |         |         |
470527fcede3SMatthew G. Knepley      |    A    0    B    |
470627fcede3SMatthew G. Knepley      |         |         |
470727fcede3SMatthew G. Knepley      0---------0---------1
470827fcede3SMatthew G. Knepley      */
470927fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
471027fcede3SMatthew G. Knepley       const PetscInt  newp = (cMax - cStart)*8 + (c - cMax)*4;
471127fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *fornt;
4712d273725eSMatthew G. Knepley       PetscInt        coneNew[6], orntNew[6], o, of, i;
471327fcede3SMatthew G. Knepley 
471427fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
471527fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
471627fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr);
4717d273725eSMatthew G. Knepley       o = ornt[0] < 0 ? -1 : 1;
471827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
471927fcede3SMatthew G. Knepley         PetscInt subfA = GetQuadSubface_Static(ornt[0], r);
472027fcede3SMatthew G. Knepley         PetscInt edgeA = GetQuadEdge_Static(ornt[0], r);
4721d273725eSMatthew G. Knepley         PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4);
472227fcede3SMatthew 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]);
472327fcede3SMatthew G. Knepley         coneNew[0]         = fStartNew + (cone[0] - fStart)*4 + subfA;
472427fcede3SMatthew G. Knepley         orntNew[0]         = ornt[0];
472527fcede3SMatthew G. Knepley         coneNew[1]         = fStartNew + (cone[1] - fStart)*4 + subfA;
472627fcede3SMatthew G. Knepley         orntNew[1]         = ornt[0];
4727d273725eSMatthew G. Knepley         of = fornt[edgeA] < 0 ? -1 : 1;
4728d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], r) + 2;
4729d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0);
4730d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeA];
4731d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2;
4732d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeA;
4733d273725eSMatthew G. Knepley         orntNew[i] = 0;
4734d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2;
4735d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd          - fMax)*2 + (c - cMax)*4 + edgeB;
4736d273725eSMatthew G. Knepley         orntNew[i] = -2;
4737d273725eSMatthew G. Knepley         of = fornt[edgeB] < 0 ? -1 : 1;
4738d273725eSMatthew G. Knepley         i  = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2;
4739d273725eSMatthew G. Knepley         coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1);
4740d273725eSMatthew G. Knepley         orntNew[i] = ornt[edgeB];
474127fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
474227fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
474327fcede3SMatthew G. Knepley #if 1
474427fcede3SMatthew 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);
474527fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
474627fcede3SMatthew 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);
474727fcede3SMatthew G. Knepley         }
474827fcede3SMatthew G. Knepley         for (p = 2; p < 6; ++p) {
474927fcede3SMatthew 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);
475027fcede3SMatthew G. Knepley         }
475127fcede3SMatthew G. Knepley #endif
475227fcede3SMatthew G. Knepley       }
475327fcede3SMatthew G. Knepley     }
475427fcede3SMatthew G. Knepley     /* Interior split faces have 4 edges and the same cells as the parent */
475527fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
4756854ce69bSBarry Smith     ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr);
475727fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
475827fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
475927fcede3SMatthew G. Knepley         /* TODO: This can come from GetFaces_Internal() */
476027fcede3SMatthew 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};
476127fcede3SMatthew G. Knepley         const PetscInt  newp = fStartNew + (f - fStart)*4 + r;
476227fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
476327fcede3SMatthew G. Knepley         PetscInt        coneNew[4], orntNew[4], coneSize, c, supportSize, s;
476427fcede3SMatthew G. Knepley 
476527fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
476627fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
476727fcede3SMatthew G. Knepley         coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1);
476827fcede3SMatthew G. Knepley         orntNew[(r+3)%4] = ornt[(r+3)%4];
476927fcede3SMatthew G. Knepley         coneNew[(r+0)%4] = eStartNew + (cone[r]       - eStart)*2 + (ornt[r] < 0 ? 1 : 0);
477027fcede3SMatthew G. Knepley         orntNew[(r+0)%4] = ornt[r];
477127fcede3SMatthew G. Knepley         coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
477227fcede3SMatthew G. Knepley         orntNew[(r+1)%4] = 0;
477327fcede3SMatthew G. Knepley         coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4;
477427fcede3SMatthew G. Knepley         orntNew[(r+2)%4] = -2;
477527fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
477627fcede3SMatthew G. Knepley         ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
477727fcede3SMatthew G. Knepley #if 1
477827fcede3SMatthew 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);
477927fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
478027fcede3SMatthew 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);
478127fcede3SMatthew G. Knepley         }
478227fcede3SMatthew G. Knepley #endif
478327fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
478427fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
478527fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
478627fcede3SMatthew G. Knepley           PetscInt subf;
478727fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
478827fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
478927fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
479027fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
479127fcede3SMatthew G. Knepley             if (cone[c] == f) break;
479227fcede3SMatthew G. Knepley           }
479327fcede3SMatthew G. Knepley           subf = GetQuadSubfaceInverse_Static(ornt[c], r);
479427fcede3SMatthew G. Knepley           if (support[s] < cMax) {
479527fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf];
479627fcede3SMatthew G. Knepley           } else {
479727fcede3SMatthew G. Knepley             supportRef[s] = cStartNew + (cMax       - cStart)*8 + (support[s] - cMax)*4 + subf;
479827fcede3SMatthew G. Knepley           }
479927fcede3SMatthew G. Knepley         }
480027fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
480127fcede3SMatthew G. Knepley #if 1
480227fcede3SMatthew 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);
480327fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
480427fcede3SMatthew 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);
480527fcede3SMatthew G. Knepley         }
480627fcede3SMatthew G. Knepley #endif
480727fcede3SMatthew G. Knepley       }
480827fcede3SMatthew G. Knepley     }
4809d273725eSMatthew G. Knepley     /* Interior cell faces have 4 edges and 2 cells */
481027fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
481127fcede3SMatthew 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};
481227fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
481327fcede3SMatthew G. Knepley       PetscInt        newp, coneNew[4], orntNew[4], supportNew[2];
481427fcede3SMatthew G. Knepley 
481527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
481627fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
481727fcede3SMatthew G. Knepley       /* A-D face */
481827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0;
481927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3);
482027fcede3SMatthew G. Knepley       orntNew[0] = 0;
482127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
482227fcede3SMatthew G. Knepley       orntNew[1] = 0;
482327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
482427fcede3SMatthew G. Knepley       orntNew[2] = -2;
482527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0);
482627fcede3SMatthew G. Knepley       orntNew[3] = -2;
482727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
482827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
482927fcede3SMatthew G. Knepley #if 1
483027fcede3SMatthew G. Knepley       if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew);
483127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
483227fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
483327fcede3SMatthew G. Knepley       }
483427fcede3SMatthew G. Knepley #endif
483527fcede3SMatthew G. Knepley       /* C-D face */
483627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1;
483727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2);
483827fcede3SMatthew G. Knepley       orntNew[0] = 0;
483927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
484027fcede3SMatthew G. Knepley       orntNew[1] = 0;
484127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
484227fcede3SMatthew G. Knepley       orntNew[2] = -2;
484327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0);
484427fcede3SMatthew G. Knepley       orntNew[3] = -2;
484527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
484627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
484727fcede3SMatthew G. Knepley #if 1
484827fcede3SMatthew 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);
484927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
485027fcede3SMatthew 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);
485127fcede3SMatthew G. Knepley       }
485227fcede3SMatthew G. Knepley #endif
485327fcede3SMatthew G. Knepley       /* B-C face */
485427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2;
485527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1);
485627fcede3SMatthew G. Knepley       orntNew[0] = -2;
485727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0);
485827fcede3SMatthew G. Knepley       orntNew[1] = 0;
485927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
486027fcede3SMatthew G. Knepley       orntNew[2] = 0;
486127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
486227fcede3SMatthew G. Knepley       orntNew[3] = -2;
486327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
486427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
486527fcede3SMatthew G. Knepley #if 1
486627fcede3SMatthew 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);
486727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
486827fcede3SMatthew 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);
486927fcede3SMatthew G. Knepley       }
487027fcede3SMatthew G. Knepley #endif
487127fcede3SMatthew G. Knepley       /* A-B face */
487227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3;
487327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0);
487427fcede3SMatthew G. Knepley       orntNew[0] = -2;
487527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3);
487627fcede3SMatthew G. Knepley       orntNew[1] = 0;
487727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
487827fcede3SMatthew G. Knepley       orntNew[2] = 0;
487927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 0;
488027fcede3SMatthew G. Knepley       orntNew[3] = -2;
488127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
488227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
488327fcede3SMatthew G. Knepley #if 1
488427fcede3SMatthew 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);
488527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
488627fcede3SMatthew 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);
488727fcede3SMatthew G. Knepley       }
488827fcede3SMatthew G. Knepley #endif
488927fcede3SMatthew G. Knepley       /* E-F face */
489027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4;
489127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
489227fcede3SMatthew G. Knepley       orntNew[0] = -2;
489327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2);
489427fcede3SMatthew G. Knepley       orntNew[1] = -2;
489527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0);
489627fcede3SMatthew G. Knepley       orntNew[2] = 0;
489727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
489827fcede3SMatthew G. Knepley       orntNew[3] = 0;
489927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
490027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
490127fcede3SMatthew G. Knepley #if 1
490227fcede3SMatthew 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);
490327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
490427fcede3SMatthew 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);
490527fcede3SMatthew G. Knepley       }
490627fcede3SMatthew G. Knepley #endif
490727fcede3SMatthew G. Knepley       /* F-G face */
490827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5;
490927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
491027fcede3SMatthew G. Knepley       orntNew[0] = -2;
491127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2);
491227fcede3SMatthew G. Knepley       orntNew[1] = -2;
491327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1);
491427fcede3SMatthew G. Knepley       orntNew[2] = 0;
491527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
491627fcede3SMatthew G. Knepley       orntNew[3] = 0;
491727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
491827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
491927fcede3SMatthew G. Knepley #if 1
492027fcede3SMatthew 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);
492127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
492227fcede3SMatthew G. Knepley         if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew);
492327fcede3SMatthew G. Knepley       }
492427fcede3SMatthew G. Knepley #endif
492527fcede3SMatthew G. Knepley       /* G-H face */
492627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6;
492727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2);
492827fcede3SMatthew G. Knepley       orntNew[0] = -2;
492927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2);
493027fcede3SMatthew G. Knepley       orntNew[1] = 0;
493127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
493227fcede3SMatthew G. Knepley       orntNew[2] = 0;
493327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
493427fcede3SMatthew G. Knepley       orntNew[3] = -2;
493527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
493627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
493727fcede3SMatthew G. Knepley #if 1
493827fcede3SMatthew 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);
493927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
494027fcede3SMatthew 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);
494127fcede3SMatthew G. Knepley       }
494227fcede3SMatthew G. Knepley #endif
494327fcede3SMatthew G. Knepley       /* E-H face */
494427fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7;
494527fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
494627fcede3SMatthew G. Knepley       orntNew[0] = -2;
494727fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1);
494827fcede3SMatthew G. Knepley       orntNew[1] = -2;
494927fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3);
495027fcede3SMatthew G. Knepley       orntNew[2] = 0;
495127fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 1;
495227fcede3SMatthew G. Knepley       orntNew[3] = 0;
495327fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
495427fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
495527fcede3SMatthew G. Knepley #if 1
495627fcede3SMatthew 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);
495727fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
495827fcede3SMatthew 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);
495927fcede3SMatthew G. Knepley       }
496027fcede3SMatthew G. Knepley #endif
496127fcede3SMatthew G. Knepley       /* A-E face */
496227fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8;
496327fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3);
496427fcede3SMatthew G. Knepley       orntNew[0] = 0;
496527fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
496627fcede3SMatthew G. Knepley       orntNew[1] = 0;
496727fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
496827fcede3SMatthew G. Knepley       orntNew[2] = -2;
496927fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0);
497027fcede3SMatthew G. Knepley       orntNew[3] = -2;
497127fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
497227fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
497327fcede3SMatthew G. Knepley #if 1
497427fcede3SMatthew 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);
497527fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
497627fcede3SMatthew 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);
497727fcede3SMatthew G. Knepley       }
497827fcede3SMatthew G. Knepley #endif
497927fcede3SMatthew G. Knepley       /* D-F face */
498027fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9;
498127fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1);
498227fcede3SMatthew G. Knepley       orntNew[0] = -2;
498327fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3);
498427fcede3SMatthew G. Knepley       orntNew[1] = 0;
498527fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
498627fcede3SMatthew G. Knepley       orntNew[2] = 0;
498727fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 2;
498827fcede3SMatthew G. Knepley       orntNew[3] = -2;
498927fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
499027fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
499127fcede3SMatthew G. Knepley #if 1
499227fcede3SMatthew 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);
499327fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
499427fcede3SMatthew 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);
499527fcede3SMatthew G. Knepley       }
499627fcede3SMatthew G. Knepley #endif
499727fcede3SMatthew G. Knepley       /* C-G face */
499827fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10;
499927fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 4;
500027fcede3SMatthew G. Knepley       orntNew[0] = -2;
500127fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1);
500227fcede3SMatthew G. Knepley       orntNew[1] = -2;
500327fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3);
500427fcede3SMatthew G. Knepley       orntNew[2] = 0;
500527fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
500627fcede3SMatthew G. Knepley       orntNew[3] = 0;
500727fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
500827fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
500927fcede3SMatthew G. Knepley #if 1
501027fcede3SMatthew 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);
501127fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
501227fcede3SMatthew 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);
501327fcede3SMatthew G. Knepley       }
501427fcede3SMatthew G. Knepley #endif
501527fcede3SMatthew G. Knepley       /* B-H face */
501627fcede3SMatthew G. Knepley       newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11;
501727fcede3SMatthew G. Knepley       coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 5;
501827fcede3SMatthew G. Knepley       orntNew[0] = 0;
501927fcede3SMatthew G. Knepley       coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax    - fStart)*4 + (c - cStart)*6 + 3;
502027fcede3SMatthew G. Knepley       orntNew[1] = -2;
502127fcede3SMatthew G. Knepley       coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1);
502227fcede3SMatthew G. Knepley       orntNew[2] = -2;
502327fcede3SMatthew G. Knepley       coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2);
502427fcede3SMatthew G. Knepley       orntNew[3] = 0;
502527fcede3SMatthew G. Knepley       ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
502627fcede3SMatthew G. Knepley       ierr       = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
502727fcede3SMatthew G. Knepley #if 1
502827fcede3SMatthew 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);
502927fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
503027fcede3SMatthew 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);
503127fcede3SMatthew G. Knepley       }
503227fcede3SMatthew G. Knepley #endif
503327fcede3SMatthew G. Knepley       for (r = 0; r < 12; ++r) {
503427fcede3SMatthew G. Knepley         newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r;
503527fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0];
503627fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1];
503727fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
503827fcede3SMatthew G. Knepley #if 1
503927fcede3SMatthew 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);
504027fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
504127fcede3SMatthew 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);
504227fcede3SMatthew G. Knepley         }
504327fcede3SMatthew G. Knepley #endif
504427fcede3SMatthew G. Knepley       }
504527fcede3SMatthew G. Knepley     }
504627fcede3SMatthew G. Knepley     /* Hybrid split faces have 4 edges and same cells */
504727fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
504827fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt, *support;
504927fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
505027fcede3SMatthew G. Knepley       PetscInt        supportNew[2], size, s, c;
505127fcede3SMatthew G. Knepley 
505227fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
505327fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr);
505427fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
505527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
505627fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
505727fcede3SMatthew G. Knepley         const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r;
505827fcede3SMatthew G. Knepley 
505927fcede3SMatthew G. Knepley         coneNew[0]   = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r);
506027fcede3SMatthew G. Knepley         orntNew[0]   = ornt[0];
506127fcede3SMatthew G. Knepley         coneNew[1]   = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r);
506227fcede3SMatthew G. Knepley         orntNew[1]   = ornt[1];
506327fcede3SMatthew G. Knepley         coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax);
506427fcede3SMatthew G. Knepley         orntNew[2+r] = 0;
506527fcede3SMatthew G. Knepley         coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd      - eMax) + (f - fMax);
506627fcede3SMatthew G. Knepley         orntNew[3-r] = 0;
506727fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
506827fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr);
506927fcede3SMatthew G. Knepley #if 1
507027fcede3SMatthew 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);
507127fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
507227fcede3SMatthew 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);
507327fcede3SMatthew G. Knepley         }
507427fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
507527fcede3SMatthew 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);
507627fcede3SMatthew G. Knepley         }
507727fcede3SMatthew G. Knepley #endif
507827fcede3SMatthew G. Knepley         for (s = 0; s < size; ++s) {
507927fcede3SMatthew G. Knepley           const PetscInt *coneCell, *orntCell, *fornt;
5080d273725eSMatthew G. Knepley           PetscInt        o, of;
508127fcede3SMatthew G. Knepley 
508227fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
508327fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
5084d273725eSMatthew G. Knepley           o = orntCell[0] < 0 ? -1 : 1;
508527fcede3SMatthew G. Knepley           for (c = 2; c < 6; ++c) if (coneCell[c] == f) break;
508627fcede3SMatthew 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]);
508727fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr);
5088d273725eSMatthew G. Knepley           of = fornt[c-2] < 0 ? -1 : 1;
5089d273725eSMatthew 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;
509027fcede3SMatthew G. Knepley         }
509127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
509227fcede3SMatthew G. Knepley #if 1
509327fcede3SMatthew 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);
509427fcede3SMatthew G. Knepley         for (p = 0; p < size; ++p) {
509527fcede3SMatthew 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);
509627fcede3SMatthew G. Knepley         }
509727fcede3SMatthew G. Knepley #endif
509827fcede3SMatthew G. Knepley       }
509927fcede3SMatthew G. Knepley     }
510027fcede3SMatthew G. Knepley     /* Hybrid cell faces have 4 edges and 2 cells */
510127fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
510227fcede3SMatthew G. Knepley       PetscInt        newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4;
510327fcede3SMatthew G. Knepley       const PetscInt *cone, *ornt;
510427fcede3SMatthew G. Knepley       PetscInt        coneNew[4], orntNew[4];
510527fcede3SMatthew G. Knepley       PetscInt        supportNew[2];
510627fcede3SMatthew G. Knepley 
510727fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
510827fcede3SMatthew G. Knepley       ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr);
510927fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
5110d273725eSMatthew G. Knepley #if 0
511127fcede3SMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r);
511227fcede3SMatthew G. Knepley         orntNew[0] = 0;
511327fcede3SMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r);
511427fcede3SMatthew G. Knepley         orntNew[1] = 0;
511527fcede3SMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax);
511627fcede3SMatthew G. Knepley         orntNew[2] = 0;
511727fcede3SMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd                                   - fMax) + (c - cMax);
511827fcede3SMatthew G. Knepley         orntNew[3] = 0;
5119d273725eSMatthew G. Knepley #else
5120d273725eSMatthew G. Knepley         coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r;
5121d273725eSMatthew G. Knepley         orntNew[0] = 0;
5122d273725eSMatthew G. Knepley         coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r;
5123d273725eSMatthew G. Knepley         orntNew[1] = 0;
5124d273725eSMatthew G. Knepley         coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax);
5125d273725eSMatthew G. Knepley         orntNew[2] = 0;
5126d273725eSMatthew G. Knepley         coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd      - fMax) + (c - cMax);
5127d273725eSMatthew G. Knepley         orntNew[3] = 0;
5128d273725eSMatthew G. Knepley #endif
512927fcede3SMatthew G. Knepley         ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr);
513027fcede3SMatthew G. Knepley         ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr);
513127fcede3SMatthew G. Knepley #if 1
513227fcede3SMatthew 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);
513327fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
513427fcede3SMatthew 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);
513527fcede3SMatthew G. Knepley         }
513627fcede3SMatthew G. Knepley         for (p = 2; p < 4; ++p) {
513727fcede3SMatthew 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);
513827fcede3SMatthew G. Knepley         }
513927fcede3SMatthew G. Knepley #endif
514027fcede3SMatthew G. Knepley         supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r);
514127fcede3SMatthew G. Knepley         supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4);
514227fcede3SMatthew G. Knepley         ierr          = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr);
514327fcede3SMatthew G. Knepley #if 1
514427fcede3SMatthew 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);
514527fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
514627fcede3SMatthew 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);
514727fcede3SMatthew G. Knepley         }
514827fcede3SMatthew G. Knepley #endif
514927fcede3SMatthew G. Knepley       }
515027fcede3SMatthew G. Knepley     }
515127fcede3SMatthew G. Knepley     /* Interior split edges have 2 vertices and the same faces as the parent */
515227fcede3SMatthew G. Knepley     ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr);
515327fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
515427fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart);
515527fcede3SMatthew G. Knepley 
515627fcede3SMatthew G. Knepley       for (r = 0; r < 2; ++r) {
515727fcede3SMatthew G. Knepley         const PetscInt  newp = eStartNew + (e - eStart)*2 + r;
515827fcede3SMatthew G. Knepley         const PetscInt *cone, *ornt, *support;
515927fcede3SMatthew G. Knepley         PetscInt        coneNew[2], coneSize, c, supportSize, s;
516027fcede3SMatthew G. Knepley 
516127fcede3SMatthew G. Knepley         ierr             = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
516227fcede3SMatthew G. Knepley         coneNew[0]       = vStartNew + (cone[0] - vStart);
516327fcede3SMatthew G. Knepley         coneNew[1]       = vStartNew + (cone[1] - vStart);
516427fcede3SMatthew G. Knepley         coneNew[(r+1)%2] = newv;
516527fcede3SMatthew G. Knepley         ierr             = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
516627fcede3SMatthew G. Knepley #if 1
516727fcede3SMatthew 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);
516827fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
516927fcede3SMatthew 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);
517027fcede3SMatthew G. Knepley         }
517127fcede3SMatthew G. Knepley #endif
517227fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr);
517327fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
517427fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
517527fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
517627fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
517727fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr);
517827fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) {
517927fcede3SMatthew G. Knepley             if (cone[c] == e) break;
518027fcede3SMatthew G. Knepley           }
518127fcede3SMatthew G. Knepley           if (support[s] < fMax) {
518227fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4;
518327fcede3SMatthew G. Knepley           } else {
518427fcede3SMatthew G. Knepley             supportRef[s] = fStartNew + (fMax       - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r);
518527fcede3SMatthew G. Knepley           }
518627fcede3SMatthew G. Knepley         }
518727fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
518827fcede3SMatthew G. Knepley #if 1
518927fcede3SMatthew 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);
519027fcede3SMatthew G. Knepley         for (p = 0; p < supportSize; ++p) {
519127fcede3SMatthew 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);
519227fcede3SMatthew G. Knepley         }
519327fcede3SMatthew G. Knepley #endif
519427fcede3SMatthew G. Knepley       }
519527fcede3SMatthew G. Knepley     }
519627fcede3SMatthew G. Knepley     /* Interior face edges have 2 vertices and 2+cells faces */
519727fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
519827fcede3SMatthew 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};
519927fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
520027fcede3SMatthew G. Knepley       const PetscInt *cone, *coneCell, *orntCell, *support;
520127fcede3SMatthew G. Knepley       PetscInt        coneNew[2], coneSize, c, supportSize, s;
520227fcede3SMatthew G. Knepley 
520327fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
520427fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) {
520527fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r;
520627fcede3SMatthew G. Knepley 
520727fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart);
520827fcede3SMatthew G. Knepley         coneNew[1] = newv;
520927fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
521027fcede3SMatthew G. Knepley #if 1
521127fcede3SMatthew 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);
521227fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
521327fcede3SMatthew 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);
521427fcede3SMatthew G. Knepley         }
521527fcede3SMatthew G. Knepley #endif
521627fcede3SMatthew G. Knepley         ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr);
521727fcede3SMatthew G. Knepley         ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
521827fcede3SMatthew G. Knepley         supportRef[0] = fStartNew + (f - fStart)*4 + r;
521927fcede3SMatthew G. Knepley         supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4;
522027fcede3SMatthew G. Knepley         for (s = 0; s < supportSize; ++s) {
522127fcede3SMatthew G. Knepley           ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr);
522227fcede3SMatthew G. Knepley           ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr);
522327fcede3SMatthew G. Knepley           ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr);
522427fcede3SMatthew G. Knepley           for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break;
522527fcede3SMatthew G. Knepley           if (support[s] < cMax) {
522627fcede3SMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)];
522727fcede3SMatthew G. Knepley           } else {
5228d273725eSMatthew G. Knepley             supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r;
522927fcede3SMatthew G. Knepley           }
523027fcede3SMatthew G. Knepley         }
523127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
523227fcede3SMatthew G. Knepley #if 1
523327fcede3SMatthew 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);
523427fcede3SMatthew G. Knepley         for (p = 0; p < 2+supportSize; ++p) {
523527fcede3SMatthew 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);
523627fcede3SMatthew G. Knepley         }
523727fcede3SMatthew G. Knepley #endif
523827fcede3SMatthew G. Knepley       }
523927fcede3SMatthew G. Knepley     }
524027fcede3SMatthew G. Knepley     /* Interior cell edges have 2 vertices and 4 faces */
524127fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
524227fcede3SMatthew 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};
524327fcede3SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
524427fcede3SMatthew G. Knepley       const PetscInt *cone;
524527fcede3SMatthew G. Knepley       PetscInt        coneNew[2], supportNew[4];
524627fcede3SMatthew G. Knepley 
524727fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
524827fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
524927fcede3SMatthew G. Knepley         const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
525027fcede3SMatthew G. Knepley 
525127fcede3SMatthew G. Knepley         coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart);
525227fcede3SMatthew G. Knepley         coneNew[1] = newv;
525327fcede3SMatthew G. Knepley         ierr       = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
525427fcede3SMatthew G. Knepley #if 1
525527fcede3SMatthew 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);
525627fcede3SMatthew G. Knepley         for (p = 0; p < 2; ++p) {
525727fcede3SMatthew 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);
525827fcede3SMatthew G. Knepley         }
525927fcede3SMatthew G. Knepley #endif
526027fcede3SMatthew G. Knepley         for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f];
526127fcede3SMatthew G. Knepley         ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
526227fcede3SMatthew G. Knepley #if 1
526327fcede3SMatthew 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);
526427fcede3SMatthew G. Knepley         for (p = 0; p < 4; ++p) {
526527fcede3SMatthew 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);
526627fcede3SMatthew G. Knepley         }
526727fcede3SMatthew G. Knepley #endif
526827fcede3SMatthew G. Knepley       }
526927fcede3SMatthew G. Knepley     }
527027fcede3SMatthew G. Knepley     /* Hybrid edges have two vertices and the same faces */
527127fcede3SMatthew G. Knepley     for (e = eMax; e < eEnd; ++e) {
527227fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax);
527327fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *fcone;
527427fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, fsize, s;
527527fcede3SMatthew G. Knepley 
527627fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
527727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
527827fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
527927fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (cone[0] - vStart);
528027fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (cone[1] - vStart);
528127fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
528227fcede3SMatthew G. Knepley #if 1
528327fcede3SMatthew 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);
528427fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
528527fcede3SMatthew 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);
528627fcede3SMatthew G. Knepley       }
528727fcede3SMatthew G. Knepley #endif
528827fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
528927fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr);
529027fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr);
529127fcede3SMatthew G. Knepley         for (c = 0; c < fsize; ++c) if (fcone[c] == e) break;
529227fcede3SMatthew 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]);
529327fcede3SMatthew G. Knepley         supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2;
529427fcede3SMatthew G. Knepley       }
529527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
529627fcede3SMatthew G. Knepley #if 1
529727fcede3SMatthew 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);
529827fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
529927fcede3SMatthew 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);
530027fcede3SMatthew G. Knepley       }
530127fcede3SMatthew G. Knepley #endif
530227fcede3SMatthew G. Knepley     }
530327fcede3SMatthew G. Knepley     /* Hybrid face edges have 2 vertices and 2+cells faces */
530427fcede3SMatthew G. Knepley     for (f = fMax; f < fEnd; ++f) {
530527fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax);
530627fcede3SMatthew G. Knepley       const PetscInt *cone, *support, *ccone, *cornt;
530727fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size, csize, s;
530827fcede3SMatthew G. Knepley 
530927fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr);
531027fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
531127fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
531227fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart);
531327fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart);
531427fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
531527fcede3SMatthew G. Knepley #if 1
531627fcede3SMatthew 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);
531727fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
531827fcede3SMatthew 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);
531927fcede3SMatthew G. Knepley       }
532027fcede3SMatthew G. Knepley #endif
532127fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0;
532227fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1;
532327fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
532427fcede3SMatthew G. Knepley         ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr);
532527fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr);
532627fcede3SMatthew G. Knepley         ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr);
532727fcede3SMatthew G. Knepley         for (c = 0; c < csize; ++c) if (ccone[c] == f) break;
532827fcede3SMatthew 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]);
5329d273725eSMatthew G. Knepley         supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2;
533027fcede3SMatthew G. Knepley       }
533127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
533227fcede3SMatthew G. Knepley #if 1
533327fcede3SMatthew 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);
533427fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
533527fcede3SMatthew 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);
533627fcede3SMatthew G. Knepley       }
533727fcede3SMatthew G. Knepley #endif
533827fcede3SMatthew G. Knepley     }
533927fcede3SMatthew G. Knepley     /* Hybrid cell edges have 2 vertices and 4 faces */
534027fcede3SMatthew G. Knepley     for (c = cMax; c < cEnd; ++c) {
534127fcede3SMatthew G. Knepley       const PetscInt  newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax);
534227fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
534327fcede3SMatthew G. Knepley       PetscInt        coneNew[2], size;
534427fcede3SMatthew G. Knepley 
534527fcede3SMatthew G. Knepley       ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr);
534627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr);
534727fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr);
534827fcede3SMatthew G. Knepley       coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart);
534927fcede3SMatthew G. Knepley       coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart);
535027fcede3SMatthew G. Knepley       ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr);
535127fcede3SMatthew G. Knepley #if 1
535227fcede3SMatthew 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);
535327fcede3SMatthew G. Knepley       for (p = 0; p < 2; ++p) {
535427fcede3SMatthew 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);
535527fcede3SMatthew G. Knepley       }
535627fcede3SMatthew G. Knepley #endif
535727fcede3SMatthew G. Knepley       supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0;
535827fcede3SMatthew G. Knepley       supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1;
535927fcede3SMatthew G. Knepley       supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2;
536027fcede3SMatthew G. Knepley       supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3;
536127fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
536227fcede3SMatthew G. Knepley #if 1
536327fcede3SMatthew 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);
536427fcede3SMatthew G. Knepley       for (p = 0; p < 4; ++p) {
536527fcede3SMatthew 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);
536627fcede3SMatthew G. Knepley       }
536727fcede3SMatthew G. Knepley #endif
536827fcede3SMatthew G. Knepley     }
536927fcede3SMatthew G. Knepley     /* Interior vertices have identical supports */
537027fcede3SMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
537127fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (v - vStart);
537227fcede3SMatthew G. Knepley       const PetscInt *support, *cone;
537327fcede3SMatthew G. Knepley       PetscInt        size, s;
537427fcede3SMatthew G. Knepley 
537527fcede3SMatthew G. Knepley       ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr);
537627fcede3SMatthew G. Knepley       ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr);
537727fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
537827fcede3SMatthew G. Knepley         PetscInt r = 0;
537927fcede3SMatthew G. Knepley 
538027fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
538127fcede3SMatthew G. Knepley         if (cone[1] == v) r = 1;
538227fcede3SMatthew G. Knepley         if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r;
538327fcede3SMatthew G. Knepley         else                   supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax);
538427fcede3SMatthew G. Knepley       }
538527fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
538627fcede3SMatthew G. Knepley #if 1
538727fcede3SMatthew 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);
538827fcede3SMatthew G. Knepley       for (p = 0; p < size; ++p) {
538927fcede3SMatthew 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);
539027fcede3SMatthew G. Knepley       }
539127fcede3SMatthew G. Knepley #endif
539227fcede3SMatthew G. Knepley     }
539327fcede3SMatthew G. Knepley     /* Interior edge vertices have 2 + faces supports */
539427fcede3SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
539527fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (e - eStart);
539627fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
539727fcede3SMatthew G. Knepley       PetscInt        size, s;
539827fcede3SMatthew G. Knepley 
539927fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr);
540027fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr);
540127fcede3SMatthew G. Knepley       supportRef[0] = eStartNew + (e - eStart)*2 + 0;
540227fcede3SMatthew G. Knepley       supportRef[1] = eStartNew + (e - eStart)*2 + 1;
540327fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
540427fcede3SMatthew G. Knepley         PetscInt r;
540527fcede3SMatthew G. Knepley 
540627fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
540727fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r) if (cone[r] == e) break;
540827fcede3SMatthew G. Knepley         if (support[s] < fMax) {
540927fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r;
541027fcede3SMatthew G. Knepley         } else {
541127fcede3SMatthew G. Knepley           supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax       - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax);
541227fcede3SMatthew G. Knepley         }
541327fcede3SMatthew G. Knepley       }
541427fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
541527fcede3SMatthew G. Knepley #if 1
541627fcede3SMatthew 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);
541727fcede3SMatthew G. Knepley       for (p = 0; p < 2+size; ++p) {
541827fcede3SMatthew 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);
541927fcede3SMatthew G. Knepley       }
542027fcede3SMatthew G. Knepley #endif
542127fcede3SMatthew G. Knepley     }
542227fcede3SMatthew G. Knepley     /* Interior face vertices have 4 + cells supports */
542327fcede3SMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
542427fcede3SMatthew G. Knepley       const PetscInt  newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
542527fcede3SMatthew G. Knepley       const PetscInt *cone, *support;
542627fcede3SMatthew G. Knepley       PetscInt        size, s;
542727fcede3SMatthew G. Knepley 
542827fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr);
542927fcede3SMatthew G. Knepley       ierr          = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr);
543027fcede3SMatthew G. Knepley       for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 +  (f - fStart)*4 + r;
543127fcede3SMatthew G. Knepley       for (s = 0; s < size; ++s) {
543227fcede3SMatthew G. Knepley         PetscInt r;
543327fcede3SMatthew G. Knepley 
543427fcede3SMatthew G. Knepley         ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr);
543527fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r) if (cone[r] == f) break;
543627fcede3SMatthew G. Knepley         if (support[s] < cMax) {
543727fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r;
543827fcede3SMatthew G. Knepley         } else {
543927fcede3SMatthew G. Knepley           supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax       - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax);
544027fcede3SMatthew G. Knepley         }
544127fcede3SMatthew G. Knepley       }
544227fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr);
544327fcede3SMatthew G. Knepley #if 1
544427fcede3SMatthew 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);
544527fcede3SMatthew G. Knepley       for (p = 0; p < 4+size; ++p) {
544627fcede3SMatthew 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);
544727fcede3SMatthew G. Knepley       }
544827fcede3SMatthew G. Knepley #endif
544927fcede3SMatthew G. Knepley     }
545027fcede3SMatthew G. Knepley     /* Cell vertices have 6 supports */
545127fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
545227fcede3SMatthew G. Knepley       const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart);
545327fcede3SMatthew G. Knepley       PetscInt       supportNew[6];
545427fcede3SMatthew G. Knepley 
545527fcede3SMatthew G. Knepley       for (r = 0; r < 6; ++r) {
545627fcede3SMatthew G. Knepley         supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r;
545727fcede3SMatthew G. Knepley       }
545827fcede3SMatthew G. Knepley       ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr);
545927fcede3SMatthew G. Knepley     }
546027fcede3SMatthew G. Knepley     ierr = PetscFree(supportRef);CHKERRQ(ierr);
546127fcede3SMatthew G. Knepley     break;
546275d3a19aSMatthew G. Knepley   default:
546375d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
546475d3a19aSMatthew G. Knepley   }
546575d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
546675d3a19aSMatthew G. Knepley }
546775d3a19aSMatthew G. Knepley 
546886150812SJed Brown static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
546975d3a19aSMatthew G. Knepley {
547075d3a19aSMatthew G. Knepley   PetscSection          coordSection, coordSectionNew;
547175d3a19aSMatthew G. Knepley   Vec                   coordinates, coordinatesNew;
547275d3a19aSMatthew G. Knepley   PetscScalar          *coords, *coordsNew;
54733478d7aaSMatthew G. Knepley   const PetscInt        numVertices = depthSize ? depthSize[0] : 0;
547490b157c4SStefano Zampini   PetscInt              dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax;
547590b157c4SStefano Zampini   PetscInt              c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f;
54769fc2a3f3SStefano Zampini   PetscInt              cStartNew, cEndNew, vEndNew, *parentId = NULL;
54778b9ced59SLisandro Dalcin   VecType               vtype;
54789fc2a3f3SStefano Zampini   PetscBool             isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE;
547990b157c4SStefano Zampini   const PetscReal      *maxCell, *L;
548090b157c4SStefano Zampini   const DMBoundaryType *bd;
548175d3a19aSMatthew G. Knepley   PetscErrorCode        ierr;
548275d3a19aSMatthew G. Knepley 
548375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
5484a57030b0SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
548575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
548675d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
5487b5da9499SMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
548875d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
548975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
549027fcede3SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr);
549190b157c4SStefano Zampini   ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr);
549290b157c4SStefano Zampini   ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr);
5493f719d809SMatthew G. Knepley   ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr);
5494f1d7821bSLawrence Mitchell   ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr);
549575d3a19aSMatthew G. Knepley   ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr);
549675d3a19aSMatthew G. Knepley   ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr);
5497f1d7821bSLawrence Mitchell   ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr);
549890b157c4SStefano Zampini   ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr);
549990b157c4SStefano Zampini   ierr = DMSetPeriodicity(rdm, isperiodic,  maxCell,  L,  bd);CHKERRQ(ierr);
550090b157c4SStefano Zampini   /* Determine if we need to localize coordinates when generating them */
55019fc2a3f3SStefano Zampini   if (isperiodic && !maxCell) {
55029fc2a3f3SStefano Zampini     ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr);
55039fc2a3f3SStefano Zampini     if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized");
55049fc2a3f3SStefano Zampini   }
550590b157c4SStefano Zampini   if (localize) {
550690b157c4SStefano Zampini     PetscInt p, r, newp, *pi;
550790b157c4SStefano Zampini 
550890b157c4SStefano Zampini     /* New coordinates will be already localized on the cell */
550990b157c4SStefano Zampini     ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr);
551090b157c4SStefano Zampini 
551190b157c4SStefano Zampini     /* We need the parentId to properly localize coordinates */
551290b157c4SStefano Zampini     ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr);
551390b157c4SStefano Zampini     switch (refiner) {
551490b157c4SStefano Zampini     case REFINER_NOOP:
551590b157c4SStefano Zampini       break;
551690b157c4SStefano Zampini     case REFINER_SIMPLEX_1D:
551790b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
551890b157c4SStefano Zampini         for (r = 0; r < 2; ++r) {
551990b157c4SStefano Zampini           newp     = (p - cStart)*2 + r;
552090b157c4SStefano Zampini           pi[newp] = p;
552190b157c4SStefano Zampini         }
552290b157c4SStefano Zampini       }
552390b157c4SStefano Zampini       break;
552490b157c4SStefano Zampini     case REFINER_SIMPLEX_2D:
552590b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
552690b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
552790b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
552890b157c4SStefano Zampini           pi[newp] = p;
552990b157c4SStefano Zampini         }
553090b157c4SStefano Zampini       }
553190b157c4SStefano Zampini       break;
553290b157c4SStefano Zampini     case REFINER_HEX_2D:
553390b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
553490b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
553590b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
553690b157c4SStefano Zampini           pi[newp] = p;
553790b157c4SStefano Zampini         }
553890b157c4SStefano Zampini       }
553990b157c4SStefano Zampini       break;
554090b157c4SStefano Zampini     case REFINER_HYBRID_SIMPLEX_2D:
554190b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
554290b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
554390b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
554490b157c4SStefano Zampini           pi[newp] = p;
554590b157c4SStefano Zampini         }
554690b157c4SStefano Zampini       }
554790b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
554890b157c4SStefano Zampini         for (r = 0; r < 2; ++r) {
554990b157c4SStefano Zampini           newp     = (cMax - cStart)*4 + (p - cMax)*2 + r;
555090b157c4SStefano Zampini           pi[newp] = p;
555190b157c4SStefano Zampini         }
555290b157c4SStefano Zampini       }
555390b157c4SStefano Zampini       break;
555490b157c4SStefano Zampini     case REFINER_HYBRID_HEX_2D:
555590b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
555690b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
555790b157c4SStefano Zampini           newp     = (p - cStart)*4 + r;
555890b157c4SStefano Zampini           pi[newp] = p;
555990b157c4SStefano Zampini         }
556090b157c4SStefano Zampini       }
556190b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
556290b157c4SStefano Zampini         for (r = 0; r < 2; ++r) {
556390b157c4SStefano Zampini           newp     = (cMax - cStart)*4 + (p - cMax)*2 + r;
556490b157c4SStefano Zampini           pi[newp] = p;
556590b157c4SStefano Zampini         }
556690b157c4SStefano Zampini       }
556790b157c4SStefano Zampini       break;
556890b157c4SStefano Zampini     case REFINER_SIMPLEX_3D:
556990b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
557090b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
557190b157c4SStefano Zampini           newp     = (p - cStart)*8 + r;
557290b157c4SStefano Zampini           pi[newp] = p;
557390b157c4SStefano Zampini         }
557490b157c4SStefano Zampini       }
557590b157c4SStefano Zampini       break;
557690b157c4SStefano Zampini     case REFINER_HYBRID_SIMPLEX_3D:
557790b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
557890b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
557990b157c4SStefano Zampini           newp     = (p - cStart)*8 + r;
558090b157c4SStefano Zampini           pi[newp] = p;
558190b157c4SStefano Zampini         }
558290b157c4SStefano Zampini       }
558390b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
558490b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
558590b157c4SStefano Zampini           newp     = (cMax - cStart)*8 + (p - cMax)*4 + r;
558690b157c4SStefano Zampini           pi[newp] = p;
558790b157c4SStefano Zampini         }
558890b157c4SStefano Zampini       }
558990b157c4SStefano Zampini       break;
559090b157c4SStefano Zampini     case REFINER_HEX_3D:
559190b157c4SStefano Zampini       for (p = cStart; p < cEnd; ++p) {
559290b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
559390b157c4SStefano Zampini           newp = (p - cStart)*8 + r;
559490b157c4SStefano Zampini           pi[newp] = p;
559590b157c4SStefano Zampini         }
559690b157c4SStefano Zampini       }
559790b157c4SStefano Zampini       break;
559890b157c4SStefano Zampini     case REFINER_HYBRID_HEX_3D:
559990b157c4SStefano Zampini       for (p = cStart; p < cMax; ++p) {
560090b157c4SStefano Zampini         for (r = 0; r < 8; ++r) {
560190b157c4SStefano Zampini           newp = (p - cStart)*8 + r;
560290b157c4SStefano Zampini           pi[newp] = p;
560390b157c4SStefano Zampini         }
560490b157c4SStefano Zampini       }
560590b157c4SStefano Zampini       for (p = cMax; p < cEnd; ++p) {
560690b157c4SStefano Zampini         for (r = 0; r < 4; ++r) {
560790b157c4SStefano Zampini           newp = (cMax - cStart)*8 + (p - cMax)*4 + r;
560890b157c4SStefano Zampini         }
560990b157c4SStefano Zampini       }
561090b157c4SStefano Zampini       break;
561190b157c4SStefano Zampini     default:
561290b157c4SStefano Zampini       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
561390b157c4SStefano Zampini     }
561490b157c4SStefano Zampini     parentId = pi;
561590b157c4SStefano Zampini   } else {
56163478d7aaSMatthew G. Knepley     ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr);
561790b157c4SStefano Zampini   }
561827fcede3SMatthew G. Knepley   if (cMax < 0) cMax = cEnd;
561975d3a19aSMatthew G. Knepley   if (fMax < 0) fMax = fEnd;
5620b5da9499SMatthew G. Knepley   if (eMax < 0) eMax = eEnd;
562190b157c4SStefano Zampini 
5622f1d7821bSLawrence Mitchell   /* All vertices have the spaceDim coordinates */
562390b157c4SStefano Zampini   if (localize) {
56249fc2a3f3SStefano Zampini     PetscInt c;
562590b157c4SStefano Zampini 
56269fc2a3f3SStefano Zampini     for (c = cStartNew; c < cEndNew; ++c) {
56279fc2a3f3SStefano Zampini       PetscInt *cone = NULL;
56289fc2a3f3SStefano Zampini       PetscInt  closureSize, coneSize = 0, p, pdof;
56299fc2a3f3SStefano Zampini 
56309fc2a3f3SStefano Zampini       ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr);
56319fc2a3f3SStefano Zampini       if (pdof) { /* localize on all cells that are refinement of a localized parent cell */
56329fc2a3f3SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
563390b157c4SStefano Zampini         for (p = 0; p < closureSize*2; p += 2) {
563490b157c4SStefano Zampini           const PetscInt point = cone[p];
563590b157c4SStefano Zampini           if ((point >= vStartNew) && (point < vEndNew)) coneSize++;
563690b157c4SStefano Zampini         }
56379fc2a3f3SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
56389fc2a3f3SStefano Zampini         ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr);
56399fc2a3f3SStefano Zampini         ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr);
56409fc2a3f3SStefano Zampini       }
564190b157c4SStefano Zampini     }
564290b157c4SStefano Zampini   }
56433478d7aaSMatthew G. Knepley   for (v = vStartNew; v < vStartNew+numVertices; ++v) {
5644f1d7821bSLawrence Mitchell     ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr);
5645f1d7821bSLawrence Mitchell     ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr);
564675d3a19aSMatthew G. Knepley   }
564775d3a19aSMatthew G. Knepley   ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr);
564846e270d4SMatthew G. Knepley   ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr);
564975d3a19aSMatthew G. Knepley   ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr);
565075d3a19aSMatthew G. Knepley   ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr);
56518b9ced59SLisandro Dalcin   ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr);
565275d3a19aSMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr);
565375d3a19aSMatthew G. Knepley   ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr);
565460b9e8a1SMatthew G. Knepley   ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr);
565560b9e8a1SMatthew G. Knepley   ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr);
56568b9ced59SLisandro Dalcin   ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr);
56578b9ced59SLisandro Dalcin   ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr);
565875d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr);
565975d3a19aSMatthew G. Knepley   ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
56609fc2a3f3SStefano Zampini 
5661b5da9499SMatthew G. Knepley   switch (refiner) {
56629b1a0e7fSLawrence Mitchell   case REFINER_NOOP: break;
56639b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
56649b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
5665b5da9499SMatthew G. Knepley     /* Face vertices have the average of corner coordinates */
5666d856d60fSMatthew G. Knepley     for (f = fStart; f < fMax; ++f) {
566727fcede3SMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart);
5668b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
5669b5da9499SMatthew G. Knepley       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d;
5670b5da9499SMatthew G. Knepley 
5671b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5672b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
5673b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
5674b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
5675b5da9499SMatthew G. Knepley       }
567690b157c4SStefano Zampini       if (localize) {
567790b157c4SStefano Zampini         const PetscInt *support = NULL;
567890b157c4SStefano Zampini         PetscInt       *rStar = NULL;
567990b157c4SStefano Zampini         PetscInt        supportSize, rStarSize, coff, s, ccoff[8];
568090b157c4SStefano Zampini         PetscBool       cellfound = PETSC_FALSE;
568190b157c4SStefano Zampini 
568290b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
568390b157c4SStefano Zampini         ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr);
568490b157c4SStefano Zampini         ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr);
568590b157c4SStefano Zampini         /* Compute average of coordinates for each cell sharing the face */
568690b157c4SStefano Zampini         for (s = 0; s < supportSize; ++s) {
568790b157c4SStefano Zampini           PetscScalar     coordsNewAux[3] = { 0.0, 0.0, 0.0 };
568890b157c4SStefano Zampini           PetscInt       *cellCone = NULL;
56899fc2a3f3SStefano Zampini           PetscInt        cellClosureSize, cellConeSize = 0, cdof;
569090b157c4SStefano Zampini           const PetscInt  cell = support[s];
569190b157c4SStefano Zampini           PetscBool       copyoff = PETSC_FALSE;
569290b157c4SStefano Zampini 
569390b157c4SStefano Zampini           ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
569490b157c4SStefano Zampini           for (p = 0; p < cellClosureSize*2; p += 2) {
569590b157c4SStefano Zampini             const PetscInt point = cellCone[p];
569690b157c4SStefano Zampini             if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point;
569790b157c4SStefano Zampini           }
56989fc2a3f3SStefano Zampini           ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr);
56999fc2a3f3SStefano Zampini           if (!cdof) { /* the parent cell does not have localized coordinates */
57009fc2a3f3SStefano Zampini             cellfound = PETSC_TRUE;
57019fc2a3f3SStefano Zampini             for (v = 0; v < coneSize; ++v) {
57029fc2a3f3SStefano Zampini               ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
57039fc2a3f3SStefano Zampini               for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d];
57049fc2a3f3SStefano Zampini             }
57059fc2a3f3SStefano Zampini             for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
57069fc2a3f3SStefano Zampini           } else {
57079fc2a3f3SStefano Zampini             ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr);
570890b157c4SStefano Zampini             for (p = 0; p < coneSize; ++p) {
570990b157c4SStefano Zampini               const PetscInt tv = cone[p];
571090b157c4SStefano Zampini               PetscInt       cv, voff;
571190b157c4SStefano Zampini               PetscBool      locv = PETSC_TRUE;
571290b157c4SStefano Zampini 
571390b157c4SStefano Zampini               for (cv = 0; cv < cellConeSize; ++cv) {
571490b157c4SStefano Zampini                 if (cellCone[cv] == tv) {
571590b157c4SStefano Zampini                   ccoff[p] = spaceDim*cv + coff;
571690b157c4SStefano Zampini                   break;
571790b157c4SStefano Zampini                 }
571890b157c4SStefano Zampini               }
571990b157c4SStefano Zampini               if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D\n",tv);
572090b157c4SStefano Zampini 
572190b157c4SStefano Zampini               ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr);
572290b157c4SStefano Zampini               for (d = 0; d < spaceDim; ++d) {
572390b157c4SStefano Zampini                 coordsNewAux[d] += coords[ccoff[p]+d];
572490b157c4SStefano Zampini                 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE;
572590b157c4SStefano Zampini               }
572690b157c4SStefano Zampini               if (locv && !cellfound) {
572790b157c4SStefano Zampini                 cellfound = PETSC_TRUE;
572890b157c4SStefano Zampini                 copyoff   = PETSC_TRUE;
572990b157c4SStefano Zampini               }
573090b157c4SStefano Zampini             }
57319fc2a3f3SStefano Zampini             for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize;
573290b157c4SStefano Zampini 
573390b157c4SStefano Zampini             /* Found a valid face for the "vertex" part of the Section (physical space)
573490b157c4SStefano Zampini                i.e., a face that has at least one corner in the physical space */
573590b157c4SStefano Zampini             if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p];
57369fc2a3f3SStefano Zampini           }
573790b157c4SStefano Zampini 
573890b157c4SStefano Zampini           /* Localize new coordinates on each refined cell */
573990b157c4SStefano Zampini           for (v = 0; v < rStarSize*2; v += 2) {
574090b157c4SStefano Zampini             if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) {
57419fc2a3f3SStefano Zampini               PetscInt       *rcone = NULL, rclosureSize, lid, rcdof, rcoff;
574290b157c4SStefano Zampini               const PetscInt  rcell = rStar[v];
574390b157c4SStefano Zampini 
57449fc2a3f3SStefano Zampini               ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr);
57459fc2a3f3SStefano Zampini               if (!rcdof) continue;
57469fc2a3f3SStefano Zampini               ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr);
574790b157c4SStefano Zampini               ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
574890b157c4SStefano Zampini               for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
574990b157c4SStefano Zampini                 if (rcone[p] == newv) {
57509fc2a3f3SStefano Zampini                   for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d];
575190b157c4SStefano Zampini                   break;
575290b157c4SStefano Zampini                 }
575390b157c4SStefano Zampini                 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
575490b157c4SStefano Zampini               }
575590b157c4SStefano Zampini               ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
575690b157c4SStefano Zampini               if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
575790b157c4SStefano Zampini             }
575890b157c4SStefano Zampini           }
57599fc2a3f3SStefano Zampini           ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
576090b157c4SStefano Zampini         }
576190b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
576290b157c4SStefano Zampini         if (!cellfound) {
57631072f78bSStefano Zampini           /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */
57641072f78bSStefano Zampini           needcoords = PETSC_TRUE;
576590b157c4SStefano Zampini           coneSize   = 0;
576690b157c4SStefano Zampini         }
576790b157c4SStefano Zampini       } else {
5768b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) {
5769b5da9499SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
5770b5da9499SMatthew G. Knepley         }
577190b157c4SStefano Zampini       }
5772b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
577390b157c4SStefano Zampini       if (coneSize) {
57741072f78bSStefano Zampini         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
57752e17dfb7SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
5776f1d7821bSLawrence Mitchell         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
57771072f78bSStefano Zampini       } else {
57781072f78bSStefano Zampini         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
577990b157c4SStefano Zampini       }
5780b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5781b5da9499SMatthew G. Knepley     }
57829b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
57839b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
5784383c10e6SMatthew G. Knepley   case REFINER_SIMPLEX_1D:
5785b5da9499SMatthew G. Knepley     /* Cell vertices have the average of corner coordinates */
578627fcede3SMatthew G. Knepley     for (c = cStart; c < cMax; ++c) {
57872ed5862eSMatthew G. Knepley       const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0);
5788b5da9499SMatthew G. Knepley       PetscInt      *cone = NULL;
57899fc2a3f3SStefano Zampini       PetscInt       closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0;
5790b5da9499SMatthew G. Knepley 
5791b5da9499SMatthew G. Knepley       ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
5792b5da9499SMatthew G. Knepley       for (p = 0; p < closureSize*2; p += 2) {
5793b5da9499SMatthew G. Knepley         const PetscInt point = cone[p];
5794b5da9499SMatthew G. Knepley         if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point;
5795b5da9499SMatthew G. Knepley       }
579690b157c4SStefano Zampini       if (localize) {
57979fc2a3f3SStefano Zampini         ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr);
57989fc2a3f3SStefano Zampini       }
57999fc2a3f3SStefano Zampini       if (cdof) {
580090b157c4SStefano Zampini         PetscInt coff;
580190b157c4SStefano Zampini 
580290b157c4SStefano Zampini         ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr);
580390b157c4SStefano Zampini         for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff;
580490b157c4SStefano Zampini       } else {
5805b5da9499SMatthew G. Knepley         for (v = 0; v < coneSize; ++v) {
5806b5da9499SMatthew G. Knepley           ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr);
5807b5da9499SMatthew G. Knepley         }
580890b157c4SStefano Zampini       }
5809b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5810f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0;
58112e17dfb7SMatthew G. Knepley       for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);}
5812f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize;
5813b5da9499SMatthew G. Knepley       ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
58149fc2a3f3SStefano Zampini 
581590b157c4SStefano Zampini       /* Localize new coordinates on each refined cell */
58169fc2a3f3SStefano Zampini       if (cdof) {
581790b157c4SStefano Zampini         PetscInt *rStar = NULL, rStarSize;
581890b157c4SStefano Zampini 
581990b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
582090b157c4SStefano Zampini         for (v = 0; v < rStarSize*2; v += 2) {
582190b157c4SStefano Zampini           if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) {
58229fc2a3f3SStefano Zampini             PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof;
582390b157c4SStefano Zampini 
582490b157c4SStefano Zampini             rc   = rStar[v];
58259fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr);
58269fc2a3f3SStefano Zampini             if (!rcdof) continue;
582790b157c4SStefano Zampini             ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr);
582890b157c4SStefano Zampini             ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
582990b157c4SStefano Zampini             for (p = 0, lid = 0; p < closureSize*2; p += 2) {
583090b157c4SStefano Zampini               if (cone[p] == newv) {
583190b157c4SStefano Zampini                 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d];
583290b157c4SStefano Zampini                 break;
583390b157c4SStefano Zampini               }
583490b157c4SStefano Zampini               if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++;
583590b157c4SStefano Zampini             }
583690b157c4SStefano Zampini             if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
583790b157c4SStefano Zampini             ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
583890b157c4SStefano Zampini           }
583990b157c4SStefano Zampini         }
584090b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
584190b157c4SStefano Zampini       }
5842b5da9499SMatthew G. Knepley     }
58439b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
58449b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
58459b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
58469b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
5847b5da9499SMatthew G. Knepley     /* Edge vertices have the average of endpoint coordinates */
5848b5da9499SMatthew G. Knepley     for (e = eStart; e < eMax; ++e) {
5849b5da9499SMatthew G. Knepley       const PetscInt  newv = vStartNew + (vEnd - vStart) + (e - eStart);
5850b5da9499SMatthew G. Knepley       const PetscInt *cone;
5851b5da9499SMatthew G. Knepley       PetscInt        coneSize, offA, offB, offnew, d;
5852b5da9499SMatthew G. Knepley 
5853b5da9499SMatthew G. Knepley       ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr);
5854b5da9499SMatthew G. Knepley       if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize);
5855b5da9499SMatthew G. Knepley       ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr);
585690b157c4SStefano Zampini       if (localize) {
5857*3548e9b6SStefano Zampini         PetscInt   coff, toffA = -1, toffB = -1, voffA, voffB;
585890b157c4SStefano Zampini         PetscInt  *eStar = NULL, eStarSize;
585990b157c4SStefano Zampini         PetscInt  *rStar = NULL, rStarSize;
58609fc2a3f3SStefano Zampini         PetscBool  cellfound = PETSC_FALSE;
586190b157c4SStefano Zampini 
586290b157c4SStefano Zampini         offA = offB = -1;
586390b157c4SStefano Zampini         ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr);
586490b157c4SStefano Zampini         ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr);
586590b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr);
586690b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
586790b157c4SStefano Zampini         for (v = 0; v < eStarSize*2; v += 2) {
586890b157c4SStefano Zampini           if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) {
586990b157c4SStefano Zampini             PetscScalar     coordsNewAux[3];
587090b157c4SStefano Zampini             PetscInt       *cellCone = NULL;
58719fc2a3f3SStefano Zampini             PetscInt        cellClosureSize, s, cv, cdof;
587290b157c4SStefano Zampini             PetscBool       locvA = PETSC_TRUE, locvB = PETSC_TRUE;
587390b157c4SStefano Zampini             const PetscInt  cell = eStar[v];
587490b157c4SStefano Zampini 
58759fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr);
58769fc2a3f3SStefano Zampini             if (!cdof) {
58779fc2a3f3SStefano Zampini               /* Found a valid edge for the "vertex" part of the Section */
58789fc2a3f3SStefano Zampini               offA = voffA;
58799fc2a3f3SStefano Zampini               offB = voffB;
58809fc2a3f3SStefano Zampini               cellfound = PETSC_TRUE;
58819fc2a3f3SStefano Zampini             } else {
588290b157c4SStefano Zampini               ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr);
588390b157c4SStefano Zampini               ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
588490b157c4SStefano Zampini               for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) {
588590b157c4SStefano Zampini                 const PetscInt point = cellCone[s];
588690b157c4SStefano Zampini                 if ((point >= vStart) && (point < vEnd)) {
588790b157c4SStefano Zampini                   if (point == cone[0]) toffA = spaceDim*cv + coff;
588890b157c4SStefano Zampini                   else if (point == cone[1]) toffB = spaceDim*cv + coff;
588990b157c4SStefano Zampini                   cv++;
589090b157c4SStefano Zampini                 }
589190b157c4SStefano Zampini               }
589290b157c4SStefano Zampini               ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr);
589390b157c4SStefano Zampini               for (d = 0; d < spaceDim; ++d) {
589490b157c4SStefano Zampini                 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]);
589590b157c4SStefano Zampini                 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE;
589690b157c4SStefano Zampini                 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE;
589790b157c4SStefano Zampini               }
589890b157c4SStefano Zampini               /* Found a valid edge for the "vertex" part of the Section */
58999fc2a3f3SStefano Zampini               if (!cellfound && (locvA || locvB)) {
59009fc2a3f3SStefano Zampini                 cellfound = PETSC_TRUE;
59019fc2a3f3SStefano Zampini                 offA = toffA;
59029fc2a3f3SStefano Zampini                 offB = toffB;
59039fc2a3f3SStefano Zampini               }
59049fc2a3f3SStefano Zampini             }
590590b157c4SStefano Zampini 
590690b157c4SStefano Zampini             /* Localize new coordinates on each refined cell */
590790b157c4SStefano Zampini             for (s = 0; s < rStarSize*2; s += 2) {
590890b157c4SStefano Zampini               if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) {
59099fc2a3f3SStefano Zampini                 PetscInt       *rcone = NULL, rclosureSize, lid, p, rcdof;
591090b157c4SStefano Zampini                 const PetscInt  rcell = rStar[s];
591190b157c4SStefano Zampini 
59129fc2a3f3SStefano Zampini                 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr);
59139fc2a3f3SStefano Zampini                 if (!rcdof) continue;
591490b157c4SStefano Zampini                 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr);
591590b157c4SStefano Zampini                 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
591690b157c4SStefano Zampini                 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) {
591790b157c4SStefano Zampini                   if (rcone[p] == newv) {
591890b157c4SStefano Zampini                     for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d];
591990b157c4SStefano Zampini                     break;
592090b157c4SStefano Zampini                   }
592190b157c4SStefano Zampini                   if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++;
592290b157c4SStefano Zampini                 }
592390b157c4SStefano Zampini                 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr);
592490b157c4SStefano Zampini                 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
592590b157c4SStefano Zampini               }
592690b157c4SStefano Zampini             }
592790b157c4SStefano Zampini           }
592890b157c4SStefano Zampini         }
592990b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr);
593090b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
59319fc2a3f3SStefano Zampini         if (!cellfound) {
59321072f78bSStefano Zampini           /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */
59331072f78bSStefano Zampini           needcoords = PETSC_TRUE;
593490b157c4SStefano Zampini         }
593590b157c4SStefano Zampini       } else {
5936b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr);
5937b5da9499SMatthew G. Knepley         ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr);
593890b157c4SStefano Zampini       }
5939b5da9499SMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
594090b157c4SStefano Zampini       if (offA != -1 && offB != -1) {
59412e17dfb7SMatthew G. Knepley         ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr);
5942f1d7821bSLawrence Mitchell         for (d = 0; d < spaceDim; ++d) {
5943a96104c9SMatthew G. Knepley           coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]);
5944b5da9499SMatthew G. Knepley         }
594590b157c4SStefano Zampini       } else {
59461072f78bSStefano Zampini         for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL;
594790b157c4SStefano Zampini       }
5948b5da9499SMatthew G. Knepley     }
594975d3a19aSMatthew G. Knepley     /* Old vertices have the same coordinates */
595075d3a19aSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) {
595175d3a19aSMatthew G. Knepley       const PetscInt newv = vStartNew + (v - vStart);
595275d3a19aSMatthew G. Knepley       PetscInt       off, offnew, d;
595375d3a19aSMatthew G. Knepley 
595475d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr);
595575d3a19aSMatthew G. Knepley       ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr);
5956f1d7821bSLawrence Mitchell       for (d = 0; d < spaceDim; ++d) {
595775d3a19aSMatthew G. Knepley         coordsNew[offnew+d] = coords[off+d];
595875d3a19aSMatthew G. Knepley       }
595990b157c4SStefano Zampini 
596090b157c4SStefano Zampini       /* Localize new coordinates on each refined cell */
596190b157c4SStefano Zampini       if (localize) {
596290b157c4SStefano Zampini         PetscInt  p;
596390b157c4SStefano Zampini         PetscInt *rStar = NULL, rStarSize;
596490b157c4SStefano Zampini 
596590b157c4SStefano Zampini         ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
596690b157c4SStefano Zampini         for (p = 0; p < rStarSize*2; p += 2) {
596790b157c4SStefano Zampini           if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) {
596890b157c4SStefano Zampini             PetscScalar  ocoords[3];
59699fc2a3f3SStefano Zampini             PetscInt    *cone = NULL, closureSize, lid, coff, s, oc, cdof;
597090b157c4SStefano Zampini 
597190b157c4SStefano Zampini             c    = rStar[p];
597290b157c4SStefano Zampini             oc   = parentId[c-cStartNew];
59739fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr);
59749fc2a3f3SStefano Zampini             if (!cdof) continue;
59759fc2a3f3SStefano Zampini             ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr);
59769fc2a3f3SStefano Zampini             if (!cdof) continue;
597790b157c4SStefano Zampini             ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr);
597890b157c4SStefano Zampini             ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
597990b157c4SStefano Zampini             for (s = 0, lid = 0; s < closureSize*2; s += 2) {
598090b157c4SStefano Zampini               if (cone[s] == v) {
598190b157c4SStefano Zampini                 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d];
598290b157c4SStefano Zampini                 break;
598390b157c4SStefano Zampini               }
598490b157c4SStefano Zampini               if (cone[s] >= vStart && cone[s] < vEnd) lid++;
598590b157c4SStefano Zampini             }
598690b157c4SStefano Zampini             if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D\n",v);
598790b157c4SStefano Zampini             ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
598890b157c4SStefano Zampini 
598990b157c4SStefano Zampini             ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr);
599090b157c4SStefano Zampini             ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
599190b157c4SStefano Zampini             for (s = 0, lid = 0; s < closureSize*2; s += 2) {
599290b157c4SStefano Zampini               if (cone[s] == newv) {
599390b157c4SStefano Zampini                 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d];
599490b157c4SStefano Zampini                 break;
599590b157c4SStefano Zampini               }
599690b157c4SStefano Zampini               if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++;
599790b157c4SStefano Zampini             }
599890b157c4SStefano Zampini             if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv);
599990b157c4SStefano Zampini             ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr);
600090b157c4SStefano Zampini           }
600190b157c4SStefano Zampini         }
600290b157c4SStefano Zampini         ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr);
600390b157c4SStefano Zampini       }
600475d3a19aSMatthew G. Knepley     }
6005b5da9499SMatthew G. Knepley     break;
6006b5da9499SMatthew G. Knepley   default:
6007b5da9499SMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
600875d3a19aSMatthew G. Knepley   }
600975d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr);
601075d3a19aSMatthew G. Knepley   ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr);
601175d3a19aSMatthew G. Knepley   ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr);
601290b157c4SStefano Zampini 
601390b157c4SStefano Zampini   /* Final reduction (if needed) if we are localizing */
601490b157c4SStefano Zampini   if (localize) {
60151072f78bSStefano Zampini     PetscBool gred;
601690b157c4SStefano Zampini 
60171072f78bSStefano Zampini     ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr);
601890b157c4SStefano Zampini     if (gred) {
601990b157c4SStefano Zampini       DM                 cdm;
60201072f78bSStefano Zampini       Vec                aux;
60211072f78bSStefano Zampini       PetscSF            sf;
60221072f78bSStefano Zampini       const PetscScalar *lArray;
60239fc2a3f3SStefano Zampini       PetscScalar       *gArray;
602490b157c4SStefano Zampini 
602590b157c4SStefano Zampini       ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr);
602690b157c4SStefano Zampini       ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr);
60271072f78bSStefano Zampini       ierr = DMGetDefaultSF(cdm, &sf);CHKERRQ(ierr);
60281072f78bSStefano Zampini       ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr);
60291072f78bSStefano Zampini       ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr);
60301072f78bSStefano Zampini       ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr);
60311072f78bSStefano Zampini       ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr);
60321072f78bSStefano Zampini       ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr);
60331072f78bSStefano Zampini       ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr);
60341072f78bSStefano Zampini       ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr);
603590b157c4SStefano Zampini       ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr);
603690b157c4SStefano Zampini       ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr);
603790b157c4SStefano Zampini       ierr = VecDestroy(&aux);CHKERRQ(ierr);
603890b157c4SStefano Zampini     }
603990b157c4SStefano Zampini   }
604075d3a19aSMatthew G. Knepley   ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr);
604175d3a19aSMatthew G. Knepley   ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr);
604290b157c4SStefano Zampini   ierr = PetscFree(parentId);CHKERRQ(ierr);
604375d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
604475d3a19aSMatthew G. Knepley }
604575d3a19aSMatthew G. Knepley 
6046963fc26aSMatthew G. Knepley /*@
6047963fc26aSMatthew G. Knepley   DMPlexCreateProcessSF - Create an SF which just has process connectivity
6048963fc26aSMatthew G. Knepley 
6049963fc26aSMatthew G. Knepley   Collective on DM
6050963fc26aSMatthew G. Knepley 
6051963fc26aSMatthew G. Knepley   Input Parameters:
6052963fc26aSMatthew G. Knepley + dm      - The DM
6053963fc26aSMatthew G. Knepley - sfPoint - The PetscSF which encodes point connectivity
6054963fc26aSMatthew G. Knepley 
6055963fc26aSMatthew G. Knepley   Output Parameters:
6056963fc26aSMatthew G. Knepley + processRanks - A list of process neighbors, or NULL
6057963fc26aSMatthew G. Knepley - sfProcess    - An SF encoding the process connectivity, or NULL
6058963fc26aSMatthew G. Knepley 
6059963fc26aSMatthew G. Knepley   Level: developer
6060963fc26aSMatthew G. Knepley 
6061963fc26aSMatthew G. Knepley .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF()
6062963fc26aSMatthew G. Knepley @*/
6063963fc26aSMatthew G. Knepley PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess)
606475d3a19aSMatthew G. Knepley {
606575d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, l;
606675d3a19aSMatthew G. Knepley   const PetscInt    *localPoints;
606775d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
606875d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
606975d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
607075d3a19aSMatthew G. Knepley   PetscInt          *ranks, *ranksNew;
60719852e123SBarry Smith   PetscMPIInt        size;
607275d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
607375d3a19aSMatthew G. Knepley 
607475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
6075963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
6076963fc26aSMatthew G. Knepley   PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2);
6077963fc26aSMatthew G. Knepley   if (processRanks) {PetscValidPointer(processRanks, 3);}
6078963fc26aSMatthew G. Knepley   if (sfProcess)    {PetscValidPointer(sfProcess, 4);}
60799852e123SBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr);
608075d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
6081785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr);
608275d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
608375d3a19aSMatthew G. Knepley     ranks[l] = remotePoints[l].rank;
608475d3a19aSMatthew G. Knepley   }
608575d3a19aSMatthew G. Knepley   ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr);
6086785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr);
6087785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr);
6088785e854fSJed Brown   ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr);
608975d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
609075d3a19aSMatthew G. Knepley     ranksNew[l]              = ranks[l];
609175d3a19aSMatthew G. Knepley     localPointsNew[l]        = l;
609275d3a19aSMatthew G. Knepley     remotePointsNew[l].index = 0;
609375d3a19aSMatthew G. Knepley     remotePointsNew[l].rank  = ranksNew[l];
609475d3a19aSMatthew G. Knepley   }
609575d3a19aSMatthew G. Knepley   ierr = PetscFree(ranks);CHKERRQ(ierr);
6096963fc26aSMatthew G. Knepley   if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);}
6097963fc26aSMatthew G. Knepley   else              {ierr = PetscFree(ranksNew);CHKERRQ(ierr);}
6098963fc26aSMatthew G. Knepley   if (sfProcess) {
609975d3a19aSMatthew G. Knepley     ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr);
6100963fc26aSMatthew G. Knepley     ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr);
610175d3a19aSMatthew G. Knepley     ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr);
61029852e123SBarry Smith     ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
6103963fc26aSMatthew G. Knepley   }
610475d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
610575d3a19aSMatthew G. Knepley }
610675d3a19aSMatthew G. Knepley 
610786150812SJed Brown static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
610875d3a19aSMatthew G. Knepley {
610975d3a19aSMatthew G. Knepley   PetscSF            sf, sfNew, sfProcess;
611075d3a19aSMatthew G. Knepley   IS                 processRanks;
611175d3a19aSMatthew G. Knepley   MPI_Datatype       depthType;
611275d3a19aSMatthew G. Knepley   PetscInt           numRoots, numLeaves, numLeavesNew = 0, l, m;
611375d3a19aSMatthew G. Knepley   const PetscInt    *localPoints, *neighbors;
611475d3a19aSMatthew G. Knepley   const PetscSFNode *remotePoints;
611575d3a19aSMatthew G. Knepley   PetscInt          *localPointsNew;
611675d3a19aSMatthew G. Knepley   PetscSFNode       *remotePointsNew;
611775d3a19aSMatthew G. Knepley   PetscInt          *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew;
611837d81139SMatthew G. Knepley   PetscInt           ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n;
61197ba685a0SMatthew G. Knepley   PetscInt           cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
612075d3a19aSMatthew G. Knepley   PetscErrorCode     ierr;
612175d3a19aSMatthew G. Knepley 
612275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
612375d3a19aSMatthew G. Knepley   ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr);
612437d81139SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr);
612537d81139SMatthew G. Knepley   ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr);
612637d81139SMatthew G. Knepley   if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %d != %d", ldepth, depth);
612775d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
612875d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
612975d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
613075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
613175d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
6132add09238SMatthew G. Knepley   cMax = cMax < 0 ? cEnd : cMax;
6133add09238SMatthew G. Knepley   fMax = fMax < 0 ? fEnd : fMax;
6134add09238SMatthew G. Knepley   eMax = eMax < 0 ? eEnd : eMax;
61353478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
613675d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr);
613775d3a19aSMatthew G. Knepley   ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr);
6138add09238SMatthew G. Knepley   /* Calculate size of new SF */
613975d3a19aSMatthew G. Knepley   ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr);
614075d3a19aSMatthew G. Knepley   if (numRoots < 0) PetscFunctionReturn(0);
614175d3a19aSMatthew G. Knepley   for (l = 0; l < numLeaves; ++l) {
614275d3a19aSMatthew G. Knepley     const PetscInt p = localPoints[l];
614375d3a19aSMatthew G. Knepley 
614475d3a19aSMatthew G. Knepley     switch (refiner) {
61450314a74cSLawrence Mitchell     case REFINER_SIMPLEX_1D:
61460314a74cSLawrence Mitchell       if ((p >= vStart) && (p < vEnd)) {
61470314a74cSLawrence Mitchell         /* Interior vertices stay the same */
61480314a74cSLawrence Mitchell         ++numLeavesNew;
61490314a74cSLawrence Mitchell       } else if ((p >= cStart && p < cMax)) {
61500314a74cSLawrence Mitchell         /* Interior cells add new cells and interior vertices */
61510314a74cSLawrence Mitchell         numLeavesNew += 2 + 1;
61520314a74cSLawrence Mitchell       }
61530314a74cSLawrence Mitchell       break;
61549b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
61559b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_2D:
6156a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
6157a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
6158a97b51b8SMatthew G. Knepley         ++numLeavesNew;
6159a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
6160a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
6161a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
6162a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
6163a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
6164a97b51b8SMatthew G. Knepley         ++numLeavesNew;
6165a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
6166a97b51b8SMatthew G. Knepley         /* Interior cells add new cells and interior faces */
6167a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 3;
6168a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
6169a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
6170a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
6171a97b51b8SMatthew G. Knepley       }
6172a97b51b8SMatthew G. Knepley       break;
61739b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
61749b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
6175a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
6176a97b51b8SMatthew G. Knepley         /* Interior vertices stay the same */
6177a97b51b8SMatthew G. Knepley         ++numLeavesNew;
6178a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
6179a97b51b8SMatthew G. Knepley         /* Interior faces add new faces and vertex */
6180a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
6181a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
6182a97b51b8SMatthew G. Knepley         /* Hybrid faces stay the same */
6183a97b51b8SMatthew G. Knepley         ++numLeavesNew;
6184a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
6185a97b51b8SMatthew G. Knepley         /* Interior cells add new cells, interior faces, and vertex */
6186a97b51b8SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
6187a97b51b8SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
6188a97b51b8SMatthew G. Knepley         /* Hybrid cells add new cells and hybrid face */
6189a97b51b8SMatthew G. Knepley         numLeavesNew += 2 + 1;
6190a97b51b8SMatthew G. Knepley       }
6191a97b51b8SMatthew G. Knepley       break;
61929b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
61939b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
61946ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
61956ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
61966ce3c06aSMatthew G. Knepley         ++numLeavesNew;
61976ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
61986ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
61996ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
62006ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
62016ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
62026ce3c06aSMatthew G. Knepley         ++numLeavesNew;
62036ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
62046ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
62056ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
62066ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
62076ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
62086ce3c06aSMatthew G. Knepley         numLeavesNew += 2 + 1;
62096ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
62106ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
62116ce3c06aSMatthew G. Knepley         numLeavesNew += 8 + 8 + 1;
62126ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
62136ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
62146ce3c06aSMatthew G. Knepley         numLeavesNew += 4 + 3;
62156ce3c06aSMatthew G. Knepley       }
62166ce3c06aSMatthew G. Knepley       break;
62179b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
62189b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
621927fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
622027fcede3SMatthew G. Knepley         /* Old vertices stay the same */
622127fcede3SMatthew G. Knepley         ++numLeavesNew;
622227fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
622327fcede3SMatthew G. Knepley         /* Interior edges add new edges, and vertex */
622427fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
622527fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
622627fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
622727fcede3SMatthew G. Knepley         ++numLeavesNew;
622827fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
622927fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
623027fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
623127fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
623227fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
623327fcede3SMatthew G. Knepley         numLeavesNew += 2 + 1;
623427fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
623527fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
623627fcede3SMatthew G. Knepley         numLeavesNew += 8 + 12 + 6 + 1;
623727fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cEnd)) {
623827fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
623927fcede3SMatthew G. Knepley         numLeavesNew += 4 + 4 + 1;
624027fcede3SMatthew G. Knepley       }
624127fcede3SMatthew G. Knepley       break;
624275d3a19aSMatthew G. Knepley     default:
624375d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
624475d3a19aSMatthew G. Knepley     }
624575d3a19aSMatthew G. Knepley   }
624675d3a19aSMatthew G. Knepley   /* Communicate depthSizes for each remote rank */
624775d3a19aSMatthew G. Knepley   ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr);
624875d3a19aSMatthew G. Knepley   ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr);
6249dcca6d9dSJed Brown   ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr);
6250dcca6d9dSJed Brown   ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr);
625175d3a19aSMatthew G. Knepley   ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr);
625275d3a19aSMatthew G. Knepley   ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr);
625375d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
625475d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr);
625575d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
625675d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr);
625775d3a19aSMatthew G. Knepley   }
625875d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cMax;
625975d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vMax;
626075d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fMax;
626175d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eMax;
626275d3a19aSMatthew G. Knepley 
626375d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
626475d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr);
626575d3a19aSMatthew G. Knepley 
626675d3a19aSMatthew G. Knepley   depthSizeOld[depth]   = cEnd - cStart;
626775d3a19aSMatthew G. Knepley   depthSizeOld[0]       = vEnd - vStart;
626875d3a19aSMatthew G. Knepley   depthSizeOld[depth-1] = fEnd - fStart;
626975d3a19aSMatthew G. Knepley   depthSizeOld[1]       = eEnd - eStart;
627075d3a19aSMatthew G. Knepley 
627175d3a19aSMatthew G. Knepley   ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
627275d3a19aSMatthew G. Knepley   ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr);
627375d3a19aSMatthew G. Knepley   for (n = 0; n < numNeighbors; ++n) {
627475d3a19aSMatthew G. Knepley     ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr);
62750252e7f5SMatthew 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];
62760252e7f5SMatthew 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];
62770252e7f5SMatthew 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];
627875d3a19aSMatthew G. Knepley   }
627975d3a19aSMatthew G. Knepley   ierr = MPI_Type_free(&depthType);CHKERRQ(ierr);
628075d3a19aSMatthew G. Knepley   ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr);
628175d3a19aSMatthew G. Knepley   /* Calculate new point SF */
6282785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr);
6283785e854fSJed Brown   ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr);
628475d3a19aSMatthew G. Knepley   ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr);
628575d3a19aSMatthew G. Knepley   for (l = 0, m = 0; l < numLeaves; ++l) {
628675d3a19aSMatthew G. Knepley     PetscInt    p     = localPoints[l];
628775d3a19aSMatthew G. Knepley     PetscInt    rp    = remotePoints[l].index, n;
628875d3a19aSMatthew G. Knepley     PetscMPIInt rrank = remotePoints[l].rank;
628975d3a19aSMatthew G. Knepley 
629075d3a19aSMatthew G. Knepley     ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr);
629175d3a19aSMatthew G. Knepley     if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank);
629275d3a19aSMatthew G. Knepley     switch (refiner) {
62930314a74cSLawrence Mitchell     case REFINER_SIMPLEX_1D:
62940314a74cSLawrence Mitchell       if ((p >= vStart) && (p < vEnd)) {
62950314a74cSLawrence Mitchell         /* Old vertices stay the same */
62960314a74cSLawrence Mitchell         localPointsNew[m]        = vStartNew     + (p  - vStart);
62970314a74cSLawrence Mitchell         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
62980314a74cSLawrence Mitchell         remotePointsNew[m].rank  = rrank;
62990314a74cSLawrence Mitchell         ++m;
63000314a74cSLawrence Mitchell       } else if ((p >= cStart) && (p < cMax)) {
63010314a74cSLawrence Mitchell         /* Old interior cells add new cells and vertex */
63020314a74cSLawrence Mitchell         for (r = 0; r < 2; ++r, ++m) {
63030314a74cSLawrence Mitchell           localPointsNew[m]        = cStartNew     + (p  - cStart)*2     + r;
63040314a74cSLawrence Mitchell           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r;
63050314a74cSLawrence Mitchell           remotePointsNew[m].rank  = rrank;
63060314a74cSLawrence Mitchell         }
63070314a74cSLawrence Mitchell         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - cStart);
63080314a74cSLawrence Mitchell         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]);
63090314a74cSLawrence Mitchell         remotePointsNew[m].rank  = rrank;
63100314a74cSLawrence Mitchell         ++m;
63110314a74cSLawrence Mitchell       }
63120314a74cSLawrence Mitchell       break;
63139b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_2D:
63149b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_2D:
631575d3a19aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
631675d3a19aSMatthew G. Knepley         /* Old vertices stay the same */
631775d3a19aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
631875d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
631975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
632075d3a19aSMatthew G. Knepley         ++m;
632175d3a19aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
632275d3a19aSMatthew G. Knepley         /* Old interior faces add new faces and vertex */
632375d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
632475d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
632575d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
632675d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
632775d3a19aSMatthew G. Knepley         }
6328add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
6329add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
6330add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
6331add09238SMatthew G. Knepley         ++m;
633275d3a19aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
633375d3a19aSMatthew G. Knepley         /* Old hybrid faces stay the same */
633475d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
633575d3a19aSMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
633675d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
633775d3a19aSMatthew G. Knepley         ++m;
633875d3a19aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
633975d3a19aSMatthew G. Knepley         /* Old interior cells add new cells and interior faces */
634075d3a19aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
634175d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
634275d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
634375d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
634475d3a19aSMatthew G. Knepley         }
634575d3a19aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
634675d3a19aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*3     + r;
634775d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r;
634875d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
634975d3a19aSMatthew G. Knepley         }
6350add09238SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
635175d3a19aSMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
635275d3a19aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
635375d3a19aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
635475d3a19aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
635575d3a19aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
635675d3a19aSMatthew G. Knepley         }
635775d3a19aSMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*3     + (p  - cMax);
635875d3a19aSMatthew 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]);
635975d3a19aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
636075d3a19aSMatthew G. Knepley         ++m;
636175d3a19aSMatthew G. Knepley       }
636275d3a19aSMatthew G. Knepley       break;
63639b1a0e7fSLawrence Mitchell     case REFINER_HEX_2D:
63649b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_2D:
6365a97b51b8SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
6366a97b51b8SMatthew G. Knepley         /* Old vertices stay the same */
6367a97b51b8SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
6368a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
6369a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
6370a97b51b8SMatthew G. Knepley         ++m;
6371a97b51b8SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
6372a97b51b8SMatthew G. Knepley         /* Old interior faces add new faces and vertex */
6373a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
6374a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*2     + r;
6375a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r;
6376a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
6377a97b51b8SMatthew G. Knepley         }
6378add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - fStart);
6379add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]);
6380add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
6381add09238SMatthew G. Knepley         ++m;
6382a97b51b8SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
6383a97b51b8SMatthew G. Knepley         /* Old hybrid faces stay the same */
6384a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - fMax);
6385a97b51b8SMatthew G. Knepley         remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]);
6386a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
6387a97b51b8SMatthew G. Knepley         ++m;
6388a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
6389a97b51b8SMatthew G. Knepley         /* Old interior cells add new cells, interior faces, and vertex */
6390a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
6391a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
6392a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
6393a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
6394a97b51b8SMatthew G. Knepley         }
6395a97b51b8SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
6396a97b51b8SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (p  - cStart)*4     + r;
6397a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r;
6398a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
6399a97b51b8SMatthew G. Knepley         }
6400add09238SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)               + (fMax                              - fStart)     + (p  - cStart);
6401add09238SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0]  + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]);
6402add09238SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
6403add09238SMatthew G. Knepley         ++m;
6404a97b51b8SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
6405a97b51b8SMatthew G. Knepley         /* Old hybrid cells add new cells and hybrid face */
6406a97b51b8SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
6407a97b51b8SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*4     + r;
6408a97b51b8SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r;
6409a97b51b8SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
6410a97b51b8SMatthew G. Knepley         }
6411a97b51b8SMatthew G. Knepley         localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*2     + (cMax                            - cStart)*4     + (p  - cMax);
6412a97b51b8SMatthew 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]);
6413a97b51b8SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
6414a97b51b8SMatthew G. Knepley         ++m;
6415a97b51b8SMatthew G. Knepley       }
6416a97b51b8SMatthew G. Knepley       break;
64179b1a0e7fSLawrence Mitchell     case REFINER_SIMPLEX_3D:
64189b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_SIMPLEX_3D:
64196ce3c06aSMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
64206ce3c06aSMatthew G. Knepley         /* Interior vertices stay the same */
64216ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
64226ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
64236ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
64246ce3c06aSMatthew G. Knepley         ++m;
64256ce3c06aSMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
64266ce3c06aSMatthew G. Knepley         /* Interior edges add new edges and vertex */
64276ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
64286ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
64296ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
64306ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
64316ce3c06aSMatthew G. Knepley         }
64326ce3c06aSMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
64336ce3c06aSMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
64346ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
64356ce3c06aSMatthew G. Knepley         ++m;
64366ce3c06aSMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
64376ce3c06aSMatthew G. Knepley         /* Hybrid edges stay the same */
64386ce3c06aSMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (p  - eMax);
64397d5cd7d5SMatthew 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]);
64406ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
64416ce3c06aSMatthew G. Knepley         ++m;
64426ce3c06aSMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
64436ce3c06aSMatthew G. Knepley         /* Interior faces add new faces and edges */
64446ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
64456ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
64466ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
64476ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
64486ce3c06aSMatthew G. Knepley         }
64496ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
64506ce3c06aSMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*3     + r;
64516ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r;
64526ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
64536ce3c06aSMatthew G. Knepley         }
64546ce3c06aSMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
64556ce3c06aSMatthew G. Knepley         /* Hybrid faces add new faces and edges */
64566ce3c06aSMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
6457899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (p  - fMax)*2                              + r;
6458899f98d0SMatthew 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;
64596ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
64606ce3c06aSMatthew G. Knepley         }
64617d5cd7d5SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (cMax                            - cStart)     + (eEnd                                    - eMax)                        + (p  - fMax);
64627d5cd7d5SMatthew 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]);
64636ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
646409b1338fSMatthew G. Knepley         ++m;
64656ce3c06aSMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
64666ce3c06aSMatthew G. Knepley         /* Interior cells add new cells, faces, and edges */
64676ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
64686ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
64696ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
64706ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
64716ce3c06aSMatthew G. Knepley         }
64726ce3c06aSMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
64736ce3c06aSMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*8     + r;
64746ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r;
64756ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
64766ce3c06aSMatthew G. Knepley         }
6477c7c54c77SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*3     + (p  - cStart)*1     + 0;
6478c7c54c77SMatthew 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;
64796ce3c06aSMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
648009b1338fSMatthew G. Knepley         ++m;
64816ce3c06aSMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
64826ce3c06aSMatthew G. Knepley         /* Hybrid cells add new cells and faces */
64836ce3c06aSMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
64846ce3c06aSMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
64856ce3c06aSMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
64866ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
64876ce3c06aSMatthew G. Knepley         }
64886ce3c06aSMatthew G. Knepley         for (r = 0; r < 3; ++r, ++m) {
6489899f98d0SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*8     + (fEnd                                          - fMax)*2                              + (p  - cMax)*3                            + r;
6490899f98d0SMatthew 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;
64916ce3c06aSMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
64926ce3c06aSMatthew G. Knepley         }
64936ce3c06aSMatthew G. Knepley       }
64946ce3c06aSMatthew G. Knepley       break;
64959b1a0e7fSLawrence Mitchell     case REFINER_HEX_3D:
64969b1a0e7fSLawrence Mitchell     case REFINER_HYBRID_HEX_3D:
649727fcede3SMatthew G. Knepley       if ((p >= vStart) && (p < vEnd)) {
649827fcede3SMatthew G. Knepley         /* Interior vertices stay the same */
649927fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (p  - vStart);
650027fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]);
650127fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
650227fcede3SMatthew G. Knepley         ++m;
650327fcede3SMatthew G. Knepley       } else if ((p >= eStart) && (p < eMax)) {
650427fcede3SMatthew G. Knepley         /* Interior edges add new edges and vertex */
650527fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
650627fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (p  - eStart)*2     + r;
650727fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r;
650827fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
650927fcede3SMatthew G. Knepley         }
651027fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (p  - eStart);
651127fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]);
651227fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
651327fcede3SMatthew G. Knepley         ++m;
651427fcede3SMatthew G. Knepley       } else if ((p >= eMax) && (p < eEnd)) {
651527fcede3SMatthew G. Knepley         /* Hybrid edges stay the same */
651627fcede3SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (p  - eMax);
6517d2701f60SMatthew 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]);
651827fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
651927fcede3SMatthew G. Knepley         ++m;
652027fcede3SMatthew G. Knepley       } else if ((p >= fStart) && (p < fMax)) {
652127fcede3SMatthew G. Knepley         /* Interior faces add new faces, edges, and vertex */
652227fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
652327fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (p  - fStart)*4     + r;
652427fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r;
652527fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
652627fcede3SMatthew G. Knepley         }
652727fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
652827fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (p  - fStart)*4     + r;
652927fcede3SMatthew G. Knepley           remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r;
653027fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
653127fcede3SMatthew G. Knepley         }
653227fcede3SMatthew G. Knepley         localPointsNew[m]        = vStartNew     + (vEnd - vStart)              + (eMax                        - eStart)     + (p  - fStart);
653327fcede3SMatthew G. Knepley         remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]);
653427fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
653527fcede3SMatthew G. Knepley         ++m;
653627fcede3SMatthew G. Knepley       } else if ((p >= fMax) && (p < fEnd)) {
653727fcede3SMatthew G. Knepley         /* Hybrid faces add new faces and edges */
653827fcede3SMatthew G. Knepley         for (r = 0; r < 2; ++r, ++m) {
6539d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (p  - fMax)*2                              + r;
6540d2701f60SMatthew 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;
654127fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
654227fcede3SMatthew G. Knepley         }
6543d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (p  - fMax);
6544d2701f60SMatthew 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]);
654527fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
654627fcede3SMatthew G. Knepley         ++m;
654727fcede3SMatthew G. Knepley       } else if ((p >= cStart) && (p < cMax)) {
654827fcede3SMatthew G. Knepley         /* Interior cells add new cells, faces, edges, and vertex */
654927fcede3SMatthew G. Knepley         for (r = 0; r < 8; ++r, ++m) {
655027fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (p  - cStart)*8     + r;
655127fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r;
655227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
655327fcede3SMatthew G. Knepley         }
655427fcede3SMatthew G. Knepley         for (r = 0; r < 12; ++r, ++m) {
655527fcede3SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (p  - cStart)*12     + r;
655627fcede3SMatthew G. Knepley           remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r;
655727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
655827fcede3SMatthew G. Knepley         }
655927fcede3SMatthew G. Knepley         for (r = 0; r < 6; ++r, ++m) {
656027fcede3SMatthew G. Knepley           localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (p  - cStart)*6     + r;
656127fcede3SMatthew 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;
656227fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
656327fcede3SMatthew G. Knepley         }
656427fcede3SMatthew G. Knepley         for (r = 0; r < 1; ++r, ++m) {
656527fcede3SMatthew G. Knepley           localPointsNew[m]        = vStartNew     + (eMax                        - eStart)     + (fMax                              - fStart)     + (p  - cStart)     + r;
656627fcede3SMatthew 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;
656727fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
656827fcede3SMatthew G. Knepley         }
656927fcede3SMatthew G. Knepley       } else if ((p >= cMax) && (p < cEnd)) {
657027fcede3SMatthew G. Knepley         /* Hybrid cells add new cells, faces, and edges */
657127fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
657227fcede3SMatthew G. Knepley           localPointsNew[m]        = cStartNew     + (cMax                            - cStart)*8     + (p  - cMax)*4                            + r;
657327fcede3SMatthew G. Knepley           remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r;
657427fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
657527fcede3SMatthew G. Knepley         }
657627fcede3SMatthew G. Knepley         for (r = 0; r < 4; ++r, ++m) {
6577d2701f60SMatthew G. Knepley           localPointsNew[m]        = fStartNew     + (fMax                              - fStart)*4     + (cMax                            - cStart)*12     + (fEnd                                          - fMax)*2                              + (p  - cMax)*4                            + r;
6578d2701f60SMatthew 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;
657927fcede3SMatthew G. Knepley           remotePointsNew[m].rank  = rrank;
658027fcede3SMatthew G. Knepley         }
6581d2701f60SMatthew G. Knepley         localPointsNew[m]        = eStartNew     + (eMax                        - eStart)*2     + (fMax                              - fStart)*4     + (cMax                            - cStart)*6     + (eEnd                                    - eMax)                        + (fEnd                                          - fMax)                              + (p  - cMax);
6582d2701f60SMatthew 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]);
658327fcede3SMatthew G. Knepley         remotePointsNew[m].rank  = rrank;
658427fcede3SMatthew G. Knepley         ++m;
658527fcede3SMatthew G. Knepley       }
658627fcede3SMatthew G. Knepley       break;
658775d3a19aSMatthew G. Knepley     default:
658875d3a19aSMatthew G. Knepley       SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
658975d3a19aSMatthew G. Knepley     }
659075d3a19aSMatthew G. Knepley   }
659109b1338fSMatthew G. Knepley   if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew);
659275d3a19aSMatthew G. Knepley   ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr);
659375d3a19aSMatthew G. Knepley   ierr = ISDestroy(&processRanks);CHKERRQ(ierr);
6594ba3c3d50SMatthew G. Knepley   {
6595ba3c3d50SMatthew G. Knepley     PetscSFNode *rp, *rtmp;
6596ba3c3d50SMatthew G. Knepley     PetscInt    *lp, *idx, *ltmp, i;
6597ba3c3d50SMatthew G. Knepley 
6598ba3c3d50SMatthew G. Knepley     /* SF needs sorted leaves to correct calculate Gather */
6599ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr);
6600ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr);
6601ba3c3d50SMatthew G. Knepley     ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr);
6602c7c54c77SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
6603c7c54c77SMatthew 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);
6604c7c54c77SMatthew G. Knepley       idx[i] = i;
6605c7c54c77SMatthew G. Knepley     }
6606ba3c3d50SMatthew G. Knepley     ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr);
6607ba3c3d50SMatthew G. Knepley     for (i = 0; i < numLeavesNew; ++i) {
6608ba3c3d50SMatthew G. Knepley       lp[i] = localPointsNew[idx[i]];
6609ba3c3d50SMatthew G. Knepley       rp[i] = remotePointsNew[idx[i]];
6610ba3c3d50SMatthew G. Knepley     }
6611ba3c3d50SMatthew G. Knepley     ltmp            = localPointsNew;
6612ba3c3d50SMatthew G. Knepley     localPointsNew  = lp;
6613ba3c3d50SMatthew G. Knepley     rtmp            = remotePointsNew;
6614ba3c3d50SMatthew G. Knepley     remotePointsNew = rp;
6615ba3c3d50SMatthew G. Knepley     ierr = PetscFree(idx);CHKERRQ(ierr);
6616ba3c3d50SMatthew G. Knepley     ierr = PetscFree(ltmp);CHKERRQ(ierr);
6617ba3c3d50SMatthew G. Knepley     ierr = PetscFree(rtmp);CHKERRQ(ierr);
6618ba3c3d50SMatthew G. Knepley   }
661975d3a19aSMatthew G. Knepley   ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr);
662075d3a19aSMatthew G. Knepley   ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr);
662106a0ba2dSMatthew G. Knepley   ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr);
662275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
662375d3a19aSMatthew G. Knepley }
662475d3a19aSMatthew G. Knepley 
662586150812SJed Brown static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm)
662675d3a19aSMatthew G. Knepley {
662775d3a19aSMatthew G. Knepley   PetscInt       numLabels, l;
66287ba685a0SMatthew G. Knepley   PetscInt       depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r;
66297ba685a0SMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
663075d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
663175d3a19aSMatthew G. Knepley 
663275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
663375d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
663475d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr);
663575d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
663675d3a19aSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr);
6637d963de37SMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
66383478d7aaSMatthew G. Knepley   if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
6639c58f1c22SToby Isaac   ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
664075d3a19aSMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr);
664175d3a19aSMatthew G. Knepley   switch (refiner) {
66429b1a0e7fSLawrence Mitchell   case REFINER_NOOP:
66430314a74cSLawrence Mitchell   case REFINER_SIMPLEX_1D:
66449b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_2D:
66459b1a0e7fSLawrence Mitchell   case REFINER_HEX_2D:
66469b1a0e7fSLawrence Mitchell   case REFINER_SIMPLEX_3D:
66479b1a0e7fSLawrence Mitchell   case REFINER_HEX_3D:
66489b1a0e7fSLawrence Mitchell     break;
66499b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_3D:
66509b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_3D:
665158b8852aSMatthew G. Knepley     if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh");
66529b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_SIMPLEX_2D:
66539b1a0e7fSLawrence Mitchell   case REFINER_HYBRID_HEX_2D:
665475d3a19aSMatthew G. Knepley     if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh");
665575d3a19aSMatthew G. Knepley     if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh");
66561e317b1dSMatthew G. Knepley     break;
66579b1a0e7fSLawrence Mitchell   default:
66589b1a0e7fSLawrence Mitchell     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
665975d3a19aSMatthew G. Knepley   }
666075d3a19aSMatthew G. Knepley   for (l = 0; l < numLabels; ++l) {
666175d3a19aSMatthew G. Knepley     DMLabel         label, labelNew;
666275d3a19aSMatthew G. Knepley     const char     *lname;
666375d3a19aSMatthew G. Knepley     PetscBool       isDepth;
666475d3a19aSMatthew G. Knepley     IS              valueIS;
666575d3a19aSMatthew G. Knepley     const PetscInt *values;
66665aa44df4SToby Isaac     PetscInt        defVal;
666775d3a19aSMatthew G. Knepley     PetscInt        numValues, val;
666875d3a19aSMatthew G. Knepley 
6669c58f1c22SToby Isaac     ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr);
667075d3a19aSMatthew G. Knepley     ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr);
667175d3a19aSMatthew G. Knepley     if (isDepth) continue;
6672c58f1c22SToby Isaac     ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr);
6673c58f1c22SToby Isaac     ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr);
6674c58f1c22SToby Isaac     ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr);
66755aa44df4SToby Isaac     ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr);
66765aa44df4SToby Isaac     ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr);
667775d3a19aSMatthew G. Knepley     ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr);
667875d3a19aSMatthew G. Knepley     ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr);
667975d3a19aSMatthew G. Knepley     ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr);
668075d3a19aSMatthew G. Knepley     for (val = 0; val < numValues; ++val) {
668175d3a19aSMatthew G. Knepley       IS              pointIS;
668275d3a19aSMatthew G. Knepley       const PetscInt *points;
668375d3a19aSMatthew G. Knepley       PetscInt        numPoints, n;
668475d3a19aSMatthew G. Knepley 
668575d3a19aSMatthew G. Knepley       ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr);
668675d3a19aSMatthew G. Knepley       ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr);
668775d3a19aSMatthew G. Knepley       ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr);
66882bc5314cSMichael Lange       /* Ensure refined label is created with same number of strata as
66892bc5314cSMichael Lange        * original (even if no entries here). */
6690ad8374ffSToby Isaac       ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr);
669175d3a19aSMatthew G. Knepley       for (n = 0; n < numPoints; ++n) {
669275d3a19aSMatthew G. Knepley         const PetscInt p = points[n];
669375d3a19aSMatthew G. Knepley         switch (refiner) {
66940314a74cSLawrence Mitchell         case REFINER_SIMPLEX_1D:
66950314a74cSLawrence Mitchell           if ((p >= vStart) && (p < vEnd)) {
66960314a74cSLawrence Mitchell             /* Old vertices stay the same */
66970314a74cSLawrence Mitchell             newp = vStartNew + (p - vStart);
66980314a74cSLawrence Mitchell             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
66990314a74cSLawrence Mitchell           } else if ((p >= cStart) && (p < cEnd)) {
67000314a74cSLawrence Mitchell             /* Old cells add new cells and vertex */
67010314a74cSLawrence Mitchell             newp = vStartNew + (vEnd - vStart) + (p - cStart);
67020314a74cSLawrence Mitchell             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
67030314a74cSLawrence Mitchell             for (r = 0; r < 2; ++r) {
67040314a74cSLawrence Mitchell               newp = cStartNew + (p - cStart)*2 + r;
67050314a74cSLawrence Mitchell               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
67060314a74cSLawrence Mitchell             }
67070314a74cSLawrence Mitchell           }
67080314a74cSLawrence Mitchell           break;
67099b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_2D:
671075d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
671175d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
671275d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
671375d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
671475d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
671575d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
671675d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
671775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
671875d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
671975d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
672075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
672175d3a19aSMatthew G. Knepley             }
672275d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
672375d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces */
672475d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
672575d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
672675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
672775d3a19aSMatthew G. Knepley             }
672875d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
672975d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
673075d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
673175d3a19aSMatthew G. Knepley             }
673275d3a19aSMatthew G. Knepley           }
673375d3a19aSMatthew G. Knepley           break;
67349b1a0e7fSLawrence Mitchell         case REFINER_HEX_2D:
673575d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
673675d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
673775d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
673875d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
673975d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
674075d3a19aSMatthew G. Knepley             /* Old faces add new faces and vertex */
674175d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
674275d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
674375d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
674475d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
674575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
674675d3a19aSMatthew G. Knepley             }
674775d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
674875d3a19aSMatthew G. Knepley             /* Old cells add new cells and interior faces and vertex */
674975d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
675075d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
675175d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
675275d3a19aSMatthew G. Knepley             }
675375d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
675475d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
675575d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
675675d3a19aSMatthew G. Knepley             }
675775d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
675875d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
675975d3a19aSMatthew G. Knepley           }
676075d3a19aSMatthew G. Knepley           break;
67619b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_2D:
676275d3a19aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
676375d3a19aSMatthew G. Knepley             /* Old vertices stay the same */
676475d3a19aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
676575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
676675d3a19aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
676775d3a19aSMatthew G. Knepley             /* Old interior faces add new faces and vertex */
676875d3a19aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
676975d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
677075d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
677175d3a19aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
677275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
677375d3a19aSMatthew G. Knepley             }
677475d3a19aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
677575d3a19aSMatthew G. Knepley             /* Old hybrid faces stay the same */
677675d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
677775d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
677875d3a19aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
677975d3a19aSMatthew G. Knepley             /* Old interior cells add new cells and interior faces */
678075d3a19aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
678175d3a19aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
678275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
678375d3a19aSMatthew G. Knepley             }
678475d3a19aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
678575d3a19aSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r;
678675d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
678775d3a19aSMatthew G. Knepley             }
678875d3a19aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
678975d3a19aSMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
679075d3a19aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
679175d3a19aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
679275d3a19aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
679375d3a19aSMatthew G. Knepley             }
679475d3a19aSMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax);
679575d3a19aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
679675d3a19aSMatthew G. Knepley           }
679775d3a19aSMatthew G. Knepley           break;
67989b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_2D:
6799a97b51b8SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
6800a97b51b8SMatthew G. Knepley             /* Old vertices stay the same */
6801a97b51b8SMatthew G. Knepley             newp = vStartNew + (p - vStart);
6802a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6803a97b51b8SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
6804a97b51b8SMatthew G. Knepley             /* Old interior faces add new faces and vertex */
6805a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - fStart);
6806a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6807a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6808a97b51b8SMatthew G. Knepley               newp = fStartNew + (p - fStart)*2 + r;
6809a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6810a97b51b8SMatthew G. Knepley             }
6811a97b51b8SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
6812a97b51b8SMatthew G. Knepley             /* Old hybrid faces stay the same */
6813a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (p - fMax);
6814a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6815a97b51b8SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
6816a97b51b8SMatthew G. Knepley             /* Old interior cells add new cells, interior faces, and vertex */
6817a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6818a97b51b8SMatthew G. Knepley               newp = cStartNew + (p - cStart)*4 + r;
6819a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6820a97b51b8SMatthew G. Knepley             }
6821a97b51b8SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6822a97b51b8SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r;
6823a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6824a97b51b8SMatthew G. Knepley             }
6825a97b51b8SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart);
6826a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6827a97b51b8SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
6828a97b51b8SMatthew G. Knepley             /* Old hybrid cells add new cells and hybrid face */
6829a97b51b8SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6830a97b51b8SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r;
6831a97b51b8SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6832a97b51b8SMatthew G. Knepley             }
6833a97b51b8SMatthew G. Knepley             newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax);
6834a97b51b8SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6835a97b51b8SMatthew G. Knepley           }
6836a97b51b8SMatthew G. Knepley           break;
68379b1a0e7fSLawrence Mitchell         case REFINER_SIMPLEX_3D:
6838b5da9499SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
6839b5da9499SMatthew G. Knepley             /* Old vertices stay the same */
6840b5da9499SMatthew G. Knepley             newp = vStartNew + (p - vStart);
6841b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6842b5da9499SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
6843b5da9499SMatthew G. Knepley             /* Old edges add new edges and vertex */
6844b5da9499SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
6845b5da9499SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
6846b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6847b5da9499SMatthew G. Knepley             }
6848b5da9499SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
6849b5da9499SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6850b5da9499SMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
6851b5da9499SMatthew G. Knepley             /* Old faces add new faces and edges */
6852b5da9499SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
6853b5da9499SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
6854b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6855b5da9499SMatthew G. Knepley             }
6856b5da9499SMatthew G. Knepley             for (r = 0; r < 3; ++r) {
6857b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r;
6858b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6859b5da9499SMatthew G. Knepley             }
6860b5da9499SMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
6861b5da9499SMatthew G. Knepley             /* Old cells add new cells and interior faces and edges */
6862b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
6863b5da9499SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
6864b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6865b5da9499SMatthew G. Knepley             }
6866b5da9499SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
6867b5da9499SMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r;
6868b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6869b5da9499SMatthew G. Knepley             }
6870b5da9499SMatthew G. Knepley             for (r = 0; r < 1; ++r) {
6871b5da9499SMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r;
6872b5da9499SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
6873b5da9499SMatthew G. Knepley             }
6874b5da9499SMatthew G. Knepley           }
6875b5da9499SMatthew G. Knepley           break;
68769b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_SIMPLEX_3D:
68776ce3c06aSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
68786ce3c06aSMatthew G. Knepley             /* Interior vertices stay the same */
68796ce3c06aSMatthew G. Knepley             newp = vStartNew + (p - vStart);
68806ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
68816ce3c06aSMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
68826ce3c06aSMatthew G. Knepley             /* Interior edges add new edges and vertex */
68836ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
68846ce3c06aSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
68856ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
68866ce3c06aSMatthew G. Knepley             }
68876ce3c06aSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
68886ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
68896ce3c06aSMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
68906ce3c06aSMatthew G. Knepley             /* Hybrid edges stay the same */
68916ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax);
68926ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
68936ce3c06aSMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
68946ce3c06aSMatthew G. Knepley             /* Interior faces add new faces and edges */
68956ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
68966ce3c06aSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
68976ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
68986ce3c06aSMatthew G. Knepley             }
68996ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
69006ce3c06aSMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r;
69016ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69026ce3c06aSMatthew G. Knepley             }
69036ce3c06aSMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
69046ce3c06aSMatthew G. Knepley             /* Hybrid faces add new faces and edges */
69056ce3c06aSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
69066ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r;
69076ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69086ce3c06aSMatthew G. Knepley             }
69096ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax);
69106ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69116ce3c06aSMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
69126ce3c06aSMatthew G. Knepley             /* Interior cells add new cells, faces, and edges */
69136ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
69146ce3c06aSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
69156ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69166ce3c06aSMatthew G. Knepley             }
69176ce3c06aSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
69186ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r;
69196ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69206ce3c06aSMatthew G. Knepley             }
69216ce3c06aSMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart);
69226ce3c06aSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
692358b8852aSMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
69246ce3c06aSMatthew G. Knepley             /* Hybrid cells add new cells and faces */
69256ce3c06aSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
69266ce3c06aSMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
69276ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69286ce3c06aSMatthew G. Knepley             }
69296ce3c06aSMatthew G. Knepley             for (r = 0; r < 3; ++r) {
69306ce3c06aSMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r;
69316ce3c06aSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69326ce3c06aSMatthew G. Knepley             }
69336ce3c06aSMatthew G. Knepley           }
69346ce3c06aSMatthew G. Knepley           break;
69359b1a0e7fSLawrence Mitchell         case REFINER_HEX_3D:
69362eabf88fSMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
69372eabf88fSMatthew G. Knepley             /* Old vertices stay the same */
69382eabf88fSMatthew G. Knepley             newp = vStartNew + (p - vStart);
69392eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
694019d7d790SMatthew G. Knepley           } else if ((p >= eStart) && (p < eEnd)) {
69412eabf88fSMatthew G. Knepley             /* Old edges add new edges and vertex */
69422eabf88fSMatthew G. Knepley             for (r = 0; r < 2; ++r) {
69432eabf88fSMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
69442eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69452eabf88fSMatthew G. Knepley             }
69462eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
69472eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69482eabf88fSMatthew G. Knepley           } else if ((p >= fStart) && (p < fEnd)) {
69492eabf88fSMatthew G. Knepley             /* Old faces add new faces, edges, and vertex */
69502eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
69512eabf88fSMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
69522eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69532eabf88fSMatthew G. Knepley             }
69542eabf88fSMatthew G. Knepley             for (r = 0; r < 4; ++r) {
69552eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r;
69562eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69572eabf88fSMatthew G. Knepley             }
69582eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart);
69592eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69602eabf88fSMatthew G. Knepley           } else if ((p >= cStart) && (p < cEnd)) {
69612eabf88fSMatthew G. Knepley             /* Old cells add new cells, faces, edges, and vertex */
69622eabf88fSMatthew G. Knepley             for (r = 0; r < 8; ++r) {
69632eabf88fSMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
69642eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69652eabf88fSMatthew G. Knepley             }
69662eabf88fSMatthew G. Knepley             for (r = 0; r < 12; ++r) {
69672eabf88fSMatthew G. Knepley               newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r;
69682eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69692eabf88fSMatthew G. Knepley             }
69702eabf88fSMatthew G. Knepley             for (r = 0; r < 6; ++r) {
69712eabf88fSMatthew G. Knepley               newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r;
69722eabf88fSMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69732eabf88fSMatthew G. Knepley             }
69742eabf88fSMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart);
69752eabf88fSMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
69762eabf88fSMatthew G. Knepley           }
69772eabf88fSMatthew G. Knepley           break;
69789b1a0e7fSLawrence Mitchell         case REFINER_HYBRID_HEX_3D:
697927fcede3SMatthew G. Knepley           if ((p >= vStart) && (p < vEnd)) {
698027fcede3SMatthew G. Knepley             /* Interior vertices stay the same */
698127fcede3SMatthew G. Knepley             newp = vStartNew + (p - vStart);
698227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
698327fcede3SMatthew G. Knepley           } else if ((p >= eStart) && (p < eMax)) {
698427fcede3SMatthew G. Knepley             /* Interior edges add new edges and vertex */
698527fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
698627fcede3SMatthew G. Knepley               newp = eStartNew + (p - eStart)*2 + r;
698727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
698827fcede3SMatthew G. Knepley             }
698927fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (p - eStart);
699027fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
699127fcede3SMatthew G. Knepley           } else if ((p >= eMax) && (p < eEnd)) {
699227fcede3SMatthew G. Knepley             /* Hybrid edges stay the same */
699327fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax);
699427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
699527fcede3SMatthew G. Knepley           } else if ((p >= fStart) && (p < fMax)) {
699627fcede3SMatthew G. Knepley             /* Interior faces add new faces, edges, and vertex */
699727fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
699827fcede3SMatthew G. Knepley               newp = fStartNew + (p - fStart)*4 + r;
699927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
700027fcede3SMatthew G. Knepley             }
700127fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
700227fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r;
700327fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
700427fcede3SMatthew G. Knepley             }
700527fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart);
700627fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
700727fcede3SMatthew G. Knepley           } else if ((p >= fMax) && (p < fEnd)) {
700827fcede3SMatthew G. Knepley             /* Hybrid faces add new faces and edges */
700927fcede3SMatthew G. Knepley             for (r = 0; r < 2; ++r) {
701027fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r;
701127fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
701227fcede3SMatthew G. Knepley             }
701327fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax);
701427fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
701527fcede3SMatthew G. Knepley           } else if ((p >= cStart) && (p < cMax)) {
701627fcede3SMatthew G. Knepley             /* Interior cells add new cells, faces, edges, and vertex */
701727fcede3SMatthew G. Knepley             for (r = 0; r < 8; ++r) {
701827fcede3SMatthew G. Knepley               newp = cStartNew + (p - cStart)*8 + r;
701927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
702027fcede3SMatthew G. Knepley             }
702127fcede3SMatthew G. Knepley             for (r = 0; r < 12; ++r) {
702227fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r;
702327fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
702427fcede3SMatthew G. Knepley             }
702527fcede3SMatthew G. Knepley             for (r = 0; r < 6; ++r) {
702627fcede3SMatthew G. Knepley               newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r;
702727fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
702827fcede3SMatthew G. Knepley             }
702927fcede3SMatthew G. Knepley             newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart);
703027fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
703127fcede3SMatthew G. Knepley           } else if ((p >= cMax) && (p < cEnd)) {
703227fcede3SMatthew G. Knepley             /* Hybrid cells add new cells, faces, and edges */
703327fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
703427fcede3SMatthew G. Knepley               newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r;
703527fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
703627fcede3SMatthew G. Knepley             }
703727fcede3SMatthew G. Knepley             for (r = 0; r < 4; ++r) {
703827fcede3SMatthew G. Knepley               newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r;
703927fcede3SMatthew G. Knepley               ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
704027fcede3SMatthew G. Knepley             }
704127fcede3SMatthew G. Knepley             newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax);
704227fcede3SMatthew G. Knepley             ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr);
704327fcede3SMatthew G. Knepley           }
704427fcede3SMatthew G. Knepley           break;
704575d3a19aSMatthew G. Knepley         default:
704675d3a19aSMatthew G. Knepley           SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner);
704775d3a19aSMatthew G. Knepley         }
704875d3a19aSMatthew G. Knepley       }
704975d3a19aSMatthew G. Knepley       ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr);
705075d3a19aSMatthew G. Knepley       ierr = ISDestroy(&pointIS);CHKERRQ(ierr);
705175d3a19aSMatthew G. Knepley     }
705275d3a19aSMatthew G. Knepley     ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr);
705375d3a19aSMatthew G. Knepley     ierr = ISDestroy(&valueIS);CHKERRQ(ierr);
705475d3a19aSMatthew G. Knepley     if (0) {
705575d3a19aSMatthew G. Knepley       ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
705675d3a19aSMatthew G. Knepley     }
705775d3a19aSMatthew G. Knepley   }
705875d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
705975d3a19aSMatthew G. Knepley }
706075d3a19aSMatthew G. Knepley 
706175d3a19aSMatthew G. Knepley /* This will only work for interpolated meshes */
7062509c9b89SMatthew G. Knepley PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined)
706375d3a19aSMatthew G. Knepley {
706475d3a19aSMatthew G. Knepley   DM             rdm;
706575d3a19aSMatthew G. Knepley   PetscInt      *depthSize;
706675d3a19aSMatthew G. Knepley   PetscInt       dim, depth = 0, d, pStart = 0, pEnd = 0;
706775d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
706875d3a19aSMatthew G. Knepley 
706975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
707075d3a19aSMatthew G. Knepley   ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr);
707175d3a19aSMatthew G. Knepley   ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr);
7072c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
7073c73cfb54SMatthew G. Knepley   ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr);
707475d3a19aSMatthew G. Knepley   /* Calculate number of new points of each depth */
707575d3a19aSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
70761e573d11SMatthew G. Knepley   if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement");
7077854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
707875d3a19aSMatthew G. Knepley   ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr);
707975d3a19aSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
708075d3a19aSMatthew G. Knepley   /* Step 1: Set chart */
708175d3a19aSMatthew G. Knepley   for (d = 0; d <= depth; ++d) pEnd += depthSize[d];
708275d3a19aSMatthew G. Knepley   ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr);
708375d3a19aSMatthew G. Knepley   /* Step 2: Set cone/support sizes */
708475d3a19aSMatthew G. Knepley   ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
708575d3a19aSMatthew G. Knepley   /* Step 3: Setup refined DM */
708675d3a19aSMatthew G. Knepley   ierr = DMSetUp(rdm);CHKERRQ(ierr);
708775d3a19aSMatthew G. Knepley   /* Step 4: Set cones and supports */
708875d3a19aSMatthew G. Knepley   ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
708975d3a19aSMatthew G. Knepley   /* Step 5: Stratify */
709075d3a19aSMatthew G. Knepley   ierr = DMPlexStratify(rdm);CHKERRQ(ierr);
70910fadad52SMatthew G. Knepley   /* Step 6: Create pointSF */
709275d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
709390b157c4SStefano Zampini   /* Step 7: Create labels */
709475d3a19aSMatthew G. Knepley   ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
709590b157c4SStefano Zampini   /* Step 8: Set coordinates */
709690b157c4SStefano Zampini   ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr);
709775d3a19aSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
709875d3a19aSMatthew G. Knepley 
709975d3a19aSMatthew G. Knepley   *dmRefined = rdm;
710075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
710175d3a19aSMatthew G. Knepley }
710275d3a19aSMatthew G. Knepley 
71032389894bSMatthew G. Knepley /*@
71042389894bSMatthew G. Knepley   DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data
71052389894bSMatthew G. Knepley 
71062389894bSMatthew G. Knepley   Input Parameter:
71072389894bSMatthew G. Knepley . dm - The coarse DM
71082389894bSMatthew G. Knepley 
71092389894bSMatthew G. Knepley   Output Parameter:
71102389894bSMatthew G. Knepley . fpointIS - The IS of all the fine points which exist in the original coarse mesh
71112389894bSMatthew G. Knepley 
71122389894bSMatthew G. Knepley   Level: developer
71132389894bSMatthew G. Knepley 
71142389894bSMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS()
71152389894bSMatthew G. Knepley @*/
71162389894bSMatthew G. Knepley PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS)
71172389894bSMatthew G. Knepley {
71182389894bSMatthew G. Knepley   CellRefiner    cellRefiner;
71192389894bSMatthew G. Knepley   PetscInt      *depthSize, *fpoints;
71202389894bSMatthew G. Knepley   PetscInt       cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0;
71212389894bSMatthew G. Knepley   PetscInt       depth, pStart, pEnd, p, vStart, vEnd, v;
71222389894bSMatthew G. Knepley   PetscErrorCode ierr;
71232389894bSMatthew G. Knepley 
71242389894bSMatthew G. Knepley   PetscFunctionBegin;
71252389894bSMatthew G. Knepley   ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr);
71262389894bSMatthew G. Knepley   ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
71272389894bSMatthew G. Knepley   ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr);
71282389894bSMatthew G. Knepley   ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr);
7129854ce69bSBarry Smith   ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr);
71302389894bSMatthew G. Knepley   ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr);
71312389894bSMatthew G. Knepley   if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);}
71322389894bSMatthew G. Knepley   ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr);
71332389894bSMatthew G. Knepley   for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1;
71342389894bSMatthew G. Knepley   switch (cellRefiner) {
71356c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_1D:
71366c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_2D:
71376c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_SIMPLEX_2D:
71386c0c04f5SMatthew G. Knepley   case REFINER_HEX_2D:
71396c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_HEX_2D:
71406c0c04f5SMatthew G. Knepley   case REFINER_SIMPLEX_3D:
71416c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_SIMPLEX_3D:
71426c0c04f5SMatthew G. Knepley   case REFINER_HEX_3D:
71436c0c04f5SMatthew G. Knepley   case REFINER_HYBRID_HEX_3D:
71442389894bSMatthew G. Knepley     for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart);
71452389894bSMatthew G. Knepley     break;
71462389894bSMatthew G. Knepley   default:
71472389894bSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner);
71482389894bSMatthew G. Knepley   }
71492389894bSMatthew G. Knepley   ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr);
71502389894bSMatthew G. Knepley   ierr = PetscFree(depthSize);CHKERRQ(ierr);
71512389894bSMatthew G. Knepley   PetscFunctionReturn(0);
71522389894bSMatthew G. Knepley }
71532389894bSMatthew G. Knepley 
71540e2b6761SMatthew G. Knepley /*@
71550e2b6761SMatthew G. Knepley   DMPlexSetRefinementUniform - Set the flag for uniform refinement
71560e2b6761SMatthew G. Knepley 
71570e2b6761SMatthew G. Knepley   Input Parameters:
71580e2b6761SMatthew G. Knepley + dm - The DM
71590e2b6761SMatthew G. Knepley - refinementUniform - The flag for uniform refinement
71600e2b6761SMatthew G. Knepley 
71610e2b6761SMatthew G. Knepley   Level: developer
71620e2b6761SMatthew G. Knepley 
71630e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
71640e2b6761SMatthew G. Knepley @*/
716575d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform)
716675d3a19aSMatthew G. Knepley {
716775d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
716875d3a19aSMatthew G. Knepley 
716975d3a19aSMatthew G. Knepley   PetscFunctionBegin;
717075d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
717175d3a19aSMatthew G. Knepley   mesh->refinementUniform = refinementUniform;
717275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
717375d3a19aSMatthew G. Knepley }
717475d3a19aSMatthew G. Knepley 
71750e2b6761SMatthew G. Knepley /*@
71760e2b6761SMatthew G. Knepley   DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement
71770e2b6761SMatthew G. Knepley 
71780e2b6761SMatthew G. Knepley   Input Parameter:
71790e2b6761SMatthew G. Knepley . dm - The DM
71800e2b6761SMatthew G. Knepley 
71810e2b6761SMatthew G. Knepley   Output Parameter:
71820e2b6761SMatthew G. Knepley . refinementUniform - The flag for uniform refinement
71830e2b6761SMatthew G. Knepley 
71840e2b6761SMatthew G. Knepley   Level: developer
71850e2b6761SMatthew G. Knepley 
71860e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
71870e2b6761SMatthew G. Knepley @*/
718875d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform)
718975d3a19aSMatthew G. Knepley {
719075d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
719175d3a19aSMatthew G. Knepley 
719275d3a19aSMatthew G. Knepley   PetscFunctionBegin;
719375d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
719475d3a19aSMatthew G. Knepley   PetscValidPointer(refinementUniform,  2);
719575d3a19aSMatthew G. Knepley   *refinementUniform = mesh->refinementUniform;
719675d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
719775d3a19aSMatthew G. Knepley }
719875d3a19aSMatthew G. Knepley 
71990e2b6761SMatthew G. Knepley /*@
72000e2b6761SMatthew G. Knepley   DMPlexSetRefinementLimit - Set the maximum cell volume for refinement
72010e2b6761SMatthew G. Knepley 
72020e2b6761SMatthew G. Knepley   Input Parameters:
72030e2b6761SMatthew G. Knepley + dm - The DM
72040e2b6761SMatthew G. Knepley - refinementLimit - The maximum cell volume in the refined mesh
72050e2b6761SMatthew G. Knepley 
72060e2b6761SMatthew G. Knepley   Level: developer
72070e2b6761SMatthew G. Knepley 
72080e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
72090e2b6761SMatthew G. Knepley @*/
721075d3a19aSMatthew G. Knepley PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit)
721175d3a19aSMatthew G. Knepley {
721275d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
721375d3a19aSMatthew G. Knepley 
721475d3a19aSMatthew G. Knepley   PetscFunctionBegin;
721575d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
721675d3a19aSMatthew G. Knepley   mesh->refinementLimit = refinementLimit;
721775d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
721875d3a19aSMatthew G. Knepley }
721975d3a19aSMatthew G. Knepley 
72200e2b6761SMatthew G. Knepley /*@
72210e2b6761SMatthew G. Knepley   DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement
72220e2b6761SMatthew G. Knepley 
72230e2b6761SMatthew G. Knepley   Input Parameter:
72240e2b6761SMatthew G. Knepley . dm - The DM
72250e2b6761SMatthew G. Knepley 
72260e2b6761SMatthew G. Knepley   Output Parameter:
72270e2b6761SMatthew G. Knepley . refinementLimit - The maximum cell volume in the refined mesh
72280e2b6761SMatthew G. Knepley 
72290e2b6761SMatthew G. Knepley   Level: developer
72300e2b6761SMatthew G. Knepley 
72310e2b6761SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform()
72320e2b6761SMatthew G. Knepley @*/
723375d3a19aSMatthew G. Knepley PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit)
723475d3a19aSMatthew G. Knepley {
723575d3a19aSMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
723675d3a19aSMatthew G. Knepley 
723775d3a19aSMatthew G. Knepley   PetscFunctionBegin;
723875d3a19aSMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
723975d3a19aSMatthew G. Knepley   PetscValidPointer(refinementLimit,  2);
724075d3a19aSMatthew G. Knepley   /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */
724175d3a19aSMatthew G. Knepley   *refinementLimit = mesh->refinementLimit;
724275d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
724375d3a19aSMatthew G. Knepley }
724475d3a19aSMatthew G. Knepley 
7245b28003e6SMatthew G. Knepley /*@
7246b28003e6SMatthew G. Knepley   DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement
7247b28003e6SMatthew G. Knepley 
7248b28003e6SMatthew G. Knepley   Input Parameters:
7249b28003e6SMatthew G. Knepley + dm - The DM
7250b28003e6SMatthew G. Knepley - refinementFunc - Function giving the maximum cell volume in the refined mesh
7251b28003e6SMatthew G. Knepley 
7252b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
7253b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
7254b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
7255b28003e6SMatthew G. Knepley 
7256b28003e6SMatthew G. Knepley   Level: developer
7257b28003e6SMatthew G. Knepley 
7258b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
7259b28003e6SMatthew G. Knepley @*/
7260b28003e6SMatthew G. Knepley PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *))
7261b28003e6SMatthew G. Knepley {
7262b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
7263b28003e6SMatthew G. Knepley 
7264b28003e6SMatthew G. Knepley   PetscFunctionBegin;
7265b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7266b28003e6SMatthew G. Knepley   mesh->refinementFunc = refinementFunc;
7267b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
7268b28003e6SMatthew G. Knepley }
7269b28003e6SMatthew G. Knepley 
7270b28003e6SMatthew G. Knepley /*@
7271b28003e6SMatthew G. Knepley   DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement
7272b28003e6SMatthew G. Knepley 
7273b28003e6SMatthew G. Knepley   Input Parameter:
7274b28003e6SMatthew G. Knepley . dm - The DM
7275b28003e6SMatthew G. Knepley 
7276b28003e6SMatthew G. Knepley   Output Parameter:
7277b28003e6SMatthew G. Knepley . refinementFunc - Function giving the maximum cell volume in the refined mesh
7278b28003e6SMatthew G. Knepley 
7279b28003e6SMatthew G. Knepley   Note: The calling sequence is refinementFunc(coords, limit)
7280b28003e6SMatthew G. Knepley $ coords - Coordinates of the current point, usually a cell centroid
7281b28003e6SMatthew G. Knepley $ limit  - The maximum cell volume for a cell containing this point
7282b28003e6SMatthew G. Knepley 
7283b28003e6SMatthew G. Knepley   Level: developer
7284b28003e6SMatthew G. Knepley 
7285b28003e6SMatthew G. Knepley .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit()
7286b28003e6SMatthew G. Knepley @*/
7287b28003e6SMatthew G. Knepley PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *))
7288b28003e6SMatthew G. Knepley {
7289b28003e6SMatthew G. Knepley   DM_Plex *mesh = (DM_Plex*) dm->data;
7290b28003e6SMatthew G. Knepley 
7291b28003e6SMatthew G. Knepley   PetscFunctionBegin;
7292b28003e6SMatthew G. Knepley   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
7293b28003e6SMatthew G. Knepley   PetscValidPointer(refinementFunc,  2);
7294b28003e6SMatthew G. Knepley   *refinementFunc = mesh->refinementFunc;
7295b28003e6SMatthew G. Knepley   PetscFunctionReturn(0);
7296b28003e6SMatthew G. Knepley }
7297b28003e6SMatthew G. Knepley 
7298509c9b89SMatthew G. Knepley PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner)
729975d3a19aSMatthew G. Knepley {
73000f9259d6SMatthew G. Knepley   PetscInt       dim, cStart, cEnd, coneSize, cMax, fMax;
730175d3a19aSMatthew G. Knepley   PetscErrorCode ierr;
730275d3a19aSMatthew G. Knepley 
730375d3a19aSMatthew G. Knepley   PetscFunctionBegin;
7304c73cfb54SMatthew G. Knepley   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
73053478d7aaSMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
73069b1a0e7fSLawrence Mitchell   if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);}
730775d3a19aSMatthew G. Knepley   ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr);
730889b38ed4SMatthew G. Knepley   ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr);
730975d3a19aSMatthew G. Knepley   switch (dim) {
73100314a74cSLawrence Mitchell   case 1:
73110314a74cSLawrence Mitchell     switch (coneSize) {
73120314a74cSLawrence Mitchell     case 2:
73130314a74cSLawrence Mitchell       *cellRefiner = REFINER_SIMPLEX_1D;
73140314a74cSLawrence Mitchell       break;
73150314a74cSLawrence Mitchell     default:
73160314a74cSLawrence Mitchell       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
73170314a74cSLawrence Mitchell     }
73180314a74cSLawrence Mitchell     break;
731975d3a19aSMatthew G. Knepley   case 2:
732075d3a19aSMatthew G. Knepley     switch (coneSize) {
732175d3a19aSMatthew G. Knepley     case 3:
73229b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D;
73239b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_2D;
732475d3a19aSMatthew G. Knepley       break;
732575d3a19aSMatthew G. Knepley     case 4:
732689b38ed4SMatthew G. Knepley       if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D;
73279b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_2D;
732875d3a19aSMatthew G. Knepley       break;
732975d3a19aSMatthew G. Knepley     default:
733075d3a19aSMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
733175d3a19aSMatthew G. Knepley     }
733275d3a19aSMatthew G. Knepley     break;
7333b5da9499SMatthew G. Knepley   case 3:
7334b5da9499SMatthew G. Knepley     switch (coneSize) {
7335b5da9499SMatthew G. Knepley     case 4:
73369b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D;
73379b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_SIMPLEX_3D;
7338b5da9499SMatthew G. Knepley       break;
73392eabf88fSMatthew G. Knepley     case 6:
73409b1a0e7fSLawrence Mitchell       if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D;
73419b1a0e7fSLawrence Mitchell       else *cellRefiner = REFINER_HEX_3D;
73422eabf88fSMatthew G. Knepley       break;
7343b5da9499SMatthew G. Knepley     default:
7344b5da9499SMatthew G. Knepley       SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim);
7345b5da9499SMatthew G. Knepley     }
7346b5da9499SMatthew G. Knepley     break;
734775d3a19aSMatthew G. Knepley   default:
734875d3a19aSMatthew G. Knepley     SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim);
734975d3a19aSMatthew G. Knepley   }
735075d3a19aSMatthew G. Knepley   PetscFunctionReturn(0);
735175d3a19aSMatthew G. Knepley }
7352